diff --git a/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp b/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp index 66990a563f6..25bb1863298 100644 --- a/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp +++ b/src/gui/text/windows/qwindowsdirectwritefontdatabase.cpp @@ -371,7 +371,7 @@ QStringList QWindowsDirectWriteFontDatabase::addApplicationFont(const QByteArray loadedData = file.readAll(); } - QList faces = createDirectWriteFaces(loadedData); + QList faces = createDirectWriteFaces(loadedData, fileName); if (faces.isEmpty()) { qCWarning(lcQpaFonts) << "Failed to create DirectWrite face from font data. Font may be unsupported."; return QStringList(); diff --git a/src/gui/text/windows/qwindowsfontdatabasebase.cpp b/src/gui/text/windows/qwindowsfontdatabasebase.cpp index 7dfd415ff92..990f20fa447 100644 --- a/src/gui/text/windows/qwindowsfontdatabasebase.cpp +++ b/src/gui/text/windows/qwindowsfontdatabasebase.cpp @@ -352,7 +352,7 @@ namespace { return E_NOTIMPL; } - class DirectWriteFontFileLoader: public IDWriteFontFileLoader + class DirectWriteFontFileLoader: public IDWriteLocalFontFileLoader { public: DirectWriteFontFileLoader() : m_referenceCount(0) {} @@ -360,12 +360,59 @@ namespace { { } - inline void addKey(const QByteArray &fontData) + inline void addKey(const QByteArray &fontData, const QString &filename) { if (!m_fontDatas.contains(fontData.data())) - m_fontDatas.insert(fontData.data(), fontData); + m_fontDatas.insert(fontData.data(), qMakePair(fontData, filename)); } + HRESULT STDMETHODCALLTYPE GetFilePathLengthFromKey(void const* fontFileReferenceKey, + UINT32 fontFileReferenceKeySize, + UINT32* filePathLength) override + { + Q_UNUSED(fontFileReferenceKeySize); + const void *key = *reinterpret_cast(fontFileReferenceKey); + auto it = m_fontDatas.constFind(key); + if (it == m_fontDatas.constEnd()) + return E_FAIL; + + *filePathLength = it.value().second.size(); + return 0; + } + + HRESULT STDMETHODCALLTYPE GetFilePathFromKey(void const* fontFileReferenceKey, + UINT32 fontFileReferenceKeySize, + WCHAR* filePath, + UINT32 filePathSize) override + { + Q_UNUSED(fontFileReferenceKeySize); + const void *key = *reinterpret_cast(fontFileReferenceKey); + const auto it = m_fontDatas.constFind(key); + if (it == m_fontDatas.constEnd()) + return E_FAIL; + + const QString &path = it.value().second; + if (filePathSize < path.size() + 1) + return E_FAIL; + + const qsizetype length = path.toWCharArray(filePath); + filePath[length] = '\0'; + + return 0; + } + + HRESULT STDMETHODCALLTYPE GetLastWriteTimeFromKey(void const* fontFileReferenceKey, + UINT32 fontFileReferenceKeySize, + FILETIME* lastWriteTime) override + { + Q_UNUSED(fontFileReferenceKey); + Q_UNUSED(fontFileReferenceKeySize); + Q_UNUSED(lastWriteTime); + // We never call this, so just fail + return E_FAIL; + } + + inline void removeKey(const void *key) { m_fontDatas.remove(key); @@ -386,13 +433,15 @@ namespace { private: ULONG m_referenceCount; - QHash m_fontDatas; + QHash > m_fontDatas; }; HRESULT STDMETHODCALLTYPE DirectWriteFontFileLoader::QueryInterface(const IID &iid, void **object) { - if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) { + if (iid == IID_IUnknown + || iid == __uuidof(IDWriteFontFileLoader) + || iid == __uuidof(IDWriteLocalFontFileLoader)) { *object = this; AddRef(); return S_OK; @@ -433,7 +482,7 @@ namespace { if (it == m_fontDatas.constEnd()) return E_FAIL; - QByteArray fontData = it.value(); + QByteArray fontData = it.value().first; DirectWriteFontFileStream *stream = new DirectWriteFontFileStream(fontData); stream->AddRef(); *fontFileStream = stream; @@ -469,10 +518,10 @@ public: m_directWriteFactory->Release(); } - void addKey(const QByteArray &fontData) + void addKey(const QByteArray &fontData, const QString &filename) { if (m_directWriteFontFileLoader != nullptr) - m_directWriteFontFileLoader->addKey(fontData); + m_directWriteFontFileLoader->addKey(fontData, filename); } void removeKey(const void *key) @@ -732,13 +781,14 @@ void QWindowsFontDatabaseBase::invalidate() #if QT_CONFIG(directwrite) && QT_CONFIG(direct2d) IDWriteFontFace *QWindowsFontDatabaseBase::createDirectWriteFace(const QByteArray &fontData) { - QList faces = createDirectWriteFaces(fontData, false); + QList faces = createDirectWriteFaces(fontData, QString{}, false); Q_ASSERT(faces.size() <= 1); return faces.isEmpty() ? nullptr : faces.first(); } QList QWindowsFontDatabaseBase::createDirectWriteFaces(const QByteArray &fontData, + const QString &filename, bool queryVariations) const { QList ret; @@ -751,7 +801,7 @@ QList QWindowsFontDatabaseBase::createDirectWriteFaces(const if (m_fontFileLoader == nullptr) m_fontFileLoader.reset(new QCustomFontFileLoader(fontEngineData->directWriteFactory)); - m_fontFileLoader->addKey(fontData); + m_fontFileLoader->addKey(fontData, filename); IDWriteFontFile *fontFile = nullptr; const void *key = fontData.data(); diff --git a/src/gui/text/windows/qwindowsfontdatabasebase_p.h b/src/gui/text/windows/qwindowsfontdatabasebase_p.h index beb9b52fe48..2c5f8f63c8b 100644 --- a/src/gui/text/windows/qwindowsfontdatabasebase_p.h +++ b/src/gui/text/windows/qwindowsfontdatabasebase_p.h @@ -99,6 +99,7 @@ protected: #if QT_CONFIG(directwrite) QList createDirectWriteFaces(const QByteArray &fontData, + const QString &filename, bool queryVariations = true) const; IDWriteFontFace *createDirectWriteFace(const QByteArray &fontData); #endif