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') 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') 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 87715cc4917e0edcc1090658ea09be508f47f3b7 Mon Sep 17 00:00:00 2001 From: Timo Jyrinki Date: Wed, 23 Mar 2016 09:41:50 +0000 Subject: Blacklist Mali-T760/Mali-T720 from supporting BGRA. Extend the blacklist with Mali-T760 and Mali-T720 as found on Meizu Pro 5 and Bq Aquaris M10 Ubuntu Editions. Reading from FBO like taking screenshots does not produce correct result otherwise. Initially reported at: https://launchpad.net/bugs/1557915 and https://launchpad.net/bugs/1559906 Change-Id: Ic875bd083277bf933863a3a50f8e874dd6e04365 Reviewed-by: Laszlo Agocs --- src/gui/opengl/qopenglframebufferobject.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/gui') diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index 5184283a31..0e1074f8d4 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -1281,9 +1281,13 @@ static inline QImage qt_gl_read_framebuffer_rgba8(const QSize &size, bool includ const char *renderer = reinterpret_cast(funcs->glGetString(GL_RENDERER)); const char *ver = reinterpret_cast(funcs->glGetString(GL_VERSION)); - // Blacklist PowerVR Rogue G6200 as it has problems with its BGRA support. + // Blacklist GPU chipsets that have problems with their BGRA support. const bool blackListed = (qstrcmp(renderer, "PowerVR Rogue G6200") == 0 - && ::strstr(ver, "1.3") != 0); + && ::strstr(ver, "1.3") != 0) || + (qstrcmp(renderer, "Mali-T760") == 0 + && ::strstr(ver, "3.1") != 0) || + (qstrcmp(renderer, "Mali-T720") == 0 + && ::strstr(ver, "3.1") != 0); const bool supports_bgra = has_bgra_ext && !blackListed; -- cgit v1.2.3 From a4e2f2e687ca7aec88ecf82f72d42ac61e17a5b9 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 4 Mar 2016 13:50:18 +0100 Subject: Fix possible crash in QImage::pixel() QImage::pixel() assumed that the color table was valid for the values in the bitmap. This was always wrong for indexed images with explicit no color table set and was wrong for mono images that were constructed from preexisting data. For mono images, we default to a black/white color table, like we do when constructing with uninitialized data. For indexed image, we always default to no color table, but instead of crashing in pixel(), we warn and return an undefined value. [ChangeLog][QtGui][Image] Fixed possible crash in QImage::pixel() for mono or indexed images. Change-Id: Ieaf19c03984badddfd06e1855a7e287b862adc70 Task-number: QTBUG-50745 Reviewed-by: Allan Sandfeld Jensen Reviewed-by: Gunnar Sletta --- src/gui/image/qimage.cpp | 57 ++++++++++++++++++++++++++++-------------------- src/gui/image/qimage_p.h | 2 +- 2 files changed, 34 insertions(+), 25 deletions(-) (limited to 'src/gui') diff --git a/src/gui/image/qimage.cpp b/src/gui/image/qimage.cpp index 6f649efcf4..29a688099b 100644 --- a/src/gui/image/qimage.cpp +++ b/src/gui/image/qimage.cpp @@ -98,35 +98,22 @@ QImageData::QImageData() { } -/*! \fn QImageData * QImageData::create(const QSize &size, QImage::Format format, int numColors) +/*! \fn QImageData * QImageData::create(const QSize &size, QImage::Format format) \internal Creates a new image data. Returns 0 if invalid parameters are give or anything else failed. */ -QImageData * QImageData::create(const QSize &size, QImage::Format format, int numColors) +QImageData * QImageData::create(const QSize &size, QImage::Format format) { - if (!size.isValid() || numColors < 0 || format == QImage::Format_Invalid) + if (!size.isValid() || format == QImage::Format_Invalid) return 0; // invalid parameter(s) uint width = size.width(); uint height = size.height(); uint depth = qt_depthForFormat(format); - switch (format) { - case QImage::Format_Mono: - case QImage::Format_MonoLSB: - numColors = 2; - break; - case QImage::Format_Indexed8: - numColors = qBound(0, numColors, 256); - break; - default: - numColors = 0; - break; - } - const int bytes_per_line = ((width * depth + 31) >> 5) << 2; // bytes per scanline (must be multiple of 4) // sanity check for potential overflows @@ -138,13 +125,16 @@ QImageData * QImageData::create(const QSize &size, QImage::Format format, int nu return 0; QScopedPointer d(new QImageData); - d->colortable.resize(numColors); - if (depth == 1) { + + switch (format) { + case QImage::Format_Mono: + case QImage::Format_MonoLSB: + d->colortable.resize(2); d->colortable[0] = QColor(Qt::black).rgba(); d->colortable[1] = QColor(Qt::white).rgba(); - } else { - for (int i = 0; i < numColors; ++i) - d->colortable[i] = 0; + break; + default: + break; } d->width = width; @@ -773,7 +763,7 @@ QImage::QImage() Q_DECL_NOEXCEPT QImage::QImage(int width, int height, Format format) : QPaintDevice() { - d = QImageData::create(QSize(width, height), format, 0); + d = QImageData::create(QSize(width, height), format); } /*! @@ -788,7 +778,7 @@ QImage::QImage(int width, int height, Format format) QImage::QImage(const QSize &size, Format format) : QPaintDevice() { - d = QImageData::create(size, format, 0); + d = QImageData::create(size, format); } @@ -832,6 +822,17 @@ QImageData *QImageData::create(uchar *data, int width, int height, int bpl, QIm d->cleanupFunction = cleanupFunction; d->cleanupInfo = cleanupInfo; + switch (format) { + case QImage::Format_Mono: + case QImage::Format_MonoLSB: + d->colortable.resize(2); + d->colortable[0] = QColor(Qt::black).rgba(); + d->colortable[1] = QColor(Qt::white).rgba(); + break; + default: + break; + } + return d; } @@ -2236,7 +2237,15 @@ QRgb QImage::pixel(int x, int y) const case Format_MonoLSB: return d->colortable.at((*(s + (x >> 3)) >> (x & 7)) & 1); case Format_Indexed8: - return d->colortable.at((int)s[x]); + { + int index = (int)s[x]; + if (index < d->colortable.size()) { + return d->colortable.at(index); + } else { + qWarning("QImage::pixel: color table index %d out of range.", index); + return 0; + } + } case Format_RGB32: return 0xff000000 | reinterpret_cast(s)[x]; case Format_ARGB32: // Keep old behaviour. diff --git a/src/gui/image/qimage_p.h b/src/gui/image/qimage_p.h index 0c0653e8ab..4979eab207 100644 --- a/src/gui/image/qimage_p.h +++ b/src/gui/image/qimage_p.h @@ -57,7 +57,7 @@ class QImageWriter; struct Q_GUI_EXPORT QImageData { // internal image data QImageData(); ~QImageData(); - static QImageData *create(const QSize &size, QImage::Format format, int numColors = 0); + static QImageData *create(const QSize &size, QImage::Format format); static QImageData *create(uchar *data, int w, int h, int bpl, QImage::Format format, bool readOnly, QImageCleanupFunction cleanupFunction = 0, void *cleanupInfo = 0); QAtomicInt ref; -- 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') 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