From 293e6f278e96e54285cefc38904e589ed812b0fd Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Fri, 7 Nov 2025 20:00:32 +0100 Subject: [PATCH 1/3] fix(font): Prevent possibility of creating invalid fonts with zero size --- .../Source/WWVegas/WW3D2/render2dsentence.cpp | 2 ++ .../GameEngine/Source/GameClient/GUI/GameFont.cpp | 7 +++++++ .../Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp | 13 +++---------- .../GameEngine/Source/GameClient/GUI/GameFont.cpp | 7 +++++++ .../Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp | 13 +++---------- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp b/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp index b10117084cc..e0b5ea9874d 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp @@ -1507,6 +1507,8 @@ FontCharsClass::Update_Current_Buffer (int char_width) void FontCharsClass::Create_GDI_Font (const char *font_name) { + WWASSERT(PointSize > 0); + HDC screen_dc = ::GetDC ((HWND)WW3D::Get_Window()); const char *fontToUseForGenerals = "Arial"; diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GameFont.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GameFont.cpp index b00065aea0d..706ae0ffef1 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GameFont.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GameFont.cpp @@ -178,6 +178,13 @@ void FontLibrary::reset( void ) //------------------------------------------------------------------------------------------------- GameFont *FontLibrary::getFont( AsciiString name, Int pointSize, Bool bold ) { + // sanity check the size - anything over 100 is probably wrong. -MW + // TheSuperHackers @fix Now also no longer creates fonts with zero size. + if (pointSize < 1 || pointSize > 100) + { + return NULL; + } + GameFont *font; // search for font in list diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp index d7dfc1c9687..2877909f24d 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp @@ -73,20 +73,13 @@ //============================================================================= Bool W3DFontLibrary::loadFontData( GameFont *font ) { - FontCharsClass *fontChar; - // sanity if( font == NULL ) return FALSE; - if ((UnsignedInt)font->pointSize > 100) //sanity check the size - anything over 100 is probably wrong. -MW - fontChar = NULL; - else - { // get the font data from the asset manager - fontChar = WW3DAssetManager:: - Get_Instance()->Get_FontChars( font->nameString.str(), font->pointSize, - font->bold ? true : false ); - } + // get the font data from the asset manager + FontCharsClass *fontChar = WW3DAssetManager::Get_Instance()->Get_FontChars( + font->nameString.str(), font->pointSize, font->bold ? true : false ); if( fontChar == NULL ) { diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameFont.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameFont.cpp index cfa42ea27cc..799f7d2776c 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameFont.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameFont.cpp @@ -178,6 +178,13 @@ void FontLibrary::reset( void ) //------------------------------------------------------------------------------------------------- GameFont *FontLibrary::getFont( AsciiString name, Int pointSize, Bool bold ) { + // sanity check the size - anything over 100 is probably wrong. -MW + // TheSuperHackers @fix Now also no longer creates fonts with zero size. + if (pointSize < 1 || pointSize > 100) + { + return NULL; + } + GameFont *font; // search for font in list diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp index 1a72300927c..f6d255d3946 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp @@ -73,20 +73,13 @@ //============================================================================= Bool W3DFontLibrary::loadFontData( GameFont *font ) { - FontCharsClass *fontChar; - // sanity if( font == NULL ) return FALSE; - if ((UnsignedInt)font->pointSize > 100) //sanity check the size - anything over 100 is probably wrong. -MW - fontChar = NULL; - else - { // get the font data from the asset manager - fontChar = WW3DAssetManager:: - Get_Instance()->Get_FontChars( font->nameString.str(), font->pointSize, - font->bold ? true : false ); - } + // get the font data from the asset manager + FontCharsClass *fontChar = WW3DAssetManager::Get_Instance()->Get_FontChars( + font->nameString.str(), font->pointSize, font->bold ? true : false ); if( fontChar == NULL ) { From 21bd422598fca68743775d13a4fe2feffac4aac2 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sat, 8 Nov 2025 19:07:44 +0100 Subject: [PATCH 2/3] Properly handle invalid fonts and do not try to render them --- .../Source/WWVegas/WW3D2/render2dsentence.cpp | 13 +++---- .../Source/WWVegas/WW3D2/render2dsentence.h | 4 +-- .../GameEngine/Source/GameClient/Credits.cpp | 2 +- .../GUI/GUICallbacks/IMECandidate.cpp | 8 ++--- .../GameClient/GUI/GameWindowGlobal.cpp | 3 ++ .../GUI/GameWindowManagerScript.cpp | 5 +-- .../GameEngine/Source/GameClient/InGameUI.cpp | 6 ++-- .../W3DDevice/GameClient/GUI/W3DGameFont.cpp | 34 +++++-------------- .../GameClient/GUI/W3DGameWindow.cpp | 5 ++- .../Source/WWVegas/WW3D2/assetmgr.cpp | 15 +++++--- .../Libraries/Source/WWVegas/WW3D2/assetmgr.h | 10 ++++-- .../GameEngine/Source/GameClient/Credits.cpp | 2 +- .../GUI/GUICallbacks/IMECandidate.cpp | 8 ++--- .../GameClient/GUI/GameWindowGlobal.cpp | 3 ++ .../GUI/GameWindowManagerScript.cpp | 5 +-- .../GameEngine/Source/GameClient/InGameUI.cpp | 6 ++-- .../W3DDevice/GameClient/GUI/W3DGameFont.cpp | 34 +++++-------------- .../GameClient/GUI/W3DGameWindow.cpp | 5 ++- .../Source/WWVegas/WW3D2/assetmgr.cpp | 15 +++++--- .../Libraries/Source/WWVegas/WW3D2/assetmgr.h | 10 ++++-- 20 files changed, 95 insertions(+), 98 deletions(-) diff --git a/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp b/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp index e0b5ea9874d..34a347c50b5 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp @@ -1170,6 +1170,8 @@ Render2DSentenceClass::Build_Sentence (const WCHAR *text, int *hkX, int *hkY) return ; } + if (Font == NULL) + return; if(Centered && (WrapWidth > 0 || wcschr(text,L'\n'))) Build_Sentence_Centered(text, hkX, hkY); @@ -1504,11 +1506,9 @@ FontCharsClass::Update_Current_Buffer (int char_width) // Create_GDI_Font // //////////////////////////////////////////////////////////////////////////////////// -void +bool FontCharsClass::Create_GDI_Font (const char *font_name) { - WWASSERT(PointSize > 0); - HDC screen_dc = ::GetDC ((HWND)WW3D::Get_Window()); const char *fontToUseForGenerals = "Arial"; @@ -1600,6 +1600,8 @@ FontCharsClass::Create_GDI_Font (const char *font_name) if (doingGenerals) { CharOverhang = 0; } + + return GDIFont != NULL && GDIBitmap != NULL; } @@ -1648,7 +1650,7 @@ FontCharsClass::Free_GDI_Font (void) // Initialize_GDI_Font // //////////////////////////////////////////////////////////////////////////////////// -void +bool FontCharsClass::Initialize_GDI_Font (const char *font_name, int point_size, bool is_bold) { // @@ -1666,8 +1668,7 @@ FontCharsClass::Initialize_GDI_Font (const char *font_name, int point_size, bool // // Create the actual font object // - Create_GDI_Font (font_name); - return ; + return Create_GDI_Font (font_name); } diff --git a/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.h b/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.h index 04817e196bc..db8771a66a7 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.h +++ b/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.h @@ -82,7 +82,7 @@ class FontCharsClass : public W3DMPO, public RefCountClass FontCharsClass *AlternateUnicodeFont; - void Initialize_GDI_Font( const char *font_name, int point_size, bool is_bold ); + bool Initialize_GDI_Font( const char *font_name, int point_size, bool is_bold ); bool Is_Font( const char *font_name, int point_size, bool is_bold ); const char * Get_Name( void ) { return Name; } @@ -99,7 +99,7 @@ class FontCharsClass : public W3DMPO, public RefCountClass // // Private methods // - void Create_GDI_Font( const char *font_name ); + bool Create_GDI_Font( const char *font_name ); void Free_GDI_Font( void ); const FontCharsClassCharDataStruct * Store_GDI_Char( WCHAR ch ); void Update_Current_Buffer( int char_width ); diff --git a/Generals/Code/GameEngine/Source/GameClient/Credits.cpp b/Generals/Code/GameEngine/Source/GameClient/Credits.cpp index 6be597df256..9289e313c80 100644 --- a/Generals/Code/GameEngine/Source/GameClient/Credits.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/Credits.cpp @@ -166,7 +166,7 @@ void CreditsManager::load(void ) TheGlobalLanguageData->adjustFontSize(TheGlobalLanguageData->m_creditsNormalFont.size), TheGlobalLanguageData->m_creditsNormalFont.bold); - m_normalFontHeight = font->height; + m_normalFontHeight = font ? font->height : 0; } void CreditsManager::reset( void ) diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/IMECandidate.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/IMECandidate.cpp index 69958c06f16..c55a5c984ff 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/IMECandidate.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/IMECandidate.cpp @@ -164,14 +164,14 @@ void IMECandidateTextAreaDraw( GameWindow *window, WinInstanceData *instData ) return; } - GameFont *font = window->winGetFont() ; - Int height; + GameFont *font = window->winGetFont(); // set the font Dstring->setFont( font ); - // cacl line height - height = font->height + IMECandidateWindowLineSpacing; + // calculate line height + Int fontHeight = font ? font->height : 0; + Int height = fontHeight + IMECandidateWindowLineSpacing; // set the clip region Dstring->setClipRegion( &textRegion ); diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowGlobal.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowGlobal.cpp index dc311d5988e..38202040834 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowGlobal.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowGlobal.cpp @@ -185,6 +185,9 @@ void GameWindowManager::winGetTextSize( GameFont *font, UnicodeString text, Int GameWindowManager::winFontHeight( GameFont *font ) { + if (font == NULL) + return 0; + return font->height; } diff --git a/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp b/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp index dcb40e294b5..f994ee3bd50 100644 --- a/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp @@ -618,12 +618,9 @@ static Bool parseFont( const char *token, WinInstanceData *instData, if( TheFontLibrary ) { - GameFont *font; - - font = TheFontLibrary->getFont( AsciiString(fontName), fontSize, fontBold ); + GameFont *font = TheFontLibrary->getFont( AsciiString(fontName), fontSize, fontBold ); if( font ) instData->m_font = font; - } return TRUE; diff --git a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp index dfbc3be41cd..bd9b5c51aa3 100644 --- a/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/Generals/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -3618,8 +3618,10 @@ void InGameUI::postDraw( void ) m_uiMessages[ i ].displayString->draw( x, y, m_uiMessages[ i ].color, dropColor ); // increment text spot to next location - GameFont *font = m_uiMessages[ i ].displayString->getFont(); - y += font->height; + if (GameFont *font = m_uiMessages[ i ].displayString->getFont()) + { + y += font->height; + } } diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp index 2877909f24d..836a338bcd0 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp @@ -77,44 +77,28 @@ Bool W3DFontLibrary::loadFontData( GameFont *font ) if( font == NULL ) return FALSE; + const char* name = font->nameString.str(); + const Int size = font->pointSize; + const Bool bold = font->bold; + // get the font data from the asset manager - FontCharsClass *fontChar = WW3DAssetManager::Get_Instance()->Get_FontChars( - font->nameString.str(), font->pointSize, font->bold ? true : false ); + FontCharsClass *fontChar = WW3DAssetManager::Get_Instance()->Get_FontChars( name, size, bold ); if( fontChar == NULL ) { - - DEBUG_LOG(( "W3D load font: unable to find font '%s' from asset manager", - font->nameString.str() )); - DEBUG_ASSERTCRASH(fontChar, ("Missing or Corrupted Font. Pleas see log for details")); + DEBUG_CRASH(( "Unable to find font '%s' in Asset Manager", name )); return FALSE; - } // assign font data font->fontData = fontChar; font->height = fontChar->Get_Char_Height(); - FontCharsClass *unicodeFontChar = NULL; - - // load unicode of same point size - if(TheGlobalLanguageData) - unicodeFontChar = WW3DAssetManager:: - Get_Instance()->Get_FontChars( TheGlobalLanguageData->m_unicodeFontName.str(), font->pointSize, - font->bold ? true : false ); - else - unicodeFontChar = WW3DAssetManager:: - Get_Instance()->Get_FontChars( "Arial Unicode MS", font->pointSize, - font->bold ? true : false ); + // load Unicode of same point size + name = TheGlobalLanguageData ? TheGlobalLanguageData->m_unicodeFontName.str() : "Arial Unicode MS"; + fontChar->AlternateUnicodeFont = WW3DAssetManager::Get_Instance()->Get_FontChars( name, size, bold ); - if ( unicodeFontChar ) - { - fontChar->AlternateUnicodeFont = unicodeFontChar; - } - - // all done and loaded return TRUE; - } // W3DFontLibrary::releaseFontData ============================================ diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameWindow.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameWindow.cpp index 3147bad59e0..82222740046 100644 --- a/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameWindow.cpp +++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameWindow.cpp @@ -520,11 +520,14 @@ void W3DGameWindow::winDrawBorder( void ) } // W3DGameWindow::winSetFont ================================================== -/** Set the font for a widow */ +/** Set the font for a window */ //============================================================================= void W3DGameWindow::winSetFont( GameFont *font ) { + if (font == NULL) + return; + // extending functionality GameWindow::winSetFont( font ); diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.cpp b/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.cpp index c5f34471380..d0dbe5124c5 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.cpp +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.cpp @@ -1485,12 +1485,17 @@ FontCharsClass * WW3DAssetManager::Get_FontChars( const char * name, int point_s } } - // If one hasn't been found, create it + // If one hasn't been found, try create it FontCharsClass * font = NEW_REF( FontCharsClass, () ); - font->Initialize_GDI_Font( name, point_size, is_bold ); - font->Add_Ref(); - FontCharsList.Add( font ); // add it to the list - return font; // return it + if (font->Initialize_GDI_Font( name, point_size, is_bold )) + { + font->Add_Ref(); + FontCharsList.Add( font ); + return font; + } + + font->Release_Ref(); + return NULL; } diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h index eeff5cc9cd5..f09a35bcd81 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h @@ -118,7 +118,7 @@ class RenderObjIterator : public AssetIterator ------------------------------------------------------------------------------------- Dec 11, 1997, Asset Manager Brainstorming: - - WW3DAssetManager will be diferentiated from other game data asset managers + - WW3DAssetManager will be differentiated from other game data asset managers (sounds, strings, etc) because they behave differently and serve different purposes @@ -172,6 +172,10 @@ class RenderObjIterator : public AssetIterator the prototype class needs to be able to tell you the class ID. Actually this code only seems to be used by tools such as SView but is needed anyway... + ------------------------------------------------------------------------------------- + TheSuperHackers @fix xezon 08/11/2025 + The Asset Manager will now return null when it cannot create a valid font with the + given inputs. This way the user knows that the requested font is unusable. */ @@ -275,12 +279,12 @@ class WW3DAssetManager /* ** Access to Font3DInstances. (These are not saved, we just use the - ** asset manager as a convienient way to create them.) + ** asset manager as a convenient way to create them.) */ virtual Font3DInstanceClass * Get_Font3DInstance( const char * name); /* - ** Access to FontChars. Used by Render2DSentenceClass + ** Access to FontChars. Used by Render2DSentenceClass. Can return null. */ virtual FontCharsClass * Get_FontChars( const char * name, int point_size, bool is_bold = false ); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/Credits.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/Credits.cpp index b3724c78c34..ec6218e8b28 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/Credits.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/Credits.cpp @@ -166,7 +166,7 @@ void CreditsManager::load(void ) TheGlobalLanguageData->adjustFontSize(TheGlobalLanguageData->m_creditsNormalFont.size), TheGlobalLanguageData->m_creditsNormalFont.bold); - m_normalFontHeight = font->height; + m_normalFontHeight = font ? font->height : 0; } void CreditsManager::reset( void ) diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/IMECandidate.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/IMECandidate.cpp index 2479b482ba7..3cfbe4722ce 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/IMECandidate.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/IMECandidate.cpp @@ -164,14 +164,14 @@ void IMECandidateTextAreaDraw( GameWindow *window, WinInstanceData *instData ) return; } - GameFont *font = window->winGetFont() ; - Int height; + GameFont *font = window->winGetFont(); // set the font Dstring->setFont( font ); - // cacl line height - height = font->height + IMECandidateWindowLineSpacing; + // calculate line height + Int fontHeight = font ? font->height : 0; + Int height = fontHeight + IMECandidateWindowLineSpacing; // set the clip region Dstring->setClipRegion( &textRegion ); diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowGlobal.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowGlobal.cpp index 60319a8d5f7..8125a7c4fb5 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowGlobal.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowGlobal.cpp @@ -185,6 +185,9 @@ void GameWindowManager::winGetTextSize( GameFont *font, UnicodeString text, Int GameWindowManager::winFontHeight( GameFont *font ) { + if (font == NULL) + return 0; + return font->height; } diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp index c7396019d21..2684dfd8324 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GameWindowManagerScript.cpp @@ -619,12 +619,9 @@ static Bool parseFont( const char *token, WinInstanceData *instData, if( TheFontLibrary ) { - GameFont *font; - - font = TheFontLibrary->getFont( AsciiString(fontName), fontSize, fontBold ); + GameFont *font = TheFontLibrary->getFont( AsciiString(fontName), fontSize, fontBold ); if( font ) instData->m_font = font; - } return TRUE; diff --git a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp index aa221089c20..ed8d6e0cc2f 100644 --- a/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp +++ b/GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp @@ -3709,8 +3709,10 @@ void InGameUI::postDraw( void ) m_uiMessages[ i ].displayString->draw( x, y, m_uiMessages[ i ].color, dropColor ); // increment text spot to next location - GameFont *font = m_uiMessages[ i ].displayString->getFont(); - y += font->height; + if (GameFont *font = m_uiMessages[ i ].displayString->getFont()) + { + y += font->height; + } } diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp index f6d255d3946..0352b2301a5 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameFont.cpp @@ -77,44 +77,28 @@ Bool W3DFontLibrary::loadFontData( GameFont *font ) if( font == NULL ) return FALSE; + const char* name = font->nameString.str(); + const Int size = font->pointSize; + const Bool bold = font->bold; + // get the font data from the asset manager - FontCharsClass *fontChar = WW3DAssetManager::Get_Instance()->Get_FontChars( - font->nameString.str(), font->pointSize, font->bold ? true : false ); + FontCharsClass *fontChar = WW3DAssetManager::Get_Instance()->Get_FontChars( name, size, bold ); if( fontChar == NULL ) { - - DEBUG_LOG(( "W3D load font: unable to find font '%s' from asset manager", - font->nameString.str() )); - DEBUG_ASSERTCRASH(fontChar, ("Missing or Corrupted Font. Pleas see log for details")); + DEBUG_CRASH(( "Unable to find font '%s' in Asset Manager", name )); return FALSE; - } // assign font data font->fontData = fontChar; font->height = fontChar->Get_Char_Height(); - FontCharsClass *unicodeFontChar = NULL; - - // load unicode of same point size - if(TheGlobalLanguageData) - unicodeFontChar = WW3DAssetManager:: - Get_Instance()->Get_FontChars( TheGlobalLanguageData->m_unicodeFontName.str(), font->pointSize, - font->bold ? true : false ); - else - unicodeFontChar = WW3DAssetManager:: - Get_Instance()->Get_FontChars( "Arial Unicode MS", font->pointSize, - font->bold ? true : false ); + // load Unicode of same point size + name = TheGlobalLanguageData ? TheGlobalLanguageData->m_unicodeFontName.str() : "Arial Unicode MS"; + fontChar->AlternateUnicodeFont = WW3DAssetManager::Get_Instance()->Get_FontChars( name, size, bold ); - if ( unicodeFontChar ) - { - fontChar->AlternateUnicodeFont = unicodeFontChar; - } - - // all done and loaded return TRUE; - } // W3DFontLibrary::releaseFontData ============================================ diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameWindow.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameWindow.cpp index 2f512c94b85..385ef028139 100644 --- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameWindow.cpp +++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/GameClient/GUI/W3DGameWindow.cpp @@ -520,11 +520,14 @@ void W3DGameWindow::winDrawBorder( void ) } // W3DGameWindow::winSetFont ================================================== -/** Set the font for a widow */ +/** Set the font for a window */ //============================================================================= void W3DGameWindow::winSetFont( GameFont *font ) { + if (font == NULL) + return; + // extending functionality GameWindow::winSetFont( font ); diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.cpp b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.cpp index bfa7f185817..c7030be4e8c 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.cpp +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.cpp @@ -1462,12 +1462,17 @@ FontCharsClass * WW3DAssetManager::Get_FontChars( const char * name, int point_s } } - // If one hasn't been found, create it + // If one hasn't been found, try create it FontCharsClass * font = NEW_REF( FontCharsClass, () ); - font->Initialize_GDI_Font( name, point_size, is_bold ); - font->Add_Ref(); - FontCharsList.Add( font ); // add it to the list - return font; // return it + if (font->Initialize_GDI_Font( name, point_size, is_bold )) + { + font->Add_Ref(); + FontCharsList.Add( font ); + return font; + } + + font->Release_Ref(); + return NULL; } diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h index 0274a897211..2ec172d07d9 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h @@ -118,7 +118,7 @@ class RenderObjIterator : public AssetIterator ------------------------------------------------------------------------------------- Dec 11, 1997, Asset Manager Brainstorming: - - WW3DAssetManager will be diferentiated from other game data asset managers + - WW3DAssetManager will be differentiated from other game data asset managers (sounds, strings, etc) because they behave differently and serve different purposes @@ -172,6 +172,10 @@ class RenderObjIterator : public AssetIterator the prototype class needs to be able to tell you the class ID. Actually this code only seems to be used by tools such as SView but is needed anyway... + ------------------------------------------------------------------------------------- + TheSuperHackers @fix xezon 08/11/2025 + The Asset Manager will now return null when it cannot create a valid font with the + given inputs. This way the user knows that the requested font is unusable. */ @@ -274,12 +278,12 @@ class WW3DAssetManager /* ** Access to Font3DInstances. (These are not saved, we just use the - ** asset manager as a convienient way to create them.) + ** asset manager as a convenient way to create them.) */ virtual Font3DInstanceClass * Get_Font3DInstance( const char * name); /* - ** Access to FontChars. Used by Render2DSentenceClass + ** Access to FontChars. Used by Render2DSentenceClass. Can return null. */ virtual FontCharsClass * Get_FontChars( const char * name, int point_size, bool is_bold = false ); From ea8cd36f8316df85be3f0c67fd787967b51c5d52 Mon Sep 17 00:00:00 2001 From: xezon <4720891+xezon@users.noreply.github.com> Date: Sat, 8 Nov 2025 19:16:03 +0100 Subject: [PATCH 3/3] Optimize comment --- Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h | 4 ++-- GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h b/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h index f09a35bcd81..c68dd00020d 100644 --- a/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h +++ b/Generals/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h @@ -174,8 +174,8 @@ class RenderObjIterator : public AssetIterator ------------------------------------------------------------------------------------- TheSuperHackers @fix xezon 08/11/2025 - The Asset Manager will now return null when it cannot create a valid font with the - given inputs. This way the user knows that the requested font is unusable. + The Asset Manager will now return null when it cannot find or create a valid font + with the given inputs. This way the user knows that the requested font is unusable. */ diff --git a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h index 2ec172d07d9..82f5b6b763d 100644 --- a/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h +++ b/GeneralsMD/Code/Libraries/Source/WWVegas/WW3D2/assetmgr.h @@ -174,8 +174,8 @@ class RenderObjIterator : public AssetIterator ------------------------------------------------------------------------------------- TheSuperHackers @fix xezon 08/11/2025 - The Asset Manager will now return null when it cannot create a valid font with the - given inputs. This way the user knows that the requested font is unusable. + The Asset Manager will now return null when it cannot find or create a valid font + with the given inputs. This way the user knows that the requested font is unusable. */