Skip to content

Commit c9e730d

Browse files
authored
fix(font): Handle malformed fonts without crashing the game (#1826)
1 parent 038f51f commit c9e730d

File tree

22 files changed

+111
-112
lines changed

22 files changed

+111
-112
lines changed

Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1170,6 +1170,8 @@ Render2DSentenceClass::Build_Sentence (const WCHAR *text, int *hkX, int *hkY)
11701170
return ;
11711171
}
11721172

1173+
if (Font == NULL)
1174+
return;
11731175

11741176
if(Centered && (WrapWidth > 0 || wcschr(text,L'\n')))
11751177
Build_Sentence_Centered(text, hkX, hkY);
@@ -1504,7 +1506,7 @@ FontCharsClass::Update_Current_Buffer (int char_width)
15041506
// Create_GDI_Font
15051507
//
15061508
////////////////////////////////////////////////////////////////////////////////////
1507-
void
1509+
bool
15081510
FontCharsClass::Create_GDI_Font (const char *font_name)
15091511
{
15101512
HDC screen_dc = ::GetDC ((HWND)WW3D::Get_Window());
@@ -1598,6 +1600,8 @@ FontCharsClass::Create_GDI_Font (const char *font_name)
15981600
if (doingGenerals) {
15991601
CharOverhang = 0;
16001602
}
1603+
1604+
return GDIFont != NULL && GDIBitmap != NULL;
16011605
}
16021606

16031607

@@ -1646,7 +1650,7 @@ FontCharsClass::Free_GDI_Font (void)
16461650
// Initialize_GDI_Font
16471651
//
16481652
////////////////////////////////////////////////////////////////////////////////////
1649-
void
1653+
bool
16501654
FontCharsClass::Initialize_GDI_Font (const char *font_name, int point_size, bool is_bold)
16511655
{
16521656
//
@@ -1664,8 +1668,7 @@ FontCharsClass::Initialize_GDI_Font (const char *font_name, int point_size, bool
16641668
//
16651669
// Create the actual font object
16661670
//
1667-
Create_GDI_Font (font_name);
1668-
return ;
1671+
return Create_GDI_Font (font_name);
16691672
}
16701673

16711674

Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class FontCharsClass : public W3DMPO, public RefCountClass
8282
FontCharsClass *AlternateUnicodeFont;
8383

8484

85-
void Initialize_GDI_Font( const char *font_name, int point_size, bool is_bold );
85+
bool Initialize_GDI_Font( const char *font_name, int point_size, bool is_bold );
8686
bool Is_Font( const char *font_name, int point_size, bool is_bold );
8787
const char * Get_Name( void ) { return Name; }
8888

@@ -99,7 +99,7 @@ class FontCharsClass : public W3DMPO, public RefCountClass
9999
//
100100
// Private methods
101101
//
102-
void Create_GDI_Font( const char *font_name );
102+
bool Create_GDI_Font( const char *font_name );
103103
void Free_GDI_Font( void );
104104
const FontCharsClassCharDataStruct * Store_GDI_Char( WCHAR ch );
105105
void Update_Current_Buffer( int char_width );

Generals/Code/GameEngine/Source/GameClient/Credits.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ void CreditsManager::load(void )
166166
TheGlobalLanguageData->adjustFontSize(TheGlobalLanguageData->m_creditsNormalFont.size),
167167
TheGlobalLanguageData->m_creditsNormalFont.bold);
168168

169-
m_normalFontHeight = font->height;
169+
m_normalFontHeight = font ? font->height : 0;
170170
}
171171

172172
void CreditsManager::reset( void )

Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/IMECandidate.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -164,14 +164,14 @@ void IMECandidateTextAreaDraw( GameWindow *window, WinInstanceData *instData )
164164
return;
165165
}
166166

167-
GameFont *font = window->winGetFont() ;
168-
Int height;
167+
GameFont *font = window->winGetFont();
169168

170169
// set the font
171170
Dstring->setFont( font );
172171

173-
// cacl line height
174-
height = font->height + IMECandidateWindowLineSpacing;
172+
// calculate line height
173+
Int fontHeight = font ? font->height : 0;
174+
Int height = fontHeight + IMECandidateWindowLineSpacing;
175175

176176
// set the clip region
177177
Dstring->setClipRegion( &textRegion );

Generals/Code/GameEngine/Source/GameClient/GUI/GameFont.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,13 @@ void FontLibrary::reset( void )
178178
//-------------------------------------------------------------------------------------------------
179179
GameFont *FontLibrary::getFont( AsciiString name, Int pointSize, Bool bold )
180180
{
181+
// sanity check the size - anything over 100 is probably wrong. -MW
182+
// TheSuperHackers @fix Now also no longer creates fonts with zero size.
183+
if (pointSize < 1 || pointSize > 100)
184+
{
185+
return NULL;
186+
}
187+
181188
GameFont *font;
182189

183190
// search for font in list

Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowGlobal.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,9 @@ void GameWindowManager::winGetTextSize( GameFont *font, UnicodeString text,
185185
Int GameWindowManager::winFontHeight( GameFont *font )
186186
{
187187

188+
if (font == NULL)
189+
return 0;
190+
188191
return font->height;
189192

190193
}

Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -618,12 +618,9 @@ static Bool parseFont( const char *token, WinInstanceData *instData,
618618

619619
if( TheFontLibrary )
620620
{
621-
GameFont *font;
622-
623-
font = TheFontLibrary->getFont( AsciiString(fontName), fontSize, fontBold );
621+
GameFont *font = TheFontLibrary->getFont( AsciiString(fontName), fontSize, fontBold );
624622
if( font )
625623
instData->m_font = font;
626-
627624
}
628625

629626
return TRUE;

Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3618,8 +3618,10 @@ void InGameUI::postDraw( void )
36183618
m_uiMessages[ i ].displayString->draw( x, y, m_uiMessages[ i ].color, dropColor );
36193619

36203620
// increment text spot to next location
3621-
GameFont *font = m_uiMessages[ i ].displayString->getFont();
3622-
y += font->height;
3621+
if (GameFont *font = m_uiMessages[ i ].displayString->getFont())
3622+
{
3623+
y += font->height;
3624+
}
36233625

36243626
}
36253627

Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp

Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -73,55 +73,32 @@
7373
//=============================================================================
7474
Bool W3DFontLibrary::loadFontData( GameFont *font )
7575
{
76-
FontCharsClass *fontChar;
77-
7876
// sanity
7977
if( font == NULL )
8078
return FALSE;
8179

82-
if ((UnsignedInt)font->pointSize > 100) //sanity check the size - anything over 100 is probably wrong. -MW
83-
fontChar = NULL;
84-
else
85-
{ // get the font data from the asset manager
86-
fontChar = WW3DAssetManager::
87-
Get_Instance()->Get_FontChars( font->nameString.str(), font->pointSize,
88-
font->bold ? true : false );
89-
}
80+
const char* name = font->nameString.str();
81+
const Int size = font->pointSize;
82+
const Bool bold = font->bold;
83+
84+
// get the font data from the asset manager
85+
FontCharsClass *fontChar = WW3DAssetManager::Get_Instance()->Get_FontChars( name, size, bold );
9086

9187
if( fontChar == NULL )
9288
{
93-
94-
DEBUG_LOG(( "W3D load font: unable to find font '%s' from asset manager",
95-
font->nameString.str() ));
96-
DEBUG_ASSERTCRASH(fontChar, ("Missing or Corrupted Font. Pleas see log for details"));
89+
DEBUG_CRASH(( "Unable to find font '%s' in Asset Manager", name ));
9790
return FALSE;
98-
9991
}
10092

10193
// assign font data
10294
font->fontData = fontChar;
10395
font->height = fontChar->Get_Char_Height();
10496

105-
FontCharsClass *unicodeFontChar = NULL;
97+
// load Unicode of same point size
98+
name = TheGlobalLanguageData ? TheGlobalLanguageData->m_unicodeFontName.str() : "Arial Unicode MS";
99+
fontChar->AlternateUnicodeFont = WW3DAssetManager::Get_Instance()->Get_FontChars( name, size, bold );
106100

107-
// load unicode of same point size
108-
if(TheGlobalLanguageData)
109-
unicodeFontChar = WW3DAssetManager::
110-
Get_Instance()->Get_FontChars( TheGlobalLanguageData->m_unicodeFontName.str(), font->pointSize,
111-
font->bold ? true : false );
112-
else
113-
unicodeFontChar = WW3DAssetManager::
114-
Get_Instance()->Get_FontChars( "Arial Unicode MS", font->pointSize,
115-
font->bold ? true : false );
116-
117-
if ( unicodeFontChar )
118-
{
119-
fontChar->AlternateUnicodeFont = unicodeFontChar;
120-
}
121-
122-
// all done and loaded
123101
return TRUE;
124-
125102
}
126103

127104
// W3DFontLibrary::releaseFontData ============================================

Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameWindow.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -520,11 +520,14 @@ void W3DGameWindow::winDrawBorder( void )
520520
}
521521

522522
// W3DGameWindow::winSetFont ==================================================
523-
/** Set the font for a widow */
523+
/** Set the font for a window */
524524
//=============================================================================
525525
void W3DGameWindow::winSetFont( GameFont *font )
526526
{
527527

528+
if (font == NULL)
529+
return;
530+
528531
// extending functionality
529532
GameWindow::winSetFont( font );
530533

0 commit comments

Comments
 (0)