summaryrefslogtreecommitdiffstats
path: root/src/gui/text/windows
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2022-10-18 12:22:51 +0200
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2022-10-19 19:24:26 +0200
commit3158068209b06e8bfa18c8fb83890953221a8176 (patch)
tree8817b390e34cb18eb9f27fd3734c060e8e59ab1f /src/gui/text/windows
parent71f020b36536edd717ef6d769b12795b7c4f8a69 (diff)
Fix generating PDFs with DirectWrite engine
The PDF print engine depends on getting unscaled glyphs and some metrics from the font engine, and for DirectWrite, we were relying on the superclass implementations of the functions in question, giving us approximated values. This caused glyphs to be slightly the wrong size when the DirectWrite engine was in use, e.g. when high-dpi scaling is enabled. [ChangeLog][QtPrintSupport][Windows] Fixed glitches in generated PDFs when the DirectWrite backend was in use, e.g. when high-dpi scaling was active. Pick-to: 6.2 6.4 Fixes: QTBUG-102098 Change-Id: I6ad72bfc8f634a1dcaee02de39960faa93f1ece3 Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io> Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Lars Knoll <lars@knoll.priv.no>
Diffstat (limited to 'src/gui/text/windows')
-rw-r--r--src/gui/text/windows/qwindowsfontenginedirectwrite.cpp74
-rw-r--r--src/gui/text/windows/qwindowsfontenginedirectwrite_p.h3
2 files changed, 77 insertions, 0 deletions
diff --git a/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp b/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp
index bc8e0b7ed1..6bce3394b1 100644
--- a/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp
+++ b/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp
@@ -500,6 +500,53 @@ void QWindowsFontEngineDirectWrite::recalcAdvances(QGlyphLayout *glyphs, QFontEn
}
}
+void QWindowsFontEngineDirectWrite::getUnscaledGlyph(glyph_t glyph,
+ QPainterPath *path,
+ glyph_metrics_t *metric)
+{
+ float advance = 0.0f;
+ UINT16 g = glyph;
+ DWRITE_GLYPH_OFFSET offset;
+ offset.advanceOffset = 0;
+ offset.ascenderOffset = 0;
+ GeometrySink geometrySink(path);
+ HRESULT hr = m_directWriteFontFace->GetGlyphRunOutline(m_unitsPerEm,
+ &g,
+ &advance,
+ &offset,
+ 1,
+ false,
+ false,
+ &geometrySink);
+ if (FAILED(hr)) {
+ qErrnoWarning("%s: GetGlyphRunOutline failed", __FUNCTION__);
+ return;
+ }
+
+ DWRITE_GLYPH_METRICS glyphMetrics;
+ hr = m_directWriteFontFace->GetDesignGlyphMetrics(&g, 1, &glyphMetrics);
+ if (FAILED(hr)) {
+ qErrnoWarning("%s: GetDesignGlyphMetrics failed", __FUNCTION__);
+ return;
+ }
+
+ QFixed advanceWidth = QFixed(int(glyphMetrics.advanceWidth));
+ QFixed leftSideBearing = QFixed(glyphMetrics.leftSideBearing);
+ QFixed rightSideBearing = QFixed(glyphMetrics.rightSideBearing);
+ QFixed advanceHeight = QFixed(int(glyphMetrics.advanceHeight));
+ QFixed verticalOriginY = QFixed(glyphMetrics.verticalOriginY);
+ QFixed topSideBearing = QFixed(glyphMetrics.topSideBearing);
+ QFixed bottomSideBearing = QFixed(glyphMetrics.bottomSideBearing);
+ QFixed width = advanceWidth - leftSideBearing - rightSideBearing;
+ QFixed height = advanceHeight - topSideBearing - bottomSideBearing;
+ *metric = glyph_metrics_t(leftSideBearing,
+ -verticalOriginY + topSideBearing,
+ width,
+ height,
+ advanceWidth,
+ 0);
+}
+
void QWindowsFontEngineDirectWrite::addGlyphsToPath(glyph_t *glyphs, QFixedPoint *positions, int nglyphs,
QPainterPath *path, QTextItem::RenderFlags flags)
{
@@ -621,6 +668,33 @@ bool QWindowsFontEngineDirectWrite::supportsHorizontalSubPixelPositions() const
return true;
}
+QFontEngine::Properties QWindowsFontEngineDirectWrite::properties() const
+{
+ IDWriteFontFace2 *directWriteFontFace2;
+ if (SUCCEEDED(m_directWriteFontFace->QueryInterface(__uuidof(IDWriteFontFace2),
+ reinterpret_cast<void **>(&directWriteFontFace2)))) {
+ DWRITE_FONT_METRICS1 metrics;
+ directWriteFontFace2->GetMetrics(&metrics);
+
+ Properties p = QFontEngine::properties();
+ p.emSquare = metrics.designUnitsPerEm;
+ p.boundingBox = QRectF(metrics.glyphBoxLeft,
+ -metrics.glyphBoxTop,
+ metrics.glyphBoxRight - metrics.glyphBoxLeft,
+ metrics.glyphBoxTop - metrics.glyphBoxBottom);
+ p.ascent = metrics.ascent;
+ p.descent = metrics.descent;
+ p.leading = metrics.lineGap;
+ p.capHeight = metrics.capHeight;
+ p.lineWidth = metrics.underlineThickness;
+
+ directWriteFontFace2->Release();
+ return p;
+ } else {
+ return QFontEngine::properties();
+ }
+}
+
QImage QWindowsFontEngineDirectWrite::imageForGlyph(glyph_t t,
const QFixedPoint &subPixelPosition,
int margin,
diff --git a/src/gui/text/windows/qwindowsfontenginedirectwrite_p.h b/src/gui/text/windows/qwindowsfontenginedirectwrite_p.h
index b672f8b2e8..df6df1ad17 100644
--- a/src/gui/text/windows/qwindowsfontenginedirectwrite_p.h
+++ b/src/gui/text/windows/qwindowsfontenginedirectwrite_p.h
@@ -98,6 +98,9 @@ public:
void initializeHeightMetrics() const override;
+ Properties properties() const override;
+ void getUnscaledGlyph(glyph_t glyph, QPainterPath *path, glyph_metrics_t *metrics) override;
+
private:
QImage imageForGlyph(glyph_t t,
const QFixedPoint &subPixelPosition,