From ac1e87d9f373ad649d989f254b37d2f29ddf25fe Mon Sep 17 00:00:00 2001 From: Konstantin Tokarev Date: Wed, 3 Aug 2016 15:45:02 +0300 Subject: 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 --- .../platforms/windows/qwindowsfontengine.cpp | 57 ++++++++++++++++++++++ src/plugins/platforms/windows/qwindowsfontengine.h | 1 + .../windows/qwindowsfontenginedirectwrite.cpp | 12 +++++ .../windows/qwindowsfontenginedirectwrite.h | 2 + 4 files changed, 72 insertions(+) (limited to 'src/plugins/platforms/windows') diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index 744d882bb2..12340182af 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -192,6 +192,7 @@ void QWindowsFontEngine::getCMap() lineWidth = otm->otmsUnderscoreSize; fsType = otm->otmfsType; free(otm); + } else { unitsPerEm = tm.tmHeight; } @@ -540,6 +541,62 @@ QFixed QWindowsFontEngine::leading() const return tm.tmExternalLeading; } +namespace { +# pragma pack(1) + + struct OS2Table + { + quint16 version; + qint16 avgCharWidth; + quint16 weightClass; + quint16 widthClass; + quint16 type; + qint16 subscriptXSize; + qint16 subscriptYSize; + qint16 subscriptXOffset; + qint16 subscriptYOffset; + qint16 superscriptXSize; + qint16 superscriptYSize; + qint16 superscriptXOffset; + qint16 superscriptYOffset; + qint16 strikeOutSize; + qint16 strikeOutPosition; + qint16 familyClass; + quint8 panose[10]; + quint32 unicodeRanges[4]; + quint8 vendorID[4]; + quint16 selection; + quint16 firstCharIndex; + quint16 lastCharIndex; + qint16 typoAscender; + qint16 typoDescender; + qint16 typoLineGap; + quint16 winAscent; + quint16 winDescent; + quint32 codepageRanges[2]; + qint16 height; + qint16 capHeight; + quint16 defaultChar; + quint16 breakChar; + quint16 maxContext; + }; + +# pragma pack() +} + +QFixed QWindowsFontEngine::capHeight() const +{ + const QByteArray tableData = getSfntTable(MAKE_TAG('O', 'S', '/', '2')); + if (tableData.size() >= sizeof(OS2Table)) { + const OS2Table *table = reinterpret_cast(tableData.constData()); + if (qFromBigEndian(table->version) >= 2) { + qint16 capHeight = qFromBigEndian(table->capHeight); + if (capHeight > 0) + return QFixed(capHeight) / designToDevice; + } + } + return calculatedCapHeight(); +} QFixed QWindowsFontEngine::xHeight() const { diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h index 921351a4b0..b63d8fd282 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.h +++ b/src/plugins/platforms/windows/qwindowsfontengine.h @@ -103,6 +103,7 @@ public: QFixed descent() const Q_DECL_OVERRIDE; QFixed leading() const Q_DECL_OVERRIDE; QFixed xHeight() const Q_DECL_OVERRIDE; + QFixed capHeight() const Q_DECL_OVERRIDE; QFixed averageCharWidth() const Q_DECL_OVERRIDE; qreal maxCharWidth() const Q_DECL_OVERRIDE; qreal minLeftBearing() const Q_DECL_OVERRIDE; diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp index 5408ff41e5..18be3b0ce6 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp @@ -208,6 +208,7 @@ QWindowsFontEngineDirectWrite::QWindowsFontEngineDirectWrite(IDWriteFontFace *di , m_lineThickness(-1) , m_unitsPerEm(-1) , m_ascent(-1) + , m_capHeight(-1) , m_descent(-1) , m_xHeight(-1) , m_lineGap(-1) @@ -244,6 +245,7 @@ void QWindowsFontEngineDirectWrite::collectMetrics() m_lineThickness = DESIGN_TO_LOGICAL(metrics.underlineThickness); m_ascent = DESIGN_TO_LOGICAL(metrics.ascent); + m_capHeight = DESIGN_TO_LOGICAL(metrics.capHeight); m_descent = DESIGN_TO_LOGICAL(metrics.descent); m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight); m_lineGap = DESIGN_TO_LOGICAL(metrics.lineGap); @@ -461,6 +463,16 @@ QFixed QWindowsFontEngineDirectWrite::ascent() const : m_ascent; } +QFixed QWindowsFontEngineDirectWrite::capHeight() const +{ + if (m_capHeight <= 0) + return calculatedCapHeight(); + + return fontDef.styleStrategy & QFont::ForceIntegerMetrics + ? m_capHeight.round() + : m_capHeight; +} + QFixed QWindowsFontEngineDirectWrite::descent() const { return fontDef.styleStrategy & QFont::ForceIntegerMetrics diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h index f038dcfde4..fb2df00b7e 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h @@ -87,6 +87,7 @@ public: const QTransform &matrix, GlyphFormat) 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; @@ -122,6 +123,7 @@ private: QFixed m_underlinePosition; int m_unitsPerEm; QFixed m_ascent; + QFixed m_capHeight; QFixed m_descent; QFixed m_xHeight; QFixed m_lineGap; -- cgit v1.2.3