diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2016-08-17 14:27:36 +0200 |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io> | 2016-09-16 07:23:26 +0000 |
commit | 001efe14f2a0af25d10179fd6c06e4a7113ec83d (patch) | |
tree | ef83bedbc5d1989b83d45a522d2ca9984ca0a432 | |
parent | 60e8714e58369fd786707847575ba842f08530f1 (diff) |
DirectWrite: Fix embedding fonts in PDF
If no filename is stored in the faceId() of the
font engine, then the PDF engine will bail out and embed
each glyph separately instead of embedding the font. This
would cause PDFs to be huge and unsearchable when high-dpi
was active, since we will automatically default to the
DirectWrite engine in this case.
[ChangeLog][QtGui][Windows] Fixed embedding fonts in PDF when
dpi scaling is active or when the hinting preference was
none or vertical hinting.
Task-number: QTBUG-54740
Change-Id: I20630595f51660109c5a12c52076738a04036520
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
-rw-r--r-- | src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp | 89 | ||||
-rw-r--r-- | src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h | 3 |
2 files changed, 92 insertions, 0 deletions
diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp index 39a4eb81ca..ec73a4c065 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp @@ -46,6 +46,7 @@ #include <QtCore/QSettings> #include <QtCore/QtEndian> #include <QtCore/QVarLengthArray> +#include <QtCore/QFile> #include <private/qstringiterator_p.h> #include <QtCore/private/qsystemlibrary_p.h> @@ -236,6 +237,82 @@ QWindowsFontEngineDirectWrite::~QWindowsFontEngineDirectWrite() m_directWriteBitmapRenderTarget->Release(); } +#ifndef Q_CC_MINGW +typedef IDWriteLocalFontFileLoader QIdWriteLocalFontFileLoader; + +static UUID uuidIdWriteLocalFontFileLoader() +{ + return __uuidof(IDWriteLocalFontFileLoader); +} +#else // !Q_CC_MINGW +DECLARE_INTERFACE_(QIdWriteLocalFontFileLoader, IDWriteFontFileLoader) +{ + STDMETHOD(GetFilePathLengthFromKey)(THIS_ void const *, UINT32, UINT32*) PURE; + STDMETHOD(GetFilePathFromKey)(THIS_ void const *, UINT32, WCHAR *, UINT32) PURE; + STDMETHOD(GetLastWriteTimeFromKey)(THIS_ void const *, UINT32, FILETIME *) PURE; +}; + +static UUID uuidIdWriteLocalFontFileLoader() +{ + static const UUID result = { 0xb2d9f3ec, 0xc9fe, 0x4a11, {0xa2, 0xec, 0xd8, 0x62, 0x8, 0xf7, 0xc0, 0xa2}}; + return result; +} +#endif // Q_CC_MINGW + +QString QWindowsFontEngineDirectWrite::filenameFromFontFile(IDWriteFontFile *fontFile) +{ + IDWriteFontFileLoader *loader = Q_NULLPTR; + + HRESULT hr = fontFile->GetLoader(&loader); + if (FAILED(hr)) { + qErrnoWarning("%s: GetLoader failed", __FUNCTION__); + return QString(); + } + + QIdWriteLocalFontFileLoader *localLoader = Q_NULLPTR; + hr = loader->QueryInterface(uuidIdWriteLocalFontFileLoader(), + reinterpret_cast<void **>(&localLoader)); + + const void *fontFileReferenceKey = Q_NULLPTR; + UINT32 fontFileReferenceKeySize = 0; + if (SUCCEEDED(hr)) { + hr = fontFile->GetReferenceKey(&fontFileReferenceKey, + &fontFileReferenceKeySize); + if (FAILED(hr)) + qErrnoWarning(hr, "%s: GetReferenceKey failed", __FUNCTION__); + } + + UINT32 filePathLength = 0; + if (SUCCEEDED(hr)) { + hr = localLoader->GetFilePathLengthFromKey(fontFileReferenceKey, + fontFileReferenceKeySize, + &filePathLength); + if (FAILED(hr)) + qErrnoWarning(hr, "GetFilePathLength failed", __FUNCTION__); + } + + QString ret; + if (SUCCEEDED(hr) && filePathLength > 0) { + QVarLengthArray<wchar_t> filePath(filePathLength + 1); + + hr = localLoader->GetFilePathFromKey(fontFileReferenceKey, + fontFileReferenceKeySize, + filePath.data(), + filePathLength + 1); + if (FAILED(hr)) + qErrnoWarning(hr, "%s: GetFilePathFromKey failed", __FUNCTION__); + else + ret = QString::fromWCharArray(filePath.data()); + } + + if (localLoader != Q_NULLPTR) + localLoader->Release(); + + if (loader != Q_NULLPTR) + loader->Release(); + return ret; +} + void QWindowsFontEngineDirectWrite::collectMetrics() { DWRITE_FONT_METRICS metrics; @@ -250,6 +327,13 @@ void QWindowsFontEngineDirectWrite::collectMetrics() m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight); m_lineGap = DESIGN_TO_LOGICAL(metrics.lineGap); m_underlinePosition = DESIGN_TO_LOGICAL(metrics.underlinePosition); + + IDWriteFontFile *fontFile = Q_NULLPTR; + UINT32 numberOfFiles = 1; + if (SUCCEEDED(m_directWriteFontFace->GetFiles(&numberOfFiles, &fontFile))) { + m_faceId.filename = QFile::encodeName(filenameFromFontFile(fontFile)); + fontFile->Release(); + } } QFixed QWindowsFontEngineDirectWrite::underlinePosition() const @@ -351,6 +435,11 @@ bool QWindowsFontEngineDirectWrite::stringToCMap(const QChar *str, int len, QGly return true; } +QFontEngine::FaceId QWindowsFontEngineDirectWrite::faceId() const +{ + return m_faceId; +} + void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEngine::ShaperFlags) const { QVarLengthArray<UINT16> glyphIndices(glyphs->numGlyphs); diff --git a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h index fb2df00b7e..1978304b13 100644 --- a/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h +++ b/src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h @@ -49,6 +49,7 @@ struct IDWriteFont; struct IDWriteFontFace; +struct IDWriteFontFile; struct IDWriteFactory; struct IDWriteBitmapRenderTarget; struct IDWriteGdiInterop; @@ -92,6 +93,7 @@ public: QFixed leading() const Q_DECL_OVERRIDE; QFixed xHeight() const Q_DECL_OVERRIDE; qreal maxCharWidth() const Q_DECL_OVERRIDE; + FaceId faceId() const Q_DECL_OVERRIDE; bool supportsSubPixelPositions() const Q_DECL_OVERRIDE; @@ -113,6 +115,7 @@ private: QImage imageForGlyph(glyph_t t, QFixed subPixelPosition, int margin, const QTransform &xform); void collectMetrics(); void renderGlyphRun(QImage *destination, float r, float g, float b, float a, IDWriteGlyphRunAnalysis *glyphAnalysis, const QRect &boundingRect); + static QString filenameFromFontFile(IDWriteFontFile *fontFile); const QSharedPointer<QWindowsFontEngineData> m_fontEngineData; |