aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2012-03-26 15:54:16 +1000
committerQt by Nokia <qt-info@nokia.com>2012-04-17 01:24:38 +0200
commitb20df2bf54aec02f46d960868562cf1b100d455c (patch)
treef883cb58b24af39921fbe8f20d9d1599c9d350af /src
parent9606b1b66721e6296d06fca343f4f2d6ffb8419a (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.cpp62
-rw-r--r--src/quick/items/qquicktext_p_p.h3
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);