From 9237cdf98fc6f20471aaeec27eef2f5100e9b82f Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Fri, 30 May 2025 09:59:31 +0200 Subject: [PATCH] DirectWrite: Avoid infinite recursion with broken font data If a font has an em square size of 0 it is not going to be useful. However, if one was encountered we returned a default value to avoid division by zero. The default implementation called ascent(), which would depend on the em square size again and we would get an infinite recursion for these fonts. To avoid this, we simply return a default value of 16 in the case of a broken font. (The Apple spec gives the range 64 .. 16384 for the em square and the Microsoft spec says 16 .. 16384, so we use the smallest of the two.) Fixes: QTBUG-137277 Pick-to: 6.9 6.8 6.5 Change-Id: I63779e44c10c7021486787d1e1e818f4c6e47835 Reviewed-by: Allan Sandfeld Jensen (cherry picked from commit ab7a80a9557e12735f4e3c3fe76ccc72feba2fc8) Reviewed-by: Qt Cherry-pick Bot --- src/gui/text/qfontengine.cpp | 10 ++++++++++ src/gui/text/qfontengine_p.h | 4 +++- .../windows/qwindowsfontenginedirectwrite.cpp | 13 +++++++++---- tests/auto/gui/text/qrawfont/CMakeLists.txt | 1 + .../auto/gui/text/qrawfont/testfont_zeroem.ttf | Bin 0 -> 22704 bytes tests/auto/gui/text/qrawfont/tst_qrawfont.cpp | 13 ++++++++++++- 6 files changed, 35 insertions(+), 6 deletions(-) create mode 100644 tests/auto/gui/text/qrawfont/testfont_zeroem.ttf diff --git a/src/gui/text/qfontengine.cpp b/src/gui/text/qfontengine.cpp index 59898f5c29b..68b31a7841a 100644 --- a/src/gui/text/qfontengine.cpp +++ b/src/gui/text/qfontengine.cpp @@ -496,6 +496,13 @@ QFixed QFontEngine::leading() const return m_leading; } + +QFixed QFontEngine::emSquareSize() const +{ + qCWarning(lcQpaFonts) << "Font engine does not reimplement emSquareSize(). Returning minimum value."; + return 16; +} + QFixed QFontEngine::ascent() const { if (!m_heightMetricsQueried) @@ -2354,6 +2361,9 @@ glyph_metrics_t QFontEngineMulti::boundingBox(glyph_t glyph) return engine(which)->boundingBox(stripped(glyph)); } +QFixed QFontEngineMulti::emSquareSize() const +{ return engine(0)->emSquareSize(); } + QFixed QFontEngineMulti::ascent() const { return engine(0)->ascent(); } diff --git a/src/gui/text/qfontengine_p.h b/src/gui/text/qfontengine_p.h index 4d1243ccc51..5e2c2963ca4 100644 --- a/src/gui/text/qfontengine_p.h +++ b/src/gui/text/qfontengine_p.h @@ -163,7 +163,7 @@ public: || QChar::category(ucs4) == QChar::Other_Control; } - virtual QFixed emSquareSize() const { return ascent(); } + virtual QFixed emSquareSize() const; /* returns 0 as glyph index for non existent glyphs */ virtual glyph_t glyphIndex(uint ucs4) const = 0; @@ -425,6 +425,7 @@ public: virtual glyph_metrics_t boundingBox(glyph_t glyph) override; virtual QFontEngine *cloneWithSize(qreal pixelSize) const override; + virtual QFixed emSquareSize() const override { return _size; } virtual QFixed ascent() const override; virtual QFixed capHeight() const override; virtual QFixed descent() const override; @@ -463,6 +464,7 @@ public: virtual void addOutlineToPath(qreal, qreal, const QGlyphLayout &, QPainterPath *, QTextItem::RenderFlags flags) override; virtual void getGlyphBearings(glyph_t glyph, qreal *leftBearing = nullptr, qreal *rightBearing = nullptr) override; + virtual QFixed emSquareSize() const override; virtual QFixed ascent() const override; virtual QFixed capHeight() const override; virtual QFixed descent() const override; diff --git a/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp b/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp index 17b0c431852..3e10cdad44f 100644 --- a/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp +++ b/src/gui/text/windows/qwindowsfontenginedirectwrite.cpp @@ -369,6 +369,14 @@ void QWindowsFontEngineDirectWrite::collectMetrics() m_directWriteFontFace->GetMetrics(&metrics); m_unitsPerEm = metrics.designUnitsPerEm; + // Something is wrong with this font. Set the em square size to the minimum value in + // the spec. + if (m_unitsPerEm == 0) { + qCWarning(lcQpaFonts) << "Font" << fontDef.families << "reports an em square size of 0." + << "Clamping to minimum value."; + m_unitsPerEm = 16; + } + m_lineThickness = DESIGN_TO_LOGICAL(metrics.underlineThickness); m_capHeight = DESIGN_TO_LOGICAL(metrics.capHeight); m_xHeight = DESIGN_TO_LOGICAL(metrics.xHeight); @@ -497,10 +505,7 @@ bool QWindowsFontEngineDirectWrite::getSfntTableData(uint tag, uchar *buffer, ui QFixed QWindowsFontEngineDirectWrite::emSquareSize() const { - if (m_unitsPerEm > 0) - return m_unitsPerEm; - else - return QFontEngine::emSquareSize(); + return m_unitsPerEm; } glyph_t QWindowsFontEngineDirectWrite::glyphIndex(uint ucs4) const diff --git a/tests/auto/gui/text/qrawfont/CMakeLists.txt b/tests/auto/gui/text/qrawfont/CMakeLists.txt index d2a318a2a36..2dcd6615951 100644 --- a/tests/auto/gui/text/qrawfont/CMakeLists.txt +++ b/tests/auto/gui/text/qrawfont/CMakeLists.txt @@ -17,6 +17,7 @@ set_source_files_properties("../../../shared/resources/testfont.ttf" ) set(testdata_resource_files "../../../shared/resources/testfont.ttf" + "testfont_zeroem.ttf" "testfont_bold_italic.ttf" "testfont_os2_v1.ttf" ) diff --git a/tests/auto/gui/text/qrawfont/testfont_zeroem.ttf b/tests/auto/gui/text/qrawfont/testfont_zeroem.ttf new file mode 100644 index 0000000000000000000000000000000000000000..04c469f4966e58bc50273e1f7cde94019567b9cf GIT binary patch literal 22704 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 0); +} + #endif // QT_NO_RAWFONT QTEST_MAIN(tst_QRawFont)