diff options
author | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2010-03-26 13:00:46 (GMT) |
---|---|---|
committer | Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com> | 2010-03-29 12:09:54 (GMT) |
commit | 732fbde53bd39d9b99e65e4aad7b028df246fce2 (patch) | |
tree | 46b132a0ab99c7d12153b9e16a7d1f036cc348f6 /src | |
parent | 3cebc02818d2025cda96528bbf289db15ef1bf89 (diff) | |
download | Qt-732fbde53bd39d9b99e65e4aad7b028df246fce2.zip Qt-732fbde53bd39d9b99e65e4aad7b028df246fce2.tar.gz Qt-732fbde53bd39d9b99e65e4aad7b028df246fce2.tar.bz2 |
Make QStaticText layout lazy
To avoid the unnecessary overhead of doing the text layout every time
a part of the QStaticText object is changed, we mark it as invalid
instead and do the layout when we have to. This means an overhead on
the first paint event for most users. The overhead can be avoided by
using the QStaticText::prepare() function and will probably not be
noticable anyway, since it's a one-time thing.
Task-number: QTBUG-9030
Reviewed-by: Gunnar
Diffstat (limited to 'src')
-rw-r--r-- | src/gui/painting/qpainter.cpp | 2 | ||||
-rw-r--r-- | src/gui/text/qstatictext.cpp | 64 | ||||
-rw-r--r-- | src/gui/text/qstatictext.h | 2 | ||||
-rw-r--r-- | src/gui/text/qstatictext_p.h | 6 |
4 files changed, 45 insertions, 29 deletions
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp index 7856881..93f2265 100644 --- a/src/gui/painting/qpainter.cpp +++ b/src/gui/painting/qpainter.cpp @@ -5864,7 +5864,7 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText // If the transform is not identical to the text transform, // we have to relayout the text (for other transformations than plain translation) - bool staticTextNeedsReinit = false; + bool staticTextNeedsReinit = staticText_d->needsRelayout; if (staticText_d->matrix != d->state->matrix) { staticText_d->matrix = d->state->matrix; staticTextNeedsReinit = true; diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp index 977355e..45252d8 100644 --- a/src/gui/text/qstatictext.cpp +++ b/src/gui/text/qstatictext.cpp @@ -99,20 +99,27 @@ QT_BEGIN_NAMESPACE point with no boundaries, and also when QPainter::drawText() is called with a bounding rectangle. - If a bounding rectangle is not required, create a QStaticText object without setting a maximum - size. The text will then occupy a single line. + If a bounding rectangle is not required, create a QStaticText object without setting a preferred + text width. The text will then occupy a single line. - If you set a maximum size on the QStaticText object, this will bound the text. The text will - be formatted so that no line exceeds the given width. When the object is painted, it will - be clipped at the given size. The position of the text is decided by the argument - passed to QPainter::drawStaticText() and can change from call to call with a minimal impact - on performance. + If you set a text width on the QStaticText object, this will bound the text. The text will + be formatted so that no line exceeds the given width. The text width set for QStaticText will + not automatically be used for clipping. To achieve clipping in addition to line breaks, use + QPainter::setClipRect(). The position of the text is decided by the argument passed to + QPainter::drawStaticText() and can change from call to call with a minimal impact on + performance. QStaticText will attempt to guess the format of the input text using Qt::mightBeRichText(). To force QStaticText to display its contents as either plain text or rich text, use the function QStaticText::setTextFormat() and pass in, respectively, Qt::PlainText and Qt::RichText. + If it's the first time the static text is drawn, or if the static text, or the painter's font + or matrix have been altered since the last time it was drawn, the text's layout has to be + recalculated. This will impose an overhead on the QPainter::drawStaticText() call where the + relayout occurs. To avoid this overhead in the paint event, you can call prepare() ahead of + time to ensure that the layout is calculated. + \sa QPainter::drawText(), QPainter::drawStaticText(), QTextLayout, QTextDocument */ @@ -147,7 +154,7 @@ QStaticText::QStaticText(const QString &text) : data(new QStaticTextPrivate) { data->text = text; - data->init(); + data->invalidate(); } /*! @@ -176,17 +183,17 @@ void QStaticText::detach() } /*! - Prepares the QStaticText object for being painted with the given \a matrix and the given - \a font to avoid overhead when the actual drawStaticText() call is made. + Prepares the QStaticText object for being painted with the given \a matrix and the given \a font + to avoid overhead when the actual drawStaticText() call is made. - When drawStaticText() is called, the layout of the QStaticText will be recalculated if the - painter's font or matrix is different from the one used for the currently cached layout. By - default, QStaticText will use a default constructed QFont and an identity matrix to create - its layout. + When drawStaticText() is called, the layout of the QStaticText will be recalculated if any part + of the QStaticText object has changed since the last time it was drawn. It will also be + recalculated if the painter's font or matrix are not the same as when the QStaticText was last + drawn. - To avoid the overhead of creating the layout the first time you draw the QStaticText with - a painter whose matrix or font are different from the defaults, you can use the prepare() - function and pass in the matrix and font you expect to use when drawing the text. + To avoid the overhead of creating the layout the first time you draw the QStaticText after + making changes, you can use the prepare() function and pass in the \a matrix and \a font you + expect to use when drawing the text. \sa QPainter::setFont(), QPainter::setMatrix() */ @@ -231,7 +238,7 @@ bool QStaticText::operator!=(const QStaticText &other) const /*! Sets the text of the QStaticText to \a text. - \note This function will cause the layout of the text to be recalculated. + \note This function will cause the layout of the text to require recalculation. \sa text() */ @@ -239,7 +246,7 @@ void QStaticText::setText(const QString &text) { detach(); data->text = text; - data->init(); + data->invalidate(); } /*! @@ -249,7 +256,7 @@ void QStaticText::setText(const QString &text) displayed as is, whereas it will be interpreted as HTML if the format is Qt::RichText. HTML tags that alter the font of the text, its color, or its layout are supported by QStaticText. - \note This function will cause the layout of the text to be recalculated. + \note This function will cause the layout of the text to require recalculation. \sa textFormat(), setText(), text() */ @@ -257,7 +264,7 @@ void QStaticText::setTextFormat(Qt::TextFormat textFormat) { detach(); data->textFormat = textFormat; - data->init(); + data->invalidate(); } /*! @@ -288,7 +295,7 @@ QString QStaticText::text() const The default is QStaticText::ModerateCaching. - \note This function will cause the layout of the text to be recalculated. + \note This function will cause the layout of the text to require recalculation. \sa performanceHint() */ @@ -300,7 +307,7 @@ void QStaticText::setPerformanceHint(PerformanceHint performanceHint) } detach(); data->useBackendOptimizations = (performanceHint == AggressiveCaching); - data->init(); + data->invalidate(); } /*! @@ -322,7 +329,7 @@ QStaticText::PerformanceHint QStaticText::performanceHint() const Use size() to get the actual size of the text. - \note This function will cause the layout of the text to be recalculated. + \note This function will cause the layout of the text to require recalculation. \sa textWidth(), size() */ @@ -330,7 +337,7 @@ void QStaticText::setTextWidth(qreal textWidth) { detach(); data->textWidth = textWidth; - data->init(); + data->invalidate(); } /*! @@ -350,18 +357,20 @@ qreal QStaticText::textWidth() const */ QSizeF QStaticText::size() const { + if (data->needsRelayout) + data->init(); return data->actualSize; } QStaticTextPrivate::QStaticTextPrivate() : items(0), itemCount(0), glyphPool(0), positionPool(0), textWidth(-1.0), - useBackendOptimizations(false), textFormat(Qt::AutoText) + needsRelayout(true), useBackendOptimizations(false), textFormat(Qt::AutoText) { } QStaticTextPrivate::QStaticTextPrivate(const QStaticTextPrivate &other) : text(other.text), font(other.font), textWidth(other.textWidth), matrix(other.matrix), - items(0), itemCount(0), glyphPool(0), positionPool(0), + items(0), itemCount(0), glyphPool(0), positionPool(0), needsRelayout(true), useBackendOptimizations(other.useBackendOptimizations), textFormat(other.textFormat) { } @@ -634,6 +643,7 @@ void QStaticTextPrivate::init() paintText(QPointF(0, 0), &painter); } + needsRelayout = false; } QT_END_NAMESPACE diff --git a/src/gui/text/qstatictext.h b/src/gui/text/qstatictext.h index c37194c..f3bef93 100644 --- a/src/gui/text/qstatictext.h +++ b/src/gui/text/qstatictext.h @@ -81,7 +81,7 @@ public: QSizeF size() const; - void prepare(const QTransform &matrix, const QFont &font); + void prepare(const QTransform &matrix = QTransform(), const QFont &font = QFont()); void setPerformanceHint(PerformanceHint performanceHint); PerformanceHint performanceHint() const; diff --git a/src/gui/text/qstatictext_p.h b/src/gui/text/qstatictext_p.h index 3bbc61f..f017ed1 100644 --- a/src/gui/text/qstatictext_p.h +++ b/src/gui/text/qstatictext_p.h @@ -118,6 +118,11 @@ public: void init(); void paintText(const QPointF &pos, QPainter *p); + void invalidate() + { + needsRelayout = true; + } + QAtomicInt ref; // 4 bytes per text QString text; // 4 bytes per text @@ -132,6 +137,7 @@ public: glyph_t *glyphPool; // 4 bytes per text QFixedPoint *positionPool; // 4 bytes per text + unsigned char needsRelayout : 1; unsigned char useBackendOptimizations : 1; // 1 byte per text unsigned char textFormat : 2; // ================ |