From e95d94cbbdcb6e7f7f87f1e636a31f21cc5e8563 Mon Sep 17 00:00:00 2001 From: Miikka Heikkinen Date: Mon, 23 Apr 2012 14:27:02 +0300 Subject: Windows: Fix QRawFont loading from data. The implementation for loading QRawFont from data was missing from Windows QPA plugin. For freetype font database, just called the parent QBasicFontDatabse implementation. For native font database, ported the implementation from Qt 4.8 qrawfont_win.cpp. Task-number: QTBUG-24197 Change-Id: Ia784d4cbc4f37c925aa49e53d04faf06a7169a73 Reviewed-by: Eskil Abrahamsen Blomfeldt --- .../platforms/windows/qwindowsfontdatabase.cpp | 632 ++++++++++++++++++++- .../platforms/windows/qwindowsfontdatabase.h | 9 + .../platforms/windows/qwindowsfontdatabase_ft.cpp | 2 +- .../platforms/windows/qwindowsfontengine.cpp | 14 +- src/plugins/platforms/windows/qwindowsfontengine.h | 1 + 5 files changed, 653 insertions(+), 5 deletions(-) (limited to 'src/plugins') diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp index 835c979579..36074b0fa9 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.cpp @@ -62,6 +62,468 @@ QT_BEGIN_NAMESPACE +// Helper classes for creating font engines directly from font data +namespace { + + template + struct BigEndian + { + quint8 data[sizeof(T)]; + + operator T() const + { + T littleEndian = 0; + for (int i = 0; i < int(sizeof(T)); ++i) + littleEndian |= data[i] << ((sizeof(T) - i - 1) * 8); + + return littleEndian; + } + + BigEndian &operator=(const T &t) + { + for (int i = 0; i < int(sizeof(T)); ++i) + data[i] = ((t >> (sizeof(T) - i - 1) * 8) & 0xff); + + return *this; + } + }; + +# pragma pack(1) + + // Common structure for all formats of the "name" table + struct NameTable + { + BigEndian format; + BigEndian count; + BigEndian stringOffset; + }; + + struct NameRecord + { + BigEndian platformID; + BigEndian encodingID; + BigEndian languageID; + BigEndian nameID; + BigEndian length; + BigEndian offset; + }; + + struct OffsetSubTable + { + BigEndian scalerType; + BigEndian numTables; + BigEndian searchRange; + BigEndian entrySelector; + BigEndian rangeShift; + }; + + struct TableDirectory + { + BigEndian identifier; + BigEndian checkSum; + BigEndian offset; + BigEndian length; + }; + + struct OS2Table + { + BigEndian version; + BigEndian avgCharWidth; + BigEndian weightClass; + BigEndian widthClass; + BigEndian type; + BigEndian subscriptXSize; + BigEndian subscriptYSize; + BigEndian subscriptXOffset; + BigEndian subscriptYOffset; + BigEndian superscriptXSize; + BigEndian superscriptYSize; + BigEndian superscriptXOffset; + BigEndian superscriptYOffset; + BigEndian strikeOutSize; + BigEndian strikeOutPosition; + BigEndian familyClass; + quint8 panose[10]; + BigEndian unicodeRanges[4]; + quint8 vendorID[4]; + BigEndian selection; + BigEndian firstCharIndex; + BigEndian lastCharIndex; + BigEndian typoAscender; + BigEndian typoDescender; + BigEndian typoLineGap; + BigEndian winAscent; + BigEndian winDescent; + BigEndian codepageRanges[2]; + BigEndian height; + BigEndian capHeight; + BigEndian defaultChar; + BigEndian breakChar; + BigEndian maxContext; + }; + +# pragma pack() + + class EmbeddedFont + { + public: + EmbeddedFont(const QByteArray &fontData) : m_fontData(fontData) {} + + QString changeFamilyName(const QString &newFamilyName); + QByteArray data() const { return m_fontData; } + TableDirectory *tableDirectoryEntry(const QByteArray &tagName); + QString familyName(TableDirectory *nameTableDirectory = 0); + + private: + QByteArray m_fontData; + }; + + TableDirectory *EmbeddedFont::tableDirectoryEntry(const QByteArray &tagName) + { + Q_ASSERT(tagName.size() == 4); + + const BigEndian *tagIdPtr = + reinterpret_cast *>(tagName.constData()); + quint32 tagId = *tagIdPtr; + + OffsetSubTable *offsetSubTable = reinterpret_cast(m_fontData.data()); + TableDirectory *tableDirectory = reinterpret_cast(offsetSubTable + 1); + + TableDirectory *nameTableDirectoryEntry = 0; + for (int i=0; inumTables; ++i, ++tableDirectory) { + if (tableDirectory->identifier == tagId) { + nameTableDirectoryEntry = tableDirectory; + break; + } + } + + return nameTableDirectoryEntry; + } + + QString EmbeddedFont::familyName(TableDirectory *nameTableDirectoryEntry) + { + QString name; + + if (nameTableDirectoryEntry == 0) + nameTableDirectoryEntry = tableDirectoryEntry("name"); + + if (nameTableDirectoryEntry != 0) { + NameTable *nameTable = reinterpret_cast(m_fontData.data() + + nameTableDirectoryEntry->offset); + NameRecord *nameRecord = reinterpret_cast(nameTable + 1); + for (int i = 0; i < nameTable->count; ++i, ++nameRecord) { + if (nameRecord->nameID == 1 + && nameRecord->platformID == 3 // Windows + && nameRecord->languageID == 0x0409) { // US English + const void *ptr = reinterpret_cast(nameTable) + + nameTable->stringOffset + + nameRecord->offset; + + const BigEndian *s = reinterpret_cast *>(ptr); + const BigEndian *e = s + nameRecord->length / sizeof(quint16); + while (s != e) + name += QChar(*s++); + break; + } + } + } + + return name; + } + + QString EmbeddedFont::changeFamilyName(const QString &newFamilyName) + { + TableDirectory *nameTableDirectoryEntry = tableDirectoryEntry("name"); + if (nameTableDirectoryEntry == 0) + return QString(); + + QString oldFamilyName = familyName(nameTableDirectoryEntry); + + // Reserve size for name table header, five required name records and string + const int requiredRecordCount = 5; + quint16 nameIds[requiredRecordCount] = { 1, 2, 3, 4, 6 }; + + int sizeOfHeader = sizeof(NameTable) + sizeof(NameRecord) * requiredRecordCount; + int newFamilyNameSize = newFamilyName.size() * sizeof(quint16); + + const QString regularString = QString::fromLatin1("Regular"); + int regularStringSize = regularString.size() * sizeof(quint16); + + // Align table size of table to 32 bits (pad with 0) + int fullSize = ((sizeOfHeader + newFamilyNameSize + regularStringSize) & ~3) + 4; + + QByteArray newNameTable(fullSize, char(0)); + + { + NameTable *nameTable = reinterpret_cast(newNameTable.data()); + nameTable->count = requiredRecordCount; + nameTable->stringOffset = sizeOfHeader; + + NameRecord *nameRecord = reinterpret_cast(nameTable + 1); + for (int i = 0; i < requiredRecordCount; ++i, nameRecord++) { + nameRecord->nameID = nameIds[i]; + nameRecord->encodingID = 1; + nameRecord->languageID = 0x0409; + nameRecord->platformID = 3; + nameRecord->length = newFamilyNameSize; + + // Special case for sub-family + if (nameIds[i] == 4) { + nameRecord->offset = newFamilyNameSize; + nameRecord->length = regularStringSize; + } + } + + // nameRecord now points to string data + BigEndian *stringStorage = reinterpret_cast *>(nameRecord); + const quint16 *sourceString = newFamilyName.utf16(); + for (int i=0; i(newNameTable.data()); + quint32 *tableEnd = reinterpret_cast(newNameTable.data() + fullSize); + + quint32 checkSum = 0; + while (p < tableEnd) + checkSum += *(p++); + + nameTableDirectoryEntry->checkSum = checkSum; + nameTableDirectoryEntry->offset = m_fontData.size(); + nameTableDirectoryEntry->length = fullSize; + + m_fontData.append(newNameTable); + + return oldFamilyName; + } + +#if !defined(QT_NO_DIRECTWRITE) + + class DirectWriteFontFileStream: public IDWriteFontFileStream + { + public: + DirectWriteFontFileStream(const QByteArray &fontData) + : m_fontData(fontData) + , m_referenceCount(0) + { + } + + ~DirectWriteFontFileStream() + { + } + + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object); + ULONG STDMETHODCALLTYPE AddRef(); + ULONG STDMETHODCALLTYPE Release(); + + HRESULT STDMETHODCALLTYPE ReadFileFragment(const void **fragmentStart, UINT64 fileOffset, + UINT64 fragmentSize, OUT void **fragmentContext); + void STDMETHODCALLTYPE ReleaseFileFragment(void *fragmentContext); + HRESULT STDMETHODCALLTYPE GetFileSize(OUT UINT64 *fileSize); + HRESULT STDMETHODCALLTYPE GetLastWriteTime(OUT UINT64 *lastWriteTime); + + private: + QByteArray m_fontData; + ULONG m_referenceCount; + }; + + HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::QueryInterface(REFIID iid, void **object) + { + if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileStream)) { + *object = this; + AddRef(); + return S_OK; + } else { + *object = NULL; + return E_NOINTERFACE; + } + } + + ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::AddRef() + { + return InterlockedIncrement(&m_referenceCount); + } + + ULONG STDMETHODCALLTYPE DirectWriteFontFileStream::Release() + { + ULONG newCount = InterlockedDecrement(&m_referenceCount); + if (newCount == 0) + delete this; + return newCount; + } + + HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::ReadFileFragment( + const void **fragmentStart, + UINT64 fileOffset, + UINT64 fragmentSize, + OUT void **fragmentContext) + { + *fragmentContext = NULL; + if (fragmentSize + fileOffset <= m_fontData.size()) { + *fragmentStart = m_fontData.data() + fileOffset; + return S_OK; + } else { + *fragmentStart = NULL; + return E_FAIL; + } + } + + void STDMETHODCALLTYPE DirectWriteFontFileStream::ReleaseFileFragment(void *) + { + } + + HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetFileSize(UINT64 *fileSize) + { + *fileSize = m_fontData.size(); + return S_OK; + } + + HRESULT STDMETHODCALLTYPE DirectWriteFontFileStream::GetLastWriteTime(UINT64 *lastWriteTime) + { + *lastWriteTime = 0; + return E_NOTIMPL; + } + + class DirectWriteFontFileLoader: public IDWriteFontFileLoader + { + public: + DirectWriteFontFileLoader() : m_referenceCount(0) {} + + ~DirectWriteFontFileLoader() + { + } + + inline void addKey(const void *key, const QByteArray &fontData) + { + Q_ASSERT(!m_fontDatas.contains(key)); + m_fontDatas.insert(key, fontData); + } + + inline void removeKey(const void *key) + { + m_fontDatas.remove(key); + } + + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void **object); + ULONG STDMETHODCALLTYPE AddRef(); + ULONG STDMETHODCALLTYPE Release(); + + HRESULT STDMETHODCALLTYPE CreateStreamFromKey(void const *fontFileReferenceKey, + UINT32 fontFileReferenceKeySize, + OUT IDWriteFontFileStream **fontFileStream); + + private: + ULONG m_referenceCount; + QHash m_fontDatas; + }; + + HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::QueryInterface(const IID &iid, + void **object) + { + if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) { + *object = this; + AddRef(); + return S_OK; + } else { + *object = NULL; + return E_NOINTERFACE; + } + } + + ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::AddRef() + { + return InterlockedIncrement(&m_referenceCount); + } + + ULONG STDMETHODCALLTYPE DirectWriteFontFileLoader::Release() + { + ULONG newCount = InterlockedDecrement(&m_referenceCount); + if (newCount == 0) + delete this; + return newCount; + } + + HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::CreateStreamFromKey( + void const *fontFileReferenceKey, + UINT32 fontFileReferenceKeySize, + IDWriteFontFileStream **fontFileStream) + { + Q_UNUSED(fontFileReferenceKeySize); + + if (fontFileReferenceKeySize != sizeof(const void *)) { + qWarning("%s: Wrong key size", __FUNCTION__); + return E_FAIL; + } + + const void *key = *reinterpret_cast(fontFileReferenceKey); + *fontFileStream = NULL; + if (!m_fontDatas.contains(key)) + return E_FAIL; + + QByteArray fontData = m_fontDatas.value(key); + DirectWriteFontFileStream *stream = new DirectWriteFontFileStream(fontData); + stream->AddRef(); + *fontFileStream = stream; + + return S_OK; + } + + class CustomFontFileLoader + { + public: + CustomFontFileLoader() : m_directWriteFactory(0), m_directWriteFontFileLoader(0) + { + HRESULT hres = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, + __uuidof(IDWriteFactory), + reinterpret_cast(&m_directWriteFactory)); + if (FAILED(hres)) { + qErrnoWarning(hres, "%s: DWriteCreateFactory failed.", __FUNCTION__); + } else { + m_directWriteFontFileLoader = new DirectWriteFontFileLoader(); + m_directWriteFactory->RegisterFontFileLoader(m_directWriteFontFileLoader); + } + } + + ~CustomFontFileLoader() + { + if (m_directWriteFactory != 0 && m_directWriteFontFileLoader != 0) + m_directWriteFactory->UnregisterFontFileLoader(m_directWriteFontFileLoader); + + if (m_directWriteFactory != 0) + m_directWriteFactory->Release(); + } + + void addKey(const void *key, const QByteArray &fontData) + { + if (m_directWriteFontFileLoader != 0) + m_directWriteFontFileLoader->addKey(key, fontData); + } + + void removeKey(const void *key) + { + if (m_directWriteFontFileLoader != 0) + m_directWriteFontFileLoader->removeKey(key); + } + + IDWriteFontFileLoader *loader() const + { + return m_directWriteFontFileLoader; + } + + private: + IDWriteFactory *m_directWriteFactory; + DirectWriteFontFileLoader *m_directWriteFontFileLoader; + }; + +#endif + +} // Anonymous namespace + /*! \struct QWindowsFontEngineData \brief Static constant data shared by the font engines. @@ -689,10 +1151,158 @@ QFontEngine * QWindowsFontDatabase::fontEngine(const QFontDef &fontDef, QFontEngine *QWindowsFontDatabase::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) { - QFontEngine *fe = QPlatformFontDatabase::fontEngine(fontData, pixelSize, hintingPreference); + EmbeddedFont font(fontData); + QFontEngine *fontEngine = 0; + +#if !defined(QT_NO_DIRECTWRITE) + if (hintingPreference == QFont::PreferDefaultHinting + || hintingPreference == QFont::PreferFullHinting) +#endif + { + GUID guid; + CoCreateGuid(&guid); + + QString uniqueFamilyName = QLatin1Char('f') + + QString::number(guid.Data1, 36) + QLatin1Char('-') + + QString::number(guid.Data2, 36) + QLatin1Char('-') + + QString::number(guid.Data3, 36) + QLatin1Char('-') + + QString::number(*reinterpret_cast(guid.Data4), 36); + + QString actualFontName = font.changeFamilyName(uniqueFamilyName); + if (actualFontName.isEmpty()) { + qWarning("%s: Can't change family name of font", __FUNCTION__); + return 0; + } + + DWORD count = 0; + QByteArray newFontData = font.data(); + HANDLE fontHandle = AddFontMemResourceEx((void *)newFontData.constData(), newFontData.size(), 0, + &count); + if (count == 0 && fontHandle != 0) { + RemoveFontMemResourceEx(fontHandle); + fontHandle = 0; + } + + if (fontHandle == 0) { + qWarning("%s: AddFontMemResourceEx failed", __FUNCTION__); + } else { + QFontDef request; + request.family = uniqueFamilyName; + request.pixelSize = pixelSize; + request.styleStrategy = QFont::NoFontMerging | QFont::PreferMatch; + request.hintingPreference = hintingPreference; + + fontEngine = QWindowsFontDatabase::createEngine(QUnicodeTables::Common, request, 0, + QWindowsContext::instance()->defaultDPI(), false, QStringList(), + m_fontEngineData); + + if (fontEngine) { + if (request.family != fontEngine->fontDef.family) { + qWarning("%s: Failed to load font. Got fallback instead: %s", + __FUNCTION__, qPrintable(fontEngine->fontDef.family)); + if (fontEngine->cache_count == 0 && fontEngine->ref.load() == 0) + delete fontEngine; + fontEngine = 0; + } else { + Q_ASSERT(fontEngine->cache_count == 0 && fontEngine->ref.load() == 0); + + // Override the generated font name + static_cast(fontEngine)->setUniqueFamilyName(uniqueFamilyName); + fontEngine->fontDef.family = actualFontName; + UniqueFontData uniqueData; + uniqueData.handle = fontHandle; + uniqueData.refCount.ref(); + m_uniqueFontData[uniqueFamilyName] = uniqueData; + } + } else { + RemoveFontMemResourceEx(fontHandle); + } + } + } +#if !defined(QT_NO_DIRECTWRITE) + else { + CustomFontFileLoader fontFileLoader; + fontFileLoader.addKey(this, fontData); + + IDWriteFactory *factory = 0; + HRESULT hres = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, + __uuidof(IDWriteFactory), + reinterpret_cast(&factory)); + if (FAILED(hres)) { + qErrnoWarning(hres, "%s: DWriteCreateFactory failed", __FUNCTION__); + return 0; + } + + IDWriteFontFile *fontFile = 0; + void *key = this; + + hres = factory->CreateCustomFontFileReference(&key, sizeof(void *), + fontFileLoader.loader(), &fontFile); + if (FAILED(hres)) { + qErrnoWarning(hres, "%s: CreateCustomFontFileReference failed", __FUNCTION__); + factory->Release(); + return 0; + } + + BOOL isSupportedFontType; + DWRITE_FONT_FILE_TYPE fontFileType; + DWRITE_FONT_FACE_TYPE fontFaceType; + UINT32 numberOfFaces; + fontFile->Analyze(&isSupportedFontType, &fontFileType, &fontFaceType, &numberOfFaces); + if (!isSupportedFontType) { + fontFile->Release(); + factory->Release(); + return 0; + } + + IDWriteFontFace *directWriteFontFace = 0; + hres = factory->CreateFontFace(fontFaceType, 1, &fontFile, 0, DWRITE_FONT_SIMULATIONS_NONE, + &directWriteFontFace); + if (FAILED(hres)) { + qErrnoWarning(hres, "%s: CreateFontFace failed", __FUNCTION__); + fontFile->Release(); + factory->Release(); + return 0; + } + + fontFile->Release(); + + fontEngine = new QWindowsFontEngineDirectWrite(directWriteFontFace, pixelSize, + m_fontEngineData); + + // Get font family from font data + fontEngine->fontDef.family = font.familyName(); + + directWriteFontFace->Release(); + factory->Release(); + } +#endif + + // Get style and weight info + if (fontEngine != 0) { + TableDirectory *os2TableEntry = font.tableDirectoryEntry("OS/2"); + if (os2TableEntry != 0) { + const OS2Table *os2Table = + reinterpret_cast(fontData.constData() + + os2TableEntry->offset); + + bool italic = os2Table->selection & 1; + bool oblique = os2Table->selection & 128; + + if (italic) + fontEngine->fontDef.style = QFont::StyleItalic; + else if (oblique) + fontEngine->fontDef.style = QFont::StyleOblique; + else + fontEngine->fontDef.style = QFont::StyleNormal; + + fontEngine->fontDef.weight = weightFromInteger(os2Table->weightClass); + } + } + if (QWindowsContext::verboseFonts) - qDebug() << __FUNCTION__ << "FONTDATA" << fontData << pixelSize << hintingPreference << fe; - return fe; + qDebug() << __FUNCTION__ << "FONTDATA" << fontData << pixelSize << hintingPreference << fontEngine; + return fontEngine; } QStringList QWindowsFontDatabase::fallbacksForFamily(const QString family, const QFont::Style &style, const QFont::StyleHint &styleHint, const QUnicodeTables::Script &script) const @@ -907,6 +1517,22 @@ bool QWindowsFontDatabase::fontsAlwaysScalable() const return true; } +void QWindowsFontDatabase::derefUniqueFont(const QString &uniqueFont) +{ + if (m_uniqueFontData.contains(uniqueFont)) { + if (!m_uniqueFontData[uniqueFont].refCount.deref()) { + RemoveFontMemResourceEx(m_uniqueFontData[uniqueFont].handle); + m_uniqueFontData.remove(uniqueFont); + } + } +} + +void QWindowsFontDatabase::refUniqueFont(const QString &uniqueFont) +{ + if (m_uniqueFontData.contains(uniqueFont)) + m_uniqueFontData[uniqueFont].refCount.ref(); +} + HFONT QWindowsFontDatabase::systemFont() { static const HFONT stock_sysfont = (HFONT)GetStockObject(SYSTEM_FONT); diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase.h b/src/plugins/platforms/windows/qwindowsfontdatabase.h index 3921992775..f442f492aa 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase.h +++ b/src/plugins/platforms/windows/qwindowsfontdatabase.h @@ -87,6 +87,8 @@ public: virtual QFont defaultFont() const { return systemDefaultFont(); } virtual bool fontsAlwaysScalable() const; + void derefUniqueFont(const QString &uniqueFont); + void refUniqueFont(const QString &uniqueFont); static QFont systemDefaultFont(); @@ -112,6 +114,13 @@ private: }; QList m_applicationFonts; + + struct UniqueFontData { + HANDLE handle; + QAtomicInt refCount; + }; + + QMap m_uniqueFontData; }; QT_END_NAMESPACE diff --git a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp index ab878a75bc..42d30f1833 100644 --- a/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp +++ b/src/plugins/platforms/windows/qwindowsfontdatabase_ft.cpp @@ -326,7 +326,7 @@ QFontEngine * QWindowsFontDatabaseFT::fontEngine(const QFontDef &fontDef, QUnico QFontEngine *QWindowsFontDatabaseFT::fontEngine(const QByteArray &fontData, qreal pixelSize, QFont::HintingPreference hintingPreference) { - QFontEngine *fe = QPlatformFontDatabase::fontEngine(fontData, pixelSize, hintingPreference); + QFontEngine *fe = QBasicFontDatabase::fontEngine(fontData, pixelSize, hintingPreference); if (QWindowsContext::verboseFonts) qDebug() << __FUNCTION__ << "FONTDATA" << fontData << pixelSize << hintingPreference << fe; return fe; diff --git a/src/plugins/platforms/windows/qwindowsfontengine.cpp b/src/plugins/platforms/windows/qwindowsfontengine.cpp index e074f79c32..f4bd3f0c53 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.cpp +++ b/src/plugins/platforms/windows/qwindowsfontengine.cpp @@ -44,6 +44,7 @@ #define _WIN32_WINNT 0x0500 #endif +#include "qwindowsintegration.h" #include "qwindowsfontengine.h" #include "qwindowsnativeimage.h" #include "qwindowscontext.h" @@ -319,6 +320,11 @@ QWindowsFontEngine::~QWindowsFontEngine() if (QWindowsContext::verboseFonts) if (QWindowsContext::verboseFonts) qDebug("%s: font='%s", __FUNCTION__, qPrintable(_name)); + + if (!uniqueFamilyName.isEmpty()) { + QPlatformFontDatabase *pfdb = QWindowsIntegration::instance()->fontDatabase(); + static_cast(pfdb)->derefUniqueFont(uniqueFamilyName); + } } HGDIOBJ QWindowsFontEngine::selectDesignFont() const @@ -1142,8 +1148,14 @@ QFontEngine *QWindowsFontEngine::cloneWithSize(qreal pixelSize) const QWindowsContext::instance()->defaultDPI(), false, QStringList(), m_fontEngineData); - if (fontEngine) + if (fontEngine) { fontEngine->fontDef.family = actualFontName; + if (!uniqueFamilyName.isEmpty()) { + static_cast(fontEngine)->setUniqueFamilyName(uniqueFamilyName); + QPlatformFontDatabase *pfdb = QWindowsIntegration::instance()->fontDatabase(); + static_cast(pfdb)->refUniqueFont(uniqueFamilyName); + } + } return fontEngine; } diff --git a/src/plugins/platforms/windows/qwindowsfontengine.h b/src/plugins/platforms/windows/qwindowsfontengine.h index f8ebc896f2..323ea7f89e 100644 --- a/src/plugins/platforms/windows/qwindowsfontengine.h +++ b/src/plugins/platforms/windows/qwindowsfontengine.h @@ -135,6 +135,7 @@ public: QSharedPointer fontEngineData() const { return m_fontEngineData; } LOGFONT logfont() const { return m_logfont; } + void setUniqueFamilyName(const QString &newName) { uniqueFamilyName = newName; } private: QWindowsNativeImage *drawGDIGlyph(HFONT font, glyph_t, int margin, const QTransform &xform, -- cgit v1.2.3