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.

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>
(cherry picked from commit 3158068209b06e8bfa18c8fb83890953221a8176)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Eskil Abrahamsen Blomfeldt 2022-10-18 12:22:51 +02:00 committed by Qt Cherry-pick Bot
parent f5a7514f42
commit 9ac433b40a
2 changed files with 77 additions and 0 deletions

View File

@ -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,

View File

@ -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,