summaryrefslogtreecommitdiffstats
path: root/src/gui/text/qfontengine_ft.cpp
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2014-08-25 12:56:34 +0200
committerAllan Sandfeld Jensen <allan.jensen@digia.com>2014-09-01 12:25:56 +0200
commit367680679ae13faaf71aa481265cb93629a36427 (patch)
treeb5d61cf342525c951041f586273c5202d69c12e3 /src/gui/text/qfontengine_ft.cpp
parent1812bb968c49d50745ab2b10787320205c54f946 (diff)
Fix advance of zero-width spaces in fonts that omits the glyph
Some fonts appear to include zero-width space in the CMAP table, but not include an actual definitions of the glyph they point to. The missing glyph causes a warning, but isn't handled making the character end up being giving the same metrics as whatever character it came after. This patch adds explicit handling of missing glyphs, and also caches their missing state when caching is enabled. Task-number: QTBUG-40912 Change-Id: I06fba9c01df59548e750e36babfdd5a6bafd6bd0 Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
Diffstat (limited to 'src/gui/text/qfontengine_ft.cpp')
-rw-r--r--src/gui/text/qfontengine_ft.cpp25
1 files changed, 18 insertions, 7 deletions
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp
index cb3cb34d27..0a22038bb4 100644
--- a/src/gui/text/qfontengine_ft.cpp
+++ b/src/gui/text/qfontengine_ft.cpp
@@ -132,6 +132,7 @@ static bool ft_getSfntTable(void *user_data, uint tag, uchar *buffer, uint *leng
return result;
}
+static QFontEngineFT::Glyph emptyGlyph = {0, 0, 0, 0, 0, 0, 0, 0};
// -------------------------- Freetype support ------------------------------
@@ -858,6 +859,9 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
if (g && g->format == format && (fetchMetricsOnly || g->data))
return g;
+ if (!g && set && set->isGlyphMissing(glyph))
+ return &emptyGlyph;
+
QFontEngineFT::GlyphInfo info;
Q_ASSERT(format != Format_None);
@@ -894,8 +898,12 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph,
load_flags |= FT_LOAD_FORCE_AUTOHINT;
err = FT_Load_Glyph(face, glyph, load_flags);
}
- if (err != FT_Err_Ok)
+ if (err != FT_Err_Ok) {
qWarning("load glyph failed err=%x face=%p, glyph=%d", err, face, glyph);
+ if (set)
+ set->setGlyphMissing(glyph);
+ return &emptyGlyph;
+ }
FT_GlyphSlot slot = face->glyph;
@@ -1633,9 +1641,12 @@ void QFontEngineFT::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlag
if (!face)
face = lockFace();
g = loadGlyph(cacheEnabled ? &defaultGlyphSet : 0, glyphs->glyphs[i], 0, Format_None, true);
- glyphs->advances[i] = design ? QFixed::fromFixed(face->glyph->linearHoriAdvance >> 10)
- : QFixed::fromFixed(face->glyph->metrics.horiAdvance).round();
- if (!cacheEnabled)
+ if (g)
+ glyphs->advances[i] = design ? QFixed::fromFixed(g->linearAdvance) : QFixed(g->advance);
+ else
+ glyphs->advances[i] = design ? QFixed::fromFixed(face->glyph->linearHoriAdvance >> 10)
+ : QFixed::fromFixed(face->glyph->metrics.horiAdvance).round();
+ if (!cacheEnabled && g != &emptyGlyph)
delete g;
}
}
@@ -1674,7 +1685,7 @@ glyph_metrics_t QFontEngineFT::boundingBox(const QGlyphLayout &glyphs)
xmax = qMax(xmax, x + g->width);
ymax = qMax(ymax, y + g->height);
overall.xoff += g->advance;
- if (!cacheEnabled)
+ if (!cacheEnabled && g != &emptyGlyph)
delete g;
} else {
int left = FLOOR(face->glyph->metrics.horiBearingX);
@@ -1717,7 +1728,7 @@ glyph_metrics_t QFontEngineFT::boundingBox(glyph_t glyph)
overall.xoff = g->advance;
if (fontDef.styleStrategy & QFont::ForceIntegerMetrics)
overall.xoff = overall.xoff.round();
- if (!cacheEnabled)
+ if (!cacheEnabled && g != &emptyGlyph)
delete g;
} else {
int left = FLOOR(face->glyph->metrics.horiBearingX);
@@ -1808,7 +1819,7 @@ glyph_metrics_t QFontEngineFT::alphaMapBoundingBox(glyph_t glyph, QFixed subPixe
overall.width = g->width;
overall.height = g->height;
overall.xoff = g->advance;
- if (!glyphSet)
+ if (!glyphSet && g != &emptyGlyph)
delete g;
} else {
int left = FLOOR(face->glyph->metrics.horiBearingX);