diff options
author | Martin Jones <martin.jones@nokia.com> | 2011-12-20 15:31:13 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2011-12-20 07:33:37 +0100 |
commit | b26bda8654e9ac4c8ede56adba9d597f24f1ecac (patch) | |
tree | f450ef5680c642398706f1263fb121165ac5f04a /src/quick/items/qquicktext.cpp | |
parent | 657f6d7111a4ee6f3e8ef0919956990fc8abbf3d (diff) |
Small Text creation performance improvements.
Change-Id: Ie92129887730d3738e14116cf22e1c30b836a415
Reviewed-by: Michael Brasser <michael.brasser@nokia.com>
Reviewed-by: Martin Jones <martin.jones@nokia.com>
Diffstat (limited to 'src/quick/items/qquicktext.cpp')
-rw-r--r-- | src/quick/items/qquicktext.cpp | 78 |
1 files changed, 51 insertions, 27 deletions
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index e73fa9f492..2a6be05851 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -78,9 +78,10 @@ QQuickTextPrivate::QQuickTextPrivate() format(QQuickText::AutoText), wrapMode(QQuickText::NoWrap), lineHeight(1), lineHeightMode(QQuickText::ProportionalHeight), lineCount(1), maximumLineCount(INT_MAX), maximumLineCountValid(false), - texture(0), + imageCache(0), texture(0), imageCacheDirty(false), updateOnComponentComplete(true), - richText(false), styledText(false), singleline(false), cacheAllTextAsImage(true), internalWidthUpdate(false), + richText(false), styledText(false), singleline(false), cacheAllTextAsImage(true), + disableDistanceField(false), internalWidthUpdate(false), requireImplicitWidth(false), truncated(false), hAlignImplicit(true), rightToLeftText(false), layoutTextElided(false), richTextAsImage(false), textureImageCacheDirty(false), textHasChanged(true), naturalWidth(0), doc(0), elipsisLayout(0), textLine(0), nodeType(NodeIsNull) @@ -91,6 +92,7 @@ QQuickTextPrivate::QQuickTextPrivate() { cacheAllTextAsImage = enableImageCache(); + disableDistanceField = qmlDisableDistanceField(); } void QQuickTextPrivate::init() @@ -188,6 +190,7 @@ QQuickTextPrivate::~QQuickTextPrivate() { delete elipsisLayout; delete textLine; textLine = 0; + delete imageCache; } qreal QQuickTextPrivate::getImplicitWidth() const @@ -217,9 +220,11 @@ void QQuickTextPrivate::updateLayout() delete elipsisLayout; elipsisLayout = 0; } - layout.clearLayout(); layout.setFont(font); - if (!styledText) { + if (text.isEmpty()) { + if (!layout.text().isEmpty()) + layout.setText(text); + } else if (!styledText) { QString tmp = text; tmp.replace(QLatin1Char('\n'), QChar::LineSeparator); singleline = !tmp.contains(QChar::LineSeparator); @@ -281,8 +286,9 @@ void QQuickTextPrivate::updateSize() QFontMetrics fm(font); if (text.isEmpty()) { - q->setImplicitSize(0, fm.height()); - paintedSize = QSize(0, fm.height()); + qreal fontHeight = fm.height(); + q->setImplicitSize(0, fontHeight); + paintedSize = QSize(0, fontHeight); emit q->paintedSizeChanged(); q->update(); return; @@ -315,7 +321,7 @@ void QQuickTextPrivate::updateSize() QTextOption option; option.setAlignment((Qt::Alignment)int(horizontalAlignment | vAlign)); option.setWrapMode(QTextOption::WrapMode(wrapMode)); - if (!cacheAllTextAsImage && !richTextAsImage && !qmlDisableDistanceField()) + if (!cacheAllTextAsImage && !richTextAsImage && !disableDistanceField) option.setUseDesignMetrics(true); doc->setDefaultTextOption(option); if (requireImplicitWidth && q->widthValid()) { @@ -451,9 +457,9 @@ void QQuickTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height, #if defined(Q_OS_MAC) if (QThread::currentThread() != paintingThread) { -#endif if (!line.lineNumber()) linesRects.clear(); +#endif if (!textLine) textLine = new QQuickTextLine; @@ -471,10 +477,11 @@ void QQuickTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height, emit q->lineLaidOut(textLine); - linesRects << QRectF(textLine->x(), textLine->y(), textLine->width(), textLine->height()); height += textLine->height(); #if defined(Q_OS_MAC) + linesRects << QRectF(textLine->x(), textLine->y(), textLine->width(), textLine->height()); + } else { if (line.lineNumber() < linesRects.count()) { QRectF r = linesRects.at(line.lineNumber()); @@ -508,7 +515,7 @@ QRect QQuickTextPrivate::setupTextLayout() QTextOption textOption = layout.textOption(); textOption.setAlignment(Qt::Alignment(q->effectiveHAlign())); textOption.setWrapMode(QTextOption::WrapMode(wrapMode)); - if (!cacheAllTextAsImage && !richTextAsImage && !qmlDisableDistanceField()) + if (!cacheAllTextAsImage && !richTextAsImage && !disableDistanceField) textOption.setUseDesignMetrics(true); layout.setTextOption(textOption); @@ -731,23 +738,33 @@ QPixmap QQuickTextPrivate::textDocumentImage(bool drawStyle) return img; } + +void QQuickTextPrivate::markDirty() +{ + Q_Q(QQuickText); + if (!invalidateImageCache() && q->isComponentComplete()) + q->update(); +} + /*! Mark the image cache as dirty. */ -void QQuickTextPrivate::invalidateImageCache() +bool QQuickTextPrivate::invalidateImageCache() { Q_Q(QQuickText); - if (richTextAsImage || cacheAllTextAsImage || (qmlDisableDistanceField() && style != QQuickText::Normal)) { // If actually using the image cache + if (richTextAsImage || cacheAllTextAsImage || (disableDistanceField && style != QQuickText::Normal)) { // If actually using the image cache if (imageCacheDirty) - return; + return true; imageCacheDirty = true; if (q->isComponentComplete()) QCoreApplication::postEvent(q, new QEvent(QEvent::User)); - } else if (q->isComponentComplete()) - q->update(); + return true; + } + + return false; } /*! @@ -762,7 +779,8 @@ void QQuickTextPrivate::checkImageCache() if (text.isEmpty()) { - imageCache = QPixmap(); + delete imageCache; + imageCache = 0; } else { @@ -779,18 +797,19 @@ void QQuickTextPrivate::checkImageCache() styledImage = textLayoutImage(true); //### should use styleColor } + delete imageCache; switch (style) { case QQuickText::Outline: - imageCache = drawOutline(textImage, styledImage); + imageCache = new QPixmap(drawOutline(textImage, styledImage)); break; case QQuickText::Sunken: - imageCache = drawOutline(textImage, styledImage, -1); + imageCache = new QPixmap(drawOutline(textImage, styledImage, -1)); break; case QQuickText::Raised: - imageCache = drawOutline(textImage, styledImage, 1); + imageCache = new QPixmap(drawOutline(textImage, styledImage, 1)); break; default: - imageCache = textImage; + imageCache = new QPixmap(textImage); break; } @@ -1183,7 +1202,7 @@ void QQuickText::setColor(const QColor &color) return; d->color = color; - d->invalidateImageCache(); + d->markDirty(); emit colorChanged(d->color); } /*! @@ -1226,7 +1245,7 @@ void QQuickText::setStyle(QQuickText::TextStyle style) if (isComponentComplete() && (d->style == Normal || style == Normal)) update(); d->style = style; - d->invalidateImageCache(); + d->markDirty(); emit styleChanged(d->style); } @@ -1258,7 +1277,7 @@ void QQuickText::setStyleColor(const QColor &color) return; d->styleColor = color; - d->invalidateImageCache(); + d->markDirty(); emit styleColorChanged(d->styleColor); } @@ -1653,6 +1672,11 @@ QRectF QQuickText::boundingRect() const void QQuickText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) { Q_D(QQuickText); + if (d->text.isEmpty()) { + QQuickItem::geometryChanged(newGeometry, oldGeometry); + return; + } + bool widthChanged = newGeometry.width() != oldGeometry.width(); bool heightChanged = newGeometry.height() != oldGeometry.height(); bool leftAligned = effectiveHAlign() == QQuickText::AlignLeft; @@ -1714,11 +1738,11 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data #endif // XXX todo - some styled text can be done by the QQuickTextNode - if (d->richTextAsImage || d->cacheAllTextAsImage || (qmlDisableDistanceField() && d->style != Normal)) { + if (d->richTextAsImage || d->cacheAllTextAsImage || (d->disableDistanceField && d->style != Normal)) { bool wasDirty = d->textureImageCacheDirty; d->textureImageCacheDirty = false; - if (d->imageCache.isNull()) { + if (!d->imageCache || d->imageCache->isNull()) { delete oldNode; return 0; } @@ -1736,12 +1760,12 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data } if (wasDirty) { - qobject_cast<QSGPlainTexture *>(d->texture)->setImage(d->imageCache.toImage()); + qobject_cast<QSGPlainTexture *>(d->texture)->setImage(d->imageCache->toImage()); node->setTexture(0); node->setTexture(d->texture); } - node->setTargetRect(QRectF(bounds.x(), bounds.y(), d->imageCache.width(), d->imageCache.height())); + node->setTargetRect(QRectF(bounds.x(), bounds.y(), d->imageCache->width(), d->imageCache->height())); node->setSourceRect(QRectF(0, 0, 1, 1)); node->setHorizontalWrapMode(QSGTexture::ClampToEdge); node->setVerticalWrapMode(QSGTexture::ClampToEdge); |