diff --git a/Core/GameEngine/Source/GameClient/GUI/GameFont.cpp b/Core/GameEngine/Source/GameClient/GUI/GameFont.cpp index e8dbc96bb4f..15ac9115628 100644 --- a/Core/GameEngine/Source/GameClient/GUI/GameFont.cpp +++ b/Core/GameEngine/Source/GameClient/GUI/GameFont.cpp @@ -178,11 +178,17 @@ void FontLibrary::reset() //------------------------------------------------------------------------------------------------- GameFont *FontLibrary::getFont( AsciiString name, Int pointSize, Bool bold ) { - // TheSuperHackers @fix No longer creates fonts with zero size. And allows fonts with size larger than 100. + // TheSuperHackers @fix No longer creates fonts with zero size and clamps oversized fonts. + // The upper bound caps glyph buffer memory when a resolution-scaled point size gets very large. + enum { FONT_POINT_SIZE_MAX = 512 }; if (pointSize < 1) { return nullptr; } + if (pointSize > FONT_POINT_SIZE_MAX) + { + pointSize = FONT_POINT_SIZE_MAX; + } GameFont *font; diff --git a/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp b/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp index 5fe9bf9a01a..29d1a22a82d 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp +++ b/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.cpp @@ -1188,7 +1188,7 @@ FontCharsClass::FontCharsClass () : FontCharsClass::~FontCharsClass () { while ( BufferList.Count() ) { - delete BufferList[0]; + delete [] BufferList[0].Buffer; BufferList.Delete(0); } @@ -1336,7 +1336,7 @@ FontCharsClass::Store_GDI_Char (WCHAR ch) // Get a pointer to the surface that this character should use // Update_Current_Buffer( char_size.cx ); - uint16* curr_buffer_p = BufferList[BufferList.Count () - 1]->Buffer; + uint16* curr_buffer_p = BufferList[BufferList.Count () - 1].Buffer; curr_buffer_p += CurrPixelOffset; // @@ -1410,7 +1410,7 @@ FontCharsClass::Store_GDI_Char (WCHAR ch) FontCharsClassCharDataStruct *char_data = W3DNEW FontCharsClassCharDataStruct; char_data->Value = ch; char_data->Width = char_size.cx; - char_data->Buffer = BufferList[BufferList.Count () - 1]->Buffer + CurrPixelOffset; + char_data->Buffer = BufferList[BufferList.Count () - 1].Buffer + CurrPixelOffset; // // Insert this character into our array @@ -1441,6 +1441,8 @@ FontCharsClass::Store_GDI_Char (WCHAR ch) void FontCharsClass::Update_Current_Buffer (int char_width) { + const int char_len = char_width * CharHeight; + // // Check to see if we need to allocate a new buffer // @@ -1450,7 +1452,7 @@ FontCharsClass::Update_Current_Buffer (int char_width) // // Would we extend past this buffer? // - if ( (CurrPixelOffset + (char_width * CharHeight)) > CHAR_BUFFER_LEN ) { + if ( (CurrPixelOffset + char_len) > BufferList[BufferList.Count () - 1].Length ) { needs_new_buffer = true; } } @@ -1460,8 +1462,9 @@ FontCharsClass::Update_Current_Buffer (int char_width) // if (needs_new_buffer) { - FontCharsBuffer* new_buffer = W3DNEW FontCharsBuffer; - BufferList.Add( new_buffer ); + // TheSuperHackers @fix arcticdolphin 07/09/2026 Length may exceed CHAR_BUFFER_LEN to fit this glyph. + const int length = max( (int)CHAR_BUFFER_LEN, char_len ); + BufferList.Add( FontCharsBuffer( length, W3DNEWARRAY uint16[length] ) ); CurrPixelOffset = 0; } } diff --git a/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.h b/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.h index 15426c1e950..a6c19625cfb 100644 --- a/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.h +++ b/Core/Libraries/Source/WWVegas/WW3D2/render2dsentence.h @@ -64,9 +64,15 @@ enum { CHAR_BUFFER_LEN = 32768 }; class FontCharsBuffer { - W3DMPO_CODE(FontCharsBuffer) public: - uint16 Buffer[CHAR_BUFFER_LEN]; + FontCharsBuffer() : Length( 0 ), Buffer( nullptr ) {} + FontCharsBuffer( int length, uint16 *buffer ) : Length( length ), Buffer( buffer ) {} + + bool operator== (const FontCharsBuffer &src) const { return Length == src.Length && Buffer == src.Buffer; } + bool operator!= (const FontCharsBuffer &src) const { return !(*this == src); } + + int Length; + uint16 * Buffer; }; @@ -112,7 +118,7 @@ class FontCharsClass : public RefCountClass // Private member data // StringClass Name; - DynamicVectorClass BufferList; + DynamicVectorClass BufferList; int CurrPixelOffset; int CharHeight; int CharAscent;