loader/ttf: Spaces and invalid glyphs rendering fix

If for any reason an invalid glyph is found in text, 
it will now be skipped when rendering 
(instead of increasing offset by last valid glyph advance).

Issue: #2687
This commit is contained in:
Łukasz Pomietło 2024-09-02 10:44:31 +02:00 committed by Hermet Park
parent ec4b08245c
commit 3c5cf13eb5
2 changed files with 17 additions and 8 deletions

View file

@ -282,6 +282,7 @@ bool TtfLoader::read()
Point offset = {0.0f, reader.metrics.hhea.ascent};
Point kerning = {0.0f, 0.0f};
auto lglyph = INVALID_GLYPH;
auto loadMinw = true;
size_t idx = 0;
while (code[idx] && idx < n) {
@ -289,11 +290,14 @@ bool TtfLoader::read()
if (rglyph != INVALID_GLYPH) {
if (lglyph != INVALID_GLYPH) reader.kerning(lglyph, rglyph, kerning);
if (!reader.convert(shape, gmetrics, offset, kerning, 1U)) break;
offset.x += (gmetrics.advanceWidth + kerning.x);
lglyph = rglyph;
//store the first glyph with outline min size for italic transform.
if (loadMinw && gmetrics.outline) {
reader.metrics.minw = gmetrics.minw;
loadMinw = false;
}
}
offset.x += (gmetrics.advanceWidth + kerning.x);
lglyph = rglyph;
//store the first glyph min size for italic transform.
if (idx == 0) reader.metrics.minw = gmetrics.minw;
++idx;
}

View file

@ -387,12 +387,11 @@ uint32_t TtfReader::glyph(uint32_t codepoint)
uint32_t TtfReader::glyph(uint32_t codepoint, TtfGlyphMetrics& gmetrics)
{
auto glyph = this->glyph(codepoint);
if (glyph == INVALID_GLYPH) {
if (glyph == INVALID_GLYPH || !glyphMetrics(glyph, gmetrics)) {
TVGERR("TTF", "invalid glyph id, codepoint(0x%x)", codepoint);
return INVALID_GLYPH;
}
return glyphMetrics(glyph, gmetrics) ? glyph : INVALID_GLYPH;
return glyph;
}
bool TtfReader::glyphMetrics(uint32_t glyphIndex, TtfGlyphMetrics& gmetrics)
@ -420,7 +419,12 @@ bool TtfReader::glyphMetrics(uint32_t glyphIndex, TtfGlyphMetrics& gmetrics)
}
gmetrics.outline = outlineOffset(glyphIndex);
if (!gmetrics.outline || !validate(gmetrics.outline, 10)) return false;
// glyph without outline
if (gmetrics.outline == 0) {
gmetrics.minw = gmetrics.minh = gmetrics.yOffset = 0;
return true;
}
if (!validate(gmetrics.outline, 10)) return false;
//read the bounding box from the font file verbatim.
float bbox[4];
@ -442,6 +446,7 @@ bool TtfReader::convert(Shape* shape, TtfGlyphMetrics& gmetrics, const Point& of
{
#define ON_CURVE 0x01
if (!gmetrics.outline) return true;
auto outlineCnt = _i16(data, gmetrics.outline);
if (outlineCnt == 0) return false;
if (outlineCnt < 0) {