aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2011-12-20 15:31:13 +1000
committerQt by Nokia <qt-info@nokia.com>2011-12-20 07:33:37 +0100
commitb26bda8654e9ac4c8ede56adba9d597f24f1ecac (patch)
treef450ef5680c642398706f1263fb121165ac5f04a /src
parent657f6d7111a4ee6f3e8ef0919956990fc8abbf3d (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')
-rw-r--r--src/quick/items/qquicktext.cpp78
-rw-r--r--src/quick/items/qquicktext_p_p.h8
2 files changed, 56 insertions, 30 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);
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index 756acbfbf8..43ca31d19e 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -103,9 +103,10 @@ public:
static QString elideChar;
- void invalidateImageCache();
+ void markDirty();
+ bool invalidateImageCache();
void checkImageCache();
- QPixmap imageCache;
+ QPixmap *imageCache;
QSGTexture *texture;
bool imageCacheDirty:1;
@@ -114,6 +115,7 @@ public:
bool styledText:1;
bool singleline:1;
bool cacheAllTextAsImage:1;
+ bool disableDistanceField:1;
bool internalWidthUpdate:1;
bool requireImplicitWidth:1;
bool truncated:1;
@@ -141,7 +143,6 @@ public:
QString anchorAt(const QPointF &pos);
QTextLayout layout;
QTextLayout *elipsisLayout;
- QList<QRectF> linesRects;
QQuickTextLine *textLine;
static QPixmap drawOutline(const QPixmap &source, const QPixmap &styleSource);
@@ -159,6 +160,7 @@ public:
NodeType nodeType;
#if defined(Q_OS_MAC)
+ QList<QRectF> linesRects;
QThread *layoutThread;
QThread *paintingThread;
#endif