diff options
author | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-03 15:45:02 +0300 |
---|---|---|
committer | Konstantin Tokarev <annulen@yandex.ru> | 2016-08-15 18:27:06 +0000 |
commit | ac1e87d9f373ad649d989f254b37d2f29ddf25fe (patch) | |
tree | b39d2a1c3d207fd2f025301a4908c472c95245a4 /src/gui | |
parent | 869513a49f7902b5942e439a972807583dab9bf9 (diff) |
Added capHeight() to QRawFont and QFontMetrics(F)
Cap height is an important metric of font, in particular it is
required to make decent implementation of "initial-letter"
CSS property in QtWebKit.
Note that some fonts lack cap height metadata, so we need to
fall back to measuring H letter height.
Change-Id: Icf69d92159d070889085e20d31f2e397d796d940
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
Diffstat (limited to 'src/gui')
-rw-r--r-- | src/gui/text/qfontengine.cpp | 15 | ||||
-rw-r--r-- | src/gui/text/qfontengine_ft.cpp | 13 | ||||
-rw-r--r-- | src/gui/text/qfontengine_ft_p.h | 1 | ||||
-rw-r--r-- | src/gui/text/qfontengine_p.h | 4 | ||||
-rw-r--r-- | src/gui/text/qfontengine_qpf2.cpp | 5 | ||||
-rw-r--r-- | src/gui/text/qfontengine_qpf2_p.h | 1 | ||||
-rw-r--r-- | src/gui/text/qfontmetrics.cpp | 36 | ||||
-rw-r--r-- | src/gui/text/qfontmetrics.h | 2 | ||||
-rw-r--r-- | src/gui/text/qrawfont.cpp | 17 | ||||
-rw-r--r-- | src/gui/text/qrawfont.h | 1 |
10 files changed, 95 insertions, 0 deletions
diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index adc8f634dc..dbd47151bd 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -418,6 +418,13 @@ glyph_metrics_t QFontEngine::boundingBox(glyph_t glyph, const QTransform &matrix return metrics; } +QFixed QFontEngine::calculatedCapHeight() const +{ + const glyph_t glyph = glyphIndex('H'); + glyph_metrics_t bb = const_cast<QFontEngine *>(this)->boundingBox(glyph); + return bb.height; +} + QFixed QFontEngine::xHeight() const { const glyph_t glyph = glyphIndex('x'); @@ -1703,6 +1710,11 @@ QFixed QFontEngineBox::ascent() const return _size; } +QFixed QFontEngineBox::capHeight() const +{ + return _size; +} + QFixed QFontEngineBox::descent() const { return 0; @@ -2163,6 +2175,9 @@ glyph_metrics_t QFontEngineMulti::boundingBox(glyph_t glyph) QFixed QFontEngineMulti::ascent() const { return engine(0)->ascent(); } +QFixed QFontEngineMulti::capHeight() const +{ return engine(0)->capHeight(); } + QFixed QFontEngineMulti::descent() const { return engine(0)->descent(); } diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 51b1418bc3..b79fa6e9db 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -414,6 +414,7 @@ QFontEngine::Properties QFreetypeFace::properties() const p.italicAngle = 0; p.capHeight = p.ascent; p.lineWidth = face->underline_thickness; + return p; } @@ -1299,6 +1300,18 @@ QFixed QFontEngineFT::ascent() const return v; } +QFixed QFontEngineFT::capHeight() const +{ + TT_OS2 *os2 = (TT_OS2 *)FT_Get_Sfnt_Table(freetype->face, ft_sfnt_os2); + if (os2 && os2->version >= 2) { + lockFace(); + QFixed answer = QFixed::fromFixed(FT_MulFix(os2->sCapHeight, freetype->face->size->metrics.y_scale)); + unlockFace(); + return answer; + } + return calculatedCapHeight(); +} + QFixed QFontEngineFT::descent() const { QFixed v = QFixed::fromFixed(-metrics.descender); diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index 3cdf0cda47..5ca3721c71 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -209,6 +209,7 @@ private: int synthesized() const Q_DECL_OVERRIDE; QFixed ascent() const Q_DECL_OVERRIDE; + QFixed capHeight() const Q_DECL_OVERRIDE; QFixed descent() const Q_DECL_OVERRIDE; QFixed leading() const Q_DECL_OVERRIDE; QFixed xHeight() const Q_DECL_OVERRIDE; diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index f3eeddab41..69331cb0bb 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -211,6 +211,7 @@ public: glyph_metrics_t tightBoundingBox(const QGlyphLayout &glyphs); virtual QFixed ascent() const = 0; + virtual QFixed capHeight() const = 0; virtual QFixed descent() const = 0; virtual QFixed leading() const = 0; virtual QFixed xHeight() const; @@ -348,6 +349,7 @@ protected: QFixed lastRightBearing(const QGlyphLayout &glyphs, bool round = false); inline void setUserData(const QVariant &userData) { m_userData = userData; } + QFixed calculatedCapHeight() const; private: struct GlyphCacheEntry { @@ -414,6 +416,7 @@ public: virtual QFontEngine *cloneWithSize(qreal pixelSize) const Q_DECL_OVERRIDE; virtual QFixed ascent() const Q_DECL_OVERRIDE; + virtual QFixed capHeight() const Q_DECL_OVERRIDE; virtual QFixed descent() const Q_DECL_OVERRIDE; virtual QFixed leading() const Q_DECL_OVERRIDE; virtual qreal maxCharWidth() const Q_DECL_OVERRIDE; @@ -451,6 +454,7 @@ public: virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = 0, qreal *rightBearing = 0) Q_DECL_OVERRIDE; virtual QFixed ascent() const Q_DECL_OVERRIDE; + virtual QFixed capHeight() const Q_DECL_OVERRIDE; virtual QFixed descent() const Q_DECL_OVERRIDE; virtual QFixed leading() const Q_DECL_OVERRIDE; virtual QFixed xHeight() const Q_DECL_OVERRIDE; diff --git a/src/gui/text/qfontengine_qpf2.cpp b/src/gui/text/qfontengine_qpf2.cpp index 2e4af09550..110d512d39 100644 --- a/src/gui/text/qfontengine_qpf2.cpp +++ b/src/gui/text/qfontengine_qpf2.cpp @@ -459,6 +459,11 @@ QFixed QFontEngineQPF2::ascent() const return QFixed::fromReal(extractHeaderField(fontData, Tag_Ascent).value<qreal>()); } +QFixed QFontEngineQPF2::capHeight() const +{ + return calculatedCapHeight(); +} + QFixed QFontEngineQPF2::descent() const { return QFixed::fromReal(extractHeaderField(fontData, Tag_Descent).value<qreal>()); diff --git a/src/gui/text/qfontengine_qpf2_p.h b/src/gui/text/qfontengine_qpf2_p.h index 50aac245c1..e5c38ffbaf 100644 --- a/src/gui/text/qfontengine_qpf2_p.h +++ b/src/gui/text/qfontengine_qpf2_p.h @@ -172,6 +172,7 @@ public: glyph_metrics_t boundingBox(glyph_t glyph) Q_DECL_OVERRIDE; QFixed ascent() const Q_DECL_OVERRIDE; + QFixed capHeight() const Q_DECL_OVERRIDE; QFixed descent() const Q_DECL_OVERRIDE; QFixed leading() const Q_DECL_OVERRIDE; qreal maxCharWidth() const Q_DECL_OVERRIDE; diff --git a/src/gui/text/qfontmetrics.cpp b/src/gui/text/qfontmetrics.cpp index 2189923b25..aca59d0288 100644 --- a/src/gui/text/qfontmetrics.cpp +++ b/src/gui/text/qfontmetrics.cpp @@ -274,6 +274,24 @@ int QFontMetrics::ascent() const return qRound(engine->ascent()); } +/*! + Returns the cap height of the font. + + \since 5.8 + + The cap height of a font is the height of a capital letter above + the baseline. It specifically is the height of capital letters + that are flat - such as H or I - as opposed to round letters such + as O, or pointed letters like A, both of which may display overshoot. + + \sa ascent() +*/ +int QFontMetrics::capHeight() const +{ + QFontEngine *engine = d->engineForScript(QChar::Script_Common); + Q_ASSERT(engine != 0); + return qRound(engine->capHeight()); +} /*! Returns the descent of the font. @@ -1138,6 +1156,24 @@ qreal QFontMetricsF::ascent() const return engine->ascent().toReal(); } +/*! + Returns the cap height of the font. + + \since 5.8 + + The cap height of a font is the height of a capital letter above + the baseline. It specifically is the height of capital letters + that are flat - such as H or I - as opposed to round letters such + as O, or pointed letters like A, both of which may display overshoot. + + \sa ascent() +*/ +qreal QFontMetricsF::capHeight() const +{ + QFontEngine *engine = d->engineForScript(QChar::Script_Common); + Q_ASSERT(engine != 0); + return engine->capHeight().toReal(); +} /*! Returns the descent of the font. diff --git a/src/gui/text/qfontmetrics.h b/src/gui/text/qfontmetrics.h index 22e51f29f7..3eac309092 100644 --- a/src/gui/text/qfontmetrics.h +++ b/src/gui/text/qfontmetrics.h @@ -73,6 +73,7 @@ public: { qSwap(d, other.d); } int ascent() const; + int capHeight() const; int descent() const; int height() const; int leading() const; @@ -146,6 +147,7 @@ public: void swap(QFontMetricsF &other) { qSwap(d, other.d); } qreal ascent() const; + qreal capHeight() const; qreal descent() const; qreal height() const; qreal leading() const; diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index 19ac4f1dbc..1fbe0ce9d1 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -325,6 +325,23 @@ qreal QRawFont::ascent() const } /*! + Returns the cap height of this QRawFont in pixel units. + + \since 5.8 + + The cap height of a font is the height of a capital letter above + the baseline. It specifically is the height of capital letters + that are flat - such as H or I - as opposed to round letters such + as O, or pointed letters like A, both of which may display overshoot. + + \sa QFontMetricsF::capHeight() +*/ +qreal QRawFont::capHeight() const +{ + return d->isValid() ? d->fontEngine->capHeight().toReal() : 0.0; +} + +/*! Returns the descent of this QRawFont in pixel units. \sa QFontMetricsF::descent() diff --git a/src/gui/text/qrawfont.h b/src/gui/text/qrawfont.h index 5791c6af16..0252e62370 100644 --- a/src/gui/text/qrawfont.h +++ b/src/gui/text/qrawfont.h @@ -118,6 +118,7 @@ public: QFont::HintingPreference hintingPreference() const; qreal ascent() const; + qreal capHeight() const; qreal descent() const; qreal leading() const; qreal xHeight() const; |