From 2119b86db25fac3165c562f9d40e5874de824c80 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 7 Mar 2016 16:29:31 +0100 Subject: QRawFont: fix UB in supportedWritingSystems() Found by UBSan: src/gui/text/qrawfont.cpp:647:55: runtime error: load of misaligned address 0x000001eeed26 for type 'quint32', which requires 4 byte alignment src/gui/text/qrawfont.cpp:648:50: runtime error: load of misaligned address 0x000001eeed02 for type 'quint32', which requires 4 byte alignment Fix by using the qFromBigEndian() overload that can read from unaligned memory. While touching the code, also disentangle the two loops so that operations are now performed in memory order instead of inter- leaved, use less magic numbers, and avoid a QByteArray detach. Change-Id: I26fa39726f6fa2e957b60863fa160280cf1dc9ac Reviewed-by: Eskil Abrahamsen Blomfeldt Reviewed-by: Konstantin Ritt --- src/gui/text/qrawfont.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'src/gui/text') diff --git a/src/gui/text/qrawfont.cpp b/src/gui/text/qrawfont.cpp index 59f13581dd..5d4044b096 100644 --- a/src/gui/text/qrawfont.cpp +++ b/src/gui/text/qrawfont.cpp @@ -627,18 +627,18 @@ QList QRawFont::supportedWritingSystems() const if (d->isValid()) { QByteArray os2Table = fontTable("OS/2"); if (os2Table.size() > 86) { - char *data = os2Table.data(); - quint32 *bigEndianUnicodeRanges = reinterpret_cast(data + 42); - quint32 *bigEndianCodepageRanges = reinterpret_cast(data + 78); + const uchar * const data = reinterpret_cast(os2Table.constData()); + const uchar * const bigEndianUnicodeRanges = data + 42; + const uchar * const bigEndianCodepageRanges = data + 78; quint32 unicodeRanges[4]; quint32 codepageRanges[2]; - for (int i=0; i<4; ++i) { - if (i < 2) - codepageRanges[i] = qFromBigEndian(bigEndianCodepageRanges[i]); - unicodeRanges[i] = qFromBigEndian(bigEndianUnicodeRanges[i]); - } + for (size_t i = 0; i < sizeof unicodeRanges / sizeof *unicodeRanges; ++i) + unicodeRanges[i] = qFromBigEndian(bigEndianUnicodeRanges + i * sizeof(quint32)); + + for (size_t i = 0; i < sizeof codepageRanges / sizeof *codepageRanges; ++i) + codepageRanges[i] = qFromBigEndian(bigEndianCodepageRanges + i * sizeof(quint32)); QSupportedWritingSystems ws = QPlatformFontDatabase::writingSystemsFromTrueTypeBits(unicodeRanges, codepageRanges); for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) { -- cgit v1.2.3 From c35795b413c6aedd6b02f03fdcaa5fb4888084d5 Mon Sep 17 00:00:00 2001 From: Gabriel de Dietrich Date: Tue, 22 Mar 2016 14:16:23 -0700 Subject: QFontEngine: Add handle() function Both QFont::handle() and QFont::freetypeFace() used to be available in Qt 4 but were removed in Qt 5. There's currently no API to get access to the native font handle, which the font engine holds in a way or another. Similar to the way it was in Qt 4, the actual handle type depends on the font engine currently in use. The types map as follows: Font Engine Native Handle ------------------------------------ DirectWrite IDWriteFontFace * Freetype FT_Face Mac CTFontRef Win HFONT All other font engines return a null handle. Change-Id: I3bea8259ac1378fd24079723aa6603bf9e74834c Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontengine.cpp | 5 +++++ src/gui/text/qfontengine_ft.cpp | 5 +++++ src/gui/text/qfontengine_ft_p.h | 1 + src/gui/text/qfontengine_p.h | 2 ++ 4 files changed, 13 insertions(+) (limited to 'src/gui/text') diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 03ad6a24e9..39348a52b0 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -1229,6 +1229,11 @@ int QFontEngine::glyphCount() const return count; } +Qt::HANDLE QFontEngine::handle() const +{ + return Q_NULLPTR; +} + const uchar *QFontEngine::getCMap(const uchar *table, uint tableSize, bool *isSymbolFont, int *cmapSize) { const uchar *header = table; diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index 8fbeff3596..ebfd2a8182 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -2005,6 +2005,11 @@ QFontEngine *QFontEngineFT::cloneWithSize(qreal pixelSize) const } } +Qt::HANDLE QFontEngineFT::handle() const +{ + return non_locked_face(); +} + QT_END_NAMESPACE #endif // QT_NO_FREETYPE diff --git a/src/gui/text/qfontengine_ft_p.h b/src/gui/text/qfontengine_ft_p.h index 6f05645a3f..a1bd21dab9 100644 --- a/src/gui/text/qfontengine_ft_p.h +++ b/src/gui/text/qfontengine_ft_p.h @@ -283,6 +283,7 @@ private: void setDefaultHintStyle(HintStyle style) Q_DECL_OVERRIDE; QFontEngine *cloneWithSize(qreal pixelSize) const Q_DECL_OVERRIDE; + Qt::HANDLE handle() const Q_DECL_OVERRIDE; bool initFromFontEngine(const QFontEngineFT *fontEngine); HintStyle defaultHintStyle() const { return default_hint_style; } diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index be9eaa5020..7ddc5c0c32 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -229,6 +229,8 @@ public: virtual QFontEngine *cloneWithSize(qreal /*pixelSize*/) const { return 0; } + virtual Qt::HANDLE handle() const; + void *harfbuzzFont() const; void *harfbuzzFace() const; bool supportsScript(QChar::Script script) const; -- cgit v1.2.3 From adc4e000fc1ffe1acba47ff932c092678a54b9f2 Mon Sep 17 00:00:00 2001 From: Alexander Volkov Date: Fri, 22 Jan 2016 14:56:18 +0300 Subject: QFontEngineFT: Apply hinting for non-scaled rotated glyphs Scaled hinted glyphs looks ugly, see QTBUG-24846. It was fixed in 6da6845f078e419ccb555fe1dd152e0ba82a7e88 by disabling hinting for them. But at the same time that commit also disabled hinting for glyphs with the most common transformation - rotating without scaling. Detect this type of transformation and don't disable hinting for it. Change-Id: I0e69a2b60e7e4bc24e9efc4fdedb984df07ad15c Task-number: QTBUG-50574 Reviewed-by: Friedemann Kleint Reviewed-by: Konstantin Ritt Reviewed-by: Eskil Abrahamsen Blomfeldt --- src/gui/text/qfontengine_ft.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'src/gui/text') diff --git a/src/gui/text/qfontengine_ft.cpp b/src/gui/text/qfontengine_ft.cpp index ebfd2a8182..361702681f 100644 --- a/src/gui/text/qfontengine_ft.cpp +++ b/src/gui/text/qfontengine_ft.cpp @@ -1780,6 +1780,12 @@ void QFontEngineFT::unlockAlphaMapForGlyph() QFontEngine::unlockAlphaMapForGlyph(); } +static inline bool is2dRotation(const QTransform &t) +{ + return qFuzzyCompare(t.m11(), t.m22()) && qFuzzyCompare(t.m12(), -t.m21()) + && qFuzzyCompare(t.m11()*t.m22() - t.m12()*t.m21(), 1.0); +} + QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g, QFixed subPixelPosition, GlyphFormat format, @@ -1793,7 +1799,7 @@ QFontEngineFT::Glyph *QFontEngineFT::loadGlyphFor(glyph_t g, Glyph *glyph = glyphSet != 0 ? glyphSet->getGlyph(g, subPixelPosition) : 0; if (!glyph || glyph->format != format || (!fetchBoundingBox && !glyph->data)) { QScopedValueRollback saved_default_hint_style(default_hint_style); - if (t.type() >= QTransform::TxScale) + if (t.type() >= QTransform::TxScale && !is2dRotation(t)) default_hint_style = HintNone; // disable hinting if the glyphs are transformed lockFace(); -- cgit v1.2.3 From 05ed49519120fa2cc4e00417efa0524ba00228a4 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 4 Mar 2016 13:15:03 +0100 Subject: Fix possible out-of-bounds access when making distance fields While extremely unlikely, there is a theoretical possibility that the '0' glyph of a given font will have a width or height of 1 pixel, in which case the (x + 1) / 2 way of getting the center would give us an out of bounds pixel. We just default to true in this case, since we cannot make any assumption based on the 0 glyph if it doesn't make any sense. If the image is invalid, we default to false. Change-Id: I36cea0b80c9d55aa10eb65db44d1b7ec8a40fc8c Reviewed-by: Yoann Lopes --- src/gui/text/qdistancefield.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/gui/text') diff --git a/src/gui/text/qdistancefield.cpp b/src/gui/text/qdistancefield.cpp index 4d189786a1..6a7019bc3c 100644 --- a/src/gui/text/qdistancefield.cpp +++ b/src/gui/text/qdistancefield.cpp @@ -687,8 +687,10 @@ static void makeDistanceField(QDistanceFieldData *data, const QPainterPath &path static bool imageHasNarrowOutlines(const QImage &im) { - if (im.isNull()) + if (im.isNull() || im.width() < 1 || im.height() < 1) return false; + else if (im.width() == 1 || im.height() == 1) + return true; int minHThick = 999; int minVThick = 999; -- cgit v1.2.3