summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2016-08-17 14:27:36 +0200
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2016-09-16 07:23:26 +0000
commit001efe14f2a0af25d10179fd6c06e4a7113ec83d (patch)
treeef83bedbc5d1989b83d45a522d2ca9984ca0a432 /src
parent60e8714e58369fd786707847575ba842f08530f1 (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>
Diffstat (limited to 'src')
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.cpp89
-rw-r--r--src/plugins/platforms/windows/qwindowsfontenginedirectwrite.h3
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;