diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2010-03-24 13:51:13 (GMT) |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2010-03-24 14:27:58 (GMT) |
commit | 6d0002fe9bc91b9901e56050d247fbded09c9c76 (patch) | |
tree | e6b14b3d69512a7bb62ccf69ae3f656a227e82d2 /src | |
parent | 4a4458d1cf5ec7885c6f63f739b7ee80c70ad211 (diff) | |
download | Qt-6d0002fe9bc91b9901e56050d247fbded09c9c76.zip Qt-6d0002fe9bc91b9901e56050d247fbded09c9c76.tar.gz Qt-6d0002fe9bc91b9901e56050d247fbded09c9c76.tar.bz2 |
Add QFont::ForceIntegerMetrics style strategy flag
WebKit uses integers internally to deal with positioning and sizing of
text objects, but on Mac, Qt uses floating point values. This caused a
discrepancy between the size used by WebKit to position text objects
and the actual size of the objects when rendered by Qt. The problem was
so bad that it has been holding back fixes for other bugs in the mac
font engine since these would make the WebKit bug more visible.
To work around the problem, we introduce a StyleStrategy flag in QFont
which allows you to force the use of integers all over the line. This
makes text rendering slightly different from native applications, but
should fix several issues with WebKit on Mac.
The WebKit-part of this patch will be submitted up-stream.
Reviewed-by: Simon Hausmann
Reviewed-by: Prasanth
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/text/qfont.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qfont.h | 23 | ||||
-rw-r--r-- | src/gui/text/qfontengine_mac.mm | 49 |
3 files changed, 53 insertions, 21 deletions
diff --git a/src/gui/text/qfont.cpp b/src/gui/text/qfont.cpp index 9b85c04..99b9f40 100644 --- a/src/gui/text/qfont.cpp +++ b/src/gui/text/qfont.cpp @@ -1297,6 +1297,8 @@ QFont::StyleHint QFont::styleHint() const \value PreferQuality prefer the best quality font. The font matcher will use the nearest standard point size that the font supports. + \value ForceIntegerMetrics forces the use of integer values in font engines that support fractional + font metrics. */ /*! diff --git a/src/gui/text/qfont.h b/src/gui/text/qfont.h index 5adf237..6f62424 100644 --- a/src/gui/text/qfont.h +++ b/src/gui/text/qfont.h @@ -76,17 +76,18 @@ public: }; enum StyleStrategy { - PreferDefault = 0x0001, - PreferBitmap = 0x0002, - PreferDevice = 0x0004, - PreferOutline = 0x0008, - ForceOutline = 0x0010, - PreferMatch = 0x0020, - PreferQuality = 0x0040, - PreferAntialias = 0x0080, - NoAntialias = 0x0100, - OpenGLCompatible = 0x0200, - NoFontMerging = 0x8000 + PreferDefault = 0x0001, + PreferBitmap = 0x0002, + PreferDevice = 0x0004, + PreferOutline = 0x0008, + ForceOutline = 0x0010, + PreferMatch = 0x0020, + PreferQuality = 0x0040, + PreferAntialias = 0x0080, + NoAntialias = 0x0100, + OpenGLCompatible = 0x0200, + ForceIntegerMetrics = 0x0400, + NoFontMerging = 0x8000 }; enum Weight { diff --git a/src/gui/text/qfontengine_mac.mm b/src/gui/text/qfontengine_mac.mm index 8588214..fd662e3 100644 --- a/src/gui/text/qfontengine_mac.mm +++ b/src/gui/text/qfontengine_mac.mm @@ -303,12 +303,20 @@ bool QCoreTextFontEngineMulti::stringToCMap(const QChar *str, int len, QGlyphLay outGlyphs[idx] = tmpGlyphs[i] | fontIndex; outAdvances_x[idx] = QFixed::fromReal(tmpPoints[i + 1].x - tmpPoints[i].x); outAdvances_y[idx] = QFixed::fromReal(tmpPoints[i + 1].y - tmpPoints[i].y); + + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { + outAdvances_x[idx] = outAdvances_x[idx].ceil(); + outAdvances_y[idx] = outAdvances_y[idx].ceil(); + } } CGSize lastGlyphAdvance; CTFontGetAdvancesForGlyphs(runFont, kCTFontHorizontalOrientation, tmpGlyphs + glyphCount - 1, &lastGlyphAdvance, 1); outGlyphs[rtl ? 0 : (glyphCount - 1)] = tmpGlyphs[glyphCount - 1] | fontIndex; - outAdvances_x[rtl ? 0 : (glyphCount - 1)] = QFixed::fromReal(lastGlyphAdvance.width); + outAdvances_x[rtl ? 0 : (glyphCount - 1)] = + (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFixed::fromReal(lastGlyphAdvance.width).ceil() + : QFixed::fromReal(lastGlyphAdvance.width); } outGlyphs += glyphCount; outAttributes += glyphCount; @@ -378,8 +386,11 @@ bool QCoreTextFontEngine::stringToCMap(const QChar *, int, QGlyphLayout *, int * glyph_metrics_t QCoreTextFontEngine::boundingBox(const QGlyphLayout &glyphs) { QFixed w; - for (int i = 0; i < glyphs.numGlyphs; ++i) - w += glyphs.effectiveAdvance(i); + for (int i = 0; i < glyphs.numGlyphs; ++i) { + w += (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? glyphs.effectiveAdvance(i).ceil() + : glyphs.effectiveAdvance(i); + } return glyph_metrics_t(0, -(ascent()), w, ascent()+descent(), w, 0); } glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph) @@ -393,33 +404,51 @@ glyph_metrics_t QCoreTextFontEngine::boundingBox(glyph_t glyph) ret.y = -QFixed::fromReal(rect.origin.y) - ret.height; CGSize advances[1]; CTFontGetAdvancesForGlyphs(ctfont, kCTFontHorizontalOrientation, &g, advances, 1); - ret.xoff = QFixed::fromReal(advances[0].width).ceil(); - ret.yoff = QFixed::fromReal(advances[0].height).ceil(); + ret.xoff = QFixed::fromReal(advances[0].width); + ret.yoff = QFixed::fromReal(advances[0].height); + + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) { + ret.xoff = ret.xoff.ceil(); + ret.yoff = ret.yoff.ceil(); + } + return ret; } QFixed QCoreTextFontEngine::ascent() const { - return QFixed::fromReal(CTFontGetAscent(ctfont)).ceil(); + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFixed::fromReal(CTFontGetAscent(ctfont)).ceil() + : QFixed::fromReal(CTFontGetAscent(ctfont)); } QFixed QCoreTextFontEngine::descent() const { + QFixed d = QFixed::fromReal(CTFontGetDescent(ctfont)); + if (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + d = d.ceil(); + // subtract a pixel to even out the historical +1 in QFontMetrics::height(). // Fix in Qt 5. - return QFixed::fromReal(CTFontGetDescent(ctfont)).ceil() - 1; + return d - 1; } QFixed QCoreTextFontEngine::leading() const { - return QFixed::fromReal(CTFontGetLeading(ctfont)).ceil(); + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFixed::fromReal(CTFontGetLeading(ctfont)).ceil() + : QFixed::fromReal(CTFontGetLeading(ctfont)); } QFixed QCoreTextFontEngine::xHeight() const { - return QFixed::fromReal(CTFontGetXHeight(ctfont)).ceil(); + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFixed::fromReal(CTFontGetXHeight(ctfont)).ceil() + : QFixed::fromReal(CTFontGetXHeight(ctfont)); } QFixed QCoreTextFontEngine::averageCharWidth() const { // ### Need to implement properly and get the information from the OS/2 Table. - return QFontEngine::averageCharWidth(); + return (fontDef.styleStrategy & QFont::ForceIntegerMetrics) + ? QFontEngine::averageCharWidth().ceil() + : QFontEngine::averageCharWidth(); } qreal QCoreTextFontEngine::maxCharWidth() const |