aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/quick/qquicktext/tst_qquicktext.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/quick/qquicktext/tst_qquicktext.cpp')
-rw-r--r--tests/auto/quick/qquicktext/tst_qquicktext.cpp2484
1 files changed, 2484 insertions, 0 deletions
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
new file mode 100644
index 0000000000..54b5a04466
--- /dev/null
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -0,0 +1,2484 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** GNU Lesser General Public License Usage
+** This file may be used under the terms of the GNU Lesser General Public
+** License version 2.1 as published by the Free Software Foundation and
+** appearing in the file LICENSE.LGPL included in the packaging of this
+** file. Please review the following information to ensure the GNU Lesser
+** General Public License version 2.1 requirements will be met:
+** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights. These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU General
+** Public License version 3.0 as published by the Free Software Foundation
+** and appearing in the file LICENSE.GPL included in the packaging of this
+** file. Please review the following information to ensure the GNU General
+** Public License version 3.0 requirements will be met:
+** http://www.gnu.org/copyleft/gpl.html.
+**
+** Other Usage
+** Alternatively, this file may be used in accordance with the terms and
+** conditions contained in a signed written agreement between you and Nokia.
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+#include <qtest.h>
+#include <QtTest/QSignalSpy>
+#include <QTextDocument>
+#include <QtQml/qqmlengine.h>
+#include <QtQml/qqmlcomponent.h>
+#include <QtQuick/private/qquicktext_p.h>
+#include <private/qquicktext_p_p.h>
+#include <private/qqmlvaluetype_p.h>
+#include <QFontMetrics>
+#include <QGraphicsSceneMouseEvent>
+#include <qmath.h>
+#include <QtQuick/QQuickView>
+#include <private/qapplication_p.h>
+#include <limits.h>
+#include <QtGui/QMouseEvent>
+#include "../../shared/util.h"
+#include "testhttpserver.h"
+
+DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD)
+
+Q_DECLARE_METATYPE(QQuickText::TextFormat)
+
+class tst_qquicktext : public QQmlDataTest
+{
+ Q_OBJECT
+public:
+ tst_qquicktext();
+
+private slots:
+ void text();
+ void width();
+ void wrap();
+ void elide();
+ void multilineElide_data();
+ void multilineElide();
+ void textFormat();
+
+ void alignments_data();
+ void alignments();
+
+ void baseUrl();
+ void embeddedImages_data();
+ void embeddedImages();
+
+ void lineCount();
+ void lineHeight();
+
+ // ### these tests may be trivial
+ void horizontalAlignment();
+ void horizontalAlignment_RightToLeft();
+ void verticalAlignment();
+ void font();
+ void style();
+ void color();
+ void smooth();
+
+ // QQmlFontValueType
+ void weight();
+ void underline();
+ void overline();
+ void strikeout();
+ void capitalization();
+ void letterSpacing();
+ void wordSpacing();
+
+ void clickLink();
+
+ void implicitSize_data();
+ void implicitSize();
+ void contentSize();
+
+ void lineLaidOut();
+
+ void imgTagsBaseUrl_data();
+ void imgTagsBaseUrl();
+ void imgTagsAlign_data();
+ void imgTagsAlign();
+ void imgTagsMultipleImages();
+ void imgTagsElide();
+ void imgTagsUpdates();
+ void imgTagsError();
+ void fontSizeMode_data();
+ void fontSizeMode();
+ void fontSizeModeMultiline_data();
+ void fontSizeModeMultiline();
+ void multilengthStrings_data();
+ void multilengthStrings();
+ void fontFormatSizes_data();
+ void fontFormatSizes();
+
+private:
+ QStringList standard;
+ QStringList richText;
+
+ QStringList horizontalAlignmentmentStrings;
+ QStringList verticalAlignmentmentStrings;
+
+ QList<Qt::Alignment> verticalAlignmentments;
+ QList<Qt::Alignment> horizontalAlignmentments;
+
+ QStringList styleStrings;
+ QList<QQuickText::TextStyle> styles;
+
+ QStringList colorStrings;
+
+ QQmlEngine engine;
+
+ QQuickView *createView(const QString &filename);
+};
+
+tst_qquicktext::tst_qquicktext()
+{
+ standard << "the quick brown fox jumped over the lazy dog"
+ << "the quick brown fox\n jumped over the lazy dog";
+
+ richText << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a> jumped over the <b>lazy</b> dog</i>"
+ << "<i>the <b>quick</b> brown <a href=\\\"http://www.google.com\\\">fox</a><br>jumped over the <b>lazy</b> dog</i>";
+
+ horizontalAlignmentmentStrings << "AlignLeft"
+ << "AlignRight"
+ << "AlignHCenter";
+
+ verticalAlignmentmentStrings << "AlignTop"
+ << "AlignBottom"
+ << "AlignVCenter";
+
+ horizontalAlignmentments << Qt::AlignLeft
+ << Qt::AlignRight
+ << Qt::AlignHCenter;
+
+ verticalAlignmentments << Qt::AlignTop
+ << Qt::AlignBottom
+ << Qt::AlignVCenter;
+
+ styleStrings << "Normal"
+ << "Outline"
+ << "Raised"
+ << "Sunken";
+
+ styles << QQuickText::Normal
+ << QQuickText::Outline
+ << QQuickText::Raised
+ << QQuickText::Sunken;
+
+ colorStrings << "aliceblue"
+ << "antiquewhite"
+ << "aqua"
+ << "darkkhaki"
+ << "darkolivegreen"
+ << "dimgray"
+ << "palevioletred"
+ << "lightsteelblue"
+ << "#000000"
+ << "#AAAAAA"
+ << "#FFFFFF"
+ << "#2AC05F";
+ //
+ // need a different test to do alpha channel test
+ // << "#AA0011DD"
+ // << "#00F16B11";
+ //
+}
+
+QQuickView *tst_qquicktext::createView(const QString &filename)
+{
+ QQuickView *canvas = new QQuickView(0);
+
+ canvas->setSource(QUrl::fromLocalFile(filename));
+ return canvas;
+}
+
+void tst_qquicktext::text()
+{
+ {
+ QQmlComponent textComponent(&engine);
+ textComponent.setData("import QtQuick 2.0\nText { text: \"\" }", QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE(textObject->text(), QString(""));
+ QVERIFY(textObject->width() == 0);
+
+ delete textObject;
+ }
+
+ for (int i = 0; i < standard.size(); i++)
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE(textObject->text(), standard.at(i));
+ QVERIFY(textObject->width() > 0);
+
+ delete textObject;
+ }
+
+ for (int i = 0; i < richText.size(); i++)
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QString expected = richText.at(i);
+ QCOMPARE(textObject->text(), expected.replace("\\\"", "\""));
+ QVERIFY(textObject->width() > 0);
+
+ delete textObject;
+ }
+}
+
+void tst_qquicktext::width()
+{
+ // uses Font metrics to find the width for standard and document to find the width for rich
+ {
+ QQmlComponent textComponent(&engine);
+ textComponent.setData("import QtQuick 2.0\nText { text: \"\" }", QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE(textObject->width(), 0.);
+
+ delete textObject;
+ }
+
+ bool requiresUnhintedMetrics = !qmlDisableDistanceField();
+
+ for (int i = 0; i < standard.size(); i++)
+ {
+ QVERIFY(!Qt::mightBeRichText(standard.at(i))); // self-test
+
+ QFont f;
+ qreal metricWidth = 0.0;
+
+ if (requiresUnhintedMetrics) {
+ QString s = standard.at(i);
+ s.replace(QLatin1Char('\n'), QChar::LineSeparator);
+
+ QTextLayout layout(s);
+ layout.setFlags(Qt::TextExpandTabs | Qt::TextShowMnemonic);
+ {
+ QTextOption option;
+ option.setUseDesignMetrics(true);
+ layout.setTextOption(option);
+ }
+
+ layout.beginLayout();
+ forever {
+ QTextLine line = layout.createLine();
+ if (!line.isValid())
+ break;
+ }
+
+ layout.endLayout();
+
+ metricWidth = layout.boundingRect().width();
+ } else {
+ QFontMetricsF fm(f);
+ metricWidth = fm.size(Qt::TextExpandTabs && Qt::TextShowMnemonic, standard.at(i)).width();
+ }
+
+ QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QVERIFY(textObject->boundingRect().width() > 0);
+ QCOMPARE(textObject->width(), qreal(metricWidth));
+ QVERIFY(textObject->textFormat() == QQuickText::AutoText); // setting text doesn't change format
+
+ delete textObject;
+ }
+
+ for (int i = 0; i < richText.size(); i++)
+ {
+ QVERIFY(Qt::mightBeRichText(richText.at(i))); // self-test
+
+ QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\"; textFormat: Text.RichText }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+ QVERIFY(textObject != 0);
+
+ QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject);
+ QVERIFY(textPrivate != 0);
+ QVERIFY(textPrivate->extra.isAllocated());
+
+ QTextDocument *doc = textPrivate->extra->doc;
+ QVERIFY(doc != 0);
+
+ QCOMPARE(int(textObject->width()), int(doc->idealWidth()));
+ QVERIFY(textObject->textFormat() == QQuickText::RichText);
+
+ delete textObject;
+ }
+}
+
+void tst_qquicktext::wrap()
+{
+ int textHeight = 0;
+ // for specified width and wrap set true
+ {
+ QQmlComponent textComponent(&engine);
+ textComponent.setData("import QtQuick 2.0\nText { text: \"Hello\"; wrapMode: Text.WordWrap; width: 300 }", QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+ textHeight = textObject->height();
+
+ QVERIFY(textObject != 0);
+ QVERIFY(textObject->wrapMode() == QQuickText::WordWrap);
+ QCOMPARE(textObject->width(), 300.);
+
+ delete textObject;
+ }
+
+ for (int i = 0; i < standard.size(); i++)
+ {
+ QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; text: \"" + standard.at(i) + "\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE(textObject->width(), 30.);
+ QVERIFY(textObject->height() > textHeight);
+
+ int oldHeight = textObject->height();
+ textObject->setWidth(100);
+ QVERIFY(textObject->height() < oldHeight);
+
+ delete textObject;
+ }
+
+ for (int i = 0; i < richText.size(); i++)
+ {
+ QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; text: \"" + richText.at(i) + "\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE(textObject->width(), 30.);
+ QVERIFY(textObject->height() > textHeight);
+
+ qreal oldHeight = textObject->height();
+ textObject->setWidth(100);
+ QVERIFY(textObject->height() < oldHeight);
+
+ delete textObject;
+ }
+
+ // richtext again with a fixed height
+ for (int i = 0; i < richText.size(); i++)
+ {
+ QString componentStr = "import QtQuick 2.0\nText { wrapMode: Text.WordWrap; width: 30; height: 50; text: \"" + richText.at(i) + "\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE(textObject->width(), 30.);
+ QVERIFY(textObject->implicitHeight() > textHeight);
+
+ qreal oldHeight = textObject->implicitHeight();
+ textObject->setWidth(100);
+ QVERIFY(textObject->implicitHeight() < oldHeight);
+
+ delete textObject;
+ }
+}
+
+void tst_qquicktext::elide()
+{
+ for (QQuickText::TextElideMode m = QQuickText::ElideLeft; m<=QQuickText::ElideNone; m=QQuickText::TextElideMode(int(m)+1)) {
+ const char* elidename[]={"ElideLeft", "ElideRight", "ElideMiddle", "ElideNone"};
+ QString elide = "elide: Text." + QString(elidename[int(m)]) + ";";
+
+ // XXX Poor coverage.
+
+ {
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(("import QtQuick 2.0\nText { text: \"\"; "+elide+" width: 100 }").toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QCOMPARE(textObject->elideMode(), m);
+ QCOMPARE(textObject->width(), 100.);
+
+ delete textObject;
+ }
+
+ for (int i = 0; i < standard.size(); i++)
+ {
+ QString componentStr = "import QtQuick 2.0\nText { "+elide+" width: 100; text: \"" + standard.at(i) + "\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QCOMPARE(textObject->elideMode(), m);
+ QCOMPARE(textObject->width(), 100.);
+
+ if (m != QQuickText::ElideNone && !standard.at(i).contains('\n'))
+ QVERIFY(textObject->contentWidth() <= textObject->width());
+
+ delete textObject;
+ }
+
+ for (int i = 0; i < richText.size(); i++)
+ {
+ QString componentStr = "import QtQuick 2.0\nText { "+elide+" width: 100; text: \"" + richText.at(i) + "\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QCOMPARE(textObject->elideMode(), m);
+ QCOMPARE(textObject->width(), 100.);
+
+ if (m != QQuickText::ElideNone && standard.at(i).contains("<br>"))
+ QVERIFY(textObject->contentWidth() <= textObject->width());
+
+ delete textObject;
+ }
+ }
+}
+
+void tst_qquicktext::multilineElide_data()
+{
+ QTest::addColumn<QQuickText::TextFormat>("format");
+ QTest::newRow("plain") << QQuickText::PlainText;
+ QTest::newRow("styled") << QQuickText::StyledText;
+}
+
+void tst_qquicktext::multilineElide()
+{
+ QFETCH(QQuickText::TextFormat, format);
+ QQuickView *canvas = createView(testFile("multilineelide.qml"));
+
+ QQuickText *myText = qobject_cast<QQuickText*>(canvas->rootObject());
+ QVERIFY(myText != 0);
+ myText->setTextFormat(format);
+
+ QCOMPARE(myText->lineCount(), 3);
+ QCOMPARE(myText->truncated(), true);
+
+ qreal lineHeight = myText->contentHeight() / 3.;
+
+ // Set a valid height greater than the truncated content height and ensure the line count is
+ // unchanged.
+ myText->setHeight(200);
+ QCOMPARE(myText->lineCount(), 3);
+ QCOMPARE(myText->truncated(), true);
+
+ // reduce size and ensure fewer lines are drawn
+ myText->setHeight(lineHeight * 2);
+ QCOMPARE(myText->lineCount(), 2);
+
+ myText->setHeight(lineHeight);
+ QCOMPARE(myText->lineCount(), 1);
+
+ myText->setHeight(5);
+ QCOMPARE(myText->lineCount(), 1);
+
+ myText->setHeight(lineHeight * 3);
+ QCOMPARE(myText->lineCount(), 3);
+
+ // remove max count and show all lines.
+ myText->setHeight(1000);
+ myText->resetMaximumLineCount();
+
+ QCOMPARE(myText->truncated(), false);
+
+ // reduce size again
+ myText->setHeight(lineHeight * 2);
+ QCOMPARE(myText->lineCount(), 2);
+ QCOMPARE(myText->truncated(), true);
+
+ // change line height
+ myText->setLineHeight(1.1);
+ QCOMPARE(myText->lineCount(), 1);
+
+ delete canvas;
+}
+
+void tst_qquicktext::textFormat()
+{
+ {
+ QQmlComponent textComponent(&engine);
+ textComponent.setData("import QtQuick 2.0\nText { text: \"Hello\"; textFormat: Text.RichText }", QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QVERIFY(textObject->textFormat() == QQuickText::RichText);
+
+ QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject);
+ QVERIFY(textPrivate != 0);
+ QVERIFY(textPrivate->richText == true);
+
+ delete textObject;
+ }
+ {
+ QQmlComponent textComponent(&engine);
+ textComponent.setData("import QtQuick 2.0\nText { text: \"<b>Hello</b>\" }", QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QVERIFY(textObject->textFormat() == QQuickText::AutoText);
+
+ QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject);
+ QVERIFY(textPrivate != 0);
+ QVERIFY(textPrivate->styledText == true);
+
+ delete textObject;
+ }
+ {
+ QQmlComponent textComponent(&engine);
+ textComponent.setData("import QtQuick 2.0\nText { text: \"<b>Hello</b>\"; textFormat: Text.PlainText }", QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QVERIFY(textObject->textFormat() == QQuickText::PlainText);
+
+ delete textObject;
+ }
+}
+
+
+void tst_qquicktext::alignments_data()
+{
+ QTest::addColumn<int>("hAlign");
+ QTest::addColumn<int>("vAlign");
+ QTest::addColumn<QString>("expectfile");
+
+ QTest::newRow("LT") << int(Qt::AlignLeft) << int(Qt::AlignTop) << testFile("alignments_lt.png");
+ QTest::newRow("RT") << int(Qt::AlignRight) << int(Qt::AlignTop) << testFile("alignments_rt.png");
+ QTest::newRow("CT") << int(Qt::AlignHCenter) << int(Qt::AlignTop) << testFile("alignments_ct.png");
+
+ QTest::newRow("LB") << int(Qt::AlignLeft) << int(Qt::AlignBottom) << testFile("alignments_lb.png");
+ QTest::newRow("RB") << int(Qt::AlignRight) << int(Qt::AlignBottom) << testFile("alignments_rb.png");
+ QTest::newRow("CB") << int(Qt::AlignHCenter) << int(Qt::AlignBottom) << testFile("alignments_cb.png");
+
+ QTest::newRow("LC") << int(Qt::AlignLeft) << int(Qt::AlignVCenter) << testFile("alignments_lc.png");
+ QTest::newRow("RC") << int(Qt::AlignRight) << int(Qt::AlignVCenter) << testFile("alignments_rc.png");
+ QTest::newRow("CC") << int(Qt::AlignHCenter) << int(Qt::AlignVCenter) << testFile("alignments_cc.png");
+}
+
+
+void tst_qquicktext::alignments()
+{
+ QSKIP("Text alignment pixmap comparison tests will not work with scenegraph");
+#if (0)// No widgets in scenegraph
+ QFETCH(int, hAlign);
+ QFETCH(int, vAlign);
+ QFETCH(QString, expectfile);
+
+ QQuickView *canvas = createView(testFile("alignments.qml"));
+ canvas->show();
+ canvas->requestActivateWindow();
+ QTest::qWait(50);
+ QTRY_COMPARE(QGuiApplication::activeWindow(), static_cast<QWidget *>(canvas));
+
+ QObject *ob = canvas->rootObject();
+ QVERIFY(ob != 0);
+ ob->setProperty("horizontalAlignment",hAlign);
+ ob->setProperty("verticalAlignment",vAlign);
+ QTRY_COMPARE(ob->property("running").toBool(),false);
+ QImage actual(canvas->width(), canvas->height(), QImage::Format_RGB32);
+ actual.fill(qRgb(255,255,255));
+ QPainter p(&actual);
+ canvas->render(&p);
+
+ QImage expect(expectfile);
+ if (QGuiApplicationPrivate::graphics_system_name == "raster" || QGuiApplicationPrivate::graphics_system_name == "") {
+ QCOMPARE(actual,expect);
+ }
+ delete canvas;
+#endif
+}
+
+//the alignment tests may be trivial o.oa
+void tst_qquicktext::horizontalAlignment()
+{
+ //test one align each, and then test if two align fails.
+
+ for (int i = 0; i < standard.size(); i++)
+ {
+ for (int j=0; j < horizontalAlignmentmentStrings.size(); j++)
+ {
+ QString componentStr = "import QtQuick 2.0\nText { horizontalAlignment: \"" + horizontalAlignmentmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QCOMPARE((int)textObject->hAlign(), (int)horizontalAlignmentments.at(j));
+
+ delete textObject;
+ }
+ }
+
+ for (int i = 0; i < richText.size(); i++)
+ {
+ for (int j=0; j < horizontalAlignmentmentStrings.size(); j++)
+ {
+ QString componentStr = "import QtQuick 2.0\nText { horizontalAlignment: \"" + horizontalAlignmentmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QCOMPARE((int)textObject->hAlign(), (int)horizontalAlignmentments.at(j));
+
+ delete textObject;
+ }
+ }
+
+}
+
+void tst_qquicktext::horizontalAlignment_RightToLeft()
+{
+ QQuickView *canvas = createView(testFile("horizontalAlignment_RightToLeft.qml"));
+ QQuickText *text = canvas->rootObject()->findChild<QQuickText*>("text");
+ QVERIFY(text != 0);
+ canvas->show();
+
+ QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(text);
+ QVERIFY(textPrivate != 0);
+
+ QTRY_VERIFY(textPrivate->layout.lineCount());
+
+ // implicit alignment should follow the reading direction of RTL text
+ QCOMPARE(text->hAlign(), QQuickText::AlignRight);
+ QCOMPARE(text->effectiveHAlign(), text->hAlign());
+ QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
+
+ // explicitly left aligned text
+ text->setHAlign(QQuickText::AlignLeft);
+ QCOMPARE(text->hAlign(), QQuickText::AlignLeft);
+ QCOMPARE(text->effectiveHAlign(), text->hAlign());
+ QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
+
+ // explicitly right aligned text
+ text->setHAlign(QQuickText::AlignRight);
+ QCOMPARE(text->hAlign(), QQuickText::AlignRight);
+ QCOMPARE(text->effectiveHAlign(), text->hAlign());
+ QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
+
+ // change to rich text
+ QString textString = text->text();
+ text->setText(QString("<i>") + textString + QString("</i>"));
+ text->setTextFormat(QQuickText::RichText);
+ text->resetHAlign();
+
+ // implicitly aligned rich text should follow the reading direction of text
+ QCOMPARE(text->hAlign(), QQuickText::AlignRight);
+ QCOMPARE(text->effectiveHAlign(), text->hAlign());
+ QVERIFY(textPrivate->extra.isAllocated());
+ QVERIFY(textPrivate->extra->doc->defaultTextOption().alignment() & Qt::AlignLeft);
+
+ // explicitly left aligned rich text
+ text->setHAlign(QQuickText::AlignLeft);
+ QCOMPARE(text->hAlign(), QQuickText::AlignLeft);
+ QCOMPARE(text->effectiveHAlign(), text->hAlign());
+ QVERIFY(textPrivate->extra->doc->defaultTextOption().alignment() & Qt::AlignRight);
+
+ // explicitly right aligned rich text
+ text->setHAlign(QQuickText::AlignRight);
+ QCOMPARE(text->hAlign(), QQuickText::AlignRight);
+ QCOMPARE(text->effectiveHAlign(), text->hAlign());
+ QVERIFY(textPrivate->extra->doc->defaultTextOption().alignment() & Qt::AlignLeft);
+
+ text->setText(textString);
+ text->setTextFormat(QQuickText::PlainText);
+
+ // explicitly center aligned
+ text->setHAlign(QQuickText::AlignHCenter);
+ QCOMPARE(text->hAlign(), QQuickText::AlignHCenter);
+ QCOMPARE(text->effectiveHAlign(), text->hAlign());
+ QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
+ QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().right() > canvas->width()/2);
+
+ // reseted alignment should go back to following the text reading direction
+ text->resetHAlign();
+ QCOMPARE(text->hAlign(), QQuickText::AlignRight);
+ QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
+
+ // mirror the text item
+ QQuickItemPrivate::get(text)->setLayoutMirror(true);
+
+ // mirrored implicit alignment should continue to follow the reading direction of the text
+ QCOMPARE(text->hAlign(), QQuickText::AlignRight);
+ QCOMPARE(text->effectiveHAlign(), QQuickText::AlignRight);
+ QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
+
+ // mirrored explicitly right aligned behaves as left aligned
+ text->setHAlign(QQuickText::AlignRight);
+ QCOMPARE(text->hAlign(), QQuickText::AlignRight);
+ QCOMPARE(text->effectiveHAlign(), QQuickText::AlignLeft);
+ QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
+
+ // mirrored explicitly left aligned behaves as right aligned
+ text->setHAlign(QQuickText::AlignLeft);
+ QCOMPARE(text->hAlign(), QQuickText::AlignLeft);
+ QCOMPARE(text->effectiveHAlign(), QQuickText::AlignRight);
+ QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
+
+ // disable mirroring
+ QQuickItemPrivate::get(text)->setLayoutMirror(false);
+ text->resetHAlign();
+
+ // English text should be implicitly left aligned
+ text->setText("Hello world!");
+ QCOMPARE(text->hAlign(), QQuickText::AlignLeft);
+ QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
+
+ // empty text with implicit alignment follows the system locale-based
+ // keyboard input direction from QInputMethod::inputDirection()
+ text->setText("");
+ QCOMPARE(text->hAlign(), qApp->inputMethod()->inputDirection() == Qt::LeftToRight ?
+ QQuickText::AlignLeft : QQuickText::AlignRight);
+ text->setHAlign(QQuickText::AlignRight);
+ QCOMPARE(text->hAlign(), QQuickText::AlignRight);
+
+ delete canvas;
+
+ // alignment of Text with no text set to it
+ QString componentStr = "import QtQuick 2.0\nText {}";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+ QCOMPARE(textObject->hAlign(), qApp->inputMethod()->inputDirection() == Qt::LeftToRight ?
+ QQuickText::AlignLeft : QQuickText::AlignRight);
+ delete textObject;
+}
+
+void tst_qquicktext::verticalAlignment()
+{
+ //test one align each, and then test if two align fails.
+
+ for (int i = 0; i < standard.size(); i++)
+ {
+ for (int j=0; j < verticalAlignmentmentStrings.size(); j++)
+ {
+ QString componentStr = "import QtQuick 2.0\nText { verticalAlignment: \"" + verticalAlignmentmentStrings.at(j) + "\"; text: \"" + standard.at(i) + "\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE((int)textObject->vAlign(), (int)verticalAlignmentments.at(j));
+
+ delete textObject;
+ }
+ }
+
+ for (int i = 0; i < richText.size(); i++)
+ {
+ for (int j=0; j < verticalAlignmentmentStrings.size(); j++)
+ {
+ QString componentStr = "import QtQuick 2.0\nText { verticalAlignment: \"" + verticalAlignmentmentStrings.at(j) + "\"; text: \"" + richText.at(i) + "\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE((int)textObject->vAlign(), (int)verticalAlignmentments.at(j));
+
+ delete textObject;
+ }
+ }
+
+}
+
+void tst_qquicktext::font()
+{
+ //test size, then bold, then italic, then family
+ {
+ QString componentStr = "import QtQuick 2.0\nText { font.pointSize: 40; text: \"Hello World\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QCOMPARE(textObject->font().pointSize(), 40);
+ QCOMPARE(textObject->font().bold(), false);
+ QCOMPARE(textObject->font().italic(), false);
+
+ delete textObject;
+ }
+
+ {
+ QString componentStr = "import QtQuick 2.0\nText { font.pixelSize: 40; text: \"Hello World\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QCOMPARE(textObject->font().pixelSize(), 40);
+ QCOMPARE(textObject->font().bold(), false);
+ QCOMPARE(textObject->font().italic(), false);
+
+ delete textObject;
+ }
+
+ {
+ QString componentStr = "import QtQuick 2.0\nText { font.bold: true; text: \"Hello World\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QCOMPARE(textObject->font().bold(), true);
+ QCOMPARE(textObject->font().italic(), false);
+
+ delete textObject;
+ }
+
+ {
+ QString componentStr = "import QtQuick 2.0\nText { font.italic: true; text: \"Hello World\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QCOMPARE(textObject->font().italic(), true);
+ QCOMPARE(textObject->font().bold(), false);
+
+ delete textObject;
+ }
+
+ {
+ QString componentStr = "import QtQuick 2.0\nText { font.family: \"Helvetica\"; text: \"Hello World\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QCOMPARE(textObject->font().family(), QString("Helvetica"));
+ QCOMPARE(textObject->font().bold(), false);
+ QCOMPARE(textObject->font().italic(), false);
+
+ delete textObject;
+ }
+
+ {
+ QString componentStr = "import QtQuick 2.0\nText { font.family: \"\"; text: \"Hello World\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QCOMPARE(textObject->font().family(), QString(""));
+
+ delete textObject;
+ }
+}
+
+void tst_qquicktext::style()
+{
+ //test style
+ for (int i = 0; i < styles.size(); i++)
+ {
+ QString componentStr = "import QtQuick 2.0\nText { style: \"" + styleStrings.at(i) + "\"; styleColor: \"white\"; text: \"Hello World\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QCOMPARE((int)textObject->style(), (int)styles.at(i));
+ QCOMPARE(textObject->styleColor(), QColor("white"));
+
+ delete textObject;
+ }
+ QString componentStr = "import QtQuick 2.0\nText { text: \"Hello World\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QRectF brPre = textObject->boundingRect();
+ textObject->setStyle(QQuickText::Outline);
+ QRectF brPost = textObject->boundingRect();
+
+ QVERIFY(brPre.width() < brPost.width());
+ QVERIFY(brPre.height() < brPost.height());
+
+ delete textObject;
+}
+
+void tst_qquicktext::color()
+{
+ //test style
+ for (int i = 0; i < colorStrings.size(); i++)
+ {
+ QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QCOMPARE(textObject->color(), QColor(colorStrings.at(i)));
+ QCOMPARE(textObject->styleColor(), QColor("black"));
+ QCOMPARE(textObject->linkColor(), QColor("blue"));
+
+ delete textObject;
+ }
+
+ for (int i = 0; i < colorStrings.size(); i++)
+ {
+ QString componentStr = "import QtQuick 2.0\nText { styleColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QCOMPARE(textObject->styleColor(), QColor(colorStrings.at(i)));
+ // default color to black?
+ QCOMPARE(textObject->color(), QColor("black"));
+ QCOMPARE(textObject->linkColor(), QColor("blue"));
+
+ delete textObject;
+ }
+
+ for (int i = 0; i < colorStrings.size(); i++)
+ {
+ QString componentStr = "import QtQuick 2.0\nText { linkColor: \"" + colorStrings.at(i) + "\"; text: \"Hello World\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QCOMPARE(textObject->styleColor(), QColor("black"));
+ QCOMPARE(textObject->color(), QColor("black"));
+ QCOMPARE(textObject->linkColor(), QColor(colorStrings.at(i)));
+
+ delete textObject;
+ }
+
+ for (int i = 0; i < colorStrings.size(); i++)
+ {
+ for (int j = 0; j < colorStrings.size(); j++)
+ {
+ QString componentStr = "import QtQuick 2.0\nText { "
+ "color: \"" + colorStrings.at(i) + "\"; "
+ "styleColor: \"" + colorStrings.at(j) + "\"; "
+ "linkColor: \"" + colorStrings.at(j) + "\"; "
+ "text: \"Hello World\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QCOMPARE(textObject->color(), QColor(colorStrings.at(i)));
+ QCOMPARE(textObject->styleColor(), QColor(colorStrings.at(j)));
+ QCOMPARE(textObject->linkColor(), QColor(colorStrings.at(j)));
+
+ delete textObject;
+ }
+ }
+ {
+ QString colorStr = "#AA001234";
+ QColor testColor("#001234");
+ testColor.setAlpha(170);
+
+ QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStr + "\"; text: \"Hello World\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QCOMPARE(textObject->color(), testColor);
+
+ delete textObject;
+ } {
+ QString colorStr = "#001234";
+ QColor testColor(colorStr);
+
+ QString componentStr = "import QtQuick 2.0\nText { color: \"" + colorStr + "\"; text: \"Hello World\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QScopedPointer<QObject> object(textComponent.create());
+ QQuickText *textObject = qobject_cast<QQuickText*>(object.data());
+
+ QSignalSpy spy(textObject, SIGNAL(colorChanged()));
+
+ QCOMPARE(textObject->color(), testColor);
+ textObject->setColor(testColor);
+ QCOMPARE(textObject->color(), testColor);
+ QCOMPARE(spy.count(), 0);
+
+ testColor = QColor("black");
+ textObject->setColor(testColor);
+ QCOMPARE(textObject->color(), testColor);
+ QCOMPARE(spy.count(), 1);
+ } {
+ QString colorStr = "#001234";
+ QColor testColor(colorStr);
+
+ QString componentStr = "import QtQuick 2.0\nText { styleColor: \"" + colorStr + "\"; text: \"Hello World\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QScopedPointer<QObject> object(textComponent.create());
+ QQuickText *textObject = qobject_cast<QQuickText*>(object.data());
+
+ QSignalSpy spy(textObject, SIGNAL(styleColorChanged()));
+
+ QCOMPARE(textObject->styleColor(), testColor);
+ textObject->setStyleColor(testColor);
+ QCOMPARE(textObject->styleColor(), testColor);
+ QCOMPARE(spy.count(), 0);
+
+ testColor = QColor("black");
+ textObject->setStyleColor(testColor);
+ QCOMPARE(textObject->styleColor(), testColor);
+ QCOMPARE(spy.count(), 1);
+ } {
+ QString colorStr = "#001234";
+ QColor testColor(colorStr);
+
+ QString componentStr = "import QtQuick 2.0\nText { linkColor: \"" + colorStr + "\"; text: \"Hello World\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QScopedPointer<QObject> object(textComponent.create());
+ QQuickText *textObject = qobject_cast<QQuickText*>(object.data());
+
+ QSignalSpy spy(textObject, SIGNAL(linkColorChanged()));
+
+ QCOMPARE(textObject->linkColor(), testColor);
+ textObject->setLinkColor(testColor);
+ QCOMPARE(textObject->linkColor(), testColor);
+ QCOMPARE(spy.count(), 0);
+
+ testColor = QColor("black");
+ textObject->setLinkColor(testColor);
+ QCOMPARE(textObject->linkColor(), testColor);
+ QCOMPARE(spy.count(), 1);
+ }
+}
+
+void tst_qquicktext::smooth()
+{
+ for (int i = 0; i < standard.size(); i++)
+ {
+ {
+ QString componentStr = "import QtQuick 2.0\nText { smooth: true; text: \"" + standard.at(i) + "\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+ QCOMPARE(textObject->smooth(), true);
+
+ delete textObject;
+ }
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"" + standard.at(i) + "\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+ QCOMPARE(textObject->smooth(), false);
+
+ delete textObject;
+ }
+ }
+ for (int i = 0; i < richText.size(); i++)
+ {
+ {
+ QString componentStr = "import QtQuick 2.0\nText { smooth: true; text: \"" + richText.at(i) + "\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+ QCOMPARE(textObject->smooth(), true);
+
+ delete textObject;
+ }
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"" + richText.at(i) + "\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+ QCOMPARE(textObject->smooth(), false);
+
+ delete textObject;
+ }
+ }
+}
+
+void tst_qquicktext::weight()
+{
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE((int)textObject->font().weight(), (int)QQmlFontValueType::Normal);
+
+ delete textObject;
+ }
+ {
+ QString componentStr = "import QtQuick 2.0\nText { font.weight: \"Bold\"; text: \"Hello world!\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE((int)textObject->font().weight(), (int)QQmlFontValueType::Bold);
+
+ delete textObject;
+ }
+}
+
+void tst_qquicktext::underline()
+{
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE(textObject->font().underline(), false);
+
+ delete textObject;
+ }
+ {
+ QString componentStr = "import QtQuick 2.0\nText { font.underline: true; text: \"Hello world!\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE(textObject->font().underline(), true);
+
+ delete textObject;
+ }
+}
+
+void tst_qquicktext::overline()
+{
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE(textObject->font().overline(), false);
+
+ delete textObject;
+ }
+ {
+ QString componentStr = "import QtQuick 2.0\nText { font.overline: true; text: \"Hello world!\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE(textObject->font().overline(), true);
+
+ delete textObject;
+ }
+}
+
+void tst_qquicktext::strikeout()
+{
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE(textObject->font().strikeOut(), false);
+
+ delete textObject;
+ }
+ {
+ QString componentStr = "import QtQuick 2.0\nText { font.strikeout: true; text: \"Hello world!\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE(textObject->font().strikeOut(), true);
+
+ delete textObject;
+ }
+}
+
+void tst_qquicktext::capitalization()
+{
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE((int)textObject->font().capitalization(), (int)QQmlFontValueType::MixedCase);
+
+ delete textObject;
+ }
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"AllUppercase\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE((int)textObject->font().capitalization(), (int)QQmlFontValueType::AllUppercase);
+
+ delete textObject;
+ }
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"AllLowercase\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE((int)textObject->font().capitalization(), (int)QQmlFontValueType::AllLowercase);
+
+ delete textObject;
+ }
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"SmallCaps\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE((int)textObject->font().capitalization(), (int)QQmlFontValueType::SmallCaps);
+
+ delete textObject;
+ }
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.capitalization: \"Capitalize\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE((int)textObject->font().capitalization(), (int)QQmlFontValueType::Capitalize);
+
+ delete textObject;
+ }
+}
+
+void tst_qquicktext::letterSpacing()
+{
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE(textObject->font().letterSpacing(), 0.0);
+
+ delete textObject;
+ }
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.letterSpacing: -2 }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE(textObject->font().letterSpacing(), -2.);
+
+ delete textObject;
+ }
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.letterSpacing: 3 }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE(textObject->font().letterSpacing(), 3.);
+
+ delete textObject;
+ }
+}
+
+void tst_qquicktext::wordSpacing()
+{
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE(textObject->font().wordSpacing(), 0.0);
+
+ delete textObject;
+ }
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.wordSpacing: -50 }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE(textObject->font().wordSpacing(), -50.);
+
+ delete textObject;
+ }
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"Hello world!\"; font.wordSpacing: 200 }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QCOMPARE(textObject->font().wordSpacing(), 200.);
+
+ delete textObject;
+ }
+}
+
+
+
+
+class EventSender : public QQuickItem
+{
+public:
+ void sendEvent(QMouseEvent *event) {
+ if (event->type() == QEvent::MouseButtonPress)
+ mousePressEvent(event);
+ else if (event->type() == QEvent::MouseButtonRelease)
+ mouseReleaseEvent(event);
+ else
+ qWarning() << "Trying to send unsupported event type";
+ }
+};
+
+class LinkTest : public QObject
+{
+ Q_OBJECT
+public:
+ LinkTest() {}
+
+ QString link;
+
+public slots:
+ void linkClicked(QString l) { link = l; }
+};
+
+void tst_qquicktext::clickLink()
+{
+ {
+ QString componentStr = "import QtQuick 2.0\nText { text: \"<a href=\\\"http://qt.nokia.com\\\">Hello world!</a>\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+
+ LinkTest test;
+ QObject::connect(textObject, SIGNAL(linkActivated(QString)), &test, SLOT(linkClicked(QString)));
+
+ {
+ QMouseEvent me(QEvent::MouseButtonPress,QPointF(textObject->x()/2, textObject->y()/2), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
+ static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&me);
+
+ }
+
+ {
+ QMouseEvent me(QEvent::MouseButtonRelease,QPointF(textObject->x()/2, textObject->y()/2), Qt::LeftButton, Qt::NoButton, Qt::NoModifier);
+ static_cast<EventSender*>(static_cast<QQuickItem*>(textObject))->sendEvent(&me);
+
+ }
+
+
+ QCOMPARE(test.link, QLatin1String("http://qt.nokia.com"));
+
+ delete textObject;
+ }
+}
+
+void tst_qquicktext::baseUrl()
+{
+ QUrl localUrl("file:///tests/text.qml");
+ QUrl remoteUrl("http://qt.nokia.com/test.qml");
+
+ QQmlComponent textComponent(&engine);
+ textComponent.setData("import QtQuick 2.0\n Text {}", localUrl);
+ QQuickText *textObject = qobject_cast<QQuickText *>(textComponent.create());
+
+ QCOMPARE(textObject->baseUrl(), localUrl);
+
+ QSignalSpy spy(textObject, SIGNAL(baseUrlChanged()));
+
+ textObject->setBaseUrl(localUrl);
+ QCOMPARE(textObject->baseUrl(), localUrl);
+ QCOMPARE(spy.count(), 0);
+
+ textObject->setBaseUrl(remoteUrl);
+ QCOMPARE(textObject->baseUrl(), remoteUrl);
+ QCOMPARE(spy.count(), 1);
+
+ textObject->resetBaseUrl();
+ QCOMPARE(textObject->baseUrl(), localUrl);
+ QCOMPARE(spy.count(), 2);
+}
+
+void tst_qquicktext::embeddedImages_data()
+{
+ QTest::addColumn<QUrl>("qmlfile");
+ QTest::addColumn<QString>("error");
+ QTest::newRow("local") << testFileUrl("embeddedImagesLocal.qml") << "";
+ QTest::newRow("local-error") << testFileUrl("embeddedImagesLocalError.qml")
+ << testFileUrl("embeddedImagesLocalError.qml").toString()+":3:1: QML Text: Cannot open: " + testFileUrl("http/notexists.png").toString();
+ QTest::newRow("local") << testFileUrl("embeddedImagesLocalRelative.qml") << "";
+ QTest::newRow("remote") << testFileUrl("embeddedImagesRemote.qml") << "";
+ QTest::newRow("remote-error") << testFileUrl("embeddedImagesRemoteError.qml")
+ << testFileUrl("embeddedImagesRemoteError.qml").toString()+":3:1: QML Text: Error downloading http://127.0.0.1:14453/notexists.png - server replied: Not found";
+ QTest::newRow("remote") << testFileUrl("embeddedImagesRemoteRelative.qml") << "";
+}
+
+void tst_qquicktext::embeddedImages()
+{
+ // Tests QTBUG-9900
+
+ QFETCH(QUrl, qmlfile);
+ QFETCH(QString, error);
+
+ TestHTTPServer server(14453);
+ server.serveDirectory(testFile("http"));
+
+ if (!error.isEmpty())
+ QTest::ignoreMessage(QtWarningMsg, error.toLatin1());
+
+ QQmlComponent textComponent(&engine, qmlfile);
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+
+ QTRY_COMPARE(textObject->resourcesLoading(), 0);
+
+ QPixmap pm(testFile("http/exists.png"));
+ if (error.isEmpty()) {
+ QCOMPARE(textObject->width(), double(pm.width()));
+ QCOMPARE(textObject->height(), double(pm.height()));
+ } else {
+ QVERIFY(16 != pm.width()); // check test is effective
+ QCOMPARE(textObject->width(), 16.0); // default size of QTextDocument broken image icon
+ QCOMPARE(textObject->height(), 16.0);
+ }
+
+ delete textObject;
+}
+
+void tst_qquicktext::lineCount()
+{
+ QQuickView *canvas = createView(testFile("lineCount.qml"));
+
+ QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
+ QVERIFY(myText != 0);
+
+ QVERIFY(myText->lineCount() > 1);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->maximumLineCount(), INT_MAX);
+
+ myText->setMaximumLineCount(2);
+ QCOMPARE(myText->lineCount(), 2);
+ QCOMPARE(myText->truncated(), true);
+ QCOMPARE(myText->maximumLineCount(), 2);
+
+ myText->resetMaximumLineCount();
+ QCOMPARE(myText->maximumLineCount(), INT_MAX);
+ QCOMPARE(myText->truncated(), false);
+
+ myText->setElideMode(QQuickText::ElideRight);
+ myText->setMaximumLineCount(2);
+ QCOMPARE(myText->lineCount(), 2);
+ QCOMPARE(myText->truncated(), true);
+ QCOMPARE(myText->maximumLineCount(), 2);
+
+ delete canvas;
+}
+
+void tst_qquicktext::lineHeight()
+{
+ QQuickView *canvas = createView(testFile("lineHeight.qml"));
+
+ QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
+ QVERIFY(myText != 0);
+
+ QVERIFY(myText->lineHeight() == 1);
+ QVERIFY(myText->lineHeightMode() == QQuickText::ProportionalHeight);
+
+ qreal h = myText->height();
+ myText->setLineHeight(1.5);
+ QCOMPARE(myText->height(), qreal(qCeil(h * 1.5)));
+
+ myText->setLineHeightMode(QQuickText::FixedHeight);
+ myText->setLineHeight(20);
+ QCOMPARE(myText->height(), myText->lineCount() * 20.0);
+
+ 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.");
+ myText->setLineHeightMode(QQuickText::ProportionalHeight);
+ myText->setLineHeight(1.0);
+
+ qreal h2 = myText->height();
+ myText->setLineHeight(2.0);
+ QVERIFY(myText->height() == h2 * 2.0);
+
+ myText->setLineHeightMode(QQuickText::FixedHeight);
+ myText->setLineHeight(10);
+ QCOMPARE(myText->height(), myText->lineCount() * 10.0);
+
+ delete canvas;
+}
+
+void tst_qquicktext::implicitSize_data()
+{
+ QTest::addColumn<QString>("text");
+ QTest::addColumn<QString>("width");
+ QTest::addColumn<QString>("wrap");
+ QTest::addColumn<QString>("elide");
+ QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.NoWrap" << "Text.ElideNone";
+ QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" <<" 50" << "Text.NoWrap" << "Text.ElideNone";
+ QTest::newRow("plain, 0 width") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.NoWrap" << "Text.ElideNone";
+ QTest::newRow("plain, elide") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.NoWrap" << "Text.ElideRight";
+ QTest::newRow("plain, 0 width, elide") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.NoWrap" << "Text.ElideRight";
+ QTest::newRow("richtext, 0 width") << "<b>The quick red fox jumped over the lazy brown dog</b>" <<" 0" << "Text.NoWrap" << "Text.ElideNone";
+ QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.Wrap" << "Text.ElideNone";
+ QTest::newRow("richtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "50" << "Text.Wrap" << "Text.ElideNone";
+ QTest::newRow("plain_wrap, 0 width") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.Wrap" << "Text.ElideNone";
+ QTest::newRow("plain_wrap, elide") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.Wrap" << "Text.ElideRight";
+ QTest::newRow("plain_wrap, 0 width, elide") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.Wrap" << "Text.ElideRight";
+ QTest::newRow("richtext_wrap, 0 width") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "0" << "Text.Wrap" << "Text.ElideNone";
+}
+
+void tst_qquicktext::implicitSize()
+{
+ QFETCH(QString, text);
+ QFETCH(QString, width);
+ QFETCH(QString, wrap);
+ QFETCH(QString, elide);
+ QString componentStr = "import QtQuick 2.0\nText { "
+ "text: \"" + text + "\"; "
+ "width: " + width + "; "
+ "wrapMode: " + wrap + "; "
+ "elide: " + elide + "; "
+ "maximumLineCount: 1 }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject->width() < textObject->implicitWidth());
+ QVERIFY(textObject->height() == textObject->implicitHeight());
+
+ textObject->resetWidth();
+ QVERIFY(textObject->width() == textObject->implicitWidth());
+ QVERIFY(textObject->height() == textObject->implicitHeight());
+
+ delete textObject;
+}
+
+void tst_qquicktext::contentSize()
+{
+ QString componentStr = "import QtQuick 2.0\nText { width: 75; height: 16; font.pixelSize: 10 }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QScopedPointer<QObject> object(textComponent.create());
+ QQuickText *textObject = qobject_cast<QQuickText *>(object.data());
+
+ QSignalSpy spy(textObject, SIGNAL(contentSizeChanged()));
+
+ textObject->setText("The quick red fox jumped over the lazy brown dog");
+
+ QVERIFY(textObject->contentWidth() > textObject->width());
+ QVERIFY(textObject->contentHeight() < textObject->height());
+ QCOMPARE(spy.count(), 1);
+
+ textObject->setWrapMode(QQuickText::WordWrap);
+ QVERIFY(textObject->contentWidth() <= textObject->width());
+ QVERIFY(textObject->contentHeight() > textObject->height());
+ QCOMPARE(spy.count(), 2);
+
+ textObject->setElideMode(QQuickText::ElideRight);
+ QVERIFY(textObject->contentWidth() <= textObject->width());
+ QVERIFY(textObject->contentHeight() < textObject->height());
+ QCOMPARE(spy.count(), 3);
+ int spyCount = 3;
+ qreal elidedWidth = textObject->contentWidth();
+
+ textObject->setText("The quickredfoxjumpedoverthe lazy brown dog");
+ QVERIFY(textObject->contentWidth() <= textObject->width());
+ QVERIFY(textObject->contentHeight() < textObject->height());
+ // this text probably won't have the same elided width, but it's not guaranteed.
+ if (textObject->contentWidth() != elidedWidth)
+ QCOMPARE(spy.count(), ++spyCount);
+ else
+ QCOMPARE(spy.count(), spyCount);
+
+ textObject->setElideMode(QQuickText::ElideNone);
+ QVERIFY(textObject->contentWidth() > textObject->width());
+ QVERIFY(textObject->contentHeight() > textObject->height());
+ QCOMPARE(spy.count(), ++spyCount);
+}
+
+void tst_qquicktext::lineLaidOut()
+{
+ QQuickView *canvas = createView(testFile("lineLayout.qml"));
+
+ QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
+ QVERIFY(myText != 0);
+
+ QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText);
+ QVERIFY(textPrivate != 0);
+
+ QVERIFY(!textPrivate->extra.isAllocated());
+
+#if defined(Q_OS_MAC)
+ QVERIFY(myText->lineCount() == textPrivate->linesRects.count());
+#endif
+
+ for (int i = 0; i < textPrivate->layout.lineCount(); ++i) {
+ QRectF r = textPrivate->layout.lineAt(i).rect();
+ QVERIFY(r.width() == i * 15);
+ if (i >= 30)
+ QVERIFY(r.x() == r.width() + 30);
+ if (i >= 60) {
+ QVERIFY(r.x() == r.width() * 2 + 60);
+ QVERIFY(r.height() == 20);
+ }
+ }
+
+ delete canvas;
+}
+
+void tst_qquicktext::imgTagsBaseUrl_data()
+{
+ QTest::addColumn<QUrl>("src");
+ QTest::addColumn<QUrl>("baseUrl");
+ QTest::addColumn<QUrl>("contextUrl");
+ QTest::addColumn<qreal>("imgHeight");
+
+ QTest::newRow("absolute local")
+ << testFileUrl("images/heart200.png")
+ << QUrl()
+ << QUrl()
+ << 181.;
+ QTest::newRow("relative local context 1")
+ << QUrl("images/heart200.png")
+ << QUrl()
+ << testFileUrl("/app.qml")
+ << 181.;
+ QTest::newRow("relative local context 2")
+ << QUrl("heart200.png")
+ << QUrl()
+ << testFileUrl("images/app.qml")
+ << 181.;
+ QTest::newRow("relative local base 1")
+ << QUrl("images/heart200.png")
+ << testFileUrl("")
+ << testFileUrl("nonexistant/app.qml")
+ << 181.;
+ QTest::newRow("relative local base 2")
+ << QUrl("heart200.png")
+ << testFileUrl("images/")
+ << testFileUrl("nonexistant/app.qml")
+ << 181.;
+ QTest::newRow("base relative to local context")
+ << QUrl("heart200.png")
+ << testFileUrl("images/")
+ << testFileUrl("/app.qml")
+ << 181.;
+
+ QTest::newRow("absolute remote")
+ << QUrl("http://127.0.0.1:14453/images/heart200.png")
+ << QUrl()
+ << QUrl()
+ << 181.;
+ QTest::newRow("relative remote base 1")
+ << QUrl("images/heart200.png")
+ << QUrl("http://127.0.0.1:14453/")
+ << testFileUrl("nonexistant/app.qml")
+ << 181.;
+ QTest::newRow("relative remote base 2")
+ << QUrl("heart200.png")
+ << QUrl("http://127.0.0.1:14453/images/")
+ << testFileUrl("nonexistant/app.qml")
+ << 181.;
+}
+
+void tst_qquicktext::imgTagsBaseUrl()
+{
+ QFETCH(QUrl, src);
+ QFETCH(QUrl, baseUrl);
+ QFETCH(QUrl, contextUrl);
+ QFETCH(qreal, imgHeight);
+
+ TestHTTPServer server(14453);
+ server.serveDirectory(testFile(""));
+
+ QByteArray baseUrlFragment;
+ if (!baseUrl.isEmpty())
+ baseUrlFragment = "; baseUrl: \"" + baseUrl.toEncoded() + "\"";
+ QByteArray componentStr = "import QtQuick 2.0\nText { text: \"This is a test <img src=\\\"" + src.toEncoded() + "\\\">\"" + baseUrlFragment + " }";
+
+ QQmlComponent component(&engine);
+ component.setData(componentStr, contextUrl);
+ QScopedPointer<QObject> object(component.create());
+ QQuickText *textObject = qobject_cast<QQuickText *>(object.data());
+ QVERIFY(textObject);
+
+ QCoreApplication::processEvents();
+
+ QTRY_COMPARE(textObject->height(), imgHeight);
+}
+
+void tst_qquicktext::imgTagsAlign_data()
+{
+ QTest::addColumn<QString>("src");
+ QTest::addColumn<int>("imgHeight");
+ QTest::addColumn<QString>("align");
+ QTest::newRow("heart-bottom") << "data/images/heart200.png" << 181 << "bottom";
+ QTest::newRow("heart-middle") << "data/images/heart200.png" << 181 << "middle";
+ QTest::newRow("heart-top") << "data/images/heart200.png" << 181 << "top";
+ QTest::newRow("starfish-bottom") << "data/images/starfish_2.png" << 217 << "bottom";
+ QTest::newRow("starfish-middle") << "data/images/starfish_2.png" << 217 << "middle";
+ QTest::newRow("starfish-top") << "data/images/starfish_2.png" << 217 << "top";
+}
+
+void tst_qquicktext::imgTagsAlign()
+{
+ QFETCH(QString, src);
+ QFETCH(int, imgHeight);
+ QFETCH(QString, align);
+ QString componentStr = "import QtQuick 2.0\nText { text: \"This is a test <img src=\\\"" + src + "\\\" align=\\\"" + align + "\\\"> of image.\" }";
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QVERIFY(textObject->height() == imgHeight);
+
+ QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject);
+ QVERIFY(textPrivate != 0);
+
+ QRectF br = textPrivate->layout.boundingRect();
+ if (align == "bottom")
+ QVERIFY(br.y() == imgHeight - br.height());
+ else if (align == "middle")
+ QVERIFY(br.y() == imgHeight / 2.0 - br.height() / 2.0);
+ else if (align == "top")
+ QVERIFY(br.y() == 0);
+
+ delete textObject;
+}
+
+void tst_qquicktext::imgTagsMultipleImages()
+{
+ 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\\\">.\" }";
+
+ QQmlComponent textComponent(&engine);
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ QVERIFY(textObject->height() == 85);
+
+ QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(textObject);
+ QVERIFY(textPrivate != 0);
+ QVERIFY(textPrivate->visibleImgTags.count() == 2);
+
+ delete textObject;
+}
+
+void tst_qquicktext::imgTagsElide()
+{
+ QQuickView *canvas = createView(testFile("imgTagsElide.qml"));
+ QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
+ QVERIFY(myText != 0);
+
+ QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText);
+ QVERIFY(textPrivate != 0);
+ QVERIFY(textPrivate->visibleImgTags.count() == 0);
+ myText->setMaximumLineCount(20);
+ QTRY_VERIFY(textPrivate->visibleImgTags.count() == 1);
+
+ delete myText;
+ delete canvas;
+}
+
+void tst_qquicktext::imgTagsUpdates()
+{
+ QQuickView *canvas = createView(testFile("imgTagsUpdates.qml"));
+ QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
+ QVERIFY(myText != 0);
+
+ QSignalSpy spy(myText, SIGNAL(contentSizeChanged()));
+
+ QQuickTextPrivate *textPrivate = QQuickTextPrivate::get(myText);
+ QVERIFY(textPrivate != 0);
+
+ myText->setText("This is a heart<img src=\"images/heart200.png\">.");
+ QVERIFY(textPrivate->visibleImgTags.count() == 1);
+ QVERIFY(spy.count() == 1);
+
+ myText->setMaximumLineCount(2);
+ myText->setText("This is another heart<img src=\"images/heart200.png\">.");
+ QTRY_VERIFY(textPrivate->visibleImgTags.count() == 1);
+
+ // if maximumLineCount is set and the img tag doesn't have an explicit size
+ // we relayout twice.
+ QVERIFY(spy.count() == 3);
+
+ delete myText;
+ delete canvas;
+}
+
+void tst_qquicktext::imgTagsError()
+{
+ QString componentStr = "import QtQuick 2.0\nText { text: \"This is a starfish<img src=\\\"data/images/starfish_2.pn\\\" width=\\\"60\\\" height=\\\"60\\\">.\" }";
+
+ QQmlComponent textComponent(&engine);
+ QTest::ignoreMessage(QtWarningMsg, "file::2:1: QML Text: Cannot open: file:data/images/starfish_2.pn");
+ textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+ QQuickText *textObject = qobject_cast<QQuickText*>(textComponent.create());
+
+ QVERIFY(textObject != 0);
+ delete textObject;
+}
+
+void tst_qquicktext::fontSizeMode_data()
+{
+ QTest::addColumn<QString>("text");
+ QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog";
+ QTest::newRow("styled") << "<b>The quick red fox jumped over the lazy brown dog</b>";
+}
+
+void tst_qquicktext::fontSizeMode()
+{
+ QFETCH(QString, text);
+
+ QScopedPointer<QQuickView> canvas(createView(testFile("fontSizeMode.qml")));
+ canvas->show();
+
+ QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
+ QVERIFY(myText != 0);
+
+ myText->setText(text);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ qreal originalWidth = myText->contentWidth();
+ qreal originalHeight = myText->contentHeight();
+
+ // The original text unwrapped should exceed the width of the item.
+ QVERIFY(originalWidth > myText->width());
+ QVERIFY(originalHeight < myText->height());
+
+ QFont font = myText->font();
+ font.setPixelSize(64);
+
+ myText->setFont(font);
+ myText->setFontSizeMode(QQuickText::HorizontalFit);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ // Font size reduced to fit within the width of the item.
+ qreal horizontalFitWidth = myText->contentWidth();
+ qreal horizontalFitHeight = myText->contentHeight();
+ QVERIFY(horizontalFitWidth <= myText->width() + 2); // rounding
+ QVERIFY(horizontalFitHeight <= myText->height() + 2);
+
+ // Elide won't affect the size with HorizontalFit.
+ myText->setElideMode(QQuickText::ElideRight);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), horizontalFitWidth);
+ QCOMPARE(myText->contentHeight(), horizontalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideLeft);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), horizontalFitWidth);
+ QCOMPARE(myText->contentHeight(), horizontalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideMiddle);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), horizontalFitWidth);
+ QCOMPARE(myText->contentHeight(), horizontalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideNone);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ myText->setFontSizeMode(QQuickText::VerticalFit);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ // Font size increased to fill the height of the item.
+ qreal verticalFitHeight = myText->contentHeight();
+ QVERIFY(myText->contentWidth() > myText->width());
+ QVERIFY(verticalFitHeight <= myText->height() + 2);
+ QVERIFY(verticalFitHeight > originalHeight);
+
+ // Elide won't affect the height of a single line with VerticalFit but will crop the width.
+ myText->setElideMode(QQuickText::ElideRight);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(myText->truncated());
+ QVERIFY(myText->contentWidth() <= myText->width() + 2);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideLeft);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(myText->truncated());
+ QVERIFY(myText->contentWidth() <= myText->width() + 2);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideMiddle);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(myText->truncated());
+ QVERIFY(myText->contentWidth() <= myText->width() + 2);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideNone);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ myText->setFontSizeMode(QQuickText::Fit);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ // Should be the same as HorizontalFit with no wrapping.
+ QCOMPARE(myText->contentWidth(), horizontalFitWidth);
+ QCOMPARE(myText->contentHeight(), horizontalFitHeight);
+
+ // Elide won't affect the size with Fit.
+ myText->setElideMode(QQuickText::ElideRight);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), horizontalFitWidth);
+ QCOMPARE(myText->contentHeight(), horizontalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideLeft);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), horizontalFitWidth);
+ QCOMPARE(myText->contentHeight(), horizontalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideMiddle);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), horizontalFitWidth);
+ QCOMPARE(myText->contentHeight(), horizontalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideNone);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ myText->setFontSizeMode(QQuickText::FixedSize);
+ myText->setWrapMode(QQuickText::Wrap);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ originalWidth = myText->contentWidth();
+ originalHeight = myText->contentHeight();
+
+ // The original text wrapped should exceed the height of the item.
+ QVERIFY(originalWidth <= myText->width() + 2);
+ QVERIFY(originalHeight > myText->height());
+
+ myText->setFontSizeMode(QQuickText::HorizontalFit);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ // HorizontalFit should reduce the font size to minimize wrapping, which brings it back to the
+ // same size as without text wrapping.
+ QCOMPARE(myText->contentWidth(), horizontalFitWidth);
+ QCOMPARE(myText->contentHeight(), horizontalFitHeight);
+
+ // Elide won't affect the size with HorizontalFit.
+ myText->setElideMode(QQuickText::ElideRight);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), horizontalFitWidth);
+ QCOMPARE(myText->contentHeight(), horizontalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideNone);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ myText->setFontSizeMode(QQuickText::VerticalFit);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ // VerticalFit should reduce the size to the wrapped text within the vertical height.
+ verticalFitHeight = myText->contentHeight();
+ qreal verticalFitWidth = myText->contentWidth();
+ QVERIFY(myText->contentWidth() <= myText->width() + 2);
+ QVERIFY(verticalFitHeight <= myText->height() + 2);
+ QVERIFY(verticalFitHeight < originalHeight);
+
+ // Elide won't affect the height or width of a wrapped text with VerticalFit.
+ myText->setElideMode(QQuickText::ElideRight);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideNone);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ myText->setFontSizeMode(QQuickText::Fit);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ // Should be the same as VerticalFit with wrapping.
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ // Elide won't affect the size with Fit.
+ myText->setElideMode(QQuickText::ElideRight);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideNone);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ myText->setFontSizeMode(QQuickText::FixedSize);
+ myText->setMaximumLineCount(2);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ // The original text wrapped should exceed the height of the item.
+ QVERIFY(originalWidth <= myText->width() + 2);
+ QVERIFY(originalHeight > myText->height());
+
+ myText->setFontSizeMode(QQuickText::HorizontalFit);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ // HorizontalFit should reduce the font size to minimize wrapping, which brings it back to the
+ // same size as without text wrapping.
+ QCOMPARE(myText->contentWidth(), horizontalFitWidth);
+ QCOMPARE(myText->contentHeight(), horizontalFitHeight);
+
+ // Elide won't affect the size with HorizontalFit.
+ myText->setElideMode(QQuickText::ElideRight);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), horizontalFitWidth);
+ QCOMPARE(myText->contentHeight(), horizontalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideNone);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ myText->setFontSizeMode(QQuickText::VerticalFit);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ // VerticalFit should reduce the size to the wrapped text within the vertical height.
+ verticalFitHeight = myText->contentHeight();
+ verticalFitWidth = myText->contentWidth();
+ QVERIFY(myText->contentWidth() <= myText->width() + 2);
+ QVERIFY(verticalFitHeight <= myText->height() + 2);
+ QVERIFY(verticalFitHeight < originalHeight);
+
+ // Elide won't affect the height or width of a wrapped text with VerticalFit.
+ myText->setElideMode(QQuickText::ElideRight);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideNone);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ myText->setFontSizeMode(QQuickText::Fit);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ // Should be the same as VerticalFit with wrapping.
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ // Elide won't affect the size with Fit.
+ myText->setElideMode(QQuickText::ElideRight);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideNone);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+}
+
+void tst_qquicktext::fontSizeModeMultiline_data()
+{
+ QTest::addColumn<QString>("text");
+ QTest::newRow("plain") << "The quick red fox jumped\n over the lazy brown dog";
+ QTest::newRow("styledtext") << "<b>The quick red fox jumped<br/> over the lazy brown dog</b>";
+}
+
+void tst_qquicktext::fontSizeModeMultiline()
+{
+ QFETCH(QString, text);
+
+ QScopedPointer<QQuickView> canvas(createView(testFile("fontSizeMode.qml")));
+ canvas->show();
+
+ QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
+ QVERIFY(myText != 0);
+
+ myText->setText(text);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ qreal originalWidth = myText->contentWidth();
+ qreal originalHeight = myText->contentHeight();
+ QCOMPARE(myText->lineCount(), 2);
+
+ // The original text unwrapped should exceed the width and height of the item.
+ QVERIFY(originalWidth > myText->width());
+ QVERIFY(originalHeight > myText->height());
+
+ QFont font = myText->font();
+ font.setPixelSize(64);
+
+ myText->setFont(font);
+ myText->setFontSizeMode(QQuickText::HorizontalFit);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ // Font size reduced to fit within the width of the item.
+ QCOMPARE(myText->lineCount(), 2);
+ qreal horizontalFitWidth = myText->contentWidth();
+ qreal horizontalFitHeight = myText->contentHeight();
+ QVERIFY(horizontalFitWidth <= myText->width() + 2); // rounding
+ QVERIFY(horizontalFitHeight > myText->height());
+
+ // Right eliding will remove the last line
+ myText->setElideMode(QQuickText::ElideRight);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(myText->truncated());
+ QCOMPARE(myText->lineCount(), 1);
+ QVERIFY(myText->contentWidth() <= myText->width() + 2);
+ QVERIFY(myText->contentHeight() <= myText->height() + 2);
+
+ // Left or middle eliding wont have any effect.
+ myText->setElideMode(QQuickText::ElideLeft);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), horizontalFitWidth);
+ QCOMPARE(myText->contentHeight(), horizontalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideMiddle);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), horizontalFitWidth);
+ QCOMPARE(myText->contentHeight(), horizontalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideNone);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ myText->setFontSizeMode(QQuickText::VerticalFit);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ // Font size reduced to fit within the height of the item.
+ qreal verticalFitWidth = myText->contentWidth();
+ qreal verticalFitHeight = myText->contentHeight();
+ QVERIFY(verticalFitWidth <= myText->width() + 2);
+ QVERIFY(verticalFitHeight <= myText->height() + 2);
+
+ // Elide will have no effect.
+ myText->setElideMode(QQuickText::ElideRight);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QVERIFY(myText->contentWidth() <= myText->width() + 2);
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideLeft);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideMiddle);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideNone);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ myText->setFontSizeMode(QQuickText::Fit);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ // Should be the same as VerticalFit with no wrapping.
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ // Elide won't affect the size with Fit.
+ myText->setElideMode(QQuickText::ElideRight);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideLeft);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideMiddle);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideNone);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ myText->setFontSizeMode(QQuickText::FixedSize);
+ myText->setWrapMode(QQuickText::Wrap);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ originalWidth = myText->contentWidth();
+ originalHeight = myText->contentHeight();
+
+ // The original text wrapped should exceed the height of the item.
+ QVERIFY(originalWidth <= myText->width() + 2);
+ QVERIFY(originalHeight > myText->height());
+
+ myText->setFontSizeMode(QQuickText::HorizontalFit);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ // HorizontalFit should reduce the font size to minimize wrapping, which brings it back to the
+ // same size as without text wrapping.
+ QCOMPARE(myText->contentWidth(), horizontalFitWidth);
+ QCOMPARE(myText->contentHeight(), horizontalFitHeight);
+
+ // Text will be elided vertically with HorizontalFit
+ myText->setElideMode(QQuickText::ElideRight);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(myText->truncated());
+ QVERIFY(myText->contentWidth() <= myText->width() + 2);
+ QVERIFY(myText->contentHeight() <= myText->height() + 2);
+
+ myText->setElideMode(QQuickText::ElideNone);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ myText->setFontSizeMode(QQuickText::VerticalFit);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ // VerticalFit should reduce the size to the wrapped text within the vertical height.
+ verticalFitHeight = myText->contentHeight();
+ verticalFitWidth = myText->contentWidth();
+ QVERIFY(myText->contentWidth() <= myText->width() + 2);
+ QVERIFY(verticalFitHeight <= myText->height() + 2);
+ QVERIFY(verticalFitHeight < originalHeight);
+
+ // Elide won't affect the height or width of a wrapped text with VerticalFit.
+ myText->setElideMode(QQuickText::ElideRight);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideNone);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ myText->setFontSizeMode(QQuickText::Fit);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ // Should be the same as VerticalFit with wrapping.
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ // Elide won't affect the size with Fit.
+ myText->setElideMode(QQuickText::ElideRight);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideNone);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ myText->setFontSizeMode(QQuickText::FixedSize);
+ myText->setMaximumLineCount(2);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ // The original text wrapped should exceed the height of the item.
+ QVERIFY(originalWidth <= myText->width() + 2);
+ QVERIFY(originalHeight > myText->height());
+
+ myText->setFontSizeMode(QQuickText::HorizontalFit);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ // HorizontalFit should reduce the font size to minimize wrapping, which brings it back to the
+ // same size as without text wrapping.
+ QCOMPARE(myText->contentWidth(), horizontalFitWidth);
+ QCOMPARE(myText->contentHeight(), horizontalFitHeight);
+
+ // Elide won't affect the size with HorizontalFit.
+ myText->setElideMode(QQuickText::ElideRight);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(myText->truncated());
+ QVERIFY(myText->contentWidth() <= myText->width() + 2);
+ QVERIFY(myText->contentHeight() <= myText->height() + 2);
+
+ myText->setElideMode(QQuickText::ElideNone);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ myText->setFontSizeMode(QQuickText::VerticalFit);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ // VerticalFit should reduce the size to the wrapped text within the vertical height.
+ verticalFitHeight = myText->contentHeight();
+ verticalFitWidth = myText->contentWidth();
+ QVERIFY(myText->contentWidth() <= myText->width() + 2);
+ QVERIFY(verticalFitHeight <= myText->height() + 2);
+ QVERIFY(verticalFitHeight < originalHeight);
+
+ // Elide won't affect the height or width of a wrapped text with VerticalFit.
+ myText->setElideMode(QQuickText::ElideRight);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideNone);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ myText->setFontSizeMode(QQuickText::Fit);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ // Should be the same as VerticalFit with wrapping.
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ // Elide won't affect the size with Fit.
+ myText->setElideMode(QQuickText::ElideRight);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ QVERIFY(!myText->truncated());
+ QCOMPARE(myText->contentWidth(), verticalFitWidth);
+ QCOMPARE(myText->contentHeight(), verticalFitHeight);
+
+ myText->setElideMode(QQuickText::ElideNone);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+}
+
+void tst_qquicktext::multilengthStrings_data()
+{
+ QTest::addColumn<QString>("source");
+ QTest::newRow("No Wrap") << testFile("multilengthStrings.qml");
+ QTest::newRow("Wrap") << testFile("multilengthStringsWrapped.qml");
+}
+
+void tst_qquicktext::multilengthStrings()
+{
+ QFETCH(QString, source);
+
+ QScopedPointer<QQuickView> canvas(createView(source));
+ canvas->show();
+
+ QQuickText *myText = canvas->rootObject()->findChild<QQuickText*>("myText");
+ QVERIFY(myText != 0);
+
+ const QString longText = "the quick brown fox jumped over the lazy dog";
+ const QString mediumText = "the brown fox jumped over the dog";
+ const QString shortText = "fox jumped dog";
+
+ myText->setText(longText);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ const qreal longWidth = myText->contentWidth();
+ const qreal longHeight = myText->contentHeight();
+
+ myText->setText(mediumText);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ const qreal mediumWidth = myText->contentWidth();
+ const qreal mediumHeight = myText->contentHeight();
+
+ myText->setText(shortText);
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+ const qreal shortWidth = myText->contentWidth();
+ const qreal shortHeight = myText->contentHeight();
+
+ myText->setElideMode(QQuickText::ElideRight);
+ myText->setText(longText + QLatin1Char('\x9c') + mediumText + QLatin1Char('\x9c') + shortText);
+
+ myText->setSize(QSizeF(longWidth, longHeight));
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ QCOMPARE(myText->contentWidth(), longWidth);
+ QCOMPARE(myText->contentHeight(), longHeight);
+ QCOMPARE(myText->truncated(), false);
+
+ myText->setSize(QSizeF(mediumWidth, mediumHeight));
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ QCOMPARE(myText->contentWidth(), mediumWidth);
+ QCOMPARE(myText->contentHeight(), mediumHeight);
+ QCOMPARE(myText->truncated(), true);
+
+ myText->setSize(QSizeF(shortWidth, shortHeight));
+ QTRY_COMPARE(QQuickItemPrivate::get(myText)->polishScheduled, false);
+
+ QCOMPARE(myText->contentWidth(), shortWidth);
+ QCOMPARE(myText->contentHeight(), shortHeight);
+ QCOMPARE(myText->truncated(), true);
+}
+
+void tst_qquicktext::fontFormatSizes_data()
+{
+ QTest::addColumn<QString>("text");
+ QTest::addColumn<QString>("textWithTag");
+ QTest::addColumn<bool>("fontIsBigger");
+
+ QTest::newRow("fs1") << "Hello world!" << "Hello <font size=\"1\">world</font>!" << false;
+ QTest::newRow("fs2") << "Hello world!" << "Hello <font size=\"2\">world</font>!" << false;
+ QTest::newRow("fs3") << "Hello world!" << "Hello <font size=\"3\">world</font>!" << false;
+ QTest::newRow("fs4") << "Hello world!" << "Hello <font size=\"4\">world</font>!" << true;
+ QTest::newRow("fs5") << "Hello world!" << "Hello <font size=\"5\">world</font>!" << true;
+ QTest::newRow("fs6") << "Hello world!" << "Hello <font size=\"6\">world</font>!" << true;
+ QTest::newRow("fs7") << "Hello world!" << "Hello <font size=\"7\">world</font>!" << true;
+ QTest::newRow("h1") << "This is<br/>a font<br/> size test." << "This is <h1>a font</h1> size test." << true;
+ QTest::newRow("h2") << "This is<br/>a font<br/> size test." << "This is <h2>a font</h2> size test." << true;
+ QTest::newRow("h3") << "This is<br/>a font<br/> size test." << "This is <h3>a font</h3> size test." << true;
+ QTest::newRow("h4") << "This is<br/>a font<br/> size test." << "This is <h4>a font</h4> size test." << true;
+ QTest::newRow("h5") << "This is<br/>a font<br/> size test." << "This is <h5>a font</h5> size test." << false;
+ QTest::newRow("h6") << "This is<br/>a font<br/> size test." << "This is <h6>a font</h6> size test." << false;
+}
+
+void tst_qquicktext::fontFormatSizes()
+{
+ QFETCH(QString, text);
+ QFETCH(QString, textWithTag);
+ QFETCH(bool, fontIsBigger);
+
+ QQuickView *view = new QQuickView;
+ {
+ view->setSource(testFileUrl("pointFontSizes.qml"));
+ view->show();
+
+ QQuickText *qtext = view->rootObject()->findChild<QQuickText*>("text");
+ QQuickText *qtextWithTag = view->rootObject()->findChild<QQuickText*>("textWithTag");
+ QVERIFY(qtext != 0);
+ QVERIFY(qtextWithTag != 0);
+
+ qtext->setText(text);
+ qtextWithTag->setText(textWithTag);
+
+ for (int size = 6; size < 100; size += 4) {
+ view->rootObject()->setProperty("pointSize", size);
+ if (fontIsBigger)
+ QVERIFY(qtext->height() <= qtextWithTag->height());
+ else
+ QVERIFY(qtext->height() >= qtextWithTag->height());
+ }
+ }
+
+ {
+ view->setSource(testFileUrl("pixelFontSizes.qml"));
+ QQuickText *qtext = view->rootObject()->findChild<QQuickText*>("text");
+ QQuickText *qtextWithTag = view->rootObject()->findChild<QQuickText*>("textWithTag");
+ QVERIFY(qtext != 0);
+ QVERIFY(qtextWithTag != 0);
+
+ qtext->setText(text);
+ qtextWithTag->setText(textWithTag);
+
+ for (int size = 6; size < 100; size += 4) {
+ view->rootObject()->setProperty("pixelSize", size);
+ if (fontIsBigger)
+ QVERIFY(qtext->height() <= qtextWithTag->height());
+ else
+ QVERIFY(qtext->height() >= qtextWithTag->height());
+ }
+ }
+ delete view;
+}
+
+QTEST_MAIN(tst_qquicktext)
+
+#include "tst_qquicktext.moc"