1 /****************************************************************************
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
6 ** This file is part of the test suite of the Qt Toolkit.
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** GNU Lesser General Public License Usage
10 ** This file may be used under the terms of the GNU Lesser General Public
11 ** License version 2.1 as published by the Free Software Foundation and
12 ** appearing in the file LICENSE.LGPL included in the packaging of this
13 ** file. Please review the following information to ensure the GNU Lesser
14 ** General Public License version 2.1 requirements will be met:
15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 ** In addition, as a special exception, Nokia gives you certain additional
18 ** rights. These rights are described in the Nokia Qt LGPL Exception
19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 ** GNU General Public License Usage
22 ** Alternatively, this file may be used under the terms of the GNU General
23 ** Public License version 3.0 as published by the Free Software Foundation
24 ** and appearing in the file LICENSE.GPL included in the packaging of this
25 ** file. Please review the following information to ensure the GNU General
26 ** Public License version 3.0 requirements will be met:
27 ** http://www.gnu.org/copyleft/gpl.html.
30 ** Alternatively, this file may be used in accordance with the terms and
31 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include <QtTest/QSignalSpy>
43 #include <QTextDocument>
44 #include <QtQml/qqmlengine.h>
45 #include <QtQml/qqmlcomponent.h>
46 #include <QtQuick/private/qquicktext_p.h>
47 #include <private/qquicktext_p_p.h>
48 #include <private/qquickvaluetypes_p.h>
49 #include <QFontMetrics>
51 #include <QtQuick/QQuickView>
52 #include <private/qguiapplication_p.h>
54 #include <QtGui/QMouseEvent>
55 #include "../../shared/util.h"
56 #include "testhttpserver.h"
58 DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
60 Q_DECLARE_METATYPE(QQuickText::TextFormat)
62 class tst_qquicktext : public QQmlDataTest
73 void multilineElide_data();
74 void multilineElide();
77 void alignments_data();
81 void embeddedImages_data();
82 void embeddedImages();
87 // ### these tests may be trivial
88 void horizontalAlignment();
89 void horizontalAlignment_RightToLeft();
90 void verticalAlignment();
96 // QQuickFontValueType
101 void capitalization();
102 void letterSpacing();
107 void implicitSize_data();
110 void implicitSizeBinding_data();
111 void implicitSizeBinding();
113 void boundingRect_data();
117 void imgTagsBaseUrl_data();
118 void imgTagsBaseUrl();
119 void imgTagsAlign_data();
121 void imgTagsMultipleImages();
123 void imgTagsUpdates();
125 void fontSizeMode_data();
127 void fontSizeModeMultiline_data();
128 void fontSizeModeMultiline();
129 void multilengthStrings_data();
130 void multilengthStrings();
131 void fontFormatSizes_data();
132 void fontFormatSizes();
135 QStringList standard;
136 QStringList richText;
138 QStringList horizontalAlignmentmentStrings;
139 QStringList verticalAlignmentmentStrings;
141 QList<Qt::Alignment> verticalAlignmentments;
142 QList<Qt::Alignment> horizontalAlignmentments;
144 QStringList styleStrings;
145 QList<QQuickText::TextStyle> styles;
147 QStringList colorStrings;
151 QQuickView *createView(const QString &filename);
154 tst_qquicktext::tst_qquicktext()
156 standard << "the quick brown fox jumped over the lazy dog"
157 << "the quick brown fox\n jumped over the lazy dog";
159 richText << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a> jumped over the <b>lazy</b> dog</i>"
160 << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a><br>jumped over the <b>lazy</b> dog</i>";
162 horizontalAlignmentmentStrings << "AlignLeft"
166 verticalAlignmentmentStrings << "AlignTop"
170 horizontalAlignmentments << Qt::AlignLeft
174 verticalAlignmentments << Qt::AlignTop
178 styleStrings << "Normal"
183 styles << QQuickText::Normal
184 << QQuickText::Outline
185 << QQuickText::Raised
186 << QQuickText::Sunken;
188 colorStrings << "aliceblue"
201 // need a different test to do alpha channel test
207 QQuickView *tst_qquicktext::createView(const QString &filename)
209 QQuickView *canvas = new QQuickView(0);
211 canvas->setSource(QUrl::fromLocalFile(filename));
215 void tst_qquicktext::text()
218 QQmlComponent textComponent(&engine);
219 textComponent.setData("import QtQuick 2.0\nText { text: \"\" }", QUrl::fromLocalFile(""));
220 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
222 QVERIFY(textObject != 0);
223 QCOMPARE(textObject->text(), QString(""));
224 QVERIFY(textObject->width() == 0);
229 for (int i = 0; i < standard.size(); i++)
231 QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }";
232 QQmlComponent textComponent(&engine);
233 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
235 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
237 QVERIFY(textObject != 0);
238 QCOMPARE(textObject->text(), standard.at(i));
239 QVERIFY(textObject->width() > 0);
244 for (int i = 0; i < richText.size(); i++)
246 QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\" }";
247 QQmlComponent textComponent(&engine);
248 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
249 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
251 QVERIFY(textObject != 0);
252 QString expected = richText.at(i);
253 QCOMPARE(textObject->text(), expected.replace("\\\"", "\""));
254 QVERIFY(textObject->width() > 0);
260 void tst_qquicktext::width()
262 // uses Font metrics to find the width for standard and document to find the width for rich
264 QQmlComponent textComponent(&engine);
265 textComponent.setData("import QtQuick 2.0\nText { text: \"\" }", QUrl::fromLocalFile(""));
266 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
268 QVERIFY(textObject != 0);
269 QCOMPARE(textObject->width(), 0.);
274 bool requiresUnhintedMetrics = !qmlDisableDistanceField();
276 for (int i = 0; i < standard.size(); i++)
278 QVERIFY(!Qt::mightBeRichText(standard.at(i))); // self-test
281 qreal metricWidth = 0.0;
283 if (requiresUnhintedMetrics) {
284 QString s = standard.at(i);
285 s.replace(QLatin1Char('\n'), QChar::LineSeparator);
287 QTextLayout layout(s);
288 layout.setFlags(Qt::TextExpandTabs | Qt::TextShowMnemonic);
291 option.setUseDesignMetrics(true);
292 layout.setTextOption(option);
295 layout.beginLayout();
297 QTextLine line = layout.createLine();
304 metricWidth = layout.boundingRect().width();
307 metricWidth = fm.size(Qt::TextExpandTabs && Qt::TextShowMnemonic, standard.at(i)).width();
310 QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }";
311 QQmlComponent textComponent(&engine);
312 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
313 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
315 QVERIFY(textObject != 0);
316 QVERIFY(textObject->boundingRect().width() > 0);
317 QCOMPARE(textObject->width(), qreal(metricWidth));
318 QVERIFY(textObject->textFormat() == QQuickText::AutoText); // setting text doesn't change format
323 for (int i = 0; i < richText.size(); i++)
325 QVERIFY(Qt::mightBeRichText(richText.at(i))); // self-test
327 QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\"; textFormat: Text.RichText }";
328 QQmlComponent textComponent(&engine);
329 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
330 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
331 QVERIFY(textObject != 0);
333 QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject);
334 QVERIFY(textPrivate != 0);
335 QVERIFY(textPrivate->extra.isAllocated());
337 QTextDocument *doc = textPrivate->extra->doc;
340 QCOMPARE(int(textObject->width()), int(doc->idealWidth()));
341 QVERIFY(textObject->textFormat() == QQuickText::RichText);
347 void tst_qquicktext::wrap()
350 // for specified width and wrap set true
352 QQmlComponent textComponent(&engine);
353 textComponent.setData("import QtQuick 2.0\nText { text: \"Hello\"; wrapMode: Text.WordWrap; width: 300 }", QUrl::fromLocalFile(""));
354 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
355 textHeight = textObject->height();
357 QVERIFY(textObject != 0);
358 QVERIFY(textObject->wrapMode() == QQuickText::WordWrap);
359 QCOMPARE(textObject->width(), 300.);
364 for (int i = 0; i < standard.size(); i++)
366 QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; text: \"" + standard.at(i) + "\" }";
367 QQmlComponent textComponent(&engine);
368 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
369 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
371 QVERIFY(textObject != 0);
372 QCOMPARE(textObject->width(), 30.);
373 QVERIFY(textObject->height() > textHeight);
375 int oldHeight = textObject->height();
376 textObject->setWidth(100);
377 QVERIFY(textObject->height() < oldHeight);
382 for (int i = 0; i < richText.size(); i++)
384 QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; text: \"" + richText.at(i) + "\" }";
385 QQmlComponent textComponent(&engine);
386 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
387 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
389 QVERIFY(textObject != 0);
390 QCOMPARE(textObject->width(), 30.);
391 QVERIFY(textObject->height() > textHeight);
393 qreal oldHeight = textObject->height();
394 textObject->setWidth(100);
395 QVERIFY(textObject->height() < oldHeight);
400 // richtext again with a fixed height
401 for (int i = 0; i < richText.size(); i++)
403 QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; height: 50; text: \"" + richText.at(i) + "\" }";
404 QQmlComponent textComponent(&engine);
405 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
406 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
408 QVERIFY(textObject != 0);
409 QCOMPARE(textObject->width(), 30.);
410 QVERIFY(textObject->implicitHeight() > textHeight);
412 qreal oldHeight = textObject->implicitHeight();
413 textObject->setWidth(100);
414 QVERIFY(textObject->implicitHeight() < oldHeight);
420 void tst_qquicktext::elide()
422 for (QQuickText::TextElideMode m = QQuickText::ElideLeft; m<=QQuickText::ElideNone; m=QQuickText::TextElideMode(int(m)+1)) {
423 const char* elidename[]={"ElideLeft", "ElideRight", "ElideMiddle", "ElideNone"};
424 QString elide = "elide: Text." + QString(elidename[int(m)]) + ";";
426 // XXX Poor coverage.
429 QQmlComponent textComponent(&engine);
430 textComponent.setData(("import QtQuick 2.0\nText { text: \"\"; "+elide+" width: 100 }").toLatin1(), QUrl::fromLocalFile(""));
431 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
433 QCOMPARE(textObject->elideMode(), m);
434 QCOMPARE(textObject->width(), 100.);
439 for (int i = 0; i < standard.size(); i++)
441 QString componentStr = "import QtQuick 2.0\nText { "+elide+" width: 100; text: \"" + standard.at(i) + "\" }";
442 QQmlComponent textComponent(&engine);
443 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
444 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
446 QCOMPARE(textObject->elideMode(), m);
447 QCOMPARE(textObject->width(), 100.);
449 if (m != QQuickText::ElideNone && !standard.at(i).contains('\n'))
450 QVERIFY(textObject->contentWidth() <= textObject->width());
455 for (int i = 0; i < richText.size(); i++)
457 QString componentStr = "import QtQuick 2.0\nText { "+elide+" width: 100; text: \"" + richText.at(i) + "\" }";
458 QQmlComponent textComponent(&engine);
459 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
460 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
462 QCOMPARE(textObject->elideMode(), m);
463 QCOMPARE(textObject->width(), 100.);
465 if (m != QQuickText::ElideNone && standard.at(i).contains("<br>"))
466 QVERIFY(textObject->contentWidth() <= textObject->width());
473 void tst_qquicktext::multilineElide_data()
475 QTest::addColumn<QQuickText::TextFormat>("format");
476 QTest::newRow("plain") << QQuickText::PlainText;
477 QTest::newRow("styled") << QQuickText::StyledText;
480 void tst_qquicktext::multilineElide()
482 QFETCH(QQuickText::TextFormat, format);
483 QQuickView *canvas = createView(testFile("multilineelide.qml"));
485 QQuickText *myText = qobject_cast<QQuickText*>(canvas->rootObject());
486 QVERIFY(myText != 0);
487 myText->setTextFormat(format);
489 QCOMPARE(myText->lineCount(), 3);
490 QCOMPARE(myText->truncated(), true);
492 qreal lineHeight = myText->contentHeight() / 3.;
494 // Set a valid height greater than the truncated content height and ensure the line count is
496 myText->setHeight(200);
497 QCOMPARE(myText->lineCount(), 3);
498 QCOMPARE(myText->truncated(), true);
500 // reduce size and ensure fewer lines are drawn
501 myText->setHeight(lineHeight * 2);
502 QCOMPARE(myText->lineCount(), 2);
504 myText->setHeight(lineHeight);
505 QCOMPARE(myText->lineCount(), 1);
507 myText->setHeight(5);
508 QCOMPARE(myText->lineCount(), 1);
510 myText->setHeight(lineHeight * 3);
511 QCOMPARE(myText->lineCount(), 3);
513 // remove max count and show all lines.
514 myText->setHeight(1000);
515 myText->resetMaximumLineCount();
517 QCOMPARE(myText->truncated(), false);
520 myText->setHeight(lineHeight * 2);
521 QCOMPARE(myText->lineCount(), 2);
522 QCOMPARE(myText->truncated(), true);
524 // change line height
525 myText->setLineHeight(1.1);
526 QCOMPARE(myText->lineCount(), 1);
531 void tst_qquicktext::textFormat()
534 QQmlComponent textComponent(&engine);
535 textComponent.setData("import QtQuick 2.0\nText { text: \"Hello\"; textFormat: Text.RichText }", QUrl::fromLocalFile(""));
536 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
538 QVERIFY(textObject != 0);
539 QVERIFY(textObject->textFormat() == QQuickText::RichText);
541 QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject);
542 QVERIFY(textPrivate != 0);
543 QVERIFY(textPrivate->richText == true);
548 QQmlComponent textComponent(&engine);
549 textComponent.setData("import QtQuick 2.0\nText { text: \"<b>Hello</b>\" }", QUrl::fromLocalFile(""));
550 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
552 QVERIFY(textObject != 0);
553 QVERIFY(textObject->textFormat() == QQuickText::AutoText);
555 QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject);
556 QVERIFY(textPrivate != 0);
557 QVERIFY(textPrivate->styledText == true);
562 QQmlComponent textComponent(&engine);
563 textComponent.setData("import QtQuick 2.0\nText { text: \"<b>Hello</b>\"; textFormat: Text.PlainText }", QUrl::fromLocalFile(""));
564 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
566 QVERIFY(textObject != 0);
567 QVERIFY(textObject->textFormat() == QQuickText::PlainText);
574 void tst_qquicktext::alignments_data()
576 QTest::addColumn<int>("hAlign");
577 QTest::addColumn<int>("vAlign");
578 QTest::addColumn<QString>("expectfile");
580 QTest::newRow("LT") << int(Qt::AlignLeft) << int(Qt::AlignTop) << testFile("alignments_lt.png");
581 QTest::newRow("RT") << int(Qt::AlignRight) << int(Qt::AlignTop) << testFile("alignments_rt.png");
582 QTest::newRow("CT") << int(Qt::AlignHCenter) << int(Qt::AlignTop) << testFile("alignments_ct.png");
584 QTest::newRow("LB") << int(Qt::AlignLeft) << int(Qt::AlignBottom) << testFile("alignments_lb.png");
585 QTest::newRow("RB") << int(Qt::AlignRight) << int(Qt::AlignBottom) << testFile("alignments_rb.png");
586 QTest::newRow("CB") << int(Qt::AlignHCenter) << int(Qt::AlignBottom) << testFile("alignments_cb.png");
588 QTest::newRow("LC") << int(Qt::AlignLeft) << int(Qt::AlignVCenter) << testFile("alignments_lc.png");
589 QTest::newRow("RC") << int(Qt::AlignRight) << int(Qt::AlignVCenter) << testFile("alignments_rc.png");
590 QTest::newRow("CC") << int(Qt::AlignHCenter) << int(Qt::AlignVCenter) << testFile("alignments_cc.png");
594 void tst_qquicktext::alignments()
596 QSKIP("Text alignment pixmap comparison tests will not work with scenegraph");
597 #if (0)// No widgets in scenegraph
600 QFETCH(QString, expectfile);
602 QQuickView *canvas = createView(testFile("alignments.qml"));
604 canvas->requestActivateWindow();
606 QTRY_COMPARE(QGuiApplication::activeWindow(), static_cast<QWidget *>(canvas));
608 QObject *ob = canvas->rootObject();
610 ob->setProperty("horizontalAlignment",hAlign);
611 ob->setProperty("verticalAlignment",vAlign);
612 QTRY_COMPARE(ob->property("running").toBool(),false);
613 QImage actual(canvas->width(), canvas->height(), QImage::Format_RGB32);
614 actual.fill(qRgb(255,255,255));
618 QImage expect(expectfile);
619 if (QGuiApplicationPrivate::graphics_system_name == "raster" || QGuiApplicationPrivate::graphics_system_name == "") {
620 QCOMPARE(actual,expect);
626 //the alignment tests may be trivial o.oa
627 void tst_qquicktext::horizontalAlignment()
629 //test one align each, and then test if two align fails.
631 for (int i = 0; i < standard.size(); i++)
633 for (int j=0; j < horizontalAlignmentmentStrings.size(); j++)
635 QString componentStr = "import QtQuick 2.0\nText { horizontalAlignment: \"" + horizontalAlignmentmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }";
636 QQmlComponent textComponent(&engine);
637 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
638 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
640 QCOMPARE((int)textObject->hAlign(), (int)horizontalAlignmentments.at(j));
646 for (int i = 0; i < richText.size(); i++)
648 for (int j=0; j < horizontalAlignmentmentStrings.size(); j++)
650 QString componentStr = "import QtQuick 2.0\nText { horizontalAlignment: \"" + horizontalAlignmentmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }";
651 QQmlComponent textComponent(&engine);
652 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
653 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
655 QCOMPARE((int)textObject->hAlign(), (int)horizontalAlignmentments.at(j));
663 void tst_qquicktext::horizontalAlignment_RightToLeft()
665 QQuickView *canvas = createView(testFile("horizontalAlignment_RightToLeft.qml"));
666 QQuickText *text = canvas->rootObject()->findChild<QQuickText*>("text");
670 QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(text);
671 QVERIFY(textPrivate != 0);
673 QTRY_VERIFY(textPrivate->layout.lineCount());
675 // implicit alignment should follow the reading direction of RTL text
676 QCOMPARE(text->hAlign(), QQuickText::AlignRight);
677 QCOMPARE(text->effectiveHAlign(), text->hAlign());
678 QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
680 // explicitly left aligned text
681 text->setHAlign(QQuickText::AlignLeft);
682 QCOMPARE(text->hAlign(), QQuickText::AlignLeft);
683 QCOMPARE(text->effectiveHAlign(), text->hAlign());
684 QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
686 // explicitly right aligned text
687 text->setHAlign(QQuickText::AlignRight);
688 QCOMPARE(text->hAlign(), QQuickText::AlignRight);
689 QCOMPARE(text->effectiveHAlign(), text->hAlign());
690 QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
692 // change to rich text
693 QString textString = text->text();
694 text->setText(QString("<i>") + textString + QString("</i>"));
695 text->setTextFormat(QQuickText::RichText);
698 // implicitly aligned rich text should follow the reading direction of text
699 QCOMPARE(text->hAlign(), QQuickText::AlignRight);
700 QCOMPARE(text->effectiveHAlign(), text->hAlign());
701 QVERIFY(textPrivate->extra.isAllocated());
702 QVERIFY(textPrivate->extra->doc->defaultTextOption().alignment() & Qt::AlignLeft);
704 // explicitly left aligned rich text
705 text->setHAlign(QQuickText::AlignLeft);
706 QCOMPARE(text->hAlign(), QQuickText::AlignLeft);
707 QCOMPARE(text->effectiveHAlign(), text->hAlign());
708 QVERIFY(textPrivate->extra->doc->defaultTextOption().alignment() & Qt::AlignRight);
710 // explicitly right aligned rich text
711 text->setHAlign(QQuickText::AlignRight);
712 QCOMPARE(text->hAlign(), QQuickText::AlignRight);
713 QCOMPARE(text->effectiveHAlign(), text->hAlign());
714 QVERIFY(textPrivate->extra->doc->defaultTextOption().alignment() & Qt::AlignLeft);
716 text->setText(textString);
717 text->setTextFormat(QQuickText::PlainText);
719 // explicitly center aligned
720 text->setHAlign(QQuickText::AlignHCenter);
721 QCOMPARE(text->hAlign(), QQuickText::AlignHCenter);
722 QCOMPARE(text->effectiveHAlign(), text->hAlign());
723 QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
724 QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().right() > canvas->width()/2);
726 // reseted alignment should go back to following the text reading direction
728 QCOMPARE(text->hAlign(), QQuickText::AlignRight);
729 QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
731 // mirror the text item
732 QQuickItemPrivate::get(text)->setLayoutMirror(true);
734 // mirrored implicit alignment should continue to follow the reading direction of the text
735 QCOMPARE(text->hAlign(), QQuickText::AlignRight);
736 QCOMPARE(text->effectiveHAlign(), QQuickText::AlignRight);
737 QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
739 // mirrored explicitly right aligned behaves as left aligned
740 text->setHAlign(QQuickText::AlignRight);
741 QCOMPARE(text->hAlign(), QQuickText::AlignRight);
742 QCOMPARE(text->effectiveHAlign(), QQuickText::AlignLeft);
743 QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
745 // mirrored explicitly left aligned behaves as right aligned
746 text->setHAlign(QQuickText::AlignLeft);
747 QCOMPARE(text->hAlign(), QQuickText::AlignLeft);
748 QCOMPARE(text->effectiveHAlign(), QQuickText::AlignRight);
749 QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
752 QQuickItemPrivate::get(text)->setLayoutMirror(false);
755 // English text should be implicitly left aligned
756 text->setText("Hello world!");
757 QCOMPARE(text->hAlign(), QQuickText::AlignLeft);
758 QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
760 // empty text with implicit alignment follows the system locale-based
761 // keyboard input direction from QInputMethod::inputDirection()
763 QCOMPARE(text->hAlign(), qApp->inputMethod()->inputDirection() == Qt::LeftToRight ?
764 QQuickText::AlignLeft : QQuickText::AlignRight);
765 text->setHAlign(QQuickText::AlignRight);
766 QCOMPARE(text->hAlign(), QQuickText::AlignRight);
770 // alignment of Text with no text set to it
771 QString componentStr = "import QtQuick 2.0\nText {}";
772 QQmlComponent textComponent(&engine);
773 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
774 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
775 QCOMPARE(textObject->hAlign(), qApp->inputMethod()->inputDirection() == Qt::LeftToRight ?
776 QQuickText::AlignLeft : QQuickText::AlignRight);
780 void tst_qquicktext::verticalAlignment()
782 //test one align each, and then test if two align fails.
784 for (int i = 0; i < standard.size(); i++)
786 for (int j=0; j < verticalAlignmentmentStrings.size(); j++)
788 QString componentStr = "import QtQuick 2.0\nText { verticalAlignment: \"" + verticalAlignmentmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }";
789 QQmlComponent textComponent(&engine);
790 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
791 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
793 QVERIFY(textObject != 0);
794 QCOMPARE((int)textObject->vAlign(), (int)verticalAlignmentments.at(j));
800 for (int i = 0; i < richText.size(); i++)
802 for (int j=0; j < verticalAlignmentmentStrings.size(); j++)
804 QString componentStr = "import QtQuick 2.0\nText { verticalAlignment: \"" + verticalAlignmentmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }";
805 QQmlComponent textComponent(&engine);
806 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
807 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
809 QVERIFY(textObject != 0);
810 QCOMPARE((int)textObject->vAlign(), (int)verticalAlignmentments.at(j));
818 void tst_qquicktext::font()
820 //test size, then bold, then italic, then family
822 QString componentStr = "import QtQuick 2.0\nText { font.pointSize: 40; text: \"Hello World\" }";
823 QQmlComponent textComponent(&engine);
824 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
825 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
827 QCOMPARE(textObject->font().pointSize(), 40);
828 QCOMPARE(textObject->font().bold(), false);
829 QCOMPARE(textObject->font().italic(), false);
835 QString componentStr = "import QtQuick 2.0\nText { font.pixelSize: 40; text: \"Hello World\" }";
836 QQmlComponent textComponent(&engine);
837 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
838 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
840 QCOMPARE(textObject->font().pixelSize(), 40);
841 QCOMPARE(textObject->font().bold(), false);
842 QCOMPARE(textObject->font().italic(), false);
848 QString componentStr = "import QtQuick 2.0\nText { font.bold: true; text: \"Hello World\" }";
849 QQmlComponent textComponent(&engine);
850 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
851 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
853 QCOMPARE(textObject->font().bold(), true);
854 QCOMPARE(textObject->font().italic(), false);
860 QString componentStr = "import QtQuick 2.0\nText { font.italic: true; text: \"Hello World\" }";
861 QQmlComponent textComponent(&engine);
862 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
863 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
865 QCOMPARE(textObject->font().italic(), true);
866 QCOMPARE(textObject->font().bold(), false);
872 QString componentStr = "import QtQuick 2.0\nText { font.family: \"Helvetica\"; text: \"Hello World\" }";
873 QQmlComponent textComponent(&engine);
874 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
875 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
877 QCOMPARE(textObject->font().family(), QString("Helvetica"));
878 QCOMPARE(textObject->font().bold(), false);
879 QCOMPARE(textObject->font().italic(), false);
885 QString componentStr = "import QtQuick 2.0\nText { font.family: \"\"; text: \"Hello World\" }";
886 QQmlComponent textComponent(&engine);
887 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
888 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
890 QCOMPARE(textObject->font().family(), QString(""));
896 void tst_qquicktext::style()
899 for (int i = 0; i < styles.size(); i++)
901 QString componentStr = "import QtQuick 2.0\nText { style: \"" + styleStrings.at(i) + "\"; styleColor: \"white\"; text: \"Hello World\" }";
902 QQmlComponent textComponent(&engine);
903 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
904 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
906 QCOMPARE((int)textObject->style(), (int)styles.at(i));
907 QCOMPARE(textObject->styleColor(), QColor("white"));
911 QString componentStr = "import QtQuick 2.0\nText { text: \"Hello World\" }";
912 QQmlComponent textComponent(&engine);
913 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
914 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
916 QRectF brPre = textObject->boundingRect();
917 textObject->setStyle(QQuickText::Outline);
918 QRectF brPost = textObject->boundingRect();
920 QVERIFY(brPre.width() < brPost.width());
921 QVERIFY(brPre.height() < brPost.height());
926 void tst_qquicktext::color()
929 for (int i = 0; i < colorStrings.size(); i++)
931 QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
932 QQmlComponent textComponent(&engine);
933 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
934 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
936 QCOMPARE(textObject->color(), QColor(colorStrings.at(i)));
937 QCOMPARE(textObject->styleColor(), QColor("black"));
938 QCOMPARE(textObject->linkColor(), QColor("blue"));
943 for (int i = 0; i < colorStrings.size(); i++)
945 QString componentStr = "import QtQuick 2.0\nText { styleColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
946 QQmlComponent textComponent(&engine);
947 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
948 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
950 QCOMPARE(textObject->styleColor(), QColor(colorStrings.at(i)));
951 // default color to black?
952 QCOMPARE(textObject->color(), QColor("black"));
953 QCOMPARE(textObject->linkColor(), QColor("blue"));
958 for (int i = 0; i < colorStrings.size(); i++)
960 QString componentStr = "import QtQuick 2.0\nText { linkColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
961 QQmlComponent textComponent(&engine);
962 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
963 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
965 QCOMPARE(textObject->styleColor(), QColor("black"));
966 QCOMPARE(textObject->color(), QColor("black"));
967 QCOMPARE(textObject->linkColor(), QColor(colorStrings.at(i)));
972 for (int i = 0; i < colorStrings.size(); i++)
974 for (int j = 0; j < colorStrings.size(); j++)
976 QString componentStr = "import QtQuick 2.0\nText { "
977 "color: \"" + colorStrings.at(i) + "\"; "
978 "styleColor: \"" + colorStrings.at(j) + "\"; "
979 "linkColor: \"" + colorStrings.at(j) + "\"; "
980 "text: \"Hello World\" }";
981 QQmlComponent textComponent(&engine);
982 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
983 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
985 QCOMPARE(textObject->color(), QColor(colorStrings.at(i)));
986 QCOMPARE(textObject->styleColor(), QColor(colorStrings.at(j)));
987 QCOMPARE(textObject->linkColor(), QColor(colorStrings.at(j)));
993 QString colorStr = "#AA001234";
994 QColor testColor("#001234");
995 testColor.setAlpha(170);
997 QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStr + "\"; text: \"Hello World\" }";
998 QQmlComponent textComponent(&engine);
999 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1000 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1002 QCOMPARE(textObject->color(), testColor);
1006 QString colorStr = "#001234";
1007 QColor testColor(colorStr);
1009 QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStr + "\"; text: \"Hello World\" }";
1010 QQmlComponent textComponent(&engine);
1011 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1012 QScopedPointer<QObject> object(textComponent.create());
1013 QQuickText *textObject = qobject_cast<QQuickText*>(object.data());
1015 QSignalSpy spy(textObject, SIGNAL(colorChanged()));
1017 QCOMPARE(textObject->color(), testColor);
1018 textObject->setColor(testColor);
1019 QCOMPARE(textObject->color(), testColor);
1020 QCOMPARE(spy.count(), 0);
1022 testColor = QColor("black");
1023 textObject->setColor(testColor);
1024 QCOMPARE(textObject->color(), testColor);
1025 QCOMPARE(spy.count(), 1);
1027 QString colorStr = "#001234";
1028 QColor testColor(colorStr);
1030 QString componentStr = "import QtQuick 2.0\nText { styleColor: \"" + colorStr + "\"; text: \"Hello World\" }";
1031 QQmlComponent textComponent(&engine);
1032 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1033 QScopedPointer<QObject> object(textComponent.create());
1034 QQuickText *textObject = qobject_cast<QQuickText*>(object.data());
1036 QSignalSpy spy(textObject, SIGNAL(styleColorChanged()));
1038 QCOMPARE(textObject->styleColor(), testColor);
1039 textObject->setStyleColor(testColor);
1040 QCOMPARE(textObject->styleColor(), testColor);
1041 QCOMPARE(spy.count(), 0);
1043 testColor = QColor("black");
1044 textObject->setStyleColor(testColor);
1045 QCOMPARE(textObject->styleColor(), testColor);
1046 QCOMPARE(spy.count(), 1);
1048 QString colorStr = "#001234";
1049 QColor testColor(colorStr);
1051 QString componentStr = "import QtQuick 2.0\nText { linkColor: \"" + colorStr + "\"; text: \"Hello World\" }";
1052 QQmlComponent textComponent(&engine);
1053 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1054 QScopedPointer<QObject> object(textComponent.create());
1055 QQuickText *textObject = qobject_cast<QQuickText*>(object.data());
1057 QSignalSpy spy(textObject, SIGNAL(linkColorChanged()));
1059 QCOMPARE(textObject->linkColor(), testColor);
1060 textObject->setLinkColor(testColor);
1061 QCOMPARE(textObject->linkColor(), testColor);
1062 QCOMPARE(spy.count(), 0);
1064 testColor = QColor("black");
1065 textObject->setLinkColor(testColor);
1066 QCOMPARE(textObject->linkColor(), testColor);
1067 QCOMPARE(spy.count(), 1);
1071 void tst_qquicktext::smooth()
1073 for (int i = 0; i < standard.size(); i++)
1076 QString componentStr = "import QtQuick 2.0\nText { smooth: false; text: \"" + standard.at(i) + "\" }";
1077 QQmlComponent textComponent(&engine);
1078 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1079 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1080 QCOMPARE(textObject->smooth(), false);
1085 QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }";
1086 QQmlComponent textComponent(&engine);
1087 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1088 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1089 QCOMPARE(textObject->smooth(), true);
1094 for (int i = 0; i < richText.size(); i++)
1097 QString componentStr = "import QtQuick 2.0\nText { smooth: false; text: \"" + richText.at(i) + "\" }";
1098 QQmlComponent textComponent(&engine);
1099 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1100 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1101 QCOMPARE(textObject->smooth(), false);
1106 QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\" }";
1107 QQmlComponent textComponent(&engine);
1108 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1109 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1110 QCOMPARE(textObject->smooth(), true);
1117 void tst_qquicktext::weight()
1120 QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
1121 QQmlComponent textComponent(&engine);
1122 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1123 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1125 QVERIFY(textObject != 0);
1126 QCOMPARE((int)textObject->font().weight(), (int)QQuickFontValueType::Normal);
1131 QString componentStr = "import QtQuick 2.0\nText { font.weight: \"Bold\"; text: \"Hello world!\" }";
1132 QQmlComponent textComponent(&engine);
1133 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1134 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1136 QVERIFY(textObject != 0);
1137 QCOMPARE((int)textObject->font().weight(), (int)QQuickFontValueType::Bold);
1143 void tst_qquicktext::underline()
1146 QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
1147 QQmlComponent textComponent(&engine);
1148 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1149 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1151 QVERIFY(textObject != 0);
1152 QCOMPARE(textObject->font().underline(), false);
1157 QString componentStr = "import QtQuick 2.0\nText { font.underline: true; text: \"Hello world!\" }";
1158 QQmlComponent textComponent(&engine);
1159 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1160 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1162 QVERIFY(textObject != 0);
1163 QCOMPARE(textObject->font().underline(), true);
1169 void tst_qquicktext::overline()
1172 QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
1173 QQmlComponent textComponent(&engine);
1174 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1175 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1177 QVERIFY(textObject != 0);
1178 QCOMPARE(textObject->font().overline(), false);
1183 QString componentStr = "import QtQuick 2.0\nText { font.overline: true; text: \"Hello world!\" }";
1184 QQmlComponent textComponent(&engine);
1185 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1186 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1188 QVERIFY(textObject != 0);
1189 QCOMPARE(textObject->font().overline(), true);
1195 void tst_qquicktext::strikeout()
1198 QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
1199 QQmlComponent textComponent(&engine);
1200 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1201 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1203 QVERIFY(textObject != 0);
1204 QCOMPARE(textObject->font().strikeOut(), false);
1209 QString componentStr = "import QtQuick 2.0\nText { font.strikeout: true; text: \"Hello world!\" }";
1210 QQmlComponent textComponent(&engine);
1211 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1212 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1214 QVERIFY(textObject != 0);
1215 QCOMPARE(textObject->font().strikeOut(), true);
1221 void tst_qquicktext::capitalization()
1224 QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
1225 QQmlComponent textComponent(&engine);
1226 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1227 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1229 QVERIFY(textObject != 0);
1230 QCOMPARE((int)textObject->font().capitalization(), (int)QQuickFontValueType::MixedCase);
1235 QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"AllUppercase\" }";
1236 QQmlComponent textComponent(&engine);
1237 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1238 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1240 QVERIFY(textObject != 0);
1241 QCOMPARE((int)textObject->font().capitalization(), (int)QQuickFontValueType::AllUppercase);
1246 QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"AllLowercase\" }";
1247 QQmlComponent textComponent(&engine);
1248 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1249 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1251 QVERIFY(textObject != 0);
1252 QCOMPARE((int)textObject->font().capitalization(), (int)QQuickFontValueType::AllLowercase);
1257 QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"SmallCaps\" }";
1258 QQmlComponent textComponent(&engine);
1259 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1260 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1262 QVERIFY(textObject != 0);
1263 QCOMPARE((int)textObject->font().capitalization(), (int)QQuickFontValueType::SmallCaps);
1268 QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"Capitalize\" }";
1269 QQmlComponent textComponent(&engine);
1270 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1271 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1273 QVERIFY(textObject != 0);
1274 QCOMPARE((int)textObject->font().capitalization(), (int)QQuickFontValueType::Capitalize);
1280 void tst_qquicktext::letterSpacing()
1283 QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
1284 QQmlComponent textComponent(&engine);
1285 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1286 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1288 QVERIFY(textObject != 0);
1289 QCOMPARE(textObject->font().letterSpacing(), 0.0);
1294 QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.letterSpacing: -2 }";
1295 QQmlComponent textComponent(&engine);
1296 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1297 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1299 QVERIFY(textObject != 0);
1300 QCOMPARE(textObject->font().letterSpacing(), -2.);
1305 QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.letterSpacing: 3 }";
1306 QQmlComponent textComponent(&engine);
1307 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1308 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1310 QVERIFY(textObject != 0);
1311 QCOMPARE(textObject->font().letterSpacing(), 3.);
1317 void tst_qquicktext::wordSpacing()
1320 QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
1321 QQmlComponent textComponent(&engine);
1322 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1323 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1325 QVERIFY(textObject != 0);
1326 QCOMPARE(textObject->font().wordSpacing(), 0.0);
1331 QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.wordSpacing: -50 }";
1332 QQmlComponent textComponent(&engine);
1333 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1334 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1336 QVERIFY(textObject != 0);
1337 QCOMPARE(textObject->font().wordSpacing(), -50.);
1342 QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.wordSpacing: 200 }";
1343 QQmlComponent textComponent(&engine);
1344 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1345 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1347 QVERIFY(textObject != 0);
1348 QCOMPARE(textObject->font().wordSpacing(), 200.);
1357 class EventSender : public QQuickItem
1360 void sendEvent(QMouseEvent *event) {
1361 if (event->type() == QEvent::MouseButtonPress)
1362 mousePressEvent(event);
1363 else if (event->type() == QEvent::MouseButtonRelease)
1364 mouseReleaseEvent(event);
1366 qWarning() << "Trying to send unsupported event type";
1370 class LinkTest : public QObject
1379 void linkClicked(QString l) { link = l; }
1382 void tst_qquicktext::clickLink()
1385 QString componentStr = "import QtQuick 2.0\nText { text: \"<a href=\\\"http://qt.nokia.com\\\">Hello world!</a>\" }";
1386 QQmlComponent textComponent(&engine);
1387 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1388 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1390 QVERIFY(textObject != 0);
1393 QObject::connect(textObject, SIGNAL(linkActivated(QString)), &test, SLOT(linkClicked(QString)));
1396 QMouseEvent me(QEvent::MouseButtonPress,QPointF(textObject->x()/2, textObject->y()/2), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
1397 static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&me);
1402 QMouseEvent me(QEvent::MouseButtonRelease,QPointF(textObject->x()/2, textObject->y()/2), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
1403 static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&me);
1408 QCOMPARE(test.link, QLatin1String("http://qt.nokia.com"));
1414 void tst_qquicktext::baseUrl()
1416 QUrl localUrl("file:///tests/text.qml");
1417 QUrl remoteUrl("http://qt.nokia.com/test.qml");
1419 QQmlComponent textComponent(&engine);
1420 textComponent.setData("import QtQuick 2.0\n Text {}", localUrl);
1421 QQuickText *textObject = qobject_cast<QQuickText *>(textComponent.create());
1423 QCOMPARE(textObject->baseUrl(), localUrl);
1425 QSignalSpy spy(textObject, SIGNAL(baseUrlChanged()));
1427 textObject->setBaseUrl(localUrl);
1428 QCOMPARE(textObject->baseUrl(), localUrl);
1429 QCOMPARE(spy.count(), 0);
1431 textObject->setBaseUrl(remoteUrl);
1432 QCOMPARE(textObject->baseUrl(), remoteUrl);
1433 QCOMPARE(spy.count(), 1);
1435 textObject->resetBaseUrl();
1436 QCOMPARE(textObject->baseUrl(), localUrl);
1437 QCOMPARE(spy.count(), 2);
1440 void tst_qquicktext::embeddedImages_data()
1442 QTest::addColumn<QUrl>("qmlfile");
1443 QTest::addColumn<QString>("error");
1444 QTest::newRow("local") << testFileUrl("embeddedImagesLocal.qml") << "";
1445 QTest::newRow("local-error") << testFileUrl("embeddedImagesLocalError.qml")
1446 << testFileUrl("embeddedImagesLocalError.qml").toString()+":3:1: QML Text: Cannot open: " + testFileUrl("http/notexists.png").toString();
1447 QTest::newRow("local") << testFileUrl("embeddedImagesLocalRelative.qml") << "";
1448 QTest::newRow("remote") << testFileUrl("embeddedImagesRemote.qml") << "";
1449 QTest::newRow("remote-error") << testFileUrl("embeddedImagesRemoteError.qml")
1450 << testFileUrl("embeddedImagesRemoteError.qml").toString()+":3:1: QML Text: Error downloading http://127.0.0.1:14453/notexists.png - server replied: Not found";
1451 QTest::newRow("remote") << testFileUrl("embeddedImagesRemoteRelative.qml") << "";
1454 void tst_qquicktext::embeddedImages()
1458 QFETCH(QUrl, qmlfile);
1459 QFETCH(QString, error);
1461 TestHTTPServer server(14453);
1462 server.serveDirectory(testFile("http"));
1464 if (!error.isEmpty())
1465 QTest::ignoreMessage(QtWarningMsg, error.toLatin1());
1467 QQmlComponent textComponent(&engine, qmlfile);
1468 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1470 QVERIFY(textObject != 0);
1472 QTRY_COMPARE(textObject->resourcesLoading(), 0);
1474 QPixmap pm(testFile("http/exists.png"));
1475 if (error.isEmpty()) {
1476 QCOMPARE(textObject->width(), double(pm.width()));
1477 QCOMPARE(textObject->height(), double(pm.height()));
1479 QVERIFY(16 != pm.width()); // check test is effective
1480 QCOMPARE(textObject->width(), 16.0); // default size of QTextDocument broken image icon
1481 QCOMPARE(textObject->height(), 16.0);
1487 void tst_qquicktext::lineCount()
1489 QQuickView *canvas = createView(testFile("lineCount.qml"));
1491 QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
1492 QVERIFY(myText != 0);
1494 QVERIFY(myText->lineCount() > 1);
1495 QVERIFY(!myText->truncated());
1496 QCOMPARE(myText->maximumLineCount(), INT_MAX);
1498 myText->setMaximumLineCount(2);
1499 QCOMPARE(myText->lineCount(), 2);
1500 QCOMPARE(myText->truncated(), true);
1501 QCOMPARE(myText->maximumLineCount(), 2);
1503 myText->resetMaximumLineCount();
1504 QCOMPARE(myText->maximumLineCount(), INT_MAX);
1505 QCOMPARE(myText->truncated(), false);
1507 myText->setElideMode(QQuickText::ElideRight);
1508 myText->setMaximumLineCount(2);
1509 QCOMPARE(myText->lineCount(), 2);
1510 QCOMPARE(myText->truncated(), true);
1511 QCOMPARE(myText->maximumLineCount(), 2);
1516 void tst_qquicktext::lineHeight()
1518 QQuickView *canvas = createView(testFile("lineHeight.qml"));
1520 QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
1521 QVERIFY(myText != 0);
1523 QVERIFY(myText->lineHeight() == 1);
1524 QVERIFY(myText->lineHeightMode() == QQuickText::ProportionalHeight);
1526 qreal h = myText->height();
1527 myText->setLineHeight(1.5);
1528 QCOMPARE(myText->height(), qreal(qCeil(h * 1.5)));
1530 myText->setLineHeightMode(QQuickText::FixedHeight);
1531 myText->setLineHeight(20);
1532 QCOMPARE(myText->height(), myText->lineCount() * 20.0);
1534 myText->setText("Lorem ipsum sit <b>amet</b>, consectetur adipiscing elit. Integer felis nisl, varius in pretium nec, venenatis non erat. Proin lobortis interdum dictum.");
1535 myText->setLineHeightMode(QQuickText::ProportionalHeight);
1536 myText->setLineHeight(1.0);
1538 qreal h2 = myText->height();
1539 myText->setLineHeight(2.0);
1540 QVERIFY(myText->height() == h2 * 2.0);
1542 myText->setLineHeightMode(QQuickText::FixedHeight);
1543 myText->setLineHeight(10);
1544 QCOMPARE(myText->height(), myText->lineCount() * 10.0);
1549 void tst_qquicktext::implicitSize_data()
1551 QTest::addColumn<QString>("text");
1552 QTest::addColumn<QString>("width");
1553 QTest::addColumn<QString>("wrap");
1554 QTest::addColumn<QString>("elide");
1555 QTest::addColumn<QString>("format");
1556 QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.NoWrap" << "Text.ElideNone" << "Text.PlainText";
1557 QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" <<" 50" << "Text.NoWrap" << "Text.ElideNone" << "Text.RichText";
1558 QTest::newRow("styledtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" <<" 50" << "Text.NoWrap" << "Text.ElideNone" << "Text.StyledText";
1559 QTest::newRow("plain, 0 width") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.NoWrap" << "Text.ElideNone" << "Text.PlainText";
1560 QTest::newRow("plain, elide") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.NoWrap" << "Text.ElideRight" << "Text.PlainText";
1561 QTest::newRow("plain, 0 width, elide") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.NoWrap" << "Text.ElideRight" << "Text.PlainText";
1562 QTest::newRow("richtext, 0 width") << "<b>The quick red fox jumped over the lazy brown dog</b>" <<" 0" << "Text.NoWrap" << "Text.ElideNone" << "Text.RichText";
1563 QTest::newRow("styledtext, 0 width") << "<b>The quick red fox jumped over the lazy brown dog</b>" <<" 0" << "Text.NoWrap" << "Text.ElideNone" << "Text.StyledText";
1564 QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.Wrap" << "Text.ElideNone" << "Text.PlainText";
1565 QTest::newRow("richtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "50" << "Text.Wrap" << "Text.ElideNone" << "Text.RichText";
1566 QTest::newRow("styledtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "50" << "Text.Wrap" << "Text.ElideNone" << "Text.StyledText";
1567 QTest::newRow("plain_wrap, 0 width") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.Wrap" << "Text.ElideNone" << "Text.PlainText";
1568 QTest::newRow("plain_wrap, elide") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.Wrap" << "Text.ElideRight" << "Text.PlainText";
1569 QTest::newRow("plain_wrap, 0 width, elide") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.Wrap" << "Text.ElideRight" << "Text.PlainText";
1570 QTest::newRow("richtext_wrap, 0 width") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "0" << "Text.Wrap" << "Text.ElideNone" << "Text.RichText";
1571 QTest::newRow("styledtext_wrap, 0 width") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "0" << "Text.Wrap" << "Text.ElideNone" << "Text.StyledText";
1574 void tst_qquicktext::implicitSize()
1576 QFETCH(QString, text);
1577 QFETCH(QString, width);
1578 QFETCH(QString, format);
1579 QFETCH(QString, wrap);
1580 QFETCH(QString, elide);
1581 QString componentStr = "import QtQuick 2.0\nText { "
1582 "text: \"" + text + "\"; "
1583 "width: " + width + "; "
1584 "textFormat: " + format + "; "
1585 "wrapMode: " + wrap + "; "
1586 "elide: " + elide + "; "
1587 "maximumLineCount: 1 }";
1588 QQmlComponent textComponent(&engine);
1589 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1590 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1592 QVERIFY(textObject->width() < textObject->implicitWidth());
1593 QVERIFY(textObject->height() == textObject->implicitHeight());
1595 textObject->resetWidth();
1596 QVERIFY(textObject->width() == textObject->implicitWidth());
1597 QVERIFY(textObject->height() == textObject->implicitHeight());
1602 void tst_qquicktext::contentSize()
1604 QString componentStr = "import QtQuick 2.0\nText { width: 75; height: 16; font.pixelSize: 10 }";
1605 QQmlComponent textComponent(&engine);
1606 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1607 QScopedPointer<QObject> object(textComponent.create());
1608 QQuickText *textObject = qobject_cast<QQuickText *>(object.data());
1610 QSignalSpy spy(textObject, SIGNAL(contentSizeChanged()));
1612 textObject->setText("The quick red fox jumped over the lazy brown dog");
1614 QVERIFY(textObject->contentWidth() > textObject->width());
1615 QVERIFY(textObject->contentHeight() < textObject->height());
1616 QCOMPARE(spy.count(), 1);
1618 textObject->setWrapMode(QQuickText::WordWrap);
1619 QVERIFY(textObject->contentWidth() <= textObject->width());
1620 QVERIFY(textObject->contentHeight() > textObject->height());
1621 QCOMPARE(spy.count(), 2);
1623 textObject->setElideMode(QQuickText::ElideRight);
1624 QVERIFY(textObject->contentWidth() <= textObject->width());
1625 QVERIFY(textObject->contentHeight() < textObject->height());
1626 QCOMPARE(spy.count(), 3);
1628 qreal elidedWidth = textObject->contentWidth();
1630 textObject->setText("The quickredfoxjumpedoverthe lazy brown dog");
1631 QVERIFY(textObject->contentWidth() <= textObject->width());
1632 QVERIFY(textObject->contentHeight() < textObject->height());
1633 // this text probably won't have the same elided width, but it's not guaranteed.
1634 if (textObject->contentWidth() != elidedWidth)
1635 QCOMPARE(spy.count(), ++spyCount);
1637 QCOMPARE(spy.count(), spyCount);
1639 textObject->setElideMode(QQuickText::ElideNone);
1640 QVERIFY(textObject->contentWidth() > textObject->width());
1641 QVERIFY(textObject->contentHeight() > textObject->height());
1642 QCOMPARE(spy.count(), ++spyCount);
1645 void tst_qquicktext::implicitSizeBinding_data()
1647 implicitSize_data();
1650 void tst_qquicktext::implicitSizeBinding()
1652 QFETCH(QString, text);
1653 QFETCH(QString, wrap);
1654 QFETCH(QString, format);
1655 QString componentStr = "import QtQuick 2.0\nText { text: \"" + text + "\"; width: implicitWidth; height: implicitHeight; wrapMode: " + wrap + "; textFormat: " + format + " }";
1657 QDeclarativeComponent textComponent(&engine);
1658 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1659 QScopedPointer<QObject> object(textComponent.create());
1660 QQuickText *textObject = qobject_cast<QQuickText *>(object.data());
1662 QCOMPARE(textObject->width(), textObject->implicitWidth());
1663 QCOMPARE(textObject->height(), textObject->implicitHeight());
1665 textObject->resetWidth();
1666 QCOMPARE(textObject->width(), textObject->implicitWidth());
1667 QCOMPARE(textObject->height(), textObject->implicitHeight());
1669 textObject->resetHeight();
1670 QCOMPARE(textObject->width(), textObject->implicitWidth());
1671 QCOMPARE(textObject->height(), textObject->implicitHeight());
1674 void tst_qquicktext::boundingRect_data()
1676 QTest::addColumn<QString>("format");
1677 QTest::newRow("PlainText") << "Text.PlainText";
1678 QTest::newRow("StyledText") << "Text.StyledText";
1679 QTest::newRow("RichText") << "Text.RichText";
1682 void tst_qquicktext::boundingRect()
1684 QFETCH(QString, format);
1686 QDeclarativeComponent component(&engine);
1687 component.setData("import QtQuick 2.0\n Text { textFormat:" + format.toUtf8() + "}", QUrl());
1688 QScopedPointer<QObject> object(component.create());
1689 QQuickText *text = qobject_cast<QQuickText *>(object.data());
1692 QCOMPARE(text->boundingRect().x(), qreal(0));
1693 QCOMPARE(text->boundingRect().y(), qreal(0));
1694 QCOMPARE(text->boundingRect().width(), qreal(0));
1695 QCOMPARE(text->boundingRect().height(), QFontMetricsF(text->font()).height());
1697 text->setText("Hello World");
1699 QTextLayout layout(text->text());
1700 layout.setFont(text->font());
1702 if (!qmlDisableDistanceField()) {
1704 option.setUseDesignMetrics(true);
1705 layout.setTextOption(option);
1707 layout.beginLayout();
1708 QTextLine line = layout.createLine();
1711 QCOMPARE(text->boundingRect().x(), qreal(0));
1712 QCOMPARE(text->boundingRect().y(), qreal(0));
1713 QCOMPARE(text->boundingRect().width(), line.naturalTextWidth());
1714 QCOMPARE(text->boundingRect().height(), line.height());
1716 // the size of the bounding rect shouldn't be bounded by the size of item.
1717 text->setWidth(text->width() / 2);
1718 QCOMPARE(text->boundingRect().x(), qreal(0));
1719 QCOMPARE(text->boundingRect().y(), qreal(0));
1720 QCOMPARE(text->boundingRect().width(), line.naturalTextWidth());
1721 QCOMPARE(text->boundingRect().height(), line.height());
1723 text->setHeight(text->height() * 2);
1724 QCOMPARE(text->boundingRect().x(), qreal(0));
1725 QCOMPARE(text->boundingRect().y(), qreal(0));
1726 QCOMPARE(text->boundingRect().width(), line.naturalTextWidth());
1727 QCOMPARE(text->boundingRect().height(), line.height());
1729 text->setHAlign(QQuickText::AlignRight);
1730 QCOMPARE(text->boundingRect().x(), text->width() - line.naturalTextWidth());
1731 QCOMPARE(text->boundingRect().y(), qreal(0));
1732 QCOMPARE(text->boundingRect().width(), line.naturalTextWidth());
1733 QCOMPARE(text->boundingRect().height(), line.height());
1735 text->setWrapMode(QQuickText::Wrap);
1736 QCOMPARE(text->boundingRect().right(), text->width());
1737 QCOMPARE(text->boundingRect().y(), qreal(0));
1738 QVERIFY(text->boundingRect().width() < line.naturalTextWidth());
1739 QVERIFY(text->boundingRect().height() > line.height());
1741 text->setVAlign(QQuickText::AlignBottom);
1742 QCOMPARE(text->boundingRect().right(), text->width());
1743 QCOMPARE(text->boundingRect().bottom(), text->height());
1744 QVERIFY(text->boundingRect().width() < line.naturalTextWidth());
1745 QVERIFY(text->boundingRect().height() > line.height());
1748 void tst_qquicktext::lineLaidOut()
1750 QQuickView *canvas = createView(testFile("lineLayout.qml"));
1752 QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
1753 QVERIFY(myText != 0);
1755 QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText);
1756 QVERIFY(textPrivate != 0);
1758 QVERIFY(!textPrivate->extra.isAllocated());
1760 #if defined(Q_OS_MAC)
1761 QVERIFY(myText->lineCount() == textPrivate->linesRects.count());
1764 for (int i = 0; i < textPrivate->layout.lineCount(); ++i) {
1765 QRectF r = textPrivate->layout.lineAt(i).rect();
1766 QVERIFY(r.width() == i * 15);
1768 QVERIFY(r.x() == r.width() + 30);
1770 QVERIFY(r.x() == r.width() * 2 + 60);
1771 QVERIFY(r.height() == 20);
1778 void tst_qquicktext::imgTagsBaseUrl_data()
1780 QTest::addColumn<QUrl>("src");
1781 QTest::addColumn<QUrl>("baseUrl");
1782 QTest::addColumn<QUrl>("contextUrl");
1783 QTest::addColumn<qreal>("imgHeight");
1785 QTest::newRow("absolute local")
1786 << testFileUrl("images/heart200.png")
1790 QTest::newRow("relative local context 1")
1791 << QUrl("images/heart200.png")
1793 << testFileUrl("/app.qml")
1795 QTest::newRow("relative local context 2")
1796 << QUrl("heart200.png")
1798 << testFileUrl("images/app.qml")
1800 QTest::newRow("relative local base 1")
1801 << QUrl("images/heart200.png")
1803 << testFileUrl("nonexistant/app.qml")
1805 QTest::newRow("relative local base 2")
1806 << QUrl("heart200.png")
1807 << testFileUrl("images/")
1808 << testFileUrl("nonexistant/app.qml")
1810 QTest::newRow("base relative to local context")
1811 << QUrl("heart200.png")
1812 << testFileUrl("images/")
1813 << testFileUrl("/app.qml")
1816 QTest::newRow("absolute remote")
1817 << QUrl("http://127.0.0.1:14453/images/heart200.png")
1821 QTest::newRow("relative remote base 1")
1822 << QUrl("images/heart200.png")
1823 << QUrl("http://127.0.0.1:14453/")
1824 << testFileUrl("nonexistant/app.qml")
1826 QTest::newRow("relative remote base 2")
1827 << QUrl("heart200.png")
1828 << QUrl("http://127.0.0.1:14453/images/")
1829 << testFileUrl("nonexistant/app.qml")
1833 void tst_qquicktext::imgTagsBaseUrl()
1836 QFETCH(QUrl, baseUrl);
1837 QFETCH(QUrl, contextUrl);
1838 QFETCH(qreal, imgHeight);
1840 TestHTTPServer server(14453);
1841 server.serveDirectory(testFile(""));
1843 QByteArray baseUrlFragment;
1844 if (!baseUrl.isEmpty())
1845 baseUrlFragment = "; baseUrl: \"" + baseUrl.toEncoded() + "\"";
1846 QByteArray componentStr = "import QtQuick 2.0\nText { text: \"This is a test <img src=\\\"" + src.toEncoded() + "\\\">\"" + baseUrlFragment + " }";
1848 QQmlComponent component(&engine);
1849 component.setData(componentStr, contextUrl);
1850 QScopedPointer<QObject> object(component.create());
1851 QQuickText *textObject = qobject_cast<QQuickText *>(object.data());
1852 QVERIFY(textObject);
1854 QCoreApplication::processEvents();
1856 QTRY_COMPARE(textObject->height(), imgHeight);
1859 void tst_qquicktext::imgTagsAlign_data()
1861 QTest::addColumn<QString>("src");
1862 QTest::addColumn<int>("imgHeight");
1863 QTest::addColumn<QString>("align");
1864 QTest::newRow("heart-bottom") << "data/images/heart200.png" << 181 << "bottom";
1865 QTest::newRow("heart-middle") << "data/images/heart200.png" << 181 << "middle";
1866 QTest::newRow("heart-top") << "data/images/heart200.png" << 181 << "top";
1867 QTest::newRow("starfish-bottom") << "data/images/starfish_2.png" << 217 << "bottom";
1868 QTest::newRow("starfish-middle") << "data/images/starfish_2.png" << 217 << "middle";
1869 QTest::newRow("starfish-top") << "data/images/starfish_2.png" << 217 << "top";
1872 void tst_qquicktext::imgTagsAlign()
1874 QFETCH(QString, src);
1875 QFETCH(int, imgHeight);
1876 QFETCH(QString, align);
1877 QString componentStr = "import QtQuick 2.0\nText { text: \"This is a test <img src=\\\"" + src + "\\\" align=\\\"" + align + "\\\"> of image.\" }";
1878 QQmlComponent textComponent(&engine);
1879 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1880 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1882 QVERIFY(textObject != 0);
1883 QVERIFY(textObject->height() == imgHeight);
1885 QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject);
1886 QVERIFY(textPrivate != 0);
1888 QRectF br = textPrivate->layout.boundingRect();
1889 if (align == "bottom")
1890 QVERIFY(br.y() == imgHeight - br.height());
1891 else if (align == "middle")
1892 QVERIFY(br.y() == imgHeight / 2.0 - br.height() / 2.0);
1893 else if (align == "top")
1894 QVERIFY(br.y() == 0);
1899 void tst_qquicktext::imgTagsMultipleImages()
1901 QString componentStr = "import QtQuick 2.0\nText { text: \"This is a starfish<img src=\\\"data/images/starfish_2.png\\\" width=\\\"60\\\" height=\\\"60\\\" > and another one<img src=\\\"data/images/heart200.png\\\" width=\\\"85\\\" height=\\\"85\\\">.\" }";
1903 QQmlComponent textComponent(&engine);
1904 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1905 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1907 QVERIFY(textObject != 0);
1908 QVERIFY(textObject->height() == 85);
1910 QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject);
1911 QVERIFY(textPrivate != 0);
1912 QVERIFY(textPrivate->visibleImgTags.count() == 2);
1917 void tst_qquicktext::imgTagsElide()
1919 QQuickView *canvas = createView(testFile("imgTagsElide.qml"));
1920 QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
1921 QVERIFY(myText != 0);
1923 QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText);
1924 QVERIFY(textPrivate != 0);
1925 QVERIFY(textPrivate->visibleImgTags.count() == 0);
1926 myText->setMaximumLineCount(20);
1927 QTRY_VERIFY(textPrivate->visibleImgTags.count() == 1);
1933 void tst_qquicktext::imgTagsUpdates()
1935 QQuickView *canvas = createView(testFile("imgTagsUpdates.qml"));
1936 QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
1937 QVERIFY(myText != 0);
1939 QSignalSpy spy(myText, SIGNAL(contentSizeChanged()));
1941 QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText);
1942 QVERIFY(textPrivate != 0);
1944 myText->setText("This is a heart<img src=\"images/heart200.png\">.");
1945 QVERIFY(textPrivate->visibleImgTags.count() == 1);
1946 QVERIFY(spy.count() == 1);
1948 myText->setMaximumLineCount(2);
1949 myText->setText("This is another heart<img src=\"images/heart200.png\">.");
1950 QTRY_VERIFY(textPrivate->visibleImgTags.count() == 1);
1952 // if maximumLineCount is set and the img tag doesn't have an explicit size
1953 // we relayout twice.
1954 QVERIFY(spy.count() == 3);
1960 void tst_qquicktext::imgTagsError()
1962 QString componentStr = "import QtQuick 2.0\nText { text: \"This is a starfish<img src=\\\"data/images/starfish_2.pn\\\" width=\\\"60\\\" height=\\\"60\\\">.\" }";
1964 QQmlComponent textComponent(&engine);
1965 QTest::ignoreMessage(QtWarningMsg, "file::2:1: QML Text: Cannot open: file:data/images/starfish_2.pn");
1966 textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
1967 QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
1969 QVERIFY(textObject != 0);
1973 void tst_qquicktext::fontSizeMode_data()
1975 QTest::addColumn<QString>("text");
1976 QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog";
1977 QTest::newRow("styled") << "<b>The quick red fox jumped over the lazy brown dog</b>";
1980 void tst_qquicktext::fontSizeMode()
1982 QFETCH(QString, text);
1984 QScopedPointer<QQuickView> canvas(createView(testFile("fontSizeMode.qml")));
1987 QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
1988 QVERIFY(myText != 0);
1990 myText->setText(text);
1991 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
1993 qreal originalWidth = myText->contentWidth();
1994 qreal originalHeight = myText->contentHeight();
1996 // The original text unwrapped should exceed the width of the item.
1997 QVERIFY(originalWidth > myText->width());
1998 QVERIFY(originalHeight < myText->height());
2000 QFont font = myText->font();
2001 font.setPixelSize(64);
2003 myText->setFont(font);
2004 myText->setFontSizeMode(QQuickText::HorizontalFit);
2005 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2006 // Font size reduced to fit within the width of the item.
2007 qreal horizontalFitWidth = myText->contentWidth();
2008 qreal horizontalFitHeight = myText->contentHeight();
2009 QVERIFY(horizontalFitWidth <= myText->width() + 2); // rounding
2010 QVERIFY(horizontalFitHeight <= myText->height() + 2);
2012 // Elide won't affect the size with HorizontalFit.
2013 myText->setElideMode(QQuickText::ElideRight);
2014 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2015 QVERIFY(!myText->truncated());
2016 QCOMPARE(myText->contentWidth(), horizontalFitWidth);
2017 QCOMPARE(myText->contentHeight(), horizontalFitHeight);
2019 myText->setElideMode(QQuickText::ElideLeft);
2020 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2021 QVERIFY(!myText->truncated());
2022 QCOMPARE(myText->contentWidth(), horizontalFitWidth);
2023 QCOMPARE(myText->contentHeight(), horizontalFitHeight);
2025 myText->setElideMode(QQuickText::ElideMiddle);
2026 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2027 QVERIFY(!myText->truncated());
2028 QCOMPARE(myText->contentWidth(), horizontalFitWidth);
2029 QCOMPARE(myText->contentHeight(), horizontalFitHeight);
2031 myText->setElideMode(QQuickText::ElideNone);
2032 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2034 myText->setFontSizeMode(QQuickText::VerticalFit);
2035 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2036 // Font size increased to fill the height of the item.
2037 qreal verticalFitHeight = myText->contentHeight();
2038 QVERIFY(myText->contentWidth() > myText->width());
2039 QVERIFY(verticalFitHeight <= myText->height() + 2);
2040 QVERIFY(verticalFitHeight > originalHeight);
2042 // Elide won't affect the height of a single line with VerticalFit but will crop the width.
2043 myText->setElideMode(QQuickText::ElideRight);
2044 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2045 QVERIFY(myText->truncated());
2046 QVERIFY(myText->contentWidth() <= myText->width() + 2);
2047 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2049 myText->setElideMode(QQuickText::ElideLeft);
2050 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2051 QVERIFY(myText->truncated());
2052 QVERIFY(myText->contentWidth() <= myText->width() + 2);
2053 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2055 myText->setElideMode(QQuickText::ElideMiddle);
2056 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2057 QVERIFY(myText->truncated());
2058 QVERIFY(myText->contentWidth() <= myText->width() + 2);
2059 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2061 myText->setElideMode(QQuickText::ElideNone);
2062 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2064 myText->setFontSizeMode(QQuickText::Fit);
2065 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2066 // Should be the same as HorizontalFit with no wrapping.
2067 QCOMPARE(myText->contentWidth(), horizontalFitWidth);
2068 QCOMPARE(myText->contentHeight(), horizontalFitHeight);
2070 // Elide won't affect the size with Fit.
2071 myText->setElideMode(QQuickText::ElideRight);
2072 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2073 QVERIFY(!myText->truncated());
2074 QCOMPARE(myText->contentWidth(), horizontalFitWidth);
2075 QCOMPARE(myText->contentHeight(), horizontalFitHeight);
2077 myText->setElideMode(QQuickText::ElideLeft);
2078 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2079 QVERIFY(!myText->truncated());
2080 QCOMPARE(myText->contentWidth(), horizontalFitWidth);
2081 QCOMPARE(myText->contentHeight(), horizontalFitHeight);
2083 myText->setElideMode(QQuickText::ElideMiddle);
2084 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2085 QVERIFY(!myText->truncated());
2086 QCOMPARE(myText->contentWidth(), horizontalFitWidth);
2087 QCOMPARE(myText->contentHeight(), horizontalFitHeight);
2089 myText->setElideMode(QQuickText::ElideNone);
2090 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2092 myText->setFontSizeMode(QQuickText::FixedSize);
2093 myText->setWrapMode(QQuickText::Wrap);
2094 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2096 originalWidth = myText->contentWidth();
2097 originalHeight = myText->contentHeight();
2099 // The original text wrapped should exceed the height of the item.
2100 QVERIFY(originalWidth <= myText->width() + 2);
2101 QVERIFY(originalHeight > myText->height());
2103 myText->setFontSizeMode(QQuickText::HorizontalFit);
2104 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2105 // HorizontalFit should reduce the font size to minimize wrapping, which brings it back to the
2106 // same size as without text wrapping.
2107 QCOMPARE(myText->contentWidth(), horizontalFitWidth);
2108 QCOMPARE(myText->contentHeight(), horizontalFitHeight);
2110 // Elide won't affect the size with HorizontalFit.
2111 myText->setElideMode(QQuickText::ElideRight);
2112 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2113 QVERIFY(!myText->truncated());
2114 QCOMPARE(myText->contentWidth(), horizontalFitWidth);
2115 QCOMPARE(myText->contentHeight(), horizontalFitHeight);
2117 myText->setElideMode(QQuickText::ElideNone);
2118 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2120 myText->setFontSizeMode(QQuickText::VerticalFit);
2121 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2122 // VerticalFit should reduce the size to the wrapped text within the vertical height.
2123 verticalFitHeight = myText->contentHeight();
2124 qreal verticalFitWidth = myText->contentWidth();
2125 QVERIFY(myText->contentWidth() <= myText->width() + 2);
2126 QVERIFY(verticalFitHeight <= myText->height() + 2);
2127 QVERIFY(verticalFitHeight < originalHeight);
2129 // Elide won't affect the height or width of a wrapped text with VerticalFit.
2130 myText->setElideMode(QQuickText::ElideRight);
2131 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2132 QVERIFY(!myText->truncated());
2133 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2134 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2136 myText->setElideMode(QQuickText::ElideNone);
2137 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2139 myText->setFontSizeMode(QQuickText::Fit);
2140 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2141 // Should be the same as VerticalFit with wrapping.
2142 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2143 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2145 // Elide won't affect the size with Fit.
2146 myText->setElideMode(QQuickText::ElideRight);
2147 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2148 QVERIFY(!myText->truncated());
2149 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2150 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2152 myText->setElideMode(QQuickText::ElideNone);
2153 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2155 myText->setFontSizeMode(QQuickText::FixedSize);
2156 myText->setMaximumLineCount(2);
2157 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2159 // The original text wrapped should exceed the height of the item.
2160 QVERIFY(originalWidth <= myText->width() + 2);
2161 QVERIFY(originalHeight > myText->height());
2163 myText->setFontSizeMode(QQuickText::HorizontalFit);
2164 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2165 // HorizontalFit should reduce the font size to minimize wrapping, which brings it back to the
2166 // same size as without text wrapping.
2167 QCOMPARE(myText->contentWidth(), horizontalFitWidth);
2168 QCOMPARE(myText->contentHeight(), horizontalFitHeight);
2170 // Elide won't affect the size with HorizontalFit.
2171 myText->setElideMode(QQuickText::ElideRight);
2172 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2173 QVERIFY(!myText->truncated());
2174 QCOMPARE(myText->contentWidth(), horizontalFitWidth);
2175 QCOMPARE(myText->contentHeight(), horizontalFitHeight);
2177 myText->setElideMode(QQuickText::ElideNone);
2178 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2180 myText->setFontSizeMode(QQuickText::VerticalFit);
2181 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2182 // VerticalFit should reduce the size to the wrapped text within the vertical height.
2183 verticalFitHeight = myText->contentHeight();
2184 verticalFitWidth = myText->contentWidth();
2185 QVERIFY(myText->contentWidth() <= myText->width() + 2);
2186 QVERIFY(verticalFitHeight <= myText->height() + 2);
2187 QVERIFY(verticalFitHeight < originalHeight);
2189 // Elide won't affect the height or width of a wrapped text with VerticalFit.
2190 myText->setElideMode(QQuickText::ElideRight);
2191 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2192 QVERIFY(!myText->truncated());
2193 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2194 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2196 myText->setElideMode(QQuickText::ElideNone);
2197 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2199 myText->setFontSizeMode(QQuickText::Fit);
2200 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2201 // Should be the same as VerticalFit with wrapping.
2202 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2203 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2205 // Elide won't affect the size with Fit.
2206 myText->setElideMode(QQuickText::ElideRight);
2207 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2208 QVERIFY(!myText->truncated());
2209 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2210 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2212 myText->setElideMode(QQuickText::ElideNone);
2213 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2216 void tst_qquicktext::fontSizeModeMultiline_data()
2218 QTest::addColumn<QString>("text");
2219 QTest::newRow("plain") << "The quick red fox jumped\n over the lazy brown dog";
2220 QTest::newRow("styledtext") << "<b>The quick red fox jumped<br/> over the lazy brown dog</b>";
2223 void tst_qquicktext::fontSizeModeMultiline()
2225 QFETCH(QString, text);
2227 QScopedPointer<QQuickView> canvas(createView(testFile("fontSizeMode.qml")));
2230 QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
2231 QVERIFY(myText != 0);
2233 myText->setText(text);
2234 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2236 qreal originalWidth = myText->contentWidth();
2237 qreal originalHeight = myText->contentHeight();
2238 QCOMPARE(myText->lineCount(), 2);
2240 // The original text unwrapped should exceed the width and height of the item.
2241 QVERIFY(originalWidth > myText->width());
2242 QVERIFY(originalHeight > myText->height());
2244 QFont font = myText->font();
2245 font.setPixelSize(64);
2247 myText->setFont(font);
2248 myText->setFontSizeMode(QQuickText::HorizontalFit);
2249 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2250 // Font size reduced to fit within the width of the item.
2251 QCOMPARE(myText->lineCount(), 2);
2252 qreal horizontalFitWidth = myText->contentWidth();
2253 qreal horizontalFitHeight = myText->contentHeight();
2254 QVERIFY(horizontalFitWidth <= myText->width() + 2); // rounding
2255 QVERIFY(horizontalFitHeight > myText->height());
2257 // Right eliding will remove the last line
2258 myText->setElideMode(QQuickText::ElideRight);
2259 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2260 QVERIFY(myText->truncated());
2261 QCOMPARE(myText->lineCount(), 1);
2262 QVERIFY(myText->contentWidth() <= myText->width() + 2);
2263 QVERIFY(myText->contentHeight() <= myText->height() + 2);
2265 // Left or middle eliding wont have any effect.
2266 myText->setElideMode(QQuickText::ElideLeft);
2267 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2268 QVERIFY(!myText->truncated());
2269 QCOMPARE(myText->contentWidth(), horizontalFitWidth);
2270 QCOMPARE(myText->contentHeight(), horizontalFitHeight);
2272 myText->setElideMode(QQuickText::ElideMiddle);
2273 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2274 QVERIFY(!myText->truncated());
2275 QCOMPARE(myText->contentWidth(), horizontalFitWidth);
2276 QCOMPARE(myText->contentHeight(), horizontalFitHeight);
2278 myText->setElideMode(QQuickText::ElideNone);
2279 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2281 myText->setFontSizeMode(QQuickText::VerticalFit);
2282 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2283 // Font size reduced to fit within the height of the item.
2284 qreal verticalFitWidth = myText->contentWidth();
2285 qreal verticalFitHeight = myText->contentHeight();
2286 QVERIFY(verticalFitWidth <= myText->width() + 2);
2287 QVERIFY(verticalFitHeight <= myText->height() + 2);
2289 // Elide will have no effect.
2290 myText->setElideMode(QQuickText::ElideRight);
2291 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2292 QVERIFY(!myText->truncated());
2293 QVERIFY(myText->contentWidth() <= myText->width() + 2);
2294 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2295 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2297 myText->setElideMode(QQuickText::ElideLeft);
2298 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2299 QVERIFY(!myText->truncated());
2300 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2301 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2303 myText->setElideMode(QQuickText::ElideMiddle);
2304 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2305 QVERIFY(!myText->truncated());
2306 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2307 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2309 myText->setElideMode(QQuickText::ElideNone);
2310 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2312 myText->setFontSizeMode(QQuickText::Fit);
2313 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2314 // Should be the same as VerticalFit with no wrapping.
2315 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2316 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2318 // Elide won't affect the size with Fit.
2319 myText->setElideMode(QQuickText::ElideRight);
2320 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2321 QVERIFY(!myText->truncated());
2322 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2323 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2325 myText->setElideMode(QQuickText::ElideLeft);
2326 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2327 QVERIFY(!myText->truncated());
2328 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2329 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2331 myText->setElideMode(QQuickText::ElideMiddle);
2332 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2333 QVERIFY(!myText->truncated());
2334 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2335 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2337 myText->setElideMode(QQuickText::ElideNone);
2338 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2340 myText->setFontSizeMode(QQuickText::FixedSize);
2341 myText->setWrapMode(QQuickText::Wrap);
2342 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2344 originalWidth = myText->contentWidth();
2345 originalHeight = myText->contentHeight();
2347 // The original text wrapped should exceed the height of the item.
2348 QVERIFY(originalWidth <= myText->width() + 2);
2349 QVERIFY(originalHeight > myText->height());
2351 myText->setFontSizeMode(QQuickText::HorizontalFit);
2352 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2353 // HorizontalFit should reduce the font size to minimize wrapping, which brings it back to the
2354 // same size as without text wrapping.
2355 QCOMPARE(myText->contentWidth(), horizontalFitWidth);
2356 QCOMPARE(myText->contentHeight(), horizontalFitHeight);
2358 // Text will be elided vertically with HorizontalFit
2359 myText->setElideMode(QQuickText::ElideRight);
2360 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2361 QVERIFY(myText->truncated());
2362 QVERIFY(myText->contentWidth() <= myText->width() + 2);
2363 QVERIFY(myText->contentHeight() <= myText->height() + 2);
2365 myText->setElideMode(QQuickText::ElideNone);
2366 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2368 myText->setFontSizeMode(QQuickText::VerticalFit);
2369 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2370 // VerticalFit should reduce the size to the wrapped text within the vertical height.
2371 verticalFitHeight = myText->contentHeight();
2372 verticalFitWidth = myText->contentWidth();
2373 QVERIFY(myText->contentWidth() <= myText->width() + 2);
2374 QVERIFY(verticalFitHeight <= myText->height() + 2);
2375 QVERIFY(verticalFitHeight < originalHeight);
2377 // Elide won't affect the height or width of a wrapped text with VerticalFit.
2378 myText->setElideMode(QQuickText::ElideRight);
2379 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2380 QVERIFY(!myText->truncated());
2381 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2382 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2384 myText->setElideMode(QQuickText::ElideNone);
2385 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2387 myText->setFontSizeMode(QQuickText::Fit);
2388 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2389 // Should be the same as VerticalFit with wrapping.
2390 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2391 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2393 // Elide won't affect the size with Fit.
2394 myText->setElideMode(QQuickText::ElideRight);
2395 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2396 QVERIFY(!myText->truncated());
2397 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2398 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2400 myText->setElideMode(QQuickText::ElideNone);
2401 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2403 myText->setFontSizeMode(QQuickText::FixedSize);
2404 myText->setMaximumLineCount(2);
2405 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2407 // The original text wrapped should exceed the height of the item.
2408 QVERIFY(originalWidth <= myText->width() + 2);
2409 QVERIFY(originalHeight > myText->height());
2411 myText->setFontSizeMode(QQuickText::HorizontalFit);
2412 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2413 // HorizontalFit should reduce the font size to minimize wrapping, which brings it back to the
2414 // same size as without text wrapping.
2415 QCOMPARE(myText->contentWidth(), horizontalFitWidth);
2416 QCOMPARE(myText->contentHeight(), horizontalFitHeight);
2418 // Elide won't affect the size with HorizontalFit.
2419 myText->setElideMode(QQuickText::ElideRight);
2420 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2421 QVERIFY(myText->truncated());
2422 QVERIFY(myText->contentWidth() <= myText->width() + 2);
2423 QVERIFY(myText->contentHeight() <= myText->height() + 2);
2425 myText->setElideMode(QQuickText::ElideNone);
2426 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2428 myText->setFontSizeMode(QQuickText::VerticalFit);
2429 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2430 // VerticalFit should reduce the size to the wrapped text within the vertical height.
2431 verticalFitHeight = myText->contentHeight();
2432 verticalFitWidth = myText->contentWidth();
2433 QVERIFY(myText->contentWidth() <= myText->width() + 2);
2434 QVERIFY(verticalFitHeight <= myText->height() + 2);
2435 QVERIFY(verticalFitHeight < originalHeight);
2437 // Elide won't affect the height or width of a wrapped text with VerticalFit.
2438 myText->setElideMode(QQuickText::ElideRight);
2439 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2440 QVERIFY(!myText->truncated());
2441 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2442 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2444 myText->setElideMode(QQuickText::ElideNone);
2445 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2447 myText->setFontSizeMode(QQuickText::Fit);
2448 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2449 // Should be the same as VerticalFit with wrapping.
2450 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2451 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2453 // Elide won't affect the size with Fit.
2454 myText->setElideMode(QQuickText::ElideRight);
2455 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2456 QVERIFY(!myText->truncated());
2457 QCOMPARE(myText->contentWidth(), verticalFitWidth);
2458 QCOMPARE(myText->contentHeight(), verticalFitHeight);
2460 myText->setElideMode(QQuickText::ElideNone);
2461 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2464 void tst_qquicktext::multilengthStrings_data()
2466 QTest::addColumn<QString>("source");
2467 QTest::newRow("No Wrap") << testFile("multilengthStrings.qml");
2468 QTest::newRow("Wrap") << testFile("multilengthStringsWrapped.qml");
2471 void tst_qquicktext::multilengthStrings()
2473 QFETCH(QString, source);
2475 QScopedPointer<QQuickView> canvas(createView(source));
2478 QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
2479 QVERIFY(myText != 0);
2481 const QString longText = "the quick brown fox jumped over the lazy dog";
2482 const QString mediumText = "the brown fox jumped over the dog";
2483 const QString shortText = "fox jumped dog";
2485 myText->setText(longText);
2486 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2487 const qreal longWidth = myText->contentWidth();
2488 const qreal longHeight = myText->contentHeight();
2490 myText->setText(mediumText);
2491 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2492 const qreal mediumWidth = myText->contentWidth();
2493 const qreal mediumHeight = myText->contentHeight();
2495 myText->setText(shortText);
2496 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2497 const qreal shortWidth = myText->contentWidth();
2498 const qreal shortHeight = myText->contentHeight();
2500 myText->setElideMode(QQuickText::ElideRight);
2501 myText->setText(longText + QLatin1Char('\x9c') + mediumText + QLatin1Char('\x9c') + shortText);
2503 myText->setSize(QSizeF(longWidth, longHeight));
2504 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2506 QCOMPARE(myText->contentWidth(), longWidth);
2507 QCOMPARE(myText->contentHeight(), longHeight);
2508 QCOMPARE(myText->truncated(), false);
2510 myText->setSize(QSizeF(mediumWidth, mediumHeight));
2511 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2513 QCOMPARE(myText->contentWidth(), mediumWidth);
2514 QCOMPARE(myText->contentHeight(), mediumHeight);
2515 QCOMPARE(myText->truncated(), true);
2517 myText->setSize(QSizeF(shortWidth, shortHeight));
2518 QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
2520 QCOMPARE(myText->contentWidth(), shortWidth);
2521 QCOMPARE(myText->contentHeight(), shortHeight);
2522 QCOMPARE(myText->truncated(), true);
2525 void tst_qquicktext::fontFormatSizes_data()
2527 QTest::addColumn<QString>("text");
2528 QTest::addColumn<QString>("textWithTag");
2529 QTest::addColumn<bool>("fontIsBigger");
2531 QTest::newRow("fs1") << "Hello world!" << "Hello <font size=\"1\">world</font>!" << false;
2532 QTest::newRow("fs2") << "Hello world!" << "Hello <font size=\"2\">world</font>!" << false;
2533 QTest::newRow("fs3") << "Hello world!" << "Hello <font size=\"3\">world</font>!" << false;
2534 QTest::newRow("fs4") << "Hello world!" << "Hello <font size=\"4\">world</font>!" << true;
2535 QTest::newRow("fs5") << "Hello world!" << "Hello <font size=\"5\">world</font>!" << true;
2536 QTest::newRow("fs6") << "Hello world!" << "Hello <font size=\"6\">world</font>!" << true;
2537 QTest::newRow("fs7") << "Hello world!" << "Hello <font size=\"7\">world</font>!" << true;
2538 QTest::newRow("h1") << "This is<br/>a font<br/> size test." << "This is <h1>a font</h1> size test." << true;
2539 QTest::newRow("h2") << "This is<br/>a font<br/> size test." << "This is <h2>a font</h2> size test." << true;
2540 QTest::newRow("h3") << "This is<br/>a font<br/> size test." << "This is <h3>a font</h3> size test." << true;
2541 QTest::newRow("h4") << "This is<br/>a font<br/> size test." << "This is <h4>a font</h4> size test." << true;
2542 QTest::newRow("h5") << "This is<br/>a font<br/> size test." << "This is <h5>a font</h5> size test." << false;
2543 QTest::newRow("h6") << "This is<br/>a font<br/> size test." << "This is <h6>a font</h6> size test." << false;
2546 void tst_qquicktext::fontFormatSizes()
2548 QFETCH(QString, text);
2549 QFETCH(QString, textWithTag);
2550 QFETCH(bool, fontIsBigger);
2552 QQuickView *view = new QQuickView;
2554 view->setSource(testFileUrl("pointFontSizes.qml"));
2557 QQuickText *qtext = view->rootObject()->findChild<QQuickText*>("text");
2558 QQuickText *qtextWithTag = view->rootObject()->findChild<QQuickText*>("textWithTag");
2559 QVERIFY(qtext != 0);
2560 QVERIFY(qtextWithTag != 0);
2562 qtext->setText(text);
2563 qtextWithTag->setText(textWithTag);
2565 for (int size = 6; size < 100; size += 4) {
2566 view->rootObject()->setProperty("pointSize", size);
2568 QVERIFY(qtext->height() <= qtextWithTag->height());
2570 QVERIFY(qtext->height() >= qtextWithTag->height());
2575 view->setSource(testFileUrl("pixelFontSizes.qml"));
2576 QQuickText *qtext = view->rootObject()->findChild<QQuickText*>("text");
2577 QQuickText *qtextWithTag = view->rootObject()->findChild<QQuickText*>("textWithTag");
2578 QVERIFY(qtext != 0);
2579 QVERIFY(qtextWithTag != 0);
2581 qtext->setText(text);
2582 qtextWithTag->setText(textWithTag);
2584 for (int size = 6; size < 100; size += 4) {
2585 view->rootObject()->setProperty("pixelSize", size);
2587 QVERIFY(qtext->height() <= qtextWithTag->height());
2589 QVERIFY(qtext->height() >= qtextWithTag->height());
2595 QTEST_MAIN(tst_qquicktext)
2597 #include "tst_qquicktext.moc"