diff options
author | Andrew den Exter <andrew.den-exter@nokia.com> | 2012-03-26 15:54:16 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-04-17 01:24:38 +0200 |
commit | b20df2bf54aec02f46d960868562cf1b100d455c (patch) | |
tree | f883cb58b24af39921fbe8f20d9d1599c9d350af /src | |
parent | 9606b1b66721e6296d06fca343f4f2d6ffb8419a (diff) |
Fix Text baselineOffset caclulations.
Update the baselineOffset when short cutting layout due to an empty
text property. And allow alterations to the baseline due to images,
font scaling and custom layouts when doing a layout.
Task-number: QTBUG-24303
Change-Id: I5a31a6108cded490fef8b0674e15558ea4e22d6b
Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/quick/items/qquicktext.cpp | 62 | ||||
-rw-r--r-- | src/quick/items/qquicktext_p_p.h | 3 |
2 files changed, 46 insertions, 19 deletions
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 24dd10ac9f..70a1551205 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -382,6 +382,22 @@ void QQuickText::imageDownloadFinished() } } +void QQuickTextPrivate::updateBaseline(qreal baseline, qreal dy) +{ + Q_Q(QQuickText); + + qreal yoff = 0; + + if (q->heightValid()) { + if (vAlign == QQuickText::AlignBottom) + yoff = dy; + else if (vAlign == QQuickText::AlignVCenter) + yoff = dy/2; + } + + q->setBaselineOffset(baseline + yoff); +} + void QQuickTextPrivate::updateSize() { Q_Q(QQuickText); @@ -398,9 +414,19 @@ void QQuickTextPrivate::updateSize() return; } - QFontMetricsF fm(font); - if (text.isEmpty()) { - qreal fontHeight = fm.height(); + if (text.isEmpty() && !isLineLaidOutConnected() && fontSizeMode() == QQuickText::FixedSize) { + // How much more expensive is it to just do a full layout on an empty string here? + // There may be subtle differences in the height and baseline calculations between + // QTextLayout and QFontMetrics and the number of variables that can affect the size + // and position of a line is increasing. + QFontMetricsF fm(font); + qreal fontHeight = qCeil(fm.height()); // QScriptLine and therefore QTextLine rounds up + if (!richText) { // line height, so we will as well. + fontHeight = lineHeightMode() == QQuickText::FixedHeight + ? lineHeight() + : fontHeight * lineHeight(); + } + updateBaseline(fm.ascent(), q->height() - fontHeight); q->setImplicitSize(0, fontHeight); layedOutTextRect = QRectF(0, 0, 0, fontHeight); emit q->contentSizeChanged(); @@ -411,7 +437,6 @@ void QQuickTextPrivate::updateSize() qreal naturalWidth = 0; - qreal dy = q->height(); QSizeF size(0, 0); QSizeF previousSize = layedOutTextRect.size(); #if defined(Q_OS_MAC) @@ -420,14 +445,15 @@ void QQuickTextPrivate::updateSize() //setup instance of QTextLayout for all cases other than richtext if (!richText) { - QRectF textRect = setupTextLayout(&naturalWidth); + qreal baseline = 0; + QRectF textRect = setupTextLayout(&naturalWidth, &baseline); if (internalWidthUpdate) // probably the result of a binding loop, but by letting it return; // get this far we'll get a warning to that effect if it is. layedOutTextRect = textRect; size = textRect.size(); - dy -= size.height(); + updateBaseline(baseline, q->height() - size.height()); } else { singleline = false; // richtext can't elide or be optimized for single-line case ensureDoc(); @@ -458,20 +484,13 @@ void QQuickTextPrivate::updateSize() extra->doc->setTextWidth(q->width()); else extra->doc->setTextWidth(extra->doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug) - dy -= extra->doc->size().height(); QSizeF dsize = extra->doc->size(); layedOutTextRect = QRectF(QPointF(0,0), dsize); size = QSizeF(extra->doc->idealWidth(),dsize.height()); - } - qreal yoff = 0; - if (q->heightValid()) { - if (vAlign == QQuickText::AlignBottom) - yoff = dy; - else if (vAlign == QQuickText::AlignVCenter) - yoff = dy/2; + QFontMetricsF fm(font); + updateBaseline(fm.ascent(), q->height() - size.height()); } - q->setBaselineOffset(fm.ascent() + yoff); //### need to comfirm cost of always setting these for richText internalWidthUpdate = true; @@ -669,7 +688,7 @@ QString QQuickTextPrivate::elidedText(qreal lineWidth, const QTextLine &line, QT already absolutely positioned horizontally). */ -QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth) +QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *const baseline) { Q_Q(QQuickText); layout.setCacheEnabled(true); @@ -712,9 +731,10 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth) internalWidthUpdate = wasInLayout; } - QFontMetrics fm(font); + QFontMetricsF fm(font); qreal height = (lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : fm.height() * lineHeight(); - return QRect(0, 0, 0, height); + *baseline = fm.ascent(); + return QRectF(0, 0, 0, height); } qreal lineWidth = q->widthValid() && q->width() > 0 ? q->width() : FLT_MAX; @@ -1024,6 +1044,12 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth) elideLayout = 0; } + QTextLine firstLine = visibleCount == 1 && elideLayout + ? elideLayout->lineAt(0) + : layout.lineAt(0); + Q_ASSERT(firstLine.isValid()); + *baseline = firstLine.y() + firstLine.ascent(); + if (!customLayout) br.setHeight(height); diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h index 0425c37406..cfa37789cc 100644 --- a/src/quick/items/qquicktext_p_p.h +++ b/src/quick/items/qquicktext_p_p.h @@ -75,6 +75,7 @@ public: ~QQuickTextPrivate(); void init(); + void updateBaseline(qreal baseline, qreal dy); void updateSize(); void updateLayout(); bool determineHorizontalAlignment(); @@ -163,7 +164,7 @@ public: void ensureDoc(); - QRectF setupTextLayout(qreal *const naturalWidth); + QRectF setupTextLayout(qreal *const naturalWidth, qreal * const baseline); void setupCustomLineGeometry(QTextLine &line, qreal &height, int lineOffset = 0); bool isLinkActivatedConnected(); QString anchorAt(const QPointF &pos); |