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
This commit is contained in:
nebiun 2024-03-04 21:14:12 +01:00
parent 4b65d83fea
commit 68e4637b79
2 changed files with 123 additions and 121 deletions

View file

@ -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);
}

View file

@ -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);