bool BitmapText::StringWillUseAlternate( const RString& sText, const RString& sAlternateText ) const { ASSERT( m_pFont != NULL ); // Can't use the alternate if there isn't one. if( !sAlternateText.size() ) return false; // False if the alternate isn't needed. if( m_pFont->FontCompleteForString(RStringToWstring(sText)) ) return false; // False if the alternate is also incomplete. if( !m_pFont->FontCompleteForString(RStringToWstring(sAlternateText)) ) return false; return true; }
void ScreenTextEntry::BeginScreen() { m_sAnswer = RStringToWstring( g_sInitialAnswer ); ScreenWithMenuElements::BeginScreen(); m_textQuestion.SetText( g_sQuestion ); SET_XY( m_textQuestion ); SET_XY( m_textAnswer ); UpdateAnswerText(); }
void ScreenTextEntry::TryAppendToAnswer( RString s ) { { wstring sNewAnswer = m_sAnswer+RStringToWstring(s); if( (int)sNewAnswer.length() > g_iMaxInputLength ) { SCREENMAN->PlayInvalidSound(); return; } } if( g_pValidateAppend && !g_pValidateAppend( WStringToRString(m_sAnswer), s ) ) { SCREENMAN->PlayInvalidSound(); return; } wstring sNewAnswer = m_sAnswer+RStringToWstring(s); m_sAnswer = sNewAnswer; m_sndType.Play(); UpdateAnswerText(); }
void GraphicsWindow::Initialize( bool bD3D ) { // A few things need to be handled differently for D3D. g_bD3D = bD3D; AppInstance inst; do { const wstring wsClassName = RStringToWstring( g_sClassName ); WNDCLASSW WindowClassW = { CS_OWNDC | CS_BYTEALIGNCLIENT, GraphicsWindow_WndProc, 0, /* cbClsExtra */ 0, /* cbWndExtra */ inst, /* hInstance */ NULL, /* set icon later */ LoadCursor( NULL, IDC_ARROW ), /* default cursor */ NULL, /* hbrBackground */ NULL, /* lpszMenuName */ wsClassName.c_str() /* lpszClassName */ }; m_bWideWindowClass = true; if( RegisterClassW( &WindowClassW ) ) break; WNDCLASS WindowClassA = { CS_OWNDC | CS_BYTEALIGNCLIENT, GraphicsWindow_WndProc, 0, /* cbClsExtra */ 0, /* cbWndExtra */ inst, /* hInstance */ NULL, /* set icon later */ LoadCursor( NULL, IDC_ARROW ), /* default cursor */ NULL, /* hbrBackground */ NULL, /* lpszMenuName */ g_sClassName /* lpszClassName */ }; m_bWideWindowClass = false; if( !RegisterClassA( &WindowClassA ) ) RageException::Throw( "%s", werr_ssprintf( GetLastError(), "RegisterClass" ).c_str() ); } while(0); g_iQueryCancelAutoPlayMessage = RegisterWindowMessage( "QueryCancelAutoPlay" ); }
void Font::LoadFontPageSettings( FontPageSettings &cfg, IniFile &ini, const RString &sTexturePath, const RString &sPageName, RString sChars ) { cfg.m_sTexturePath = sTexturePath; /* If we have any characters to map, add them. */ for( unsigned n=0; n<sChars.size(); n++ ) { char c = sChars[n]; cfg.CharToGlyphNo[c] = n; } int iNumFramesWide, iNumFramesHigh; RageTexture::GetFrameDimensionsFromFileName( sTexturePath, &iNumFramesWide, &iNumFramesHigh ); int iNumFrames = iNumFramesWide * iNumFramesHigh; ini.RenameKey("Char Widths", "main"); // LOG->Trace("Loading font page '%s' settings from page name '%s'", // TexturePath.c_str(), sPageName.c_str()); ini.GetValue( sPageName, "DrawExtraPixelsLeft", cfg.m_iDrawExtraPixelsLeft ); ini.GetValue( sPageName, "DrawExtraPixelsRight", cfg.m_iDrawExtraPixelsRight ); ini.GetValue( sPageName, "AddToAllWidths", cfg.m_iAddToAllWidths ); ini.GetValue( sPageName, "ScaleAllWidthsBy", cfg.m_fScaleAllWidthsBy ); ini.GetValue( sPageName, "LineSpacing", cfg.m_iLineSpacing ); ini.GetValue( sPageName, "Top", cfg.m_iTop ); ini.GetValue( sPageName, "Baseline", cfg.m_iBaseline ); ini.GetValue( sPageName, "DefaultWidth", cfg.m_iDefaultWidth ); ini.GetValue( sPageName, "AdvanceExtraPixels", cfg.m_iAdvanceExtraPixels ); ini.GetValue( sPageName, "TextureHints", cfg.m_sTextureHints ); /* Iterate over all keys. */ const XNode* pNode = ini.GetChild( sPageName ); if( pNode ) { FOREACH_CONST_Attr( pNode, pAttr ) { RString sName = pAttr->first; const XNodeValue *pValue = pAttr->second; sName.MakeUpper(); /* If val is an integer, it's a width, eg. "10=27". */ if( IsAnInt(sName) ) { cfg.m_mapGlyphWidths[atoi(sName)] = pValue->GetValue<int>(); continue; } /* "map codepoint=frame" maps a char to a frame. */ if( sName.substr(0, 4) == "MAP " ) { /* * map CODEPOINT=frame. CODEPOINT can be * 1. U+hexval * 2. an alias ("oq") * 3. a character in quotes ("X") * * map 1=2 is the same as * range unicode #1-1=2 */ RString sCodepoint = sName.substr(4); /* "CODEPOINT" */ wchar_t c; if( sCodepoint.substr(0, 2) == "U+" && IsHexVal(sCodepoint.substr(2)) ) sscanf( sCodepoint.substr(2).c_str(), "%x", &c ); else if( sCodepoint.size() > 0 && utf8_get_char_len(sCodepoint[0]) == int(sCodepoint.size()) ) { c = utf8_get_char( sCodepoint.c_str() ); if(c == wchar_t(-1)) LOG->Warn("Font definition '%s' has an invalid value '%s'.", ini.GetPath().c_str(), sName.c_str() ); } else if( !FontCharAliases::GetChar(sCodepoint, c) ) { LOG->Warn("Font definition '%s' has an invalid value '%s'.", ini.GetPath().c_str(), sName.c_str() ); continue; } cfg.CharToGlyphNo[c] = pValue->GetValue<int>(); continue; } if( sName.substr(0, 6) == "RANGE " ) { /* * range CODESET=first_frame or * range CODESET #start-end=first_frame * eg * range CP1252=0 (default for 256-frame fonts) * range ASCII=0 (default for 128-frame fonts) * * (Start and end are in hex.) * * Map two high-bit portions of ISO-8859- to one font: * range ISO-8859-2 #80-FF=0 * range ISO-8859-3 #80-FF=128 * * Map hiragana to 0-84: * range Unicode #3041-3094=0 */ vector<RString> asMatches; static Regex parse("^RANGE ([A-Z0-9\\-]+)( ?#([0-9A-F]+)-([0-9A-F]+))?$"); bool bMatch = parse.Compare( sName, asMatches ); ASSERT( asMatches.size() == 4 ); /* 4 parens */ if( !bMatch || asMatches[0].empty() ) RageException::Throw( "Font definition \"%s\" has an invalid range \"%s\": parse error.", ini.GetPath().c_str(), sName.c_str() ); /* We must have either 1 match (just the codeset) or 4 (the whole thing). */ int iCount = -1; int iFirst = 0; if( !asMatches[2].empty() ) { sscanf( asMatches[2].c_str(), "%x", &iFirst ); int iLast; sscanf( asMatches[3].c_str(), "%x", &iLast ); if( iLast < iFirst ) RageException::Throw( "Font definition \"%s\" has an invalid range \"%s\": %i < %i.", ini.GetPath().c_str(), sName.c_str(), iLast, iFirst ); iCount = iLast - iFirst + 1; } RString sRet = cfg.MapRange( asMatches[0], iFirst, pValue->GetValue<int>(), iCount ); if( !sRet.empty() ) RageException::Throw( "Font definition \"%s\" has an invalid range \"%s\": %s.", ini.GetPath().c_str(), sName.c_str(), sRet.c_str() ); continue; } if( sName.substr(0, 5) == "LINE " ) { /* line ROW=CHAR1CHAR2CHAR3CHAR4 * eg. * line 0=ABCDEFGH * * This lets us assign characters very compactly and readably. */ RString sRowStr = sName.substr(5); TrimLeft( sRowStr ); ASSERT( IsAnInt(sRowStr) ); const int iRow = atoi( sRowStr.c_str() ); const int iFirstFrame = iRow * iNumFramesWide; if( iRow > iNumFramesHigh ) RageException::Throw( "The font definition \"%s\" tries to assign line %i, but the font is only %i characters high.", ini.GetPath().c_str(), iFirstFrame, iNumFramesHigh ); /* Decode the string. */ const wstring wdata( RStringToWstring(pValue->GetValue<RString>()) ); if( int(wdata.size()) > iNumFramesWide ) RageException::Throw( "The font definition \"%s\" assigns %i characters to row %i (\"%ls\"), but the font is only %i characters wide.", ini.GetPath().c_str(), (int)wdata.size(), iRow, wdata.c_str(), iNumFramesWide ); for( unsigned i = 0; i < wdata.size(); ++i ) cfg.CharToGlyphNo[wdata[i]] = iFirstFrame+i; } } }
void BitmapText::SetTextInternal() { // Break the string into lines. m_wTextLines.clear(); if( m_iWrapWidthPixels == -1 ) { split( RStringToWstring(m_sText), L"\n", m_wTextLines, false ); } else { // Break sText into lines that don't exceed iWrapWidthPixels. (if only // one word fits on the line, it may be larger than iWrapWidthPixels). // This does not work in all languages: /* "...I can add Japanese wrapping, at least. We could handle hyphens * and soft hyphens and pretty easily, too." -glenn */ // TODO: Move this wrapping logic into Font. vector<RString> asLines; split( m_sText, "\n", asLines, false ); for( unsigned line = 0; line < asLines.size(); ++line ) { vector<RString> asWords; split( asLines[line], " ", asWords ); RString sCurLine; int iCurLineWidth = 0; for( unsigned i=0; i<asWords.size(); i++ ) { const RString &sWord = asWords[i]; int iWidthWord = m_pFont->GetLineWidthInSourcePixels( RStringToWstring(sWord) ); if( sCurLine.empty() ) { sCurLine = sWord; iCurLineWidth = iWidthWord; continue; } RString sToAdd = " " + sWord; int iWidthToAdd = m_pFont->GetLineWidthInSourcePixels(L" ") + iWidthWord; if( iCurLineWidth + iWidthToAdd <= m_iWrapWidthPixels ) // will fit on current line { sCurLine += sToAdd; iCurLineWidth += iWidthToAdd; } else { m_wTextLines.push_back( RStringToWstring(sCurLine) ); sCurLine = sWord; iCurLineWidth = iWidthWord; } } m_wTextLines.push_back( RStringToWstring(sCurLine) ); } } BuildChars(); UpdateBaseZoom(); }
void ColorBitmapText::SimpleAddLine( const RString &sAddition, const int iWidthPixels) { m_wTextLines.push_back( RStringToWstring( sAddition ) ); m_iLineWidths.push_back( iWidthPixels ); }
RString ConvertUTF8ToACP( const RString &s ) { return ConvertWstringToCodepage( RStringToWstring(s), CP_ACP ); }