aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items/qquicktext.cpp
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2011-12-07 11:20:25 +1000
committerQt by Nokia <qt-info@nokia.com>2011-12-07 07:18:55 +0100
commit3bb47f45ebf1f2a5dc26067c762f30b15f2308c4 (patch)
treeb68cb40de89a7999fe7ee35cead36de819568c01 /src/quick/items/qquicktext.cpp
parentd052d2f569324f9a5416ee69ad60d4d4ded84ad3 (diff)
Avoid Text layout being triggered unnecessarily
Text was quite often layed out twice during construction due to geometry changes, and often at run time due to other geometry changes. This change checks for cases which do not require relayouting and drops out early. These are easier to detect than trying to have a single giant if statement covering all the positive combinations. Change-Id: I2deb2ab52d35b3d02bced698d05fef91c9e2f745 Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
Diffstat (limited to 'src/quick/items/qquicktext.cpp')
-rw-r--r--src/quick/items/qquicktext.cpp77
1 files changed, 60 insertions, 17 deletions
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 274ea93abb..07de537a98 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -224,8 +224,12 @@ void QQuickTextPrivate::updateLayout()
tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
singleline = !tmp.contains(QChar::LineSeparator);
if (singleline && !maximumLineCountValid && elideMode != QQuickText::ElideNone && q->widthValid() && wrapMode == QQuickText::NoWrap) {
- QFontMetrics fm(font);
- tmp = fm.elidedText(tmp,(Qt::TextElideMode)elideMode,q->width());
+ if (q->width() <= 0) {
+ tmp = QString();
+ } else {
+ QFontMetrics fm(font);
+ tmp = fm.elidedText(tmp,(Qt::TextElideMode)elideMode,q->width());
+ }
if (tmp != text) {
layoutTextElided = true;
if (!truncated) {
@@ -536,10 +540,26 @@ QRect QQuickTextPrivate::setupTextLayout()
layout.setText(elidedText);
}
+ if ((q->widthValid() && q->width() <= 0. && elideMode != QQuickText::ElideNone)
+ || (q->heightValid() && q->height() <= 0. && wrapMode != QQuickText::NoWrap && elideMode == QQuickText::ElideRight)) {
+ // we are elided and we have a zero width or height
+ if (!truncated) {
+ truncated = true;
+ emit q->truncatedChanged();
+ }
+ if (lineCount) {
+ lineCount = 0;
+ emit q->lineCountChanged();
+ }
+
+ qreal height = (lineHeightMode == QQuickText::FixedHeight) ? lineHeight : fm.height() * lineHeight;
+ return QRect(0, 0, 0, height);
+ }
+
qreal height = 0;
QRectF br;
- bool truncate = false;
+ bool truncate = layoutTextElided;
bool customLayout = isLineLaidOutConnected();
bool elideEnabled = elideMode == QQuickText::ElideRight && q->widthValid();
@@ -1633,21 +1653,44 @@ QRectF QQuickText::boundingRect() const
void QQuickText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
Q_D(QQuickText);
- bool elide = d->elideMode != QQuickText::ElideNone && widthValid();
- if ((!d->internalWidthUpdate
- && (newGeometry.width() != oldGeometry.width() || (elide && newGeometry.height() != oldGeometry.height())))
- && (d->wrapMode != QQuickText::NoWrap
- || d->elideMode != QQuickText::ElideNone
- || d->hAlign != QQuickText::AlignLeft)) {
- if ((d->singleline || d->maximumLineCountValid || heightValid()) && elide) {
- // We need to re-elide
- d->updateLayout();
- } else {
- // We just need to re-layout
- d->updateSize();
- }
+ bool widthChanged = newGeometry.width() != oldGeometry.width();
+ bool heightChanged = newGeometry.height() != oldGeometry.height();
+ bool leftAligned = effectiveHAlign() == QQuickText::AlignLeft;
+ bool wrapped = d->wrapMode != QQuickText::NoWrap;
+ bool elide = d->elideMode != QQuickText::ElideNone;
+
+ if ((!widthChanged && !heightChanged) || d->internalWidthUpdate)
+ goto geomChangeDone;
+
+ if (leftAligned && !wrapped && !elide)
+ goto geomChangeDone; // left aligned unwrapped text without eliding never needs relayout
+
+ if (!widthChanged && !wrapped && d->singleline)
+ goto geomChangeDone; // only height has changed which doesn't affect single line unwrapped text
+
+ if (!widthChanged && wrapped && d->elideMode != QQuickText::ElideRight)
+ goto geomChangeDone; // only height changed and no multiline eliding.
+
+ if (leftAligned && d->elideMode == QQuickText::ElideRight && !d->truncated && d->singleline
+ && !wrapped && newGeometry.width() > oldGeometry.width())
+ goto geomChangeDone; // Eliding not affected if we're not currently truncated and we get wider.
+
+ if (d->elideMode == QQuickText::ElideRight && wrapped && newGeometry.height() > oldGeometry.height()) {
+ if (!d->truncated)
+ goto geomChangeDone; // Multiline eliding not affected if we're not currently truncated and we get higher.
+ if (d->maximumLineCountValid && d->lineCount == d->maximumLineCount)
+ goto geomChangeDone; // Multiline eliding not affected if we're already at max line count and we get higher.
}
+ if (d->updateOnComponentComplete || (elide && widthValid())) {
+ // We need to re-elide
+ d->updateLayout();
+ } else {
+ // We just need to re-layout
+ d->updateSize();
+ }
+
+geomChangeDone:
QQuickItem::geometryChanged(newGeometry, oldGeometry);
}
@@ -1724,7 +1767,7 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
d->ensureDoc();
node->addTextDocument(bounds.topLeft(), d->doc, d->color, d->style, d->styleColor);
- } else {
+ } else if (d->elideMode == QQuickText::ElideNone || bounds.width() > 0.) {
node->addTextLayout(QPoint(0, bounds.y()), &d->layout, d->color, d->style, d->styleColor);
if (d->elipsisLayout)
node->addTextLayout(QPoint(0, bounds.y()), d->elipsisLayout, d->color, d->style, d->styleColor);