diff options
-rw-r--r-- | src/quick/items/qquicktext.cpp | 111 | ||||
-rw-r--r-- | src/quick/items/qquicktext_p_p.h | 4 | ||||
-rw-r--r-- | tests/auto/quick/qquicktext/tst_qquicktext.cpp | 10 |
3 files changed, 70 insertions, 55 deletions
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index e6c9a9b763..f64b0cdb19 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -254,8 +254,11 @@ QQuickTextPrivate::~QQuickTextPrivate() { delete elideLayout; delete textLine; textLine = 0; - qDeleteAll(imgTags); - imgTags.clear(); + + if (extra.isAllocated()) { + qDeleteAll(extra->imgTags); + extra->imgTags.clear(); + } } qreal QQuickTextPrivate::getImplicitWidth() const @@ -305,8 +308,8 @@ void QQuickTextPrivate::updateLayout() updateOnComponentComplete = false; layoutTextElided = false; - if (!visibleImgTags.isEmpty()) - visibleImgTags.clear(); + if (extra.isAllocated()) + extra->visibleImgTags.clear(); needToUpdateLayout = false; // Setup instance of QTextLayout for all cases other than richtext @@ -316,7 +319,10 @@ void QQuickTextPrivate::updateLayout() layout.setFont(font); // needs temporary bool because formatModifiesFontSize is in a bit-field bool fontSizeModified = false; - QQuickStyledText::parse(text, layout, imgTags, q->baseUrl(), qmlContext(q), !maximumLineCountValid, &fontSizeModified); + QList<QQuickStyledTextImgTag*> someImgTags = extra.isAllocated() ? extra->imgTags : QList<QQuickStyledTextImgTag*>(); + QQuickStyledText::parse(text, layout, someImgTags, q->baseUrl(), qmlContext(q), !maximumLineCountValid, &fontSizeModified); + if (someImgTags.size() || extra.isAllocated()) + extra.value().imgTags = someImgTags; formatModifiesFontSize = fontSizeModified; multilengthEos = -1; } else { @@ -373,7 +379,7 @@ void QQuickText::imageDownloadFinished() if (d->extra.isAllocated() && d->extra->nbActiveDownloads == 0) { bool needToUpdateLayout = false; - foreach (QQuickStyledTextImgTag *img, d->visibleImgTags) { + foreach (QQuickStyledTextImgTag *img, d->extra->visibleImgTags) { if (!img->size.isValid()) { img->size = img->pix->implicitSize(); needToUpdateLayout = true; @@ -705,8 +711,8 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline) } bool shouldUseDesignMetrics = renderType != QQuickText::NativeRendering; - if (!visibleImgTags.isEmpty()) - visibleImgTags.clear(); + if (extra.isAllocated()) + extra->visibleImgTags.clear(); layout.setCacheEnabled(true); QTextOption textOption = layout.textOption(); if (textOption.alignment() != q->effectiveHAlign() @@ -1106,7 +1112,7 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal Q_Q(QQuickText); line.setLineWidth(lineWidth); - if (imgTags.isEmpty()) { + if (extra.isAllocated() && extra->imgTags.isEmpty()) { line.setPosition(QPointF(line.position().x(), height)); height += (lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : line.height() * lineHeight(); return; @@ -1118,39 +1124,41 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal QList<QQuickStyledTextImgTag *> imagesInLine; - foreach (QQuickStyledTextImgTag *image, imgTags) { - if (image->position >= line.textStart() && - image->position < line.textStart() + line.textLength()) { - - if (!image->pix) { - QUrl url = q->baseUrl().resolved(image->url); - image->pix = new QQuickPixmap(qmlEngine(q), url, image->size); - if (image->pix->isLoading()) { - image->pix->connectFinished(q, SLOT(imageDownloadFinished())); - if (!extra.isAllocated() || !extra->nbActiveDownloads) - extra.value().nbActiveDownloads = 0; - extra->nbActiveDownloads++; - } else if (image->pix->isReady()) { - if (!image->size.isValid()) { - image->size = image->pix->implicitSize(); - // if the size of the image was not explicitly set, we need to - // call updateLayout() once again. - needToUpdateLayout = true; + if (extra.isAllocated()) { + foreach (QQuickStyledTextImgTag *image, extra->imgTags) { + if (image->position >= line.textStart() && + image->position < line.textStart() + line.textLength()) { + + if (!image->pix) { + QUrl url = q->baseUrl().resolved(image->url); + image->pix = new QQuickPixmap(qmlEngine(q), url, image->size); + if (image->pix->isLoading()) { + image->pix->connectFinished(q, SLOT(imageDownloadFinished())); + if (!extra.isAllocated() || !extra->nbActiveDownloads) + extra.value().nbActiveDownloads = 0; + extra->nbActiveDownloads++; + } else if (image->pix->isReady()) { + if (!image->size.isValid()) { + image->size = image->pix->implicitSize(); + // if the size of the image was not explicitly set, we need to + // call updateLayout() once again. + needToUpdateLayout = true; + } + } else if (image->pix->isError()) { + qmlInfo(q) << image->pix->error(); } - } else if (image->pix->isError()) { - qmlInfo(q) << image->pix->error(); } - } - qreal ih = qreal(image->size.height()); - if (image->align == QQuickStyledTextImgTag::Top) - image->pos.setY(0); - else if (image->align == QQuickStyledTextImgTag::Middle) - image->pos.setY((textHeight / 2.0) - (ih / 2.0)); - else - image->pos.setY(textHeight - ih); - imagesInLine << image; - textTop = qMax(textTop, qAbs(image->pos.y())); + qreal ih = qreal(image->size.height()); + if (image->align == QQuickStyledTextImgTag::Top) + image->pos.setY(0); + else if (image->align == QQuickStyledTextImgTag::Middle) + image->pos.setY((textHeight / 2.0) - (ih / 2.0)); + else + image->pos.setY(textHeight - ih); + imagesInLine << image; + textTop = qMax(textTop, qAbs(image->pos.y())); + } } } @@ -1158,7 +1166,7 @@ void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal totalLineHeight = qMax(totalLineHeight, textTop + image->pos.y() + image->size.height()); image->pos.setX(line.cursorToX(image->position)); image->pos.setY(image->pos.y() + height + textTop); - visibleImgTags << image; + extra->visibleImgTags << image; } line.setPosition(QPointF(line.position().x(), height + textTop)); @@ -1500,8 +1508,11 @@ void QQuickText::setText(const QString &n) d->textHasChanged = true; d->implicitWidthValid = false; d->implicitHeightValid = false; - qDeleteAll(d->imgTags); - d->imgTags.clear(); + + if (d->extra.isAllocated()) { + qDeleteAll(d->extra->imgTags); + d->extra->imgTags.clear(); + } d->updateLayout(); setAcceptHoverEvents(d->richText || d->styledText); emit textChanged(d->text); @@ -2078,8 +2089,10 @@ void QQuickText::setBaseUrl(const QUrl &url) } if (d->styledText) { d->textHasChanged = true; - qDeleteAll(d->imgTags); - d->imgTags.clear(); + if (d->extra.isAllocated()) { + qDeleteAll(d->extra->imgTags); + d->extra->imgTags.clear(); + } d->updateLayout(); } emit baseUrlChanged(); @@ -2256,10 +2269,12 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data if (d->elideLayout) 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() + dx, img->pos.y() + dy, pix->width(), pix->height()), pix->image()); + if (d->extra.isAllocated()) { + foreach (QQuickStyledTextImgTag *img, d->extra->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()); + } } } diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h index 0c9af613fc..ff128389e5 100644 --- a/src/quick/items/qquicktext_p_p.h +++ b/src/quick/items/qquicktext_p_p.h @@ -97,6 +97,8 @@ public: int maximumLineCount; QQuickText::LineHeightMode lineHeightMode; QQuickText::FontSizeMode fontSizeMode; + QList<QQuickStyledTextImgTag*> imgTags; + QList<QQuickStyledTextImgTag*> visibleImgTags; }; QLazilyAllocated<ExtraData> extra; @@ -104,8 +106,6 @@ public: QUrl baseUrl; QFont font; QFont sourceFont; - QList<QQuickStyledTextImgTag*> imgTags; - QList<QQuickStyledTextImgTag*> visibleImgTags; QTextLayout layout; QTextLayout *elideLayout; diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp index ae1fd49970..9a7f15c953 100644 --- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp +++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp @@ -2871,7 +2871,7 @@ void tst_qquicktext::imgTagsMultipleImages() QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject); QVERIFY(textPrivate != 0); - QVERIFY(textPrivate->visibleImgTags.count() == 2); + QVERIFY(textPrivate->extra->visibleImgTags.count() == 2); delete textObject; } @@ -2884,9 +2884,9 @@ void tst_qquicktext::imgTagsElide() QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText); QVERIFY(textPrivate != 0); - QVERIFY(textPrivate->visibleImgTags.count() == 0); + QVERIFY(textPrivate->extra->visibleImgTags.count() == 0); myText->setMaximumLineCount(20); - QTRY_VERIFY(textPrivate->visibleImgTags.count() == 1); + QTRY_VERIFY(textPrivate->extra->visibleImgTags.count() == 1); delete myText; delete window; @@ -2904,12 +2904,12 @@ void tst_qquicktext::imgTagsUpdates() QVERIFY(textPrivate != 0); myText->setText("This is a heart<img src=\"images/heart200.png\">."); - QVERIFY(textPrivate->visibleImgTags.count() == 1); + QVERIFY(textPrivate->extra->visibleImgTags.count() == 1); QVERIFY(spy.count() == 1); myText->setMaximumLineCount(2); myText->setText("This is another heart<img src=\"images/heart200.png\">."); - QTRY_VERIFY(textPrivate->visibleImgTags.count() == 1); + QTRY_VERIFY(textPrivate->extra->visibleImgTags.count() == 1); // if maximumLineCount is set and the img tag doesn't have an explicit size // we relayout twice. |