From 68e4637b7919d87d58282d12ecf7e6a83de1f690 Mon Sep 17 00:00:00 2001 From: nebiun Date: Mon, 4 Mar 2024 21:14:12 +0100 Subject: [PATCH] Removed code duplicate Optimized memory allocation Change return value for GRRLIB_PrintfTTFW and GRRLIB_PrintfTTF: now they return the width of the printed text in pixel --- GRRLIB/GRRLIB/GRRLIB_ttf.c | 240 +++++++++++++++-------------- GRRLIB/GRRLIB/grrlib/GRRLIB__lib.h | 4 +- 2 files changed, 123 insertions(+), 121 deletions(-) diff --git a/GRRLIB/GRRLIB/GRRLIB_ttf.c b/GRRLIB/GRRLIB/GRRLIB_ttf.c index 82715c2..4d23b75 100644 --- a/GRRLIB/GRRLIB/GRRLIB_ttf.c +++ b/GRRLIB/GRRLIB/GRRLIB_ttf.c @@ -27,10 +27,36 @@ THE SOFTWARE. #include FT_FREETYPE_H static FT_Library ftLibrary; /**< A handle to a FreeType library instance. */ +static wchar_t *_utf32 = NULL; +static u32 _utf32_len = 0; -// Static function prototypes -static void DrawBitmap(FT_Bitmap *bitmap, int offset, int top, const u8 cR, const u8 cG, const u8 cB, const u8 cA); +/** + * Draw a character on the screen. + * @param bitmap Bitmap to draw. + * @param offset x-coordinate offset. + * @param top y-coordinate. + * @param cR Red component of the colour. + * @param cG Green component of the colour. + * @param cB Blue component of the colour. + * @param cA Alpha component of the colour. + */ +static inline void DrawBitmap(FT_Bitmap *bitmap, int offset, int top, const u8 cR, const u8 cG, const u8 cB, const u8 cA) { + const FT_Int x_max = offset + bitmap->width; + const FT_Int y_max = top + bitmap->rows; + for (FT_Int i = offset, p = 0; i < x_max; i++, p++ ) { + for (FT_Int j = top, q = 0; j < y_max; j++, q++ ) { + s16 alpha = bitmap->buffer[ q * bitmap->width + p ] - (0xFF - cA); + if(alpha < 0) { + alpha = 0; + } + GX_Begin(GX_POINTS, GX_VTXFMT0, 1); + GX_Position3f32(i, j, 0); + GX_Color4u8(cR, cG, cB, alpha); + GX_End(); + } + } +} /** * Initialize FreeType library. @@ -48,6 +74,11 @@ int GRRLIB_InitTTF (void) { */ void GRRLIB_ExitTTF (void) { FT_Done_FreeType(ftLibrary); + if(_utf32 != NULL) { + free(_utf32); + _utf32 = NULL; + _utf32_len = 0; + } } /** @@ -87,44 +118,13 @@ void GRRLIB_FreeTTF (GRRLIB_ttfFont *myFont) { } /** - * Print function for TTF font. - * @param x Specifies the x-coordinate of the upper-left corner of the text. - * @param y Specifies the y-coordinate of the upper-left corner of the text. - * @param myFont A TTF. - * @param string Text to draw. - * @param fontSize Size of the font. - * @param color Text color in RGBA format. + * Common code for GRRLIB_PrintfTTFW() and GRRLIB_WidthTTFW() */ -void GRRLIB_PrintfTTF(int x, int y, GRRLIB_ttfFont *myFont, const char *string, unsigned int fontSize, const u32 color) { - if (myFont == NULL || string == NULL) { - return; - } - - size_t length = strlen(string) + 1; - wchar_t *utf32 = (wchar_t*)malloc(length * sizeof(wchar_t)); - if (utf32 != NULL) { - length = mbstowcs(utf32, string, length); - if (length > 0) { - utf32[length] = L'\0'; - GRRLIB_PrintfTTFW(x, y, myFont, utf32, fontSize, color); - } - free(utf32); - } -} - -/** - * Print function for TTF font. - * @author wplaat and DrTwox - * @param x Specifies the x-coordinate of the upper-left corner of the text. - * @param y Specifies the y-coordinate of the upper-left corner of the text. - * @param myFont A TTF. - * @param utf32 Text to draw. - * @param fontSize Size of the font. - * @param color Text color in RGBA format. - */ -void GRRLIB_PrintfTTFW(int x, int y, GRRLIB_ttfFont *myFont, const wchar_t *utf32, unsigned int fontSize, const u32 color) { +static u32 _PrintfTTFW(int x, int y, GRRLIB_ttfFont *myFont, const wchar_t *utf32, unsigned int fontSize, + const u32 color, bool noprint) +{ if (myFont == NULL || utf32 == NULL) { - return; + return 0; } FT_Face Face = (FT_Face)myFont->face; @@ -154,66 +154,33 @@ void GRRLIB_PrintfTTFW(int x, int y, GRRLIB_ttfFont *myFont, const wchar_t *utf3 if (FT_Load_Glyph(myFont->face, glyphIndex, FT_LOAD_RENDER) != 0) { continue; } - - DrawBitmap(&slot->bitmap, - penX + slot->bitmap_left + x, - penY - slot->bitmap_top + y, - cR, cG, cB, cA); + if(!noprint) { + DrawBitmap(&slot->bitmap, + penX + slot->bitmap_left + x, + penY - slot->bitmap_top + y, + cR, cG, cB, cA); + } penX += slot->advance.x >> 6; previousGlyph = glyphIndex; - } + } + + return penX; } /** - * Draw a character on the screen. - * @param bitmap Bitmap to draw. - * @param offset x-coordinate offset. - * @param top y-coordinate. - * @param cR Red component of the colour. - * @param cG Green component of the colour. - * @param cB Blue component of the colour. - * @param cA Alpha component of the colour. - */ -static void DrawBitmap(FT_Bitmap *bitmap, int offset, int top, const u8 cR, const u8 cG, const u8 cB, const u8 cA) { - const FT_Int x_max = offset + bitmap->width; - const FT_Int y_max = top + bitmap->rows; - - for (FT_Int i = offset, p = 0; i < x_max; i++, p++ ) { - for (FT_Int j = top, q = 0; j < y_max; j++, q++ ) { - s16 alpha = bitmap->buffer[ q * bitmap->width + p ] - (0xFF - cA); - if(alpha < 0) { - alpha = 0; - } - GX_Begin(GX_POINTS, GX_VTXFMT0, 1); - GX_Position3f32(i, j, 0); - GX_Color4u8(cR, cG, cB, alpha); - GX_End(); - } - } -} - -/** - * Get the width of a text in pixel. + * Print function for TTF font. + * @author wplaat and DrTwox + * @param x Specifies the x-coordinate of the upper-left corner of the text. + * @param y Specifies the y-coordinate of the upper-left corner of the text. * @param myFont A TTF. - * @param string The text to check. - * @param fontSize The size of the font. + * @param utf32 Text to draw. + * @param fontSize Size of the font. + * @param color Text color in RGBA format. * @return The width of a text in pixel. */ -u32 GRRLIB_WidthTTF(GRRLIB_ttfFont *myFont, const char *string, unsigned int fontSize) { - if (myFont == NULL || string == NULL) { - return 0; - } - u32 penX; - size_t length = strlen(string) + 1; - wchar_t *utf32 = (wchar_t*)malloc(length * sizeof(wchar_t)); - length = mbstowcs(utf32, string, length); - utf32[length] = L'\0'; - - penX = GRRLIB_WidthTTFW(myFont, utf32, fontSize); - - free(utf32); - - return penX; +u32 GRRLIB_PrintfTTFW(int x, int y, GRRLIB_ttfFont *myFont, const wchar_t *utf32, unsigned int fontSize, const u32 color) +{ + return _PrintfTTFW(x, y, myFont, utf32, fontSize, color, false); } /** @@ -223,35 +190,70 @@ u32 GRRLIB_WidthTTF(GRRLIB_ttfFont *myFont, const char *string, unsigned int fon * @param fontSize The size of the font. * @return The width of a text in pixel. */ -u32 GRRLIB_WidthTTFW(GRRLIB_ttfFont *myFont, const wchar_t *utf32, unsigned int fontSize) { - if (myFont == NULL || utf32 == NULL) { +u32 GRRLIB_WidthTTFW(GRRLIB_ttfFont *myFont, const wchar_t *utf32, unsigned int fontSize) +{ + return _PrintfTTFW(0, 0, myFont, utf32, fontSize, 0x00000000, true); +} + +/** + * Common code for GRRLIB_PrintfTTF() and GRRLIB_WidthTTF() + */ +static u32 _PrintfTTF(int x, int y, GRRLIB_ttfFont *myFont, const char *string, unsigned int fontSize, + const u32 color, bool noprint) +{ + if (myFont == NULL || string == NULL) { return 0; } - - FT_Face Face = (FT_Face)myFont->face; - u32 penX = 0; - FT_UInt glyphIndex; - FT_UInt previousGlyph = 0; - - if (FT_Set_Pixel_Sizes(myFont->face, 0, fontSize) != 0) { - FT_Set_Pixel_Sizes(myFont->face, 0, 12); - } - - while(*utf32) { - glyphIndex = FT_Get_Char_Index(myFont->face, *utf32++); - - if (myFont->kerning && previousGlyph && glyphIndex) { - FT_Vector delta; - FT_Get_Kerning(Face, previousGlyph, glyphIndex, FT_KERNING_DEFAULT, &delta); - penX += delta.x >> 6; - } - if (FT_Load_Glyph(Face, glyphIndex, FT_LOAD_RENDER) != 0) { - continue; - } - - penX += Face->glyph->advance.x >> 6; - previousGlyph = glyphIndex; - } - - return penX; + u32 penX = 0; + size_t length; + + length = mbstowcs(NULL, string, 0); + if(length == (size_t) -1) { + return 0; + } + length++; + + if(length > _utf32_len) { + if(_utf32 != NULL) { + free(_utf32); + _utf32 = NULL; + _utf32_len = 0; + } + _utf32 = (wchar_t*)malloc(length * sizeof(wchar_t)); + _utf32_len = length; + } + if (_utf32 != NULL) { + if(mbstowcs(_utf32, string, length) > 0) { + _utf32[length-1] = L'\0'; + penX = _PrintfTTFW(x, y, myFont, _utf32, fontSize, color, noprint); + } + } + return penX; +} + +/** + * Print function for TTF font. + * @param x Specifies the x-coordinate of the upper-left corner of the text. + * @param y Specifies the y-coordinate of the upper-left corner of the text. + * @param myFont A TTF. + * @param string Text to draw. + * @param fontSize Size of the font. + * @param color Text color in RGBA format. + * @return The width of a text in pixel. + */ +u32 GRRLIB_PrintfTTF(int x, int y, GRRLIB_ttfFont *myFont, const char *string, unsigned int fontSize, const u32 color) +{ + return _PrintfTTF(x, y, myFont, string, fontSize, color, false); +} + +/** + * Get the width of a text in pixel. + * @param myFont A TTF. + * @param string The text to check. + * @param fontSize The size of the font. + * @return The width of a text in pixel. + */ +u32 GRRLIB_WidthTTF(GRRLIB_ttfFont *myFont, const char *string, unsigned int fontSize) +{ + return _PrintfTTF(0, 0, myFont, string, fontSize, 0x00000000, true); } diff --git a/GRRLIB/GRRLIB/grrlib/GRRLIB__lib.h b/GRRLIB/GRRLIB/grrlib/GRRLIB__lib.h index ad30218..cc195bb 100644 --- a/GRRLIB/GRRLIB/grrlib/GRRLIB__lib.h +++ b/GRRLIB/GRRLIB/grrlib/GRRLIB__lib.h @@ -177,8 +177,8 @@ void GRRLIB_SetLightOff(void); // GRRLIB_ttf.c - FreeType function for GRRLIB GRRLIB_ttfFont* GRRLIB_LoadTTF(const u8* file_base, s32 file_size); void GRRLIB_FreeTTF(GRRLIB_ttfFont *myFont); -void GRRLIB_PrintfTTF(int x, int y, GRRLIB_ttfFont *myFont, const char *string, unsigned int fontSize, const u32 color); -void GRRLIB_PrintfTTFW(int x, int y, GRRLIB_ttfFont *myFont, const wchar_t *string, unsigned int fontSize, const u32 color); +u32 GRRLIB_PrintfTTF(int x, int y, GRRLIB_ttfFont *myFont, const char *string, unsigned int fontSize, const u32 color); +u32 GRRLIB_PrintfTTFW(int x, int y, GRRLIB_ttfFont *myFont, const wchar_t *string, unsigned int fontSize, const u32 color); u32 GRRLIB_WidthTTF(GRRLIB_ttfFont *myFont, const char *, unsigned int); u32 GRRLIB_WidthTTFW(GRRLIB_ttfFont *myFont, const wchar_t *, unsigned int);