summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gui/painting/qpaintbuffer.cpp33
-rw-r--r--src/gui/painting/qpainter.cpp56
-rw-r--r--src/gui/painting/qpainter.h6
-rw-r--r--src/gui/text/qstatictext.cpp163
-rw-r--r--src/gui/text/qstatictext.h8
-rw-r--r--src/gui/text/qstatictext_p.h13
-rw-r--r--tests/auto/qstatictext/tst_qstatictext.cpp135
7 files changed, 282 insertions, 132 deletions
diff --git a/src/gui/painting/qpaintbuffer.cpp b/src/gui/painting/qpaintbuffer.cpp
index ca2077f..e1156dc 100644
--- a/src/gui/painting/qpaintbuffer.cpp
+++ b/src/gui/painting/qpaintbuffer.cpp
@@ -557,11 +557,7 @@ QString QPaintBuffer::commandDescription(int command) const
debug << "Cmd_Translate:" << delta;
break; }
case QPaintBufferPrivate::Cmd_DrawStaticText: {
- QPointF delta(d_ptr->floats.at(cmd.extra), d_ptr->floats.at(cmd.extra+1));
- QVariantList variants(d_ptr->variants.at(cmd.offset).value<QVariantList>());
-
- QStaticText text(variants.at(0).value<QStaticText>());
- debug << "Cmd_DrawStaticText:" << text.text();
+ debug << "Cmd_DrawStaticText";
break; }
}
@@ -1272,13 +1268,14 @@ void QPaintBufferEngine::drawTiledPixmap(const QRectF &r, const QPixmap &pm, con
void QPaintBufferEngine::drawStaticTextItem(QStaticTextItem *staticTextItem)
{
- QString text = QString(staticTextItem->chars, staticTextItem->numChars);
+ QVariantList variants;
- QStaticText staticText(text);
- staticText.prepare(state()->matrix, staticTextItem->font);
+ variants << QVariant(staticTextItem->font);
+ for (int i=0; i<staticTextItem->numGlyphs; ++i) {
+ variants.append(staticTextItem->glyphs[i]);
+ variants.append(staticTextItem->glyphPositions[i].toPointF());
+ }
- QVariantList variants;
- variants << QVariant(staticTextItem->font) << QVariant::fromValue(staticText);
buffer->addCommand(QPaintBufferPrivate::Cmd_DrawStaticText, QVariant(variants));
}
@@ -1761,11 +1758,19 @@ void QPainterReplayer::process(const QPaintBufferCommand &cmd)
QVariantList variants(d->variants.at(cmd.offset).value<QVariantList>());
- QFont font(variants.at(0).value<QFont>());
- QStaticText text(variants.at(0).value<QStaticText>());
-
+ QFont font = variants.at(0).value<QFont>();
+
+ QVector<quint32> glyphs;
+ QVector<QPointF> positions;
+
+ for (int i=0; i<(variants.size() - 1) / 2; ++i) {
+ glyphs.append(variants.at(i*2 + 1).toUInt());
+ positions.append(variants.at(i*2 + 2).toPointF());
+ }
+
painter->setFont(font);
- painter->drawStaticText(QPointF(0, 0), text);
+
+ qt_draw_glyphs(painter, glyphs.constData(), positions.constData(), glyphs.size());
break;
}
diff --git a/src/gui/painting/qpainter.cpp b/src/gui/painting/qpainter.cpp
index 1c528fe..7b5fcc2 100644
--- a/src/gui/painting/qpainter.cpp
+++ b/src/gui/painting/qpainter.cpp
@@ -5720,6 +5720,16 @@ void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, const QPointF *posit
QFontEngine *fontEngine = state->font.d->engineForScript(QUnicodeTables::Common);
+ while (fontEngine->type() == QFontEngine::Multi) {
+ // Pick engine based on first glyph in array if we are using a multi engine.
+ // (all glyphs must be for same font)
+ int engineIdx = 0;
+ if (glyphCount > 0)
+ engineIdx = glyphArray[0] >> 24;
+
+ fontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx);
+ }
+
QVarLengthArray<QFixedPoint, 128> positions;
for (int i=0; i<glyphCount; ++i) {
QFixedPoint fp = QFixedPoint::fromPointF(positionArray[i]);
@@ -5762,19 +5772,24 @@ void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, const QPointF *posit
/*!
- \fn void QPainter::drawStaticText(const QPoint &position, const QStaticText &staticText)
+ \fn void QPainter::drawStaticText(const QPoint &topLeftPosition, const QStaticText &staticText)
\since 4.7
\overload
- Draws the \a staticText at the \a position.
+ Draws the \a staticText at the \a topLeftPosition.
+
+ \note The y-position is used as the top of the font.
+
*/
/*!
- \fn void QPainter::drawStaticText(int x, int y, const QStaticText &staticText)
+ \fn void QPainter::drawStaticText(int left, int top, const QStaticText &staticText)
\since 4.7
\overload
- Draws the \a staticText at coordinates \a x and \a y.
+ Draws the \a staticText at coordinates \a left and \a top.
+
+ \note The y-position is used as the top of the font.
*/
/*!
@@ -5802,7 +5817,7 @@ void QPainter::drawText(const QPointF &p, const QString &str)
/*!
\since 4.7
- Draws the given \a staticText at the given \a position.
+ Draws the given \a staticText at the given \a topLeftPosition.
The text will be drawn using the font and the transformation set on the painter. If the
font and/or transformation set on the painter are different from the ones used to initialize
@@ -5810,15 +5825,17 @@ void QPainter::drawText(const QPointF &p, const QString &str)
QStaticText::prepare() to initialize \a staticText with the font and transformation with which
it will later be drawn.
- If \a position is not the same as when \a staticText was initialized, or when it was last drawn,
- then there will be a slight overhead when translating the text to its new position.
+ If \a topLeftPosition is not the same as when \a staticText was initialized, or when it was
+ last drawn, then there will be a slight overhead when translating the text to its new position.
+
+ \note If the painter's transformation is not affine, then \a staticText will be drawn using
+ regular calls to drawText(), losing any potential for performance improvement.
- \note If the painter's transformation is not affine, then \a staticText will be drawn using regular
- calls to drawText(), losing any potential performance improvement.
+ \note The y-position is used as the top of the font.
\sa QStaticText
*/
-void QPainter::drawStaticText(const QPointF &position, const QStaticText &staticText)
+void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText &staticText)
{
Q_D(QPainter);
if (!d->engine || staticText.text().isEmpty() || pen().style() == Qt::NoPen)
@@ -5830,13 +5847,13 @@ void QPainter::drawStaticText(const QPointF &position, const QStaticText &static
// If we don't have an extended paint engine, or if the painter is projected,
// we go through standard code path
if (d->extended == 0 || !d->state->matrix.isAffine()) {
- staticText_d->paintText(position, this);
+ staticText_d->paintText(topLeftPosition, this);
return;
}
// Don't recalculate entire layout because of translation, rather add the dx and dy
// into the position to move each text item the correct distance.
- QPointF transformedPosition = position * d->state->matrix;
+ QPointF transformedPosition = topLeftPosition * d->state->matrix;
QTransform matrix = d->state->matrix;
// The translation has been applied to transformedPosition. Remove translation
@@ -5857,20 +5874,12 @@ void QPainter::drawStaticText(const QPointF &position, const QStaticText &static
// 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;
}
- bool restoreWhenFinished = false;
- if (staticText_d->needsClipRect) {
- save();
- setClipRect(QRectF(position, staticText_d->maximumSize));
-
- restoreWhenFinished = true;
- }
-
if (font() != staticText_d->font) {
staticText_d->font = font();
staticTextNeedsReinit = true;
@@ -5901,7 +5910,7 @@ void QPainter::drawStaticText(const QPointF &position, const QStaticText &static
QColor currentColor = oldPen.color();
for (int i=0; i<staticText_d->itemCount; ++i) {
QStaticTextItem *item = staticText_d->items + i;
- if (currentColor != item->color) {
+ if (item->color.isValid() && currentColor != item->color) {
setPen(item->color);
currentColor = item->color;
}
@@ -5910,9 +5919,6 @@ void QPainter::drawStaticText(const QPointF &position, const QStaticText &static
if (currentColor != oldPen.color())
setPen(oldPen);
- if (restoreWhenFinished)
- restore();
-
if (matrix.isTranslating())
d->state->matrix = matrix;
}
diff --git a/src/gui/painting/qpainter.h b/src/gui/painting/qpainter.h
index 443925b..edfb67e 100644
--- a/src/gui/painting/qpainter.h
+++ b/src/gui/painting/qpainter.h
@@ -396,9 +396,9 @@ public:
void setLayoutDirection(Qt::LayoutDirection direction);
Qt::LayoutDirection layoutDirection() const;
- void drawStaticText(const QPointF &p, const QStaticText &staticText);
- inline void drawStaticText(const QPoint &p, const QStaticText &staticText);
- inline void drawStaticText(int x, int y, const QStaticText &staticText);
+ void drawStaticText(const QPointF &topLeftPosition, const QStaticText &staticText);
+ inline void drawStaticText(const QPoint &topLeftPosition, const QStaticText &staticText);
+ inline void drawStaticText(int left, int top, const QStaticText &staticText);
void drawText(const QPointF &p, const QString &s);
inline void drawText(const QPoint &p, const QString &s);
diff --git a/src/gui/text/qstatictext.cpp b/src/gui/text/qstatictext.cpp
index d685cd9..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
*/
@@ -143,12 +150,11 @@ QStaticText::QStaticText()
If an invalid size is passed for \a size the text will be unbounded.
*/
-QStaticText::QStaticText(const QString &text, const QSizeF &size)
+QStaticText::QStaticText(const QString &text)
: data(new QStaticTextPrivate)
{
data->text = text;
- data->maximumSize = size;
- data->init();
+ data->invalidate();
}
/*!
@@ -177,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()
*/
@@ -209,7 +215,7 @@ QStaticText &QStaticText::operator=(const QStaticText &other)
}
/*!
- Compares \a other to this QStaticText. Returns true if the texts, fonts and maximum sizes
+ Compares \a other to this QStaticText. Returns true if the texts, fonts and text widths
are equal.
*/
bool QStaticText::operator==(const QStaticText &other) const
@@ -217,7 +223,7 @@ bool QStaticText::operator==(const QStaticText &other) const
return (data == other.data
|| (data->text == other.data->text
&& data->font == other.data->font
- && data->maximumSize == other.data->maximumSize));
+ && data->textWidth == other.data->textWidth));
}
/*!
@@ -232,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()
*/
@@ -240,7 +246,7 @@ void QStaticText::setText(const QString &text)
{
detach();
data->text = text;
- data->init();
+ data->invalidate();
}
/*!
@@ -250,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()
*/
@@ -258,7 +264,7 @@ void QStaticText::setTextFormat(Qt::TextFormat textFormat)
{
detach();
data->textFormat = textFormat;
- data->init();
+ data->invalidate();
}
/*!
@@ -289,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()
*/
@@ -301,7 +307,7 @@ void QStaticText::setPerformanceHint(PerformanceHint performanceHint)
}
detach();
data->useBackendOptimizations = (performanceHint == AggressiveCaching);
- data->init();
+ data->invalidate();
}
/*!
@@ -315,48 +321,56 @@ QStaticText::PerformanceHint QStaticText::performanceHint() const
}
/*!
- Sets the maximum size of the QStaticText to \a size.
+ Sets the preferred width for this QStaticText. If the text is wider than the specified width,
+ it will be broken into multiple lines and grow vertically. If the text cannot be split into
+ multiple lines, it will be larger than the specified \a textWidth.
- \note This function will cause the layout of the text to be recalculated.
+ Setting the preferred text width to a negative number will cause the text to be unbounded.
- \sa maximumSize(), size()
+ Use size() to get the actual size of the text.
+
+ \note This function will cause the layout of the text to require recalculation.
+
+ \sa textWidth(), size()
*/
-void QStaticText::setMaximumSize(const QSizeF &size)
+void QStaticText::setTextWidth(qreal textWidth)
{
detach();
- data->maximumSize = size;
- data->init();
+ data->textWidth = textWidth;
+ data->invalidate();
}
/*!
- Returns the maximum size of the QStaticText.
+ Returns the preferred width for this QStaticText.
- \sa setMaximumSize()
+ \sa setTextWidth()
*/
-QSizeF QStaticText::maximumSize() const
+qreal QStaticText::textWidth() const
{
- return data->maximumSize;
+ return data->textWidth;
}
/*!
Returns the size of the bounding rect for this QStaticText.
- \sa maximumSize()
+ \sa textWidth()
*/
QSizeF QStaticText::size() const
{
+ if (data->needsRelayout)
+ data->init();
return data->actualSize;
}
QStaticTextPrivate::QStaticTextPrivate()
- : items(0), itemCount(0), glyphPool(0), positionPool(0), needsClipRect(false),
- useBackendOptimizations(false), textFormat(Qt::AutoText)
+ : items(0), itemCount(0), glyphPool(0), positionPool(0), textWidth(-1.0),
+ needsRelayout(true), useBackendOptimizations(false), textFormat(Qt::AutoText)
{
}
QStaticTextPrivate::QStaticTextPrivate(const QStaticTextPrivate &other)
- : text(other.text), font(other.font), maximumSize(other.maximumSize), matrix(other.matrix),
- items(0), itemCount(0), glyphPool(0), positionPool(0), needsClipRect(false),
+ : text(other.text), font(other.font), textWidth(other.textWidth), matrix(other.matrix),
+ items(0), itemCount(0), glyphPool(0), positionPool(0), needsRelayout(true),
useBackendOptimizations(other.useBackendOptimizations), textFormat(other.textFormat)
{
}
@@ -388,8 +402,15 @@ namespace {
m_expectedItemCount(expectedItemCount),
m_expectedGlyphCount(expectedGlyphCount),
m_glyphPool(glyphPool),
- m_positionPool(positionPool)
+ m_positionPool(positionPool),
+ m_dirtyPen(false)
+ {
+ }
+
+ virtual void updateState(const QPaintEngineState &newState)
{
+ if (newState.state() & QPaintEngine::DirtyPen)
+ m_dirtyPen = true;
}
virtual void drawTextItem(const QPointF &position, const QTextItem &textItem)
@@ -412,7 +433,8 @@ namespace {
currentItem->numGlyphs = ti.glyphs.numGlyphs;
currentItem->glyphs = m_glyphPool;
currentItem->glyphPositions = m_positionPool;
- currentItem->color = state->pen().color();
+ if (m_dirtyPen)
+ currentItem->color = state->pen().color();
QTransform matrix = state->transform();
matrix.translate(position.x(), position.y());
@@ -435,7 +457,6 @@ namespace {
virtual bool begin(QPaintDevice *) { return true; }
virtual bool end() { return true; }
- virtual void updateState(const QPaintEngineState &) {}
virtual void drawPixmap(const QRectF &, const QPixmap &, const QRectF &) {}
virtual Type type() const
{
@@ -461,6 +482,8 @@ namespace {
glyph_t *m_glyphPool;
QFixedPoint *m_positionPool;
+
+ bool m_dirtyPen;
};
class DrawTextItemDevice: public QPaintDevice
@@ -530,43 +553,50 @@ namespace {
};
}
-void QStaticTextPrivate::paintText(const QPointF &pos, QPainter *p)
+void QStaticTextPrivate::paintText(const QPointF &topLeftPosition, QPainter *p)
{
bool preferRichText = textFormat == Qt::RichText
|| (textFormat == Qt::AutoText && Qt::mightBeRichText(text));
if (!preferRichText) {
- if (maximumSize.isValid()) {
- QRectF boundingRect;
- p->drawText(QRectF(pos, maximumSize), Qt::TextWordWrap, text, &boundingRect);
-
- actualSize = boundingRect.size();
- needsClipRect = boundingRect.width() > maximumSize.width()
- || boundingRect.height() > maximumSize.height();
- } else {
- p->drawText(pos, text);
- needsClipRect = false;
-
- QFontMetrics fm(font);
- actualSize = fm.boundingRect(text).size();
+ QTextLayout textLayout;
+ textLayout.setText(text);
+ textLayout.setFont(font);
+
+ qreal leading = QFontMetricsF(font).leading();
+ qreal height = -leading;
+
+ textLayout.beginLayout();
+ while (1) {
+ QTextLine line = textLayout.createLine();
+ if (!line.isValid())
+ break;
+
+ if (textWidth >= 0.0)
+ line.setLineWidth(textWidth);
+ height += leading;
+ line.setPosition(QPointF(0.0, height));
+ height += line.height();
}
+ textLayout.endLayout();
+
+ actualSize = textLayout.boundingRect().size();
+ textLayout.draw(p, topLeftPosition);
} else {
QTextDocument document;
document.setDefaultFont(font);
document.setDocumentMargin(0.0);
+ if (textWidth >= 0.0)
+ document.setTextWidth(textWidth);
document.setHtml(text);
- QPointF adjustedPos = pos - QPointF(0, QFontMetricsF(font).ascent());
- QRectF rect = maximumSize.isValid() ? QRectF(adjustedPos, maximumSize) : QRectF();
document.adjustSize();
p->save();
- p->translate(adjustedPos);
- document.drawContents(p, rect);
+ p->translate(topLeftPosition);
+ document.drawContents(p);
p->restore();
+
actualSize = document.size();
- needsClipRect = maximumSize.isValid()
- && (actualSize.width() > maximumSize.width()
- || actualSize.height() > maximumSize.height());
}
}
@@ -613,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 00d42e0..f3bef93 100644
--- a/src/gui/text/qstatictext.h
+++ b/src/gui/text/qstatictext.h
@@ -66,7 +66,7 @@ public:
};
QStaticText();
- QStaticText(const QString &text, const QSizeF &maximumSize = QSizeF());
+ QStaticText(const QString &text);
QStaticText(const QStaticText &other);
~QStaticText();
@@ -76,12 +76,12 @@ public:
void setTextFormat(Qt::TextFormat textFormat);
Qt::TextFormat textFormat() const;
- void setMaximumSize(const QSizeF &maximumSize);
- QSizeF maximumSize() const;
+ void setTextWidth(qreal textWidth);
+ qreal textWidth() const;
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 e758244..f017ed1 100644
--- a/src/gui/text/qstatictext_p.h
+++ b/src/gui/text/qstatictext_p.h
@@ -118,11 +118,16 @@ 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
QFont font; // 8 bytes per text
- QSizeF maximumSize; // 16 bytes per text
+ qreal textWidth; // 8 bytes per text
QSizeF actualSize; // 16 bytes per text
QPointF position; // 16 bytes per text
@@ -132,11 +137,11 @@ public:
glyph_t *glyphPool; // 4 bytes per text
QFixedPoint *positionPool; // 4 bytes per text
- unsigned char needsClipRect : 1; // 1 byte per text
- unsigned char useBackendOptimizations : 1;
+ unsigned char needsRelayout : 1;
+ unsigned char useBackendOptimizations : 1; // 1 byte per text
unsigned char textFormat : 2;
// ================
- // 171 bytes per text
+ // 163 bytes per text
static QStaticTextPrivate *get(const QStaticText *q);
};
diff --git a/tests/auto/qstatictext/tst_qstatictext.cpp b/tests/auto/qstatictext/tst_qstatictext.cpp
index a038878..e7a22b3 100644
--- a/tests/auto/qstatictext/tst_qstatictext.cpp
+++ b/tests/auto/qstatictext/tst_qstatictext.cpp
@@ -69,7 +69,7 @@ private slots:
void drawToRect_data();
void drawToRect();
void setFont();
- void setMaximumSize();
+ void setTextWidth();
void prepareToCorrectData();
void prepareToWrongData();
@@ -81,6 +81,10 @@ private slots:
void transformationChanged();
void plainTextVsRichText();
+
+ void setPenPlainText();
+ void setPenRichText();
+ void richTextOverridesPen();
};
void tst_QStaticText::init()
@@ -123,7 +127,7 @@ void tst_QStaticText::drawToPoint()
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
text.setTextFormat(Qt::PlainText);
text.setPerformanceHint(performanceHint);
- p.drawStaticText(QPointF(11, 12), text);
+ p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text);
}
QCOMPARE(imageDrawStaticText, imageDrawText);
@@ -152,12 +156,19 @@ void tst_QStaticText::drawToRect()
imageDrawStaticText.fill(Qt::white);
{
QPainter p(&imageDrawStaticText);
- QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.", QSizeF(10, 500));
+ QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
+ text.setTextWidth(10),
+ p.setClipRect(QRectF(11, 12, 10, 500));
text.setPerformanceHint(performanceHint);
text.setTextFormat(Qt::PlainText);
p.drawStaticText(QPointF(11, 12), text);
}
+#if defined(DEBUG_SAVE_IMAGE)
+ imageDrawText.save("drawToRect_imageDrawText.png");
+ imageDrawStaticText.save("drawToRect_imageDrawStaticText.png");
+#endif
+
QCOMPARE(imageDrawStaticText, imageDrawText);
}
@@ -183,7 +194,7 @@ void tst_QStaticText::prepareToCorrectData()
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
text.prepare(transform, p.font());
text.setTextFormat(Qt::PlainText);
- p.drawStaticText(QPointF(11, 12), text);
+ p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text);
}
if (!supportsTransformations())
@@ -211,7 +222,7 @@ void tst_QStaticText::prepareToWrongData()
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
text.prepare(transform, p.font());
text.setTextFormat(Qt::PlainText);
- p.drawStaticText(QPointF(11, 12), text);
+ p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text);
}
QCOMPARE(imageDrawStaticText, imageDrawText);
@@ -228,10 +239,10 @@ void tst_QStaticText::setFont()
imageDrawText.fill(Qt::white);
{
QPainter p(&imageDrawText);
- p.drawText(0, 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
+ p.drawText(0, 0 + QFontMetrics(p.font()).ascent(), "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
p.setFont(font);
- p.drawText(11, 120, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
+ p.drawText(11, 120 + QFontMetrics(p.font()).ascent(), "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
}
QPixmap imageDrawStaticText(1000, 1000);
@@ -249,10 +260,15 @@ void tst_QStaticText::setFont()
p.drawStaticText(11, 120, text);
}
+#if defined(DEBUG_SAVE_IMAGE)
+ imageDrawText.save("setFont_imageDrawText.png");
+ imageDrawStaticText.save("setFont_imageDrawStaticText.png");
+#endif
+
QCOMPARE(imageDrawStaticText, imageDrawText);
}
-void tst_QStaticText::setMaximumSize()
+void tst_QStaticText::setTextWidth()
{
QPixmap imageDrawText(1000, 1000);
imageDrawText.fill(Qt::white);
@@ -266,7 +282,8 @@ void tst_QStaticText::setMaximumSize()
{
QPainter p(&imageDrawStaticText);
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
- text.setMaximumSize(QSizeF(10, 500));
+ text.setTextWidth(10);
+ p.setClipRect(QRectF(11, 12, 10, 500));
p.drawStaticText(QPointF(11, 12), text);
}
@@ -293,7 +310,7 @@ void tst_QStaticText::translatedPainter()
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
text.setTextFormat(Qt::PlainText);
- p.drawStaticText(QPointF(11, 12), text);
+ p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text);
}
QCOMPARE(imageDrawStaticText, imageDrawText);
@@ -325,7 +342,7 @@ void tst_QStaticText::rotatedPainter()
{
QPainter p(&imageDrawText);
p.rotate(30.0);
- p.drawText(0, 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
+ p.drawText(0, 0 + QFontMetricsF(p.font()).ascent(), "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
}
QPixmap imageDrawStaticText(1000, 1000);
@@ -369,7 +386,7 @@ void tst_QStaticText::scaledPainter()
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
text.setTextFormat(Qt::PlainText);
- p.drawStaticText(QPointF(11, 12), text);
+ p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text);
}
if (!supportsTransformations())
@@ -400,7 +417,7 @@ void tst_QStaticText::projectedPainter()
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
text.setTextFormat(Qt::PlainText);
- p.drawStaticText(QPointF(11, 12), text);
+ p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text);
}
QCOMPARE(imageDrawStaticText, imageDrawText);
@@ -430,7 +447,7 @@ void tst_QStaticText::rotatedScaledAndTranslatedPainter()
QStaticText text("Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
text.setTextFormat(Qt::PlainText);
- p.drawStaticText(QPointF(11, 12), text);
+ p.drawStaticText(QPointF(11, 12 - QFontMetricsF(p.font()).ascent()), text);
}
#if defined(DEBUG_SAVE_IMAGE)
@@ -452,10 +469,10 @@ void tst_QStaticText::transformationChanged()
p.rotate(33.0);
p.scale(0.5, 0.7);
- p.drawText(0, 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
+ p.drawText(0, 0 + QFontMetricsF(p.font()).ascent(), "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
p.scale(7.0, 5.0);
- p.drawText(0, 0, "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
+ p.drawText(0, 0 + QFontMetricsF(p.font()).ascent(), "Lorem ipsum dolor sit amet, consectetur adipiscing elit.");
}
QPixmap imageDrawStaticText(1000, 1000);
@@ -518,5 +535,91 @@ void tst_QStaticText::plainTextVsRichText()
QCOMPARE(imagePlainText, imageRichText);
}
+void tst_QStaticText::setPenPlainText()
+{
+ QFont font = QApplication::font();
+ font.setStyleStrategy(QFont::NoAntialias);
+
+ QFontMetricsF fm(font);
+ QPixmap image(qCeil(fm.width("XXXXX")), qCeil(fm.height()));
+ image.fill(Qt::white);
+ {
+ QPainter p(&image);
+ p.setFont(font);
+ p.setPen(Qt::green);
+
+ QStaticText staticText("XXXXX");
+ staticText.setTextFormat(Qt::PlainText);
+ p.drawStaticText(0, fm.ascent(), staticText);
+ }
+
+ QImage img = image.toImage();
+ for (int x=0; x<img.width(); ++x) {
+ for (int y=0; y<img.height(); ++y) {
+ QRgb pixel = img.pixel(x, y);
+ QVERIFY(pixel == QColor(Qt::white).rgba()
+ || pixel == QColor(Qt::green).rgba());
+ }
+ }
+}
+
+void tst_QStaticText::setPenRichText()
+{
+ QFont font = QApplication::font();
+ font.setStyleStrategy(QFont::NoAntialias);
+
+ QFontMetricsF fm(font);
+ QPixmap image(qCeil(fm.width("XXXXX")), qCeil(fm.height()));
+ image.fill(Qt::white);
+ {
+ QPainter p(&image);
+ p.setFont(font);
+ p.setPen(Qt::green);
+
+ QStaticText staticText;
+ staticText.setText("<html><body>XXXXX</body></html>");
+ staticText.setTextFormat(Qt::RichText);
+ p.drawStaticText(0, 0, staticText);
+ }
+
+ QImage img = image.toImage();
+ for (int x=0; x<img.width(); ++x) {
+ for (int y=0; y<img.height(); ++y) {
+ QRgb pixel = img.pixel(x, y);
+ QVERIFY(pixel == QColor(Qt::white).rgba()
+ || pixel == QColor(Qt::green).rgba());
+ }
+ }
+}
+
+void tst_QStaticText::richTextOverridesPen()
+{
+ QFont font = QApplication::font();
+ font.setStyleStrategy(QFont::NoAntialias);
+
+ QFontMetricsF fm(font);
+ QPixmap image(qCeil(fm.width("XXXXX")), qCeil(fm.height()));
+ image.fill(Qt::white);
+ {
+ QPainter p(&image);
+ p.setFont(font);
+ p.setPen(Qt::green);
+
+ QStaticText staticText;
+ staticText.setText("<html><body><font color=\"#ff0000\">XXXXX</font></body></html>");
+ staticText.setTextFormat(Qt::RichText);
+ p.drawStaticText(0, 0, staticText);
+ }
+
+ QImage img = image.toImage();
+ for (int x=0; x<img.width(); ++x) {
+ for (int y=0; y<img.height(); ++y) {
+ QRgb pixel = img.pixel(x, y);
+ QVERIFY(pixel == QColor(Qt::white).rgba()
+ || pixel == QColor(Qt::red).rgba());
+ }
+ }
+}
+
QTEST_MAIN(tst_QStaticText)
#include "tst_qstatictext.moc"