Пример #1
0
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();
}
Пример #4
0
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" );
}
Пример #5
0
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;
			}
		}
	}
Пример #6
0
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 );
}
Пример #8
0
RString ConvertUTF8ToACP( const RString &s )
{
	return ConvertWstringToCodepage( RStringToWstring(s), CP_ACP );
}