From 69fb70f6b3c88d4d2bb5ca97dbb7f77f42c828c5 Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Mon, 9 Jul 2012 15:52:13 +0200 Subject: Support fallback fonts in DirectWrite font engine When selecting fallback fonts for a DirectWrite font, we would cast the font engine to QWindowsFontEngine and get unpredictable results and crashes. This change factors out getting the LOGFONT data from the QFontDef struct and will use this to create a new DirectWrite engine. Task-number: QTBUG-22658 Change-Id: I743944d9a44d8742b47b1aa3354532493362cc4a Reviewed-by: Jiang Jiang --- .../platforms/windows/qwindowsfontengine.cpp | 66 +++++++++++++++++++++- 1 file changed, 63 insertions(+), 3 deletions(-) (limited to 'src/plugins/platforms/windows/qwindowsfontengine.cpp') diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index d7f48e59c5..a78b6f1620 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -50,6 +50,7 @@ #include "qwindowscontext.h" #include "qwindowsfontdatabase.h" #include "qtwindows_additional.h" +#include "qwindowsfontenginedirectwrite.h" #include // glyph_metrics_t #include @@ -74,6 +75,10 @@ # include "qplatformfunctions_wince.h" #endif +#if !defined(QT_NO_DIRECTWRITE) +# include +#endif + QT_BEGIN_NAMESPACE //### mingw needed define @@ -1318,10 +1323,65 @@ void QWindowsMultiFontEngine::loadEngine(int at) Q_ASSERT(at < engines.size()); Q_ASSERT(engines.at(at) == 0); + QFontEngine *fontEngine = engines.at(0); + QSharedPointer data; + LOGFONT lf; + +#ifndef QT_NO_DIRECTWRITE + if (fontEngine->type() == QFontEngine::DirectWrite) { + QWindowsFontEngineDirectWrite *fe = static_cast(fontEngine); + lf = QWindowsFontDatabase::fontDefToLOGFONT(fe->fontDef); + + data = fe->fontEngineData(); + } else +#endif + { + QWindowsFontEngine *fe = static_cast(fontEngine); + lf = fe->logFont(); + + data = fe->fontEngineData(); + } + const QString fam = fallbacks.at(at-1); - QWindowsFontEngine *fe = static_cast(engines.at(0)); - LOGFONT lf = fe->logFont(); memcpy(lf.lfFaceName, fam.utf16(), sizeof(wchar_t) * qMin(fam.length() + 1, 32)); // 32 = Windows hard-coded + +#ifndef QT_NO_DIRECTWRITE + if (fontEngine->type() == QFontEngine::DirectWrite) { + const QString nameSubstitute = QWindowsFontEngineDirectWrite::fontNameSubstitute(QString::fromWCharArray(lf.lfFaceName)); + memcpy(lf.lfFaceName, nameSubstitute.utf16(), + sizeof(wchar_t) * qMin(nameSubstitute.length() + 1, LF_FACESIZE)); + + IDWriteFont *directWriteFont = 0; + HRESULT hr = data->directWriteGdiInterop->CreateFontFromLOGFONT(&lf, &directWriteFont); + if (FAILED(hr)) { + qErrnoWarning("%s: CreateFontFromLOGFONT failed", __FUNCTION__); + } else { + IDWriteFontFace *directWriteFontFace = NULL; + HRESULT hr = directWriteFont->CreateFontFace(&directWriteFontFace); + if (SUCCEEDED(hr)) { + QWindowsFontEngineDirectWrite *fedw = new QWindowsFontEngineDirectWrite(directWriteFontFace, + fontEngine->fontDef.pixelSize, + data); + fedw->setObjectName(QStringLiteral("QWindowsFontEngineDirectWrite_") + fontEngine->fontDef.family); + + fedw->fontDef = fontDef; + fedw->ref.ref(); + engines[at] = fedw; + + if (QWindowsContext::verboseFonts) + qDebug("%s %d %s", __FUNCTION__, at, qPrintable(fam)); + + return; + } else { + qErrnoWarning("%s: CreateFontFace failed", __FUNCTION__); + } + + } + } +#endif + + // Get here if original font is not DirectWrite or DirectWrite creation failed for some + // reason HFONT hfont = CreateFontIndirect(&lf); bool stockFont = false; @@ -1329,7 +1389,7 @@ void QWindowsMultiFontEngine::loadEngine(int at) hfont = (HFONT)GetStockObject(ANSI_VAR_FONT); stockFont = true; } - engines[at] = new QWindowsFontEngine(fam, hfont, stockFont, lf, fe->fontEngineData()); + engines[at] = new QWindowsFontEngine(fam, hfont, stockFont, lf, data); engines[at]->ref.ref(); engines[at]->fontDef = fontDef; if (QWindowsContext::verboseFonts) -- cgit v1.2.3