diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com> | 2013-03-18 14:13:53 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-03-19 03:55:44 +0100 |
commit | 9bf5870eb9a4e4449eda731029db5af2bcea39a3 (patch) | |
tree | 07964d4f5cdd3844a56379e004bafef3c4e8aee0 /src/gui/text/qfontengine_ft.cpp | |
parent | 0554341d9f684e6867b36a9ce6af7c846c64057d (diff) |
Fix missing glyphs for large fonts
For large fonts, we would get invalid metrics due to the metrics
being too large to fit in the signed chars of the cache struct.
This in turn would lead to the bounding box reported by the
font engine being wrong, and subsequently, the algorithm which
decides whether any part of the glyph is visible in the raster
engine would make the wrong decision, hiding glyphs that should
not be hidden.
Task-number: QTBUG-30026
Change-Id: I59b613ce889fcac0bd50ffec9d369728068d0263
Reviewed-by: Samuel Rødal <samuel.rodal@digia.com>
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Diffstat (limited to 'src/gui/text/qfontengine_ft.cpp')
-rw-r--r-- | src/gui/text/qfontengine_ft.cpp | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 07e4cae1ee..83ba89263a 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -889,18 +889,28 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyph(QGlyphSet *set, uint glyph, info.yOff = 0; if ((set && set->outline_drawing) || fetchMetricsOnly) { - // If the advance doesn't fit in signed char, don't cache it - if (qAbs(info.xOff) >= 128) - return 0; - g = new Glyph; - g->data = 0; - g->linearAdvance = slot->linearHoriAdvance >> 10; int left = FLOOR(slot->metrics.horiBearingX); int right = CEIL(slot->metrics.horiBearingX + slot->metrics.width); int top = CEIL(slot->metrics.horiBearingY); int bottom = FLOOR(slot->metrics.horiBearingY - slot->metrics.height); - g->width = TRUNC(right-left); - g->height = TRUNC(top-bottom); + int width = right-left; + int height = top-bottom; + + // If any of the metrics are too large to fit, don't cache them + if (qAbs(info.xOff) >= 128 + || qAbs(TRUNC(top)) >= 128 + || TRUNC(width) >= 256 + || TRUNC(height) >= 256 + || qAbs(TRUNC(left)) >= 128 + || qAbs(TRUNC(ROUND(slot->advance.x))) >= 128) { + return 0; + } + + g = new Glyph; + g->data = 0; + g->linearAdvance = slot->linearHoriAdvance >> 10; + g->width = TRUNC(width); + g->height = TRUNC(height); g->x = TRUNC(left); g->y = TRUNC(top); g->advance = TRUNC(ROUND(slot->advance.x)); |