Skip to content

Commit a91f28c

Browse files
committed
Create a cache around fontCalcGlyphPos for ASCII characters
...since this function is pretty slow. This applies both to the system font and user-loaded fonts. This is cache is now used downstream of `C2D_TextFontParseLine`, which should improve its performance.
1 parent 147b02a commit a91f28c

File tree

5 files changed

+51
-2
lines changed

5 files changed

+51
-2
lines changed

include/c2d/font.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,16 @@ charWidthInfo_s* C2D_FontGetCharWidthInfo(C2D_Font font, int glyphIndex);
8686
*/
8787
void C2D_FontCalcGlyphPos(C2D_Font font, fontGlyphPos_s* out, int glyphIndex, u32 flags, float scaleX, float scaleY);
8888

89+
/** @brief Calculate glyph position of given codepoint. Uses a cached value when the codepoint is ASCII, flags are 0, and scales are 1.
90+
* @param[in] font Font to read from, or NULL for system font
91+
* @param[out] out Glyph position
92+
* @param[in] codepoint The Unicode codepoint of the glyph
93+
* @param[in] flags Misc flags
94+
* @param[in] scaleX Size to scale in X
95+
* @param[in] scaleY Size to scale in Y
96+
*/
97+
void C2D_FontCalcGlyphPosFromCodePoint(C2D_Font font, fontGlyphPos_s* out, u32 codepoint, u32 flags, float scaleX, float scaleY);
98+
8999
/** @brief Get the font info structure associated with the font
90100
* @param[in] font Font to read from, or NULL for the system font
91101
* @returns FINF associated with the font

source/base.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -575,7 +575,7 @@ void C2Di_FlushVtxBuf(void)
575575
ctx->idxBufLastPos = ctx->idxBufPos;
576576
}
577577

578-
void C2Di_Update(void)
578+
void C2Di_Update()
579579
{
580580
C2Di_Context* ctx = C2Di_GetContext();
581581
u32 flags = ctx->flags & C2DiF_DirtyAny;

source/font.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
#include "internal.h"
55
#include <c2d/font.h>
66

7+
fontGlyphPos_s g_systemFontASCIICache[128];
8+
79
C2D_Font C2D_FontLoad(const char* filename)
810
{
911
FILE* f = fopen(filename, "rb");
@@ -51,6 +53,11 @@ static C2D_Font C2Di_PostLoadFont(C2D_Font font)
5153
tex->border = 0;
5254
tex->lodParam = 0;
5355
}
56+
57+
for (i = 0; i < NUM_ASCII_CHARACTERS; i++)
58+
{
59+
fontCalcGlyphPos(&font->asciiCache[i], font->cfnt, fontGlyphIndexFromCodePoint(font->cfnt, i), 0, 1.0, 1.0);
60+
}
5461
}
5562
return font;
5663
}
@@ -243,6 +250,26 @@ void C2D_FontCalcGlyphPos(C2D_Font font, fontGlyphPos_s* out, int glyphIndex, u3
243250
fontCalcGlyphPos(out, font->cfnt, glyphIndex, flags, scaleX, scaleY);
244251
}
245252

253+
void C2D_FontCalcGlyphPosFromCodePoint(C2D_Font font, fontGlyphPos_s* out, u32 codepoint, u32 flags, float scaleX, float scaleY)
254+
{
255+
// Building glyph positions is pretty expensive, but we could just store the results for plain ASCII.
256+
if (codepoint < NUM_ASCII_CHARACTERS && flags == 0 && scaleX == 1 && scaleY == 1)
257+
{
258+
if (font)
259+
{
260+
*out = font->asciiCache[codepoint];
261+
}
262+
else
263+
{
264+
*out = g_systemFontASCIICache[codepoint];
265+
}
266+
}
267+
else
268+
{
269+
C2D_FontCalcGlyphPos(font, out, C2D_FontGlyphIndexFromCodePoint(font, codepoint), 0, 1.0f, 1.0f);
270+
}
271+
}
272+
246273
FINF_s* C2D_FontGetInfo(C2D_Font font)
247274
{
248275
if (!font)

source/internal.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#pragma once
22
#include <c2d/base.h>
3+
#include <3ds/font.h>
34

45
typedef struct
56
{
@@ -77,6 +78,7 @@ struct C2D_Font_s
7778
CFNT_s* cfnt;
7879
C3D_Tex* glyphSheets;
7980
float textScale;
81+
fontGlyphPos_s asciiCache[128];
8082
};
8183

8284
static inline C2Di_Context* C2Di_GetContext(void)
@@ -117,3 +119,6 @@ void C2Di_AppendQuad(void);
117119
void C2Di_AppendVtx(float x, float y, float z, float u, float v, float ptx, float pty, u32 color);
118120
void C2Di_FlushVtxBuf(void);
119121
void C2Di_Update(void);
122+
123+
#define NUM_ASCII_CHARACTERS 128
124+
extern fontGlyphPos_s g_systemFontASCIICache[NUM_ASCII_CHARACTERS];

source/text.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,13 @@ static void C2Di_TextEnsureLoad(void)
8989
tex->border = 0;
9090
tex->lodParam = 0;
9191
}
92+
93+
// Initialize system font ASCII cache for C2D_FontCalcGlyphPosFromCodePoint
94+
for (int i = 0; i < NUM_ASCII_CHARACTERS; i++)
95+
{
96+
// This will readjust glyph UVs to account for being a part of the combined texture.
97+
C2D_FontCalcGlyphPos(NULL, &g_systemFontASCIICache[i], fontGlyphIndexFromCodePoint(font, i), 0, 1.0, 1.0);
98+
}
9299
}
93100

94101
C2D_TextBuf C2D_TextBufNew(size_t maxGlyphs)
@@ -161,7 +168,7 @@ const char* C2D_TextFontParseLine(C2D_Text* text, C2D_Font font, C2D_TextBuf buf
161168
p += units;
162169

163170
fontGlyphPos_s glyphData;
164-
C2D_FontCalcGlyphPos(font, &glyphData, C2D_FontGlyphIndexFromCodePoint(font, code), 0, 1.0f, 1.0f);
171+
C2D_FontCalcGlyphPosFromCodePoint(font, &glyphData, code, 0, 1.0f, 1.0f);
165172
if (glyphData.width > 0.0f)
166173
{
167174
C2Di_Glyph* glyph = &buf->glyphs[buf->glyphCount++];

0 commit comments

Comments
 (0)