diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2016-09-20 13:58:18 +0200 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2016-09-27 07:59:56 +0000 |
commit | 6af82fe9fd19361f56ea4bf5a6be371722bafde3 (patch) | |
tree | ef9539f2c61ccc4107c59e96bf3072a66db1803e /src/plugins | |
parent | 8cd28ea8850c5365c47dd65de16f528e2e223835 (diff) |
Windows: Fix crash when loading color fonts from data
When color fonts are loaded from data, the font returned will
be a DirectWrite engine even the hinting preference does not
require it. This would cause a crash as we unconditionally cast
the pointer to QWindowsFontEngine*.
Using GDI and the unique family name hack to load the font from
data works fine, but we need to make sure we reference count
the font resource in this case, so we have to implement the
setUniqueFamilyName() logic in the DirectWrite engine as well
for this specific case.
[ChangeLog][Windows] Fixed crash when loading color fonts from
data.
Task-number: QTBUG-55595
Change-Id: I05443e8a396105da68ac4872b48339130b86c7f6
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src/plugins')
3 files changed, 35 insertions, 5 deletions
diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 314da702eb..bc237bc88c 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -1231,8 +1231,23 @@ QT_WARNING_POP Q_ASSERT(fontEngine->ref.load() == 0); // Override the generated font name - static_cast<QWindowsFontEngine *>(fontEngine)->setUniqueFamilyName(uniqueFamilyName); - fontEngine->fontDef.family = actualFontName; + switch (fontEngine->type()) { + case QFontEngine::Win: + static_cast<QWindowsFontEngine *>(fontEngine)->setUniqueFamilyName(uniqueFamilyName); + fontEngine->fontDef.family = actualFontName; + break; + +#if !defined(QT_NO_DIRECTWRITE) + case QFontEngine::DirectWrite: + static_cast<QWindowsFontEngineDirectWrite *>(fontEngine)->setUniqueFamilyName(uniqueFamilyName); + fontEngine->fontDef.family = actualFontName; + break; +#endif // !QT_NO_DIRECTWRITE + + default: + Q_ASSERT_X(false, Q_FUNC_INFO, "Unhandled font engine."); + } + UniqueFontData uniqueData; uniqueData.handle = fontHandle; uniqueData.refCount.ref(); diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp index 49eb7cfdec..0fdd4615f6 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp @@ -48,6 +48,8 @@ #include <QtCore/QVarLengthArray> #include <private/qstringiterator_p.h> #include <QtCore/private/qsystemlibrary_p.h> +#include <QtGui/private/qguiapplication_p.h> +#include <qpa/qplatformintegration.h> #if defined(QT_USE_DIRECTWRITE2) # include <dwrite_2.h> @@ -233,6 +235,11 @@ QWindowsFontEngineDirectWrite::~QWindowsFontEngineDirectWrite() if (m_directWriteBitmapRenderTarget != 0) m_directWriteBitmapRenderTarget->Release(); + + if (!m_uniqueFamilyName.isEmpty()) { + QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase(); + static_cast<QWindowsFontDatabase *>(pfdb)->derefUniqueFont(m_uniqueFamilyName); + } } void QWindowsFontEngineDirectWrite::collectMetrics() @@ -765,12 +772,17 @@ QImage QWindowsFontEngineDirectWrite::alphaRGBMapForGlyph(glyph_t t, QFontEngine *QWindowsFontEngineDirectWrite::cloneWithSize(qreal pixelSize) const { - QFontEngine *fontEngine = new QWindowsFontEngineDirectWrite(m_directWriteFontFace, - pixelSize, - m_fontEngineData); + QWindowsFontEngineDirectWrite *fontEngine = new QWindowsFontEngineDirectWrite(m_directWriteFontFace, + pixelSize, + m_fontEngineData); fontEngine->fontDef = fontDef; fontEngine->fontDef.pixelSize = pixelSize; + if (!m_uniqueFamilyName.isEmpty()) { + fontEngine->setUniqueFamilyName(m_uniqueFamilyName); + QPlatformFontDatabase *pfdb = QGuiApplicationPrivate::platformIntegration()->fontDatabase(); + static_cast<QWindowsFontDatabase *>(pfdb)->refUniqueFont(m_uniqueFamilyName); + } return fontEngine; } diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h index f038dcfde4..37e511ce3e 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h @@ -108,6 +108,8 @@ public: IDWriteFontFace *directWriteFontFace() const { return m_directWriteFontFace; } + void setUniqueFamilyName(const QString &newName) { m_uniqueFamilyName = newName; } + private: QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform); void collectMetrics(); @@ -126,6 +128,7 @@ private: QFixed m_xHeight; QFixed m_lineGap; FaceId m_faceId; + QString m_uniqueFamilyName; }; QT_END_NAMESPACE |