From 076dc0c4930586d388ebd883d25246239c75313f Mon Sep 17 00:00:00 2001 From: slipher Date: Sun, 5 Oct 2025 03:44:09 -0500 Subject: [PATCH 1/5] RE_RegisterFont: fix possibly uninitialized pointer faceData might not be valid at the point it hits the warning "RE_RegisterFont: Unable to read font file %s". --- src/engine/renderer/tr_font.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/renderer/tr_font.cpp b/src/engine/renderer/tr_font.cpp index 339aabe634..1a9b2755ee 100644 --- a/src/engine/renderer/tr_font.cpp +++ b/src/engine/renderer/tr_font.cpp @@ -583,7 +583,7 @@ static void RE_FreeFontFile( void *data ) fontInfo_t* RE_RegisterFont( const char *fontName, int pointSize ) { FT_Face face; - void *faceData; + void *faceData = nullptr; int i, len, fontNo; char fileName[ MAX_QPATH ]; char strippedName[ MAX_QPATH ]; From c593352ecf060e787850072a1df450fef965b982 Mon Sep 17 00:00:00 2001 From: slipher Date: Sun, 5 Oct 2025 01:33:56 -0500 Subject: [PATCH 2/5] Remove unused font things RE_Glyph(), fontInfo_t::height, fontInfo_t::glyphScale, a couple macros --- src/engine/RefAPI.h | 1 - src/engine/null/null_renderer.cpp | 7 +------ src/engine/qcommon/q_shared.h | 4 ---- src/engine/renderer/tr_font.cpp | 19 ++----------------- src/engine/renderer/tr_init.cpp | 1 - src/engine/renderer/tr_local.h | 1 - 6 files changed, 3 insertions(+), 30 deletions(-) diff --git a/src/engine/RefAPI.h b/src/engine/RefAPI.h index f42d3ae6c6..8b4bea8992 100644 --- a/src/engine/RefAPI.h +++ b/src/engine/RefAPI.h @@ -77,7 +77,6 @@ struct refexport_t { qhandle_t( *RegisterShader )( const char* name, int flags ); fontInfo_t* ( *RegisterFont )( const char* fontName, int pointSize ); void ( *UnregisterFont )( fontInfo_t* font ); - void ( *Glyph )( fontInfo_t* font, const char* str, glyphInfo_t* glyph ); void ( *GlyphChar )( fontInfo_t* font, int ch, glyphInfo_t* glyph ); void ( *LoadWorld )( const char* name ); diff --git a/src/engine/null/null_renderer.cpp b/src/engine/null/null_renderer.cpp index 6611bd169a..4313dcdf83 100644 --- a/src/engine/null/null_renderer.cpp +++ b/src/engine/null/null_renderer.cpp @@ -54,7 +54,7 @@ fontInfo_t* RE_RegisterFont( const char *, int ) { return nullptr; } -void RE_Glyph( fontInfo_t *, const char *, glyphInfo_t *glyph ) +void RE_GlyphChar( fontInfo_t *, int, glyphInfo_t *glyph ) { glyph->height = 1; glyph->top = 1; @@ -70,10 +70,6 @@ void RE_Glyph( fontInfo_t *, const char *, glyphInfo_t *glyph ) glyph->glyph = 1; glyph->shaderName[0] = '\0'; } -void RE_GlyphChar( fontInfo_t *font, int, glyphInfo_t *glyph ) -{ - RE_Glyph( font, nullptr, glyph ); -} void RE_UnregisterFont( fontInfo_t* ) { } void RE_LoadWorldMap( const char * ) { } void RE_SetWorldVisData( const byte * ) { } @@ -205,7 +201,6 @@ refexport_t *GetRefAPI( int, refimport_t* ) re.RegisterSkin = RE_RegisterSkin; re.RegisterShader = RE_RegisterShader; re.RegisterFont = RE_RegisterFont; - re.Glyph = RE_Glyph; re.GlyphChar = RE_GlyphChar; re.UnregisterFont = RE_UnregisterFont; re.LoadWorld = RE_LoadWorldMap; diff --git a/src/engine/qcommon/q_shared.h b/src/engine/qcommon/q_shared.h index e83252ee48..764650ee05 100644 --- a/src/engine/qcommon/q_shared.h +++ b/src/engine/qcommon/q_shared.h @@ -2156,8 +2156,6 @@ union OpaquePlayerState { #define GLYPH_START 0 #define GLYPH_END 255 -#define GLYPH_CHARSTART 32 -#define GLYPH_CHAREND 127 #define GLYPHS_PER_FONT ( GLYPH_END - GLYPH_START + 1 ) struct glyphInfo_t { @@ -2186,8 +2184,6 @@ struct fontInfo_t void *face, *faceData; glyphInfo_t *glyphBlock[0x110000 / 256]; // glyphBlock_t int pointSize; - int height; - float glyphScale; char name[ MAX_QPATH ]; }; diff --git a/src/engine/renderer/tr_font.cpp b/src/engine/renderer/tr_font.cpp index 1a9b2755ee..f0c4514204 100644 --- a/src/engine/renderer/tr_font.cpp +++ b/src/engine/renderer/tr_font.cpp @@ -360,11 +360,6 @@ void RE_GlyphChar( fontInfo_t *font, int ch, glyphInfo_t *glyph ) *glyph = font->glyphBlock[ ch / 256][ ch % 256 ]; } -void RE_Glyph( fontInfo_t *font, const char *str, glyphInfo_t *glyph ) -{ - RE_GlyphChar( font, Q_UTF8_CodePoint( str ), glyph ); -} - static void RE_StoreImage( fontInfo_t *font, int chunk, int page, int from, int to, const unsigned char *bitmap, int yEnd ) { int scaledSize = FONT_SIZE * FONT_SIZE; @@ -642,7 +637,6 @@ fontInfo_t* RE_RegisterFont( const char *fontName, int pointSize ) if ( len > 0x5004 && len <= 0x5004 + MAX_QPATH ) // 256 glyphs, scale info, and the bitmap name { glyphInfo_t *glyphs; - int height = 0; ri.FS_ReadFile( fileName, &faceData ); fdOffset = 0; @@ -652,13 +646,7 @@ fontInfo_t* RE_RegisterFont( const char *fontName, int pointSize ) for ( i = 0; i < GLYPHS_PER_FONT; i++ ) { - glyphs[ i ].height = readInt(); - - if ( glyphs[ i ].height > height ) - { - height = glyphs[ i ].height; - } - + /* height */ readInt(); glyphs[ i ].top = readInt(); glyphs[ i ].bottom = readInt(); glyphs[ i ].pitch = readInt(); @@ -675,8 +663,7 @@ fontInfo_t* RE_RegisterFont( const char *fontName, int pointSize ) } font->pointSize = pointSize; - font->height = height; - font->glyphScale = readFloat(); + /* glyphScale */ readFloat(); Q_strncpyz( font->name, registeredName, sizeof( font->name ) ); ri.FS_FreeFile( faceData ); @@ -728,8 +715,6 @@ fontInfo_t* RE_RegisterFont( const char *fontName, int pointSize ) font->face = face; font->faceData = faceData; font->pointSize = pointSize; - font->glyphScale = 64.0f / pointSize; - font->height = ceil( ( face->height / 64.0 ) * ( face->size->metrics.y_scale / 65536.0 ) * font->glyphScale ); RE_RenderChunk( font, 0 ); diff --git a/src/engine/renderer/tr_init.cpp b/src/engine/renderer/tr_init.cpp index 7016b35d9a..e2db9fe8f9 100644 --- a/src/engine/renderer/tr_init.cpp +++ b/src/engine/renderer/tr_init.cpp @@ -1660,7 +1660,6 @@ ScreenshotCmd screenshotPNGRegistration("screenshotPNG", ssFormat_t::SSF_PNG, "p re.SetMatrixTransform = RE_SetMatrixTransform; re.ResetMatrixTransform = RE_ResetMatrixTransform; - re.Glyph = RE_Glyph; re.GlyphChar = RE_GlyphChar; re.RegisterFont = RE_RegisterFont; re.UnregisterFont = RE_UnregisterFont; diff --git a/src/engine/renderer/tr_local.h b/src/engine/renderer/tr_local.h index f28e2beb4c..a6cfc3d47e 100644 --- a/src/engine/renderer/tr_local.h +++ b/src/engine/renderer/tr_local.h @@ -3668,7 +3668,6 @@ void GLimp_LogComment_( std::string comment ); void R_DoneFreeType(); fontInfo_t* RE_RegisterFont( const char *fontName, int pointSize ); void RE_UnregisterFont( fontInfo_t *font ); - void RE_Glyph(fontInfo_t *font, const char *str, glyphInfo_t *glyph); void RE_GlyphChar(fontInfo_t *font, int ch, glyphInfo_t *glyph); void R_SetAltShaderTokens( const char * ); From 7ecdc7af2a517ffbd070fa72e0d0cfb1518a43bf Mon Sep 17 00:00:00 2001 From: slipher Date: Sun, 5 Oct 2025 01:42:32 -0500 Subject: [PATCH 3/5] NUKE .dat pre-rasterized font file format The lengthy comment which is also deleted here explains that once upon a time, pre-rasterized fonts were shipped with Q3A to work around licensing issues with FreeType. The file format being NUKED here was a binary format with a .dat extension, which just specified size, tex coords, etc. for 256 glyphs; the rasterized images were stored in other files. --- src/engine/qcommon/q_shared.h | 3 - src/engine/renderer/tr_font.cpp | 144 +------------------------------- 2 files changed, 2 insertions(+), 145 deletions(-) diff --git a/src/engine/qcommon/q_shared.h b/src/engine/qcommon/q_shared.h index 764650ee05..1a798138be 100644 --- a/src/engine/qcommon/q_shared.h +++ b/src/engine/qcommon/q_shared.h @@ -2154,9 +2154,6 @@ union OpaquePlayerState { // font support -#define GLYPH_START 0 -#define GLYPH_END 255 -#define GLYPHS_PER_FONT ( GLYPH_END - GLYPH_START + 1 ) struct glyphInfo_t { int height; // number of scan lines diff --git a/src/engine/renderer/tr_font.cpp b/src/engine/renderer/tr_font.cpp index f0c4514204..314036303e 100644 --- a/src/engine/renderer/tr_font.cpp +++ b/src/engine/renderer/tr_font.cpp @@ -33,49 +33,6 @@ Maryland 20850 USA. */ // tr_font.c -// -// -// The font system uses FreeType 2.x to render TrueType fonts for use within the game. -// As of this writing ( Nov, 2000 ) Team Arena uses these fonts for all of the ui and -// about 90% of the cgame presentation. A few areas of the CGAME were left uses the old -// fonts since the code is shared with standard Q3A. -// -// If you include this font rendering code in a commercial product you MUST include the -// following somewhere with your product, see www.freetype.org for specifics or changes. -// The Freetype code also uses some hinting techniques that MIGHT infringe on patents -// held by apple so be aware of that also. -// -// As of Q3A 1.25+ and Team Arena, we are shipping the game with the font rendering code -// disabled. This removes any potential patent issues and it keeps us from having to -// distribute an actual TrueTrype font which is 1. expensive to do and 2. seems to require -// an act of god to accomplish. -// -// What we did was pre-render the fonts using FreeType ( which is why we leave the FreeType -// credit in the credits ) and then saved off the glyph data and then hand touched up the -// font bitmaps so they scale a bit better in GL. -// -// There are limitations in the way fonts are saved and reloaded in that it is based on -// point size and not name. So if you pre-render Helvetica in 18 point and Impact in 18 point -// you will end up with a single 18 point data file and image set. Typically you will want to -// choose 3 sizes to best approximate the scaling you will be doing in the ui scripting system -// -// In the UI Scripting code, a scale of 1.0 is equal to a 48 point font. In Team Arena, we -// use three or four scales, most of them exactly equaling the specific rendered size. We -// rendered three sizes in Team Arena, 12, 16, and 20. -// -// To generate new font data you need to go through the following steps. -// 1. delete the fontImage_x_xx.png files and fontImage_xx.dat files from the fonts path. -// 2. in a ui script, specify a font, smallFont, and bigFont keyword with font name and -// point size. the original TrueType fonts must exist in fonts at this point. -// 3. run the game. you should see things. -// 4. Exit the game and there will be three dat files and at least three PNG files. The -// PNGs are in 256x256 pages so if it takes three images to render a 24 point font you -// will end up with fontImage_0_24.tga through fontImage_2_24.tga -// 5. In future runs of the game, the system looks for these images and data files when a -// specific point sized font is rendered and loads them for use. -// 6. Because of the original beta nature of the FreeType code you will probably want to hand -// touch the font bitmaps. - #include "tr_local.h" @@ -299,43 +256,6 @@ static glyphInfo_t *RE_ConstructGlyphInfo( unsigned char *imageOut, int *xOut, i return nullptr; } - -static int fdOffset; -static byte *fdFile; - -int readInt() -{ - int i = - fdFile[ fdOffset ] + ( fdFile[ fdOffset + 1 ] << 8 ) + ( fdFile[ fdOffset + 2 ] << 16 ) + ( fdFile[ fdOffset + 3 ] << 24 ); - fdOffset += 4; - return i; -} - -union poor -{ - byte fred[ 4 ]; - float ffred; -}; - -float readFloat() -{ - poor me; - -#ifdef Q3_BIG_ENDIAN - me.fred[ 0 ] = fdFile[ fdOffset + 3 ]; - me.fred[ 1 ] = fdFile[ fdOffset + 2 ]; - me.fred[ 2 ] = fdFile[ fdOffset + 1 ]; - me.fred[ 3 ] = fdFile[ fdOffset + 0 ]; -#else - me.fred[ 0 ] = fdFile[ fdOffset + 0 ]; - me.fred[ 1 ] = fdFile[ fdOffset + 1 ]; - me.fred[ 2 ] = fdFile[ fdOffset + 2 ]; - me.fred[ 3 ] = fdFile[ fdOffset + 3 ]; -#endif - fdOffset += 4; - return me.ffred; -} - void RE_GlyphChar( fontInfo_t *font, int ch, glyphInfo_t *glyph ) { // default if out of range @@ -580,9 +500,7 @@ fontInfo_t* RE_RegisterFont( const char *fontName, int pointSize ) FT_Face face; void *faceData = nullptr; int i, len, fontNo; - char fileName[ MAX_QPATH ]; char strippedName[ MAX_QPATH ]; - char registeredName[ MAX_QPATH ]; if ( pointSize <= 0 ) { @@ -594,17 +512,6 @@ fontInfo_t* RE_RegisterFont( const char *fontName, int pointSize ) COM_StripExtension2( fontName, strippedName, sizeof( strippedName ) ); - if ( !Q_stricmp( strippedName, fontName ) ) - { - Com_sprintf( fileName, sizeof( fileName ), "fonts/fontImage_%i.dat", pointSize ); - } - else - { - Com_sprintf( fileName, sizeof( fileName ), "fonts/%s_%i.dat", strippedName, pointSize ); - } - - Com_sprintf( registeredName, sizeof( registeredName ), "%s#%d", strippedName, pointSize ); - fontNo = -1; for ( i = 0; i < MAX_FONTS; i++ ) @@ -632,51 +539,6 @@ fontInfo_t* RE_RegisterFont( const char *fontName, int pointSize ) fontInfo_t* font = ®isteredFont[ fontNo ]; ResetStruct( *font ); - len = ri.FS_ReadFile( fileName, nullptr ); - - if ( len > 0x5004 && len <= 0x5004 + MAX_QPATH ) // 256 glyphs, scale info, and the bitmap name - { - glyphInfo_t *glyphs; - - ri.FS_ReadFile( fileName, &faceData ); - fdOffset = 0; - fdFile = (byte*) faceData; - - glyphs = font->glyphBlock[0] = (glyphInfo_t*) Z_Calloc( sizeof( glyphBlock_t ) ); - - for ( i = 0; i < GLYPHS_PER_FONT; i++ ) - { - /* height */ readInt(); - glyphs[ i ].top = readInt(); - glyphs[ i ].bottom = readInt(); - glyphs[ i ].pitch = readInt(); - glyphs[ i ].xSkip = readInt(); - glyphs[ i ].imageWidth = readInt(); - glyphs[ i ].imageHeight = readInt(); - glyphs[ i ].s = readFloat(); - glyphs[ i ].t = readFloat(); - glyphs[ i ].s2 = readFloat(); - glyphs[ i ].t2 = readFloat(); - glyphs[ i ].glyph = readInt(); - Q_strncpyz( glyphs[ i ].shaderName, (const char *) &fdFile[ fdOffset ], sizeof( glyphs[ i ].shaderName ) ); - fdOffset += sizeof( glyphs[ i ].shaderName ); - } - - font->pointSize = pointSize; - /* glyphScale */ readFloat(); - Q_strncpyz( font->name, registeredName, sizeof( font->name ) ); - - ri.FS_FreeFile( faceData ); - - for ( i = GLYPH_START; i <= GLYPH_END; i++ ) - { - glyphs[ i ].glyph = RE_RegisterShader( glyphs[ i ].shaderName, RSF_NOMIP ); - } - - ++fontUsage[ fontNo ]; - return font; - } - if ( ftLibrary == nullptr ) { Log::Warn("RE_RegisterFont: FreeType not initialized." ); @@ -685,13 +547,11 @@ fontInfo_t* RE_RegisterFont( const char *fontName, int pointSize ) Q_strncpyz( font->name, strippedName, sizeof( font->name ) ); - Q_strncpyz( fileName, fontName, sizeof( fileName ) ); - - len = RE_LoadFontFile( fileName, &faceData ); + len = RE_LoadFontFile( fontName, &faceData ); if ( len <= 0 ) { - Log::Warn("RE_RegisterFont: Unable to read font file %s", fileName ); + Log::Warn("RE_RegisterFont: Unable to read font file %s", fontName ); RE_FreeFontFile( faceData ); return nullptr; } From 2436d6ddeb2bb7b6cf796a3ca74c6facf8da996e Mon Sep 17 00:00:00 2001 From: slipher Date: Sun, 5 Oct 2025 03:07:24 -0500 Subject: [PATCH 4/5] NUKE font handle table We only load one font, one time - the console font. No need for a font table caching system to detect duplicate font load requests. --- src/engine/client/cl_main.cpp | 5 +- src/engine/qcommon/q_shared.h | 3 - src/engine/renderer/tr_font.cpp | 166 +++++--------------------------- 3 files changed, 25 insertions(+), 149 deletions(-) diff --git a/src/engine/client/cl_main.cpp b/src/engine/client/cl_main.cpp index 64dcec19c2..da09557b88 100644 --- a/src/engine/client/cl_main.cpp +++ b/src/engine/client/cl_main.cpp @@ -1440,8 +1440,7 @@ void CL_Vid_Restart_f() Audio::StopAllSounds(); // shutdown the CGame CL_ShutdownCGame(); - // clear the font cache - re.UnregisterFont( nullptr ); + re.UnregisterFont( cls.consoleFont ); cls.consoleFont = nullptr; // shutdown the renderer and clear the renderer interface CL_ShutdownRef(); @@ -2461,7 +2460,7 @@ void CL_Shutdown() if ( re.UnregisterFont ) { - re.UnregisterFont( nullptr ); + re.UnregisterFont( cls.consoleFont ); cls.consoleFont = nullptr; } diff --git a/src/engine/qcommon/q_shared.h b/src/engine/qcommon/q_shared.h index 1a798138be..147431eac1 100644 --- a/src/engine/qcommon/q_shared.h +++ b/src/engine/qcommon/q_shared.h @@ -2171,9 +2171,6 @@ struct glyphInfo_t char shaderName[ 32 ]; }; -// Unlike with many other handle types, 0 is valid, not an error or default return value. -using fontHandle_t = int; - using glyphBlock_t = glyphInfo_t[256]; struct fontInfo_t diff --git a/src/engine/renderer/tr_font.cpp b/src/engine/renderer/tr_font.cpp index 314036303e..16d51d4708 100644 --- a/src/engine/renderer/tr_font.cpp +++ b/src/engine/renderer/tr_font.cpp @@ -54,18 +54,6 @@ FT_Library ftLibrary = nullptr; static const int FONT_SIZE = 512; -static const int MAX_FONTS = 16; -static const int MAX_FILES = ( MAX_FONTS ); -static fontInfo_t registeredFont[ MAX_FONTS ]; -static unsigned int fontUsage[ MAX_FONTS ]; - -static struct { - void *data; - int length; - int count; - char name[ MAX_QPATH ]; -} fontData[ MAX_FILES ]; - void RE_RenderChunk( fontInfo_t *font, const int chunk ); @@ -427,79 +415,33 @@ void RE_RenderChunk( fontInfo_t *font, const int chunk ) static int RE_LoadFontFile( const char *name, void **buffer ) { - int i; + void *tmp; + int length = ri.FS_ReadFile( name, &tmp ); - // if we already have this file, return it - for ( i = 0; i < MAX_FILES; ++i ) + if ( length <= 0 ) { - if ( !fontData[ i ].count || Q_stricmp( name, fontData[ i ].name ) ) - { - continue; - } - - ++fontData[ i ].count; - - *buffer = fontData[ i ].data; - return fontData[ i ].length; + return 0; } - // otherwise, find a free entry and load the file - for ( i = 0; i < MAX_FILES; ++i ) - { - if ( !fontData [ i ].count ) - { - void *tmp; - int length = ri.FS_ReadFile( name, &tmp ); + void *data = Z_AllocUninit( length ); + *buffer = data; - if ( length <= 0 ) - { - return 0; - } + memcpy( data, tmp, length ); + ri.FS_FreeFile( tmp ); - fontData[ i ].data = Z_AllocUninit( length ); - fontData[ i ].length = length; - fontData[ i ].count = 1; - *buffer = fontData[ i ].data; - - memcpy( fontData[ i ].data, tmp, length ); - ri.FS_FreeFile( tmp ); - - Q_strncpyz( fontData[ i ].name, name, sizeof( fontData[ i ].name ) ); - - return length; - } - } - - return 0; + return length; } static void RE_FreeFontFile( void *data ) { - int i; - - if ( !data ) - { - return; - } - - for ( i = 0; i < MAX_FILES; ++i ) - { - if ( fontData[ i ].data == data ) - { - if ( !--fontData[ i ].count ) - { - Z_Free( fontData[ i ].data ); - } - break; - } - } + Z_Free( data ); } fontInfo_t* RE_RegisterFont( const char *fontName, int pointSize ) { FT_Face face; void *faceData = nullptr; - int i, len, fontNo; + int len; char strippedName[ MAX_QPATH ]; if ( pointSize <= 0 ) @@ -512,41 +454,12 @@ fontInfo_t* RE_RegisterFont( const char *fontName, int pointSize ) COM_StripExtension2( fontName, strippedName, sizeof( strippedName ) ); - fontNo = -1; - - for ( i = 0; i < MAX_FONTS; i++ ) - { - if ( !fontUsage[ i ] ) - { - if ( fontNo < 0 ) - { - fontNo = i; - } - } - else if ( pointSize == registeredFont[ i ].pointSize && Q_stricmp( strippedName, registeredFont[ i ].name ) == 0 ) - { - ++fontUsage[ i ]; - return ®isteredFont[ i ]; - } - } - - if ( fontNo < 0 ) - { - Log::Warn("RE_RegisterFont: Too many fonts registered already." ); - return nullptr; - } - - fontInfo_t* font = ®isteredFont[ fontNo ]; - ResetStruct( *font ); - if ( ftLibrary == nullptr ) { Log::Warn("RE_RegisterFont: FreeType not initialized." ); return nullptr; } - Q_strncpyz( font->name, strippedName, sizeof( font->name ) ); - len = RE_LoadFontFile( fontName, &faceData ); if ( len <= 0 ) @@ -572,13 +485,14 @@ fontInfo_t* RE_RegisterFont( const char *fontName, int pointSize ) return nullptr; } + auto *font = new fontInfo_t{}; + Q_strncpyz( font->name, strippedName, sizeof( font->name ) ); font->face = face; font->faceData = faceData; font->pointSize = pointSize; RE_RenderChunk( font, 0 ); - ++fontUsage[ fontNo ]; return font; } @@ -590,69 +504,35 @@ void R_InitFreeType() } } -void RE_UnregisterFont_Internal( fontHandle_t handle ) +void RE_UnregisterFont( fontInfo_t *font ) { - int i; - - if ( !fontUsage[ handle ] ) - { - return; - } - - if ( --fontUsage[ handle ] ) + if ( !font ) { return; } - - if ( registeredFont[ handle ].face ) + if ( font->face ) { - FT_Done_Face( (FT_Face) registeredFont[ handle ].face ); - RE_FreeFontFile( registeredFont[ handle ].faceData ); + FT_Done_Face( (FT_Face) font->face ); + RE_FreeFontFile( font->faceData ); } - for ( i = 0; i < 0x1100; ++i ) + for ( int i = 0; i < 0x1100; ++i ) { - if ( registeredFont[ handle ].glyphBlock[ i ] && registeredFont[ handle ].glyphBlock[ i ] != nullGlyphs ) + if ( font->glyphBlock[ i ] && font->glyphBlock[ i ] != nullGlyphs ) { - Z_Free( registeredFont[ handle ].glyphBlock[ i ] ); - registeredFont[ handle ].glyphBlock[ i ] = nullptr; + Z_Free( font->glyphBlock[ i ] ); + font->glyphBlock[ i ] = nullptr; } } - ResetStruct( registeredFont[ handle ] ); -} - -void RE_UnregisterFont( fontInfo_t *font ) -{ - int i; - - for ( i = 0; i < MAX_FONTS; ++i ) - { - if ( !fontUsage[ i ] ) - { - continue; - } - - if ( font && font != ®isteredFont[ i ] ) - { - continue; // name & size don't match - } - - RE_UnregisterFont_Internal( i ); - - if ( font ) - { - break; - } - } + delete font; } void R_DoneFreeType() { if ( ftLibrary ) { - RE_UnregisterFont( nullptr ); FT_Done_FreeType( ftLibrary ); ftLibrary = nullptr; } From 3451be2f426221065b5f70df69ff0d81f2097fa3 Mon Sep 17 00:00:00 2001 From: slipher Date: Sun, 5 Oct 2025 03:20:01 -0500 Subject: [PATCH 5/5] Move font stuff out of q_shared.h --- src/engine/RefAPI.h | 26 ++++++++++++++++++++++++++ src/engine/qcommon/q_shared.h | 29 ----------------------------- src/engine/renderer/tr_font.cpp | 2 ++ 3 files changed, 28 insertions(+), 29 deletions(-) diff --git a/src/engine/RefAPI.h b/src/engine/RefAPI.h index 8b4bea8992..d1129e01ef 100644 --- a/src/engine/RefAPI.h +++ b/src/engine/RefAPI.h @@ -51,6 +51,32 @@ struct WindowConfig { int vidWidth, vidHeight; // what the game is using }; +// font support +struct glyphInfo_t +{ + int height; // number of scan lines + int top; // top of glyph in buffer + int bottom; // bottom of glyph in buffer + int pitch; // width for copying + int xSkip; // x adjustment + int imageWidth; // width of actual image + int imageHeight; // height of actual image + float s; // x offset in image where glyph starts + float t; // y offset in image where glyph starts + float s2; + float t2; + qhandle_t glyph; // handle to the shader with the glyph + char shaderName[ 32 ]; +}; + +struct fontInfo_t +{ + void *face, *faceData; + glyphInfo_t *glyphBlock[0x110000 / 256]; // glyphBlock_t + int pointSize; + char name[ MAX_QPATH ]; +}; + // // these are the functions exported by the refresh module // diff --git a/src/engine/qcommon/q_shared.h b/src/engine/qcommon/q_shared.h index 147431eac1..cab27c8744 100644 --- a/src/engine/qcommon/q_shared.h +++ b/src/engine/qcommon/q_shared.h @@ -2152,35 +2152,6 @@ union OpaquePlayerState { CA_ACTIVE, // game views should be displayed }; -// font support - -struct glyphInfo_t -{ - int height; // number of scan lines - int top; // top of glyph in buffer - int bottom; // bottom of glyph in buffer - int pitch; // width for copying - int xSkip; // x adjustment - int imageWidth; // width of actual image - int imageHeight; // height of actual image - float s; // x offset in image where glyph starts - float t; // y offset in image where glyph starts - float s2; - float t2; - qhandle_t glyph; // handle to the shader with the glyph - char shaderName[ 32 ]; -}; - -using glyphBlock_t = glyphInfo_t[256]; - -struct fontInfo_t -{ - void *face, *faceData; - glyphInfo_t *glyphBlock[0x110000 / 256]; // glyphBlock_t - int pointSize; - char name[ MAX_QPATH ]; -}; - // real time //============================================= diff --git a/src/engine/renderer/tr_font.cpp b/src/engine/renderer/tr_font.cpp index 16d51d4708..db14b98ad9 100644 --- a/src/engine/renderer/tr_font.cpp +++ b/src/engine/renderer/tr_font.cpp @@ -50,6 +50,8 @@ Maryland 20850 USA. #define _CEIL( x ) ( ( ( x ) + 63 ) & - 64 ) #define _TRUNC( x ) ( ( x ) >> 6 ) +using glyphBlock_t = glyphInfo_t[256]; + FT_Library ftLibrary = nullptr; static const int FONT_SIZE = 512;