aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/quick/items/qquicktext.cpp355
-rw-r--r--src/quick/items/qquicktext_p_p.h12
-rw-r--r--src/quick/items/qquicktextutil.cpp12
-rw-r--r--src/quick/items/qquicktextutil_p.h5
-rw-r--r--tests/auto/quick/qquicktext/tst_qquicktext.cpp260
5 files changed, 505 insertions, 139 deletions
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index b19b13fec2..fa5652141c 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -78,6 +78,7 @@ QQuickTextPrivate::QQuickTextPrivate()
#if defined(Q_OS_MAC)
, layoutThread(0), paintingThread(0)
#endif
+ , lineWidth(0)
, color(0xFF000000), linkColor(0xFF0000FF), styleColor(0xFF000000)
, lineCount(1), multilengthEos(-1)
, elideMode(QQuickText::ElideNone), hAlign(QQuickText::AlignLeft), vAlign(QQuickText::AlignTop)
@@ -85,7 +86,8 @@ QQuickTextPrivate::QQuickTextPrivate()
, style(QQuickText::Normal)
, updateType(UpdatePaintNode)
, maximumLineCountValid(false), updateOnComponentComplete(true), richText(false)
- , styledText(false), singleline(false), internalWidthUpdate(false), requireImplicitWidth(false)
+ , styledText(false), widthExceeded(false), heightExceeded(false), internalWidthUpdate(false)
+ , requireImplicitSize(false), implicitWidthValid(false), implicitHeightValid(false)
, truncated(false), hAlignImplicit(true), rightToLeftText(false)
, layoutTextElided(false), textHasChanged(true), needToUpdateLayout(false), formatModifiesFontSize(false)
{
@@ -278,16 +280,26 @@ QQuickTextPrivate::~QQuickTextPrivate()
qreal QQuickTextPrivate::getImplicitWidth() const
{
- if (!requireImplicitWidth) {
+ if (!requireImplicitSize) {
// We don't calculate implicitWidth unless it is required.
// We need to force a size update now to ensure implicitWidth is calculated
QQuickTextPrivate *me = const_cast<QQuickTextPrivate*>(this);
- me->requireImplicitWidth = true;
+ me->requireImplicitSize = true;
me->updateSize();
}
return implicitWidth;
}
+qreal QQuickTextPrivate::getImplicitHeight() const
+{
+ if (!requireImplicitSize) {
+ QQuickTextPrivate *me = const_cast<QQuickTextPrivate*>(this);
+ me->requireImplicitSize = true;
+ me->updateSize();
+ }
+ return implicitHeight;
+}
+
void QQuickText::q_imagesLoaded()
{
Q_D(QQuickText);
@@ -409,10 +421,11 @@ void QQuickTextPrivate::updateSize()
return;
}
- if (!requireImplicitWidth) {
+ if (!requireImplicitSize) {
emit q->implicitWidthChanged();
+ emit q->implicitHeightChanged();
// if the implicitWidth is used, then updateSize() has already been called (recursively)
- if (requireImplicitWidth)
+ if (requireImplicitSize)
return;
}
@@ -437,8 +450,6 @@ void QQuickTextPrivate::updateSize()
return;
}
- qreal naturalWidth = 0;
-
QSizeF size(0, 0);
QSizeF previousSize = layedOutTextRect.size();
#if defined(Q_OS_MAC)
@@ -448,7 +459,7 @@ void QQuickTextPrivate::updateSize()
//setup instance of QTextLayout for all cases other than richtext
if (!richText) {
qreal baseline = 0;
- QRectF textRect = setupTextLayout(&naturalWidth, &baseline);
+ QRectF textRect = setupTextLayout(&baseline);
if (internalWidthUpdate) // probably the result of a binding loop, but by letting it
return; // get this far we'll get a warning to that effect if it is.
@@ -457,7 +468,8 @@ void QQuickTextPrivate::updateSize()
size = textRect.size();
updateBaseline(baseline, q->height() - size.height());
} else {
- singleline = false; // richtext can't elide or be optimized for single-line case
+ widthExceeded = true; // always relayout rich text on width changes..
+ heightExceeded = false; // rich text layout isn't affected by height changes.
ensureDoc();
extra->doc->setDefaultFont(font);
QQuickText::HAlignment horizontalAlignment = q->effectiveHAlign();
@@ -472,7 +484,8 @@ void QQuickTextPrivate::updateSize()
option.setWrapMode(QTextOption::WrapMode(wrapMode));
option.setUseDesignMetrics(true);
extra->doc->setDefaultTextOption(option);
- if (requireImplicitWidth && q->widthValid()) {
+ qreal naturalWidth = 0;
+ if (requireImplicitSize && q->widthValid()) {
extra->doc->setTextWidth(-1);
naturalWidth = extra->doc->idealWidth();
const bool wasInLayout = internalWidthUpdate;
@@ -486,25 +499,27 @@ void QQuickTextPrivate::updateSize()
extra->doc->setTextWidth(q->width());
else
extra->doc->setTextWidth(extra->doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug)
+ widthExceeded = extra->doc->textWidth() < extra->doc->idealWidth();
QSizeF dsize = extra->doc->size();
layedOutTextRect = QRectF(QPointF(0,0), dsize);
size = QSizeF(extra->doc->idealWidth(),dsize.height());
QFontMetricsF fm(font);
updateBaseline(fm.ascent(), q->height() - size.height());
- }
- //### need to comfirm cost of always setting these for richText
- internalWidthUpdate = true;
- qreal iWidth = -1;
- if (!q->widthValid())
- iWidth = size.width();
- if (iWidth > -1)
- q->setImplicitSize(iWidth, size.height());
- internalWidthUpdate = false;
+ //### need to confirm cost of always setting these for richText
+ internalWidthUpdate = true;
+ qreal iWidth = -1;
+ if (!q->widthValid())
+ iWidth = size.width();
+ if (iWidth > -1)
+ q->setImplicitSize(iWidth, size.height());
+ internalWidthUpdate = false;
+
+ if (iWidth == -1)
+ q->setImplicitHeight(size.height());
+ }
- if (iWidth == -1)
- q->setImplicitHeight(size.height());
if (layedOutTextRect.size() != previousSize)
emit q->contentSizeChanged();
updateType = UpdatePaintNode;
@@ -661,7 +676,6 @@ void QQuickTextPrivate::elideFormats(
QString QQuickTextPrivate::elidedText(qreal lineWidth, const QTextLine &line, QTextLine *nextLine) const
{
if (nextLine) {
- nextLine->setLineWidth(INT_MAX);
return layout.engine()->elidedText(
Qt::TextElideMode(elideMode),
QFixed::fromReal(lineWidth),
@@ -690,22 +704,21 @@ QString QQuickTextPrivate::elidedText(qreal lineWidth, const QTextLine &line, QT
already absolutely positioned horizontally).
*/
-QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *const baseline)
+QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
{
Q_Q(QQuickText);
- layout.setCacheEnabled(true);
- QTextOption textOption = layout.textOption();
- textOption.setAlignment(Qt::Alignment(q->effectiveHAlign()));
- textOption.setWrapMode(QTextOption::WrapMode(wrapMode));
- textOption.setUseDesignMetrics(true);
- layout.setTextOption(textOption);
- layout.setFont(font);
-
- if (!requireImplicitWidth
- && ((q->widthValid() && q->width() <= 0. && elideMode != QQuickText::ElideNone)
- || (q->heightValid() && q->height() <= 0. && wrapMode != QQuickText::NoWrap && elideMode == QQuickText::ElideRight))) {
+ bool singlelineElide = elideMode != QQuickText::ElideNone && q->widthValid();
+ bool multilineElide = elideMode == QQuickText::ElideRight
+ && q->widthValid()
+ && (q->heightValid() || maximumLineCountValid);
+
+ if ((!requireImplicitSize || (implicitWidthValid && implicitHeightValid))
+ && ((singlelineElide && q->width() <= 0.) || (multilineElide && q->heightValid() && q->height() <= 0.))) {
// we are elided and we have a zero width or height
+ widthExceeded = q->widthValid() && q->width() <= 0.;
+ heightExceeded = q->heightValid() && q->height() <= 0.;
+
if (!truncated) {
truncated = true;
emit q->truncatedChanged();
@@ -716,21 +729,32 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *cons
}
QFontMetricsF fm(font);
- qreal height = (lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : fm.height() * lineHeight();
+ qreal height = (lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : qCeil(fm.height()) * lineHeight();
*baseline = fm.ascent();
return QRectF(0, 0, 0, height);
}
- qreal lineWidth = q->widthValid() && q->width() > 0 ? q->width() : FLT_MAX;
- const qreal maxHeight = q->heightValid() ? q->height() : FLT_MAX;
+ layout.setCacheEnabled(true);
+ QTextOption textOption = layout.textOption();
+ if (textOption.alignment() != q->effectiveHAlign()
+ || textOption.wrapMode() != QTextOption::WrapMode(wrapMode)
+ || !textOption.useDesignMetrics()) {
+ textOption.setAlignment(Qt::Alignment(q->effectiveHAlign()));
+ textOption.setWrapMode(QTextOption::WrapMode(wrapMode));
+ textOption.setUseDesignMetrics(true);
+ layout.setTextOption(textOption);
+ }
+ if (layout.font() != font)
+ layout.setFont(font);
+
+ lineWidth = (q->widthValid() || implicitWidthValid) && q->width() > 0
+ ? q->width()
+ : FLT_MAX;
+ qreal maxHeight = q->heightValid() ? q->height() : FLT_MAX;
const bool customLayout = isLineLaidOutConnected();
const bool wasTruncated = truncated;
- bool singlelineElide = elideMode != QQuickText::ElideNone && q->widthValid();
- bool multilineElide = elideMode == QQuickText::ElideRight
- && q->widthValid()
- && (q->heightValid() || maximumLineCountValid);
bool canWrap = wrapMode != QQuickText::NoWrap && q->widthValid();
bool horizontalFit = fontSizeMode() & QQuickText::HorizontalFit && q->widthValid();
@@ -746,11 +770,13 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *cons
: largeFont;
int scaledFontSize = largeFont;
+ widthExceeded = q->width() <= 0 && (singlelineElide || canWrap || horizontalFit);
+ heightExceeded = q->height() <= 0 && (multilineElide || verticalFit);
+
QRectF br;
QFont scaledFont = font;
- QTextLine line;
int visibleCount = 0;
bool elide;
qreal height = 0;
@@ -759,19 +785,19 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *cons
int elideStart = 0;
int elideEnd = 0;
- *naturalWidth = 0;
-
int eos = multilengthEos;
// Repeated layouts with reduced font sizes or abbreviated strings may be required if the text
- // doesn't fit within the element dimensions.
+ // doesn't fit within the item dimensions, or a binding to implicitWidth/Height changes
+ // the item dimensions.
for (;;) {
if (!once) {
if (pixelSize)
scaledFont.setPixelSize(scaledFontSize);
else
scaledFont.setPointSize(scaledFontSize);
- layout.setFont(scaledFont);
+ if (layout.font() != scaledFont)
+ layout.setFont(scaledFont);
}
layout.beginLayout();
@@ -784,27 +810,31 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *cons
int unwrappedLineCount = 1;
int maxLineCount = maximumLineCount();
height = 0;
+ qreal naturalHeight = 0;
+ qreal previousHeight = 0;
br = QRectF();
- line = layout.createLine();
- for (visibleCount = 1; ; ++visibleCount) {
- qreal preLayoutHeight = height;
+ QRectF unelidedRect;
+ QTextLine line = layout.createLine();
+ for (visibleCount = 1; ; ++visibleCount) {
if (customLayout) {
- setupCustomLineGeometry(line, height);
+ setupCustomLineGeometry(line, naturalHeight);
} else {
- setLineGeometry(line, lineWidth, height);
+ setLineGeometry(line, lineWidth, naturalHeight);
}
+ unelidedRect = br.united(line.naturalTextRect());
+
// Elide the previous line if the accumulated height of the text exceeds the height
// of the element.
- if (multilineElide && height > maxHeight && visibleCount > 1) {
+ if (multilineElide && naturalHeight > maxHeight && visibleCount > 1) {
elide = true;
+ heightExceeded = true;
if (eos != -1) // There's an abbreviated string available, skip the rest as it's
break; // all going to be discarded.
truncated = true;
truncateHeight = true;
- height = preLayoutHeight;
characterCount = line.textStart() + line.textLength();
visibleCount -= 1;
@@ -816,36 +846,37 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *cons
elideStart = previousLine.textStart();
// elideEnd isn't required for right eliding.
- line = previousLine;
- height -= (lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : previousLine.height() * lineHeight();
+ height = previousHeight;
break;
}
- QTextLine nextLine = layout.createLine();
- if (!nextLine.isValid()) {
- characterCount = line.textStart() + line.textLength();
- if (singlelineElide && visibleCount == 1 && line.naturalTextWidth() > lineWidth) {
- // Elide a single line of text if its width exceeds the element width.
+ const QTextLine previousLine = line;
+ line = layout.createLine();
+ if (!line.isValid()) {
+ characterCount = previousLine.textStart() + previousLine.textLength();
+ if (singlelineElide && visibleCount == 1 && previousLine.naturalTextWidth() > lineWidth) {
+ // Elide a single previousLine of text if its width exceeds the element width.
elide = true;
+ widthExceeded = true;
if (eos != -1) // There's an abbreviated string available.
break;
truncated = true;
- height = preLayoutHeight;
elideText = layout.engine()->elidedText(
Qt::TextElideMode(elideMode),
QFixed::fromReal(lineWidth),
0,
- line.textStart(),
- line.textLength());
- elideStart = line.textStart();
- elideEnd = elideStart + line.textLength();
+ previousLine.textStart(),
+ previousLine.textLength());
+ elideStart = previousLine.textStart();
+ elideEnd = elideStart + previousLine.textLength();
} else {
- br = br.united(line.naturalTextRect());
+ br = unelidedRect;
+ height = naturalHeight;
}
break;
} else {
- const bool wrappedLine = layoutText.at(nextLine.textStart() - 1) != QChar::LineSeparator;
+ const bool wrappedLine = layoutText.at(line.textStart() - 1) != QChar::LineSeparator;
wrapped |= wrappedLine;
if (!wrappedLine)
@@ -855,58 +886,66 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *cons
// if enabled.
if (visibleCount == maxLineCount) {
truncated = true;
- characterCount = nextLine.textStart() + nextLine.textLength();
+ heightExceeded |= wrapped;
+ characterCount = line.textStart() + line.textLength();
if (multilineElide) {
elide = true;
if (eos != -1) // There's an abbreviated string available
break;
- height = preLayoutHeight;
elideText = wrappedLine
- ? elidedText(lineWidth, line, &nextLine)
- : elidedText(lineWidth, line);
- elideStart = line.textStart();
+ ? elidedText(lineWidth, previousLine, &line)
+ : elidedText(lineWidth, previousLine);
+ elideStart = previousLine.textStart();
// elideEnd isn't required for right eliding.
} else {
- br = br.united(line.naturalTextRect());
+ br = unelidedRect;
+ height = naturalHeight;
}
break;
}
}
- br = br.united(line.naturalTextRect());
- line = nextLine;
+ br = unelidedRect;
+ previousHeight = height;
+ height = naturalHeight;
}
- layout.endLayout();
- br.moveTop(0);
+ widthExceeded |= wrapped;
- // Save the implicitWidth of the text on the first layout only.
+ // Save the implicit size of the text on the first layout only.
if (once) {
- *naturalWidth = layout.maximumWidth();
once = false;
- if (requireImplicitWidth
- && characterCount < layoutText.length()
- && unwrappedLineCount < maxLineCount) {
- // Use a new layout to get the maximum width for the remaining text. Using a
- // different layout excludes the truncated text from rendering.
- QTextLayout widthLayout(layoutText.mid(characterCount), scaledFont);
- widthLayout.setTextOption(layout.textOption());
-
- widthLayout.beginLayout();
- for (; unwrappedLineCount <= maxLineCount; ++unwrappedLineCount) {
- QTextLine line = widthLayout.createLine();
+ // If implicit sizes are required layout any additional lines up to the maximum line
+ // count.
+ if ((requireImplicitSize) && line.isValid() && unwrappedLineCount < maxLineCount) {
+ // Layout the remainder of the wrapped lines up to maxLineCount to get the implicit
+ // height.
+ for (int lineCount = layout.lineCount(); lineCount < maxLineCount; ++lineCount) {
+ line = layout.createLine();
if (!line.isValid())
break;
+ if (layoutText.at(line.textStart() - 1) == QChar::LineSeparator)
+ ++unwrappedLineCount;
+ setLineGeometry(line, lineWidth, naturalHeight);
}
- widthLayout.endLayout();
- *naturalWidth = qMax(*naturalWidth, widthLayout.maximumWidth());
+
+ // Create the remainder of the unwrapped lines up to maxLineCount to get the
+ // implicit width.
+ if (line.isValid() && layoutText.at(line.textStart() + line.textLength()) != QChar::LineSeparator)
+ line = layout.createLine();
+ for (; line.isValid() && unwrappedLineCount <= maxLineCount; ++unwrappedLineCount)
+ line = layout.createLine();
}
+ layout.endLayout();
+
+ const qreal naturalWidth = layout.maximumWidth();
bool wasInLayout = internalWidthUpdate;
internalWidthUpdate = true;
- q->setImplicitWidth(*naturalWidth);
+ q->setImplicitSize(naturalWidth, naturalHeight);
internalWidthUpdate = wasInLayout;
+ // Update any variables that are dependent on the validity of the width or height.
singlelineElide = elideMode != QQuickText::ElideNone && q->widthValid();
multilineElide = elideMode == QQuickText::ElideRight
&& q->widthValid()
@@ -918,13 +957,38 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *cons
&& (q->heightValid() || (maximumLineCountValid && canWrap));
const qreal oldWidth = lineWidth;
- lineWidth = q->widthValid() && q->width() > 0 ? q->width() : *naturalWidth;
- if (lineWidth != oldWidth && (singlelineElide || multilineElide || canWrap || horizontalFit))
+ const qreal oldHeight = maxHeight;
+
+ lineWidth = q->widthValid() && q->width() > 0 ? q->width() : naturalWidth;
+ maxHeight = q->heightValid() ? q->height() : FLT_MAX;
+
+ // If the width of the item has changed and it's possible the result of wrapping,
+ // eliding, or scaling has changed do another layout.
+ if ((lineWidth < qMin(oldWidth, naturalWidth) || (widthExceeded && lineWidth > oldWidth))
+ && (singlelineElide || multilineElide || canWrap || horizontalFit)) {
+ widthExceeded = false;
+ heightExceeded = false;
+ continue;
+ }
+
+ // If the height of the item has changed and it's possible the result of eliding,
+ // line count truncation or scaling has changed, do another layout.
+ if ((maxHeight < qMin(oldHeight, naturalHeight) || (heightExceeded && maxHeight > oldHeight))
+ && (multilineElide || (canWrap && maximumLineCountValid))) {
+ widthExceeded = false;
+ heightExceeded = false;
continue;
+ }
+
// If the horizontal alignment is not left and the width was not valid we need to relayout
// now that we know the maximum line width.
- if (!q->widthValid() && maxLineCount > 1 && q->effectiveHAlign() != QQuickText::AlignLeft)
+ if (!implicitWidthValid && lineCount > 1 && q->effectiveHAlign() != QQuickText::AlignLeft) {
+ widthExceeded = false;
+ heightExceeded = false;
continue;
+ }
+ } else {
+ layout.endLayout();
}
// If the next needs to be elided and there's an abbreviated string available
@@ -939,14 +1003,15 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *cons
continue;
}
+ br.moveTop(0);
+
if (!horizontalFit && !verticalFit)
break;
// Try and find a font size that better fits the dimensions of the element.
- QRectF unelidedRect = br.united(line.naturalTextRect());
-
if (horizontalFit) {
if (unelidedRect.width() > lineWidth || (!verticalFit && wrapped)) {
+ widthExceeded = true;
largeFont = scaledFontSize - 1;
if (smallFont > largeFont)
break;
@@ -966,6 +1031,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *cons
if (verticalFit) {
if (truncateHeight || unelidedRect.height() > maxHeight) {
+ heightExceeded = true;
largeFont = scaledFontSize - 1;
if (smallFont > largeFont)
break;
@@ -980,6 +1046,9 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *cons
}
}
+ implicitWidthValid = true;
+ implicitHeightValid = true;
+
if (eos != multilengthEos)
truncated = true;
@@ -1023,7 +1092,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *cons
QTextLine elidedLine = elideLayout->createLine();
elidedLine.setPosition(QPointF(0, height));
if (customLayout) {
- setupCustomLineGeometry(elidedLine, height, line.lineNumber());
+ setupCustomLineGeometry(elidedLine, height, visibleCount - 1);
} else {
setLineGeometry(elidedLine, lineWidth, height);
}
@@ -1389,6 +1458,8 @@ void QQuickText::setFont(const QFont &font)
// with headings or <font> tag, we need to re-parse
if (d->formatModifiesFontSize)
d->textHasChanged = true;
+ d->implicitWidthValid = false;
+ d->implicitHeightValid = false;
d->updateLayout();
}
@@ -1429,6 +1500,8 @@ void QQuickText::setText(const QString &n)
d->determineHorizontalAlignment();
}
d->textHasChanged = true;
+ d->implicitWidthValid = false;
+ d->implicitHeightValid = false;
qDeleteAll(d->imgTags);
d->imgTags.clear();
d->updateLayout();
@@ -1788,6 +1861,7 @@ void QQuickText::setMaximumLineCount(int lines)
d->maximumLineCountValid = lines==INT_MAX ? false : true;
if (d->maximumLineCount() != lines) {
d->extra.value().maximumLineCount = lines;
+ d->implicitHeightValid = false;
d->updateLayout();
emit maximumLineCountChanged();
}
@@ -2013,8 +2087,8 @@ QRectF QQuickText::boundingRect() const
Q_D(const QQuickText);
QRectF rect = d->layedOutTextRect;
- rect.moveLeft(QQuickTextUtil::alignedX(rect, width(), d->hAlign));
- rect.moveTop(QQuickTextUtil::alignedY(rect, height(), d->vAlign));
+ rect.moveLeft(QQuickTextUtil::alignedX(rect.width(), width(), d->hAlign));
+ rect.moveTop(QQuickTextUtil::alignedY(rect.height(), height(), d->vAlign));
if (d->style != Normal)
rect.adjust(-1, 0, 1, 2);
@@ -2044,32 +2118,54 @@ void QQuickText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeo
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;
bool scaleFont = d->fontSizeMode() != QQuickText::FixedSize && (widthValid() || heightValid());
+ bool verticalScale = (d->fontSizeMode() & QQuickText::VerticalFit) && heightValid();
+
+ bool widthMaximum = newGeometry.width() >= oldGeometry.width() && !d->widthExceeded;
+ bool heightMaximum = newGeometry.height() >= oldGeometry.height() && !d->heightExceeded;
if ((!widthChanged && !heightChanged) || d->internalWidthUpdate)
goto geomChangeDone;
- if (leftAligned && !wrapped && !elide && !scaleFont)
- goto geomChangeDone; // left aligned unwrapped text without eliding never needs relayout
+ if (effectiveHAlign() != QQuickText::AlignLeft && widthChanged) {
+ // If the width has changed and we're not left aligned do an update so the text is
+ // repositioned even if a full layout isn't required.
+ d->updateType = QQuickTextPrivate::UpdatePaintNode;
+ update();
+ }
- if (!widthChanged && !wrapped && d->singleline && !scaleFont)
- goto geomChangeDone; // only height has changed which doesn't affect single line unwrapped text
+ if (!wrapped && !elide && !scaleFont)
+ goto geomChangeDone; // left aligned unwrapped text without eliding never needs relayout
- if (!widthChanged && wrapped && d->elideMode != QQuickText::ElideRight && !scaleFont && !d->isLineLaidOutConnected())
- goto geomChangeDone; // only height changed and no multiline eliding.
+ if (elide // eliding and dimensions were and remain invalid;
+ && ((widthValid() && oldGeometry.width() <= 0 && newGeometry.width() <= 0)
+ || (heightValid() && oldGeometry.height() <= 0 && newGeometry.height() <= 0))) {
+ goto geomChangeDone;
+ }
- if (leftAligned && d->elideMode == QQuickText::ElideRight && !d->truncated && d->singleline
- && !wrapped && newGeometry.width() > oldGeometry.width() && !scaleFont)
- goto geomChangeDone; // Eliding not affected if we're not currently truncated and we get wider.
+ if (widthMaximum && heightMaximum && !d->isLineLaidOutConnected()) // Size is sufficient and growing.
+ goto geomChangeDone;
- if (d->elideMode == QQuickText::ElideRight && wrapped && newGeometry.height() > oldGeometry.height() && !scaleFont) {
- 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 (!(widthChanged || widthMaximum) && !d->isLineLaidOutConnected()) { // only height has changed
+ if (newGeometry.height() > oldGeometry.height()) {
+ if (!d->heightExceeded) // Height is adequate and growing.
+ goto geomChangeDone;
+ if (d->lineCount == d->maximumLineCount()) // Reached maximum line and height is growing.
+ goto geomChangeDone;
+ } else if (newGeometry.height() < oldGeometry.height()) {
+ if (d->lineCount < 2 && !verticalScale && newGeometry.height() > 0) // A single line won't be truncated until the text is 0 height.
+ goto geomChangeDone;
+
+ if (!verticalScale // no scaling, no eliding, and either unwrapped, or no maximum line count.
+ && d->elideMode != QQuickText::ElideRight
+ && !(d->maximumLineCountValid && d->widthExceeded)) {
+ goto geomChangeDone;
+ }
+ }
+ } else if (!heightChanged && widthMaximum) {
+ goto geomChangeDone;
}
if (d->updateOnComponentComplete || d->textHasChanged) {
@@ -2110,7 +2206,7 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
d->updateType = QQuickTextPrivate::UpdateNone;
- const qreal dy = QQuickTextUtil::alignedY(d->layedOutTextRect, height(), d->vAlign);
+ const qreal dy = QQuickTextUtil::alignedY(d->layedOutTextRect.height(), height(), d->vAlign);
// We need to make sure the layout is done in the current thread
#if defined(Q_OS_MAC)
@@ -2134,29 +2230,30 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
const QColor linkColor = QColor::fromRgba(d->linkColor);
if (d->richText) {
+ const qreal dx = QQuickTextUtil::alignedX(d->layedOutTextRect.width(), width(), d->hAlign);
d->ensureDoc();
- const qreal dx = QQuickTextUtil::alignedX(d->layedOutTextRect, width(), d->hAlign);
node->addTextDocument(QPointF(dx, dy), d->extra->doc, color, d->style, styleColor, linkColor);
- } else if (d->elideMode == QQuickText::ElideNone || d->layedOutTextRect.width() > 0.) {
+ } else if (d->layedOutTextRect.width() > 0) {
+ const qreal dx = QQuickTextUtil::alignedX(d->lineWidth, width(), d->hAlign);
int unelidedLineCount = d->lineCount;
if (d->elideLayout)
unelidedLineCount -= 1;
if (unelidedLineCount > 0) {
node->addTextLayout(
- QPoint(0, dy),
+ QPointF(dx, dy),
&d->layout,
color, d->style, styleColor, linkColor,
QColor(), QColor(), -1, -1,
0, unelidedLineCount);
}
if (d->elideLayout)
- node->addTextLayout(QPoint(0, dy), d->elideLayout, color, d->style, styleColor, linkColor);
- }
+ node->addTextLayout(QPointF(dx, dy), d->elideLayout, color, d->style, styleColor, linkColor);
- foreach (QQuickStyledTextImgTag *img, d->visibleImgTags) {
- QQuickPixmap *pix = img->pix;
- if (pix && pix->isReady())
- node->addImage(QRectF(img->pos.x(), img->pos.y() + dy, pix->width(), pix->height()), pix->image());
+ foreach (QQuickStyledTextImgTag *img, d->visibleImgTags) {
+ QQuickPixmap *pix = img->pix;
+ if (pix && pix->isReady())
+ node->addImage(QRectF(img->pos.x() + dx, img->pos.y() + dy, pix->width(), pix->height()), pix->image());
+ }
}
return node;
}
@@ -2214,6 +2311,7 @@ void QQuickText::setLineHeight(qreal lineHeight)
return;
d->extra.value().lineHeight = lineHeight;
+ d->implicitHeightValid = false;
d->updateLayout();
emit lineHeightChanged(lineHeight);
}
@@ -2242,6 +2340,7 @@ void QQuickText::setLineHeightMode(LineHeightMode mode)
if (mode == d->lineHeightMode())
return;
+ d->implicitHeightValid = false;
d->extra.value().lineHeightMode = mode;
d->updateLayout();
@@ -2400,14 +2499,14 @@ QString QQuickTextPrivate::anchorAt(const QPointF &mousePos) const
{
Q_Q(const QQuickText);
QPointF translatedMousePos = mousePos;
- translatedMousePos.ry() -= QQuickTextUtil::alignedY(layedOutTextRect, q->height(), vAlign);
+ translatedMousePos.ry() -= QQuickTextUtil::alignedY(layedOutTextRect.height(), q->height(), vAlign);
if (styledText) {
QString link = anchorAt(&layout, translatedMousePos);
if (link.isEmpty() && elideLayout)
link = anchorAt(elideLayout, translatedMousePos);
return link;
} else if (richText && extra.isAllocated() && extra->doc) {
- translatedMousePos.rx() -= QQuickTextUtil::alignedX(layedOutTextRect, q->width(), hAlign);
+ translatedMousePos.rx() -= QQuickTextUtil::alignedX(layedOutTextRect.width(), q->width(), hAlign);
return extra->doc->documentLayout()->anchorAt(translatedMousePos);
}
return QString();
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index 985b1e1c80..49d3580578 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -121,6 +121,8 @@ public:
QThread *paintingThread;
#endif
+ qreal lineWidth;
+
QRgb color;
QRgb linkColor;
QRgb styleColor;
@@ -146,9 +148,12 @@ public:
bool updateOnComponentComplete:1;
bool richText:1;
bool styledText:1;
- bool singleline:1;
+ bool widthExceeded:1;
+ bool heightExceeded:1;
bool internalWidthUpdate:1;
- bool requireImplicitWidth:1;
+ bool requireImplicitSize:1;
+ bool implicitWidthValid:1;
+ bool implicitHeightValid:1;
bool truncated:1;
bool hAlignImplicit:1;
bool rightToLeftText:1;
@@ -160,10 +165,11 @@ public:
static const QChar elideChar;
virtual qreal getImplicitWidth() const;
+ virtual qreal getImplicitHeight() const;
void ensureDoc();
- QRectF setupTextLayout(qreal *const naturalWidth, qreal * const baseline);
+ QRectF setupTextLayout(qreal * const baseline);
void setupCustomLineGeometry(QTextLine &line, qreal &height, int lineOffset = 0);
bool isLinkActivatedConnected();
static QString anchorAt(const QTextLayout *layout, const QPointF &mousePos);
diff --git a/src/quick/items/qquicktextutil.cpp b/src/quick/items/qquicktextutil.cpp
index 176301d450..151d72c6ee 100644
--- a/src/quick/items/qquicktextutil.cpp
+++ b/src/quick/items/qquicktextutil.cpp
@@ -78,7 +78,7 @@ QQuickItem *QQuickTextUtil::createCursor(
return item;
}
-qreal QQuickTextUtil::alignedX(const QRectF &rect, qreal width, int alignment)
+qreal QQuickTextUtil::alignedX(const qreal textWidth, const qreal itemWidth, int alignment)
{
qreal x = 0;
switch (alignment) {
@@ -86,26 +86,26 @@ qreal QQuickTextUtil::alignedX(const QRectF &rect, qreal width, int alignment)
case Qt::AlignJustify:
break;
case Qt::AlignRight:
- x = width - rect.width();
+ x = itemWidth - textWidth;
break;
case Qt::AlignHCenter:
- x = (width - rect.width()) / 2;
+ x = (itemWidth - textWidth) / 2;
break;
}
return x;
}
-qreal QQuickTextUtil::alignedY(const QRectF &rect, const qreal height, int alignment)
+qreal QQuickTextUtil::alignedY(const qreal textHeight, const qreal itemHeight, int alignment)
{
qreal y = 0;
switch (alignment) {
case Qt::AlignTop:
break;
case Qt::AlignBottom:
- y = height - rect.height();
+ y = itemHeight - textHeight;
break;
case Qt::AlignVCenter:
- y = (height - rect.height()) / 2;
+ y = (itemHeight - textHeight) / 2;
break;
}
return y;
diff --git a/src/quick/items/qquicktextutil_p.h b/src/quick/items/qquicktextutil_p.h
index d6c05aac3b..21435c31f8 100644
--- a/src/quick/items/qquicktextutil_p.h
+++ b/src/quick/items/qquicktextutil_p.h
@@ -66,8 +66,9 @@ public:
template <typename Private> static void setCursorDelegate(Private *d, QQmlComponent *delegate);
template <typename Private> static void createCursor(Private *d);
- static qreal alignedX(const QRectF &rect, qreal width, int alignment);
- static qreal alignedY(const QRectF &rect, qreal height, int alignment);
+
+ static qreal alignedX(qreal textWidth, qreal itemWidth, int alignment);
+ static qreal alignedY(qreal textHeight, qreal itemHeight, int alignment);
private:
static QQuickItem *createCursor(
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index 0adddb9c85..7a7f5cc053 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -62,6 +62,10 @@ DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
Q_DECLARE_METATYPE(QQuickText::TextFormat)
+QT_BEGIN_NAMESPACE
+extern void qt_setQtEnableTestFont(bool value);
+QT_END_NAMESPACE
+
class tst_qquicktext : public QQmlDataTest
{
Q_OBJECT
@@ -116,6 +120,7 @@ private slots:
void contentSize();
void implicitSizeBinding_data();
void implicitSizeBinding();
+ void geometryChanged();
void boundingRect_data();
void boundingRect();
@@ -218,6 +223,7 @@ tst_qquicktext::tst_qquicktext()
// << "#AA0011DD"
// << "#00F16B11";
//
+ qt_setQtEnableTestFont(true);
}
QQuickView *tst_qquicktext::createView(const QString &filename)
@@ -2031,6 +2037,260 @@ void tst_qquicktext::contentSize()
QCOMPARE(spy.count(), ++spyCount);
}
+void tst_qquicktext::geometryChanged()
+{
+ // Test that text is re-laid out when the geometry of the item by verifying changes in content
+ // size. Implicit width is also tested as that in combination with item geometry provides a
+ // reference for expected content sizes.
+
+ QString componentStr = "import QtQuick 2.0\nText { font.family: \"__Qt__Box__Engine__\"; font.pixelSize: 10 }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QScopedPointer<QObject> object(textComponent.create());
+ QQuickText *textObject = qobject_cast<QQuickText *>(object.data());
+
+ const qreal implicitHeight = textObject->implicitHeight();
+
+ const qreal widths[] = { 100, 2000, 3000, -100, 100 };
+ const qreal heights[] = { implicitHeight, 2000, 3000, -implicitHeight, implicitHeight };
+
+ QCOMPARE(textObject->implicitWidth(), 0.);
+ QVERIFY(implicitHeight > 0.);
+ QCOMPARE(textObject->width(), textObject->implicitWidth());
+ QCOMPARE(textObject->height(), implicitHeight);
+ QCOMPARE(textObject->contentWidth(), textObject->implicitWidth());
+ QCOMPARE(textObject->contentHeight(), implicitHeight);
+
+ textObject->setText("The quick red fox jumped over the lazy brown dog");
+
+ const qreal implicitWidth = textObject->implicitWidth();
+
+ QVERIFY(implicitWidth > 0.);
+ QCOMPARE(textObject->implicitHeight(), implicitHeight);
+ QCOMPARE(textObject->width(), textObject->implicitWidth());
+ QCOMPARE(textObject->height(), textObject->implicitHeight());
+ QCOMPARE(textObject->contentWidth(), textObject->implicitWidth());
+ QCOMPARE(textObject->contentHeight(), textObject->implicitHeight());
+
+ // Changing the geometry with no eliding, or wrapping doesn't change the content size.
+ for (int i = 0; i < 5; ++i) {
+ textObject->setWidth(widths[i]);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), implicitHeight);
+ QCOMPARE(textObject->width(), widths[i]);
+ QCOMPARE(textObject->height(), implicitHeight);
+ QCOMPARE(textObject->contentWidth(), implicitWidth);
+ QCOMPARE(textObject->contentHeight(), implicitHeight);
+ }
+
+ // With eliding enabled the content width is bounded to the item width, but is never
+ // larger than the implicit width.
+ textObject->setElideMode(QQuickText::ElideRight);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), implicitHeight);
+ QCOMPARE(textObject->width(), 100.);
+ QCOMPARE(textObject->height(), implicitHeight);
+ QVERIFY(textObject->contentWidth() <= 100.);
+ QCOMPARE(textObject->contentHeight(), implicitHeight);
+
+ textObject->setWidth(2000.);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), implicitHeight);
+ QCOMPARE(textObject->width(), 2000.);
+ QCOMPARE(textObject->height(), implicitHeight);
+ QCOMPARE(textObject->contentWidth(), implicitWidth);
+ QCOMPARE(textObject->contentHeight(), implicitHeight);
+
+ textObject->setWidth(3000.);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), implicitHeight);
+ QCOMPARE(textObject->width(), 3000.);
+ QCOMPARE(textObject->height(), implicitHeight);
+ QCOMPARE(textObject->contentWidth(), implicitWidth);
+ QCOMPARE(textObject->contentHeight(), implicitHeight);
+
+ textObject->setWidth(-100);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), implicitHeight);
+ QCOMPARE(textObject->width(), -100.);
+ QCOMPARE(textObject->height(), implicitHeight);
+ QCOMPARE(textObject->contentWidth(), 0.);
+ QCOMPARE(textObject->contentHeight(), implicitHeight);
+
+ textObject->setWidth(100.);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), implicitHeight);
+ QCOMPARE(textObject->width(), 100.);
+ QCOMPARE(textObject->height(), implicitHeight);
+ QVERIFY(textObject->contentWidth() <= 100.);
+ QCOMPARE(textObject->contentHeight(), implicitHeight);
+
+ // With wrapping enabled the implicit height changes with the width.
+ textObject->setElideMode(QQuickText::ElideNone);
+ textObject->setWrapMode(QQuickText::Wrap);
+ const qreal wrappedImplicitHeight = textObject->implicitHeight();
+
+ QVERIFY(wrappedImplicitHeight > implicitHeight);
+
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->width(), 100.);
+ QCOMPARE(textObject->height(), wrappedImplicitHeight);
+ QVERIFY(textObject->contentWidth() <= 100.);
+ QCOMPARE(textObject->contentHeight(), wrappedImplicitHeight);
+
+ textObject->setWidth(2000.);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), implicitHeight);
+ QCOMPARE(textObject->width(), 2000.);
+ QCOMPARE(textObject->height(), implicitHeight);
+ QCOMPARE(textObject->contentWidth(), implicitWidth);
+ QCOMPARE(textObject->contentHeight(), implicitHeight);
+
+ textObject->setWidth(3000.);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), implicitHeight);
+ QCOMPARE(textObject->width(), 3000.);
+ QCOMPARE(textObject->height(), implicitHeight);
+ QCOMPARE(textObject->contentWidth(), implicitWidth);
+ QCOMPARE(textObject->contentHeight(), implicitHeight);
+
+ textObject->setWidth(-100);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), implicitHeight);
+ QCOMPARE(textObject->width(), -100.);
+ QCOMPARE(textObject->height(), implicitHeight);
+ QCOMPARE(textObject->contentWidth(), implicitWidth); // 0 or negative width item won't wrap.
+ QCOMPARE(textObject->contentHeight(), implicitHeight);
+
+ textObject->setWidth(100.);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), wrappedImplicitHeight);
+ QCOMPARE(textObject->width(), 100.);
+ QCOMPARE(textObject->height(), wrappedImplicitHeight);
+ QVERIFY(textObject->contentWidth() <= 100.);
+ QCOMPARE(textObject->contentHeight(), wrappedImplicitHeight);
+
+ // With no eliding or maximum line count the content height is the same as the implicit height.
+ for (int i = 0; i < 5; ++i) {
+ textObject->setHeight(heights[i]);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), wrappedImplicitHeight);
+ QCOMPARE(textObject->width(), 100.);
+ QCOMPARE(textObject->height(), heights[i]);
+ QVERIFY(textObject->contentWidth() <= 100.);
+ QCOMPARE(textObject->contentHeight(), wrappedImplicitHeight);
+ }
+
+ // The implicit height is unaffected by eliding but the content height will change.
+ textObject->setElideMode(QQuickText::ElideRight);
+
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), wrappedImplicitHeight);
+ QCOMPARE(textObject->width(), 100.);
+ QCOMPARE(textObject->height(), implicitHeight);
+ QVERIFY(textObject->contentWidth() <= 100.);
+ QCOMPARE(textObject->contentHeight(), implicitHeight);
+
+ textObject->setHeight(2000);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), wrappedImplicitHeight);
+ QCOMPARE(textObject->width(), 100.);
+ QCOMPARE(textObject->height(), 2000.);
+ QVERIFY(textObject->contentWidth() <= 100.);
+ QCOMPARE(textObject->contentHeight(), wrappedImplicitHeight);
+
+ textObject->setHeight(3000);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), wrappedImplicitHeight);
+ QCOMPARE(textObject->width(), 100.);
+ QCOMPARE(textObject->height(), 3000.);
+ QVERIFY(textObject->contentWidth() <= 100.);
+ QCOMPARE(textObject->contentHeight(), wrappedImplicitHeight);
+
+ textObject->setHeight(-implicitHeight);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), wrappedImplicitHeight);
+ QCOMPARE(textObject->width(), 100.);
+ QCOMPARE(textObject->height(), -implicitHeight);
+ QVERIFY(textObject->contentWidth() <= 0.);
+ QCOMPARE(textObject->contentHeight(), implicitHeight); // content height is never less than font height. seems a little odd in this instance.
+
+ textObject->setHeight(implicitHeight);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), wrappedImplicitHeight);
+ QCOMPARE(textObject->width(), 100.);
+ QCOMPARE(textObject->height(), implicitHeight);
+ QVERIFY(textObject->contentWidth() <= 100.);
+ QCOMPARE(textObject->contentHeight(), implicitHeight);
+
+ // Varying the height with a maximum line count but no eliding won't affect the content height.
+ textObject->setElideMode(QQuickText::ElideNone);
+ textObject->setMaximumLineCount(2);
+ textObject->resetHeight();
+
+ const qreal maxLineCountImplicitHeight = textObject->implicitHeight();
+ QVERIFY(maxLineCountImplicitHeight > implicitHeight);
+ QVERIFY(maxLineCountImplicitHeight < wrappedImplicitHeight);
+
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->width(), 100.);
+ QCOMPARE(textObject->height(), maxLineCountImplicitHeight);
+ QVERIFY(textObject->contentWidth() <= 100.);
+ QCOMPARE(textObject->contentHeight(), maxLineCountImplicitHeight);
+
+ for (int i = 0; i < 5; ++i) {
+ textObject->setHeight(heights[i]);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), maxLineCountImplicitHeight);
+ QCOMPARE(textObject->width(), 100.);
+ QCOMPARE(textObject->height(), heights[i]);
+ QVERIFY(textObject->contentWidth() <= 100.);
+ QCOMPARE(textObject->contentHeight(), maxLineCountImplicitHeight);
+ }
+
+ // Varying the width with a maximum line count won't increase the implicit height beyond the
+ // height of the maximum number of lines.
+ textObject->setWidth(2000.);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), implicitHeight);
+ QCOMPARE(textObject->width(), 2000.);
+ QCOMPARE(textObject->height(), implicitHeight);
+ QCOMPARE(textObject->contentWidth(), implicitWidth);
+ QCOMPARE(textObject->contentHeight(), implicitHeight);
+
+ textObject->setWidth(3000.);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), implicitHeight);
+ QCOMPARE(textObject->width(), 3000.);
+ QCOMPARE(textObject->height(), implicitHeight);
+ QCOMPARE(textObject->contentWidth(), implicitWidth);
+ QCOMPARE(textObject->contentHeight(), implicitHeight);
+
+ textObject->setWidth(-100);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), implicitHeight);
+ QCOMPARE(textObject->width(), -100.);
+ QCOMPARE(textObject->height(), implicitHeight);
+ QCOMPARE(textObject->contentWidth(), implicitWidth); // 0 or negative width item won't wrap.
+ QCOMPARE(textObject->contentHeight(), implicitHeight);
+
+ textObject->setWidth(50.);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), maxLineCountImplicitHeight);
+ QCOMPARE(textObject->width(), 50.);
+ QCOMPARE(textObject->height(), implicitHeight);
+ QVERIFY(textObject->contentWidth() <= 50.);
+ QCOMPARE(textObject->contentHeight(), maxLineCountImplicitHeight);
+
+ textObject->setWidth(100.);
+ QCOMPARE(textObject->implicitWidth(), implicitWidth);
+ QCOMPARE(textObject->implicitHeight(), maxLineCountImplicitHeight);
+ QCOMPARE(textObject->width(), 100.);
+ QCOMPARE(textObject->height(), implicitHeight);
+ QVERIFY(textObject->contentWidth() <= 100.);
+ QCOMPARE(textObject->contentHeight(), maxLineCountImplicitHeight);
+}
+
void tst_qquicktext::implicitSizeBinding_data()
{
implicitSize_data();