Fix bounding box of zero-width entities in QFontEngineFT

Freetype can give us non empty bounds for zero-width characters,
this change just makes us skip metrics of characters already found to
not contribute to text advance. The coretext and windows
font-engines already uses the already calculated advance.

Change-Id: I82b3521a4fb92614be509be5982cd5ab9c1eb7de
Fixes: QTBUG-58854
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>
This commit is contained in:
Allan Sandfeld Jensen 2020-02-25 15:59:31 +01:00
parent d32a6793a4
commit 25677ec4b2
3 changed files with 30 additions and 0 deletions

View File

@ -663,6 +663,9 @@ glyph_metrics_t QFontEngine::tightBoundingBox(const QGlyphLayout &glyphs)
QFixed ymax = 0; QFixed ymax = 0;
QFixed xmax = 0; QFixed xmax = 0;
for (int i = 0; i < glyphs.numGlyphs; i++) { for (int i = 0; i < glyphs.numGlyphs; i++) {
// If shaping has found this should be ignored, ignore it.
if (!glyphs.advances[i] || glyphs.attributes[i].dontPrint)
continue;
glyph_metrics_t bb = boundingBox(glyphs.glyphs[i]); glyph_metrics_t bb = boundingBox(glyphs.glyphs[i]);
QFixed x = overall.xoff + glyphs.offsets[i].x + bb.x; QFixed x = overall.xoff + glyphs.offsets[i].x + bb.x;
QFixed y = overall.yoff + glyphs.offsets[i].y + bb.y; QFixed y = overall.yoff + glyphs.offsets[i].y + bb.y;

View File

@ -1672,6 +1672,9 @@ glyph_metrics_t QFontEngineFT::boundingBox(const QGlyphLayout &glyphs)
QFixed ymax = 0; QFixed ymax = 0;
QFixed xmax = 0; QFixed xmax = 0;
for (int i = 0; i < glyphs.numGlyphs; i++) { for (int i = 0; i < glyphs.numGlyphs; i++) {
// If shaping has found this should be ignored, ignore it.
if (!glyphs.advances[i] || glyphs.attributes[i].dontPrint)
continue;
Glyph *g = cacheEnabled ? defaultGlyphSet.getGlyph(glyphs.glyphs[i]) : 0; Glyph *g = cacheEnabled ? defaultGlyphSet.getGlyph(glyphs.glyphs[i]) : 0;
if (!g) { if (!g) {
if (!face) if (!face)

View File

@ -59,6 +59,7 @@ private slots:
void mnemonicTextWidth(); void mnemonicTextWidth();
void leadingBelowLine(); void leadingBelowLine();
void elidedMetrics(); void elidedMetrics();
void zeroWidthMetrics();
}; };
void tst_QFontMetrics::same() void tst_QFontMetrics::same()
@ -358,5 +359,28 @@ void tst_QFontMetrics::elidedMetrics()
QFontDatabase::removeApplicationFont(id); QFontDatabase::removeApplicationFont(id);
} }
void tst_QFontMetrics::zeroWidthMetrics()
{
QString zwnj(QChar(0x200c));
QString zwsp(QChar(0x200b));
QFont font;
QFontMetricsF fm(font);
QCOMPARE(fm.horizontalAdvance(zwnj), 0);
QCOMPARE(fm.horizontalAdvance(zwsp), 0);
QCOMPARE(fm.boundingRect(zwnj).width(), 0);
QCOMPARE(fm.boundingRect(zwsp).width(), 0);
QString string1 = QStringLiteral("(") + zwnj + QStringLiteral(")");
QString string2 = QStringLiteral("(") + zwnj + zwnj + QStringLiteral(")");
QString string3 = QStringLiteral("(") + zwsp + QStringLiteral(")");
QString string4 = QStringLiteral("(") + zwsp + zwsp + QStringLiteral(")");
QCOMPARE(fm.horizontalAdvance(string1), fm.horizontalAdvance(string2));
QCOMPARE(fm.horizontalAdvance(string3), fm.horizontalAdvance(string4));
QCOMPARE(fm.boundingRect(string1).width(), fm.boundingRect(string2).width());
QCOMPARE(fm.boundingRect(string3).width(), fm.boundingRect(string4).width());
}
QTEST_MAIN(tst_QFontMetrics) QTEST_MAIN(tst_QFontMetrics)
#include "tst_qfontmetrics.moc" #include "tst_qfontmetrics.moc"