From 07880542ecc479807c23c5646d263135240822ff Mon Sep 17 00:00:00 2001 From: Eskil Abrahamsen Blomfeldt Date: Wed, 9 Sep 2009 17:38:57 +0200 Subject: Account for right bearing in QFontMetrics::boundingRect(string) QFontMetrics::boundingRect() that takes a string needs to account for the right bearing of the last glyph, as it is documented to be the rectangle that contains the pixels of the text. I've added a test for this, and fixed tst_QFontMetrics::elidedText() to use boundingRect() to find the actual width of the text drawn (width() will return the advance of the text, which is larger than the actual width of the pixels.) I've also fixed a small typo in the "len" -> "ilen". Reviewed-by: Simon Hausmann --- src/gui/text/qtextengine.cpp | 9 +++++++-- tests/auto/qfontmetrics/tst_qfontmetrics.cpp | 14 +++++++++++++- 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/gui/text/qtextengine.cpp b/src/gui/text/qtextengine.cpp index c9b6c38..88837ca 100644 --- a/src/gui/text/qtextengine.cpp +++ b/src/gui/text/qtextengine.cpp @@ -1594,11 +1594,13 @@ glyph_metrics_t QTextEngine::boundingBox(int from, int len) const for (int i = 0; i < layoutData->items.size(); i++) { const QScriptItem *si = layoutData->items.constData() + i; + QFontEngine *fe = fontEngine(*si); + int pos = si->position; int ilen = length(i); if (pos > from + len) break; - if (pos + len > from) { + if (pos + ilen > from) { if (!si->num_glyphs) shape(i); @@ -1631,7 +1633,6 @@ glyph_metrics_t QTextEngine::boundingBox(int from, int len) const charEnd++; glyphEnd = (charEnd == ilen) ? si->num_glyphs : logClusters[charEnd]; if (glyphStart <= glyphEnd ) { - QFontEngine *fe = fontEngine(*si); glyph_metrics_t m = fe->boundingBox(glyphs.mid(glyphStart, glyphEnd - glyphStart)); gm.x = qMin(gm.x, m.x + gm.xoff); gm.y = qMin(gm.y, m.y + gm.yoff); @@ -1641,6 +1642,10 @@ glyph_metrics_t QTextEngine::boundingBox(int from, int len) const gm.yoff += m.yoff; } } + + glyph_t glyph = glyphs.glyphs[logClusters[pos + ilen - 1]]; + glyph_metrics_t gi = fe->boundingBox(glyph); + gm.width -= qRound(gi.xoff - gi.x - gi.width); } } return gm; diff --git a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp index ee6d442..665107a 100644 --- a/tests/auto/qfontmetrics/tst_qfontmetrics.cpp +++ b/tests/auto/qfontmetrics/tst_qfontmetrics.cpp @@ -72,6 +72,7 @@ private slots: void veryNarrowElidedText(); void averageCharWidth(); void elidedMultiLength(); + void bearingIncludedInBoundingRect(); }; tst_QFontMetrics::tst_QFontMetrics() @@ -214,7 +215,7 @@ void tst_QFontMetrics::elidedMultiLength() QCOMPARE(fm.elidedText(text1,Qt::ElideRight, 8000), text1_long); QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_long + 1), text1_long); QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_long - 1), text1_short); - int width_short = fm.width(text1_short); + int width_short = fm.boundingRect(text1_short).width(); QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_short + 1), text1_short); QCOMPARE(fm.elidedText(text1,Qt::ElideRight, width_short - 1), text1_small); @@ -226,5 +227,16 @@ void tst_QFontMetrics::elidedMultiLength() } +void tst_QFontMetrics::bearingIncludedInBoundingRect() +{ + QFont font; + font.setItalic(true); + QRect brectItalic = QFontMetrics(font).boundingRect("ITALIC"); + font.setItalic(false); + QRect brectNormal = QFontMetrics(font).boundingRect("ITALIC"); + + QVERIFY(brectItalic.width() > brectNormal.width()); +} + QTEST_MAIN(tst_QFontMetrics) #include "tst_qfontmetrics.moc" -- cgit v0.12