REVIEWED: WARNING: LoadFontData() avoid fallback glyphs

This is a redesign on font loading, missing glyphs are skipped instead of falling back to font `.notdef` special character (usually "tofu" character).
It is changed because not all fonts support a fallback glyph.
One improvement could be allowing users to define a custom fallback character, for example `?` glyph.
This commit is contained in:
Ray 2023-12-04 17:32:55 +01:00
parent a016b4ded2
commit 731b210f51

View File

@ -625,9 +625,19 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz
// stbtt_GetCodepointBitmapBox() -- how big the bitmap must be
// stbtt_MakeCodepointBitmap() -- renders into bitmap you provide
if (type != FONT_SDF) chars[i].image.data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, ch, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY);
else if (ch != 32) chars[i].image.data = stbtt_GetCodepointSDF(&fontInfo, scaleFactor, ch, FONT_SDF_CHAR_PADDING, FONT_SDF_ON_EDGE_VALUE, FONT_SDF_PIXEL_DIST_SCALE, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY);
else chars[i].image.data = NULL;
// Check if a glyph is available in the font
// WARNING: if (index == 0), glyph not found, it could fallback to default .notdef glyph (if defined in font)
int index = stbtt_FindGlyphIndex(&fontInfo, ch);
if (index > 0)
{
switch (type)
{
case FONT_DEFAULT:
case FONT_BITMAP: chars[i].image.data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, ch, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY); break;
case FONT_SDF: if (ch != 32) chars[i].image.data = stbtt_GetCodepointSDF(&fontInfo, scaleFactor, ch, FONT_SDF_CHAR_PADDING, FONT_SDF_ON_EDGE_VALUE, FONT_SDF_PIXEL_DIST_SCALE, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY); break;
default: break;
}
if (chars[i].image.data != NULL) // Glyph data has been found in the font
{
@ -643,9 +653,13 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz
chars[i].offsetY += (int)((float)ascent*scaleFactor);
}
// NOTE: We create an empty image for space character, it could be further required for atlas packing
// NOTE: We create an empty image for space character,
// it could be further required for atlas packing
if (ch == 32)
{
stbtt_GetCodepointHMetrics(&fontInfo, ch, &chars[i].advanceX, NULL);
chars[i].advanceX = (int)((float)chars[i].advanceX*scaleFactor);
Image imSpace = {
.data = RL_CALLOC(chars[i].advanceX*fontSize, 2),
.width = chars[i].advanceX,
@ -667,15 +681,11 @@ GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSiz
else ((unsigned char *)chars[i].image.data)[p] = 255;
}
}
// Get bounding box for character (maybe offset to account for chars that dip above or below the line)
/*
int chX1, chY1, chX2, chY2;
stbtt_GetCodepointBitmapBox(&fontInfo, ch, scaleFactor, scaleFactor, &chX1, &chY1, &chX2, &chY2);
TRACELOGD("FONT: Character box measures: %i, %i, %i, %i", chX1, chY1, chX2 - chX1, chY2 - chY1);
TRACELOGD("FONT: Character offsetY: %i", (int)((float)ascent*scaleFactor) + chY1);
*/
}
else
{
// TODO: Use some fallback glyph for codepoints not found in the font
}
}
}
else TRACELOG(LOG_WARNING, "FONT: Failed to process TTF font data");