Fix text shifting vertically when elided

When eliding text we would check for the existence of the ellipsis
character and fall back to using the dot if it was not available.
However, when font merging was in use, we would also use ellipsis
from a fallback font if available. This could cause the metrics
of the text to increase if the fallback font had larger metrics,
and the result was that text could shift when elided.

It is better to prefer the dot from the current font than to use
the ellipsis from a fallback, so we only use the ellipsis if
it is in the main font.

[ChangeLog][QtGui][Text] Fixed a bug where eliding text could
change the height of its bounding rectangle for certain fonts.

Fixes: QTBUG-72553
Change-Id: Ib27fc65302465ddce661801bcc5ae32e55f1aeb9
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Eskil Abrahamsen Blomfeldt 2018-12-20 09:27:09 +01:00
parent b45c1e1c0e
commit e6880e7cd1
3 changed files with 38 additions and 0 deletions

View File

@ -3192,6 +3192,16 @@ QString QTextEngine::elidedText(Qt::TextElideMode mode, const QFixed &width, int
QChar ellipsisChar(0x2026);
// We only want to use the ellipsis character if it is from the main
// font (not one of the fallbacks), since using a fallback font
// will affect the metrics of the text, potentially causing it to shift
// when it is being elided.
if (engine->type() == QFontEngine::Multi) {
QFontEngineMulti *multiEngine = static_cast<QFontEngineMulti *>(engine);
multiEngine->ensureEngineAt(0);
engine = multiEngine->engine(0);
}
glyph_t glyph = engine->glyphIndex(ellipsisChar.unicode());
QGlyphLayout glyphs;

View File

@ -1,5 +1,6 @@
<RCC>
<qresource prefix="/fonts">
<file>ucs4font.ttf</file>
<file alias="testfont.ttf">../../../shared/resources/testfont.ttf</file>
</qresource>
</RCC>

View File

@ -58,6 +58,7 @@ private slots:
void lineWidth();
void mnemonicTextWidth();
void leadingBelowLine();
void elidedMetrics();
};
void tst_QFontMetrics::same()
@ -331,5 +332,31 @@ void tst_QFontMetrics::leadingBelowLine()
QCOMPARE(line.base(), line.ascent);
}
void tst_QFontMetrics::elidedMetrics()
{
QString testFont = QFINDTESTDATA("fonts/testfont.ttf");
QVERIFY(!testFont.isEmpty());
int id = QFontDatabase::addApplicationFont(testFont);
QVERIFY(id >= 0);
QFont font(QFontDatabase::applicationFontFamilies(id).at(0));
font.setPixelSize(12.0);
QFontMetricsF metrics(font);
QString s = QStringLiteral("VeryLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongLongText");
QRectF boundingRect = metrics.boundingRect(s);
QString elided = metrics.elidedText(s, Qt::ElideRight, boundingRect.width() / 2.0);
QRectF elidedBoundingRect = metrics.boundingRect(elided);
QCOMPARE(boundingRect.height(), elidedBoundingRect.height());
QCOMPARE(boundingRect.y(), elidedBoundingRect.y());
QFontDatabase::removeApplicationFont(id);
}
QTEST_MAIN(tst_QFontMetrics)
#include "tst_qfontmetrics.moc"