Fix alignment bug in QQuickText with multi-line text and implicit width
authorYann Bodson <yann.bodson@nokia.com>
Thu, 3 May 2012 05:00:33 +0000 (15:00 +1000)
committerQt by Nokia <qt-info@nokia.com>
Thu, 3 May 2012 06:05:33 +0000 (08:05 +0200)
If the horizontal alignment is not left and the width of the text is not
known during the first pass, we need to relayout once we know the
maximum line width.

Task-number: QTBUG-18617
Change-Id: I0cad100946beda151034067e23439185684de144
Reviewed-by: Andrew den Exter <andrew.den-exter@nokia.com>
src/quick/items/qquicktext.cpp
tests/auto/quick/qquicktext/data/hAlignImplicitWidth.qml [new file with mode: 0644]
tests/auto/quick/qquicktext/tst_qquicktext.cpp

index 4d39f0b..104a6ab 100644 (file)
@@ -916,9 +916,13 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth, qreal *cons
                     && (q->heightValid() || (maximumLineCountValid && canWrap));
 
             const qreal oldWidth = lineWidth;
-            lineWidth = q->widthValid() && q->width() > 0 ? q->width() : FLT_MAX;
+            lineWidth = q->widthValid() && q->width() > 0 ? q->width() : *naturalWidth;
             if (lineWidth != oldWidth && (singlelineElide || multilineElide || canWrap || horizontalFit))
                 continue;
+            // If the horizontal alignment is not left and the width was not valid we need to relayout
+            // now that we know the maximum line width.
+            if (!q->widthValid() && maxLineCount > 1 && q->effectiveHAlign() != QQuickText::AlignLeft)
+                continue;
         }
 
         // If the next needs to be elided and there's an abbreviated string available
diff --git a/tests/auto/quick/qquicktext/data/hAlignImplicitWidth.qml b/tests/auto/quick/qquicktext/data/hAlignImplicitWidth.qml
new file mode 100644 (file)
index 0000000..136e5d2
--- /dev/null
@@ -0,0 +1,13 @@
+import QtQuick 2.0
+
+Rectangle {
+    width: 200
+    height: 100
+
+    Text {
+        objectName: "textItem"
+        text: "AA\nBBBBB\nCCCCCCCCCCCCCCCC"
+        anchors.centerIn: parent
+        horizontalAlignment: Text.AlignLeft
+    }
+}
index a83a10e..d9395ca 100644 (file)
@@ -90,6 +90,7 @@ private slots:
     void horizontalAlignment();
     void horizontalAlignment_RightToLeft();
     void verticalAlignment();
+    void hAlignImplicitWidth();
     void font();
     void style();
     void color();
@@ -158,6 +159,7 @@ private:
     QQmlEngine engine;
 
     QQuickView *createView(const QString &filename);
+    int numberOfNonWhitePixels(int fromX, int toX, const QImage &image);
 };
 
 tst_qquicktext::tst_qquicktext()
@@ -836,6 +838,59 @@ void tst_qquicktext::horizontalAlignment_RightToLeft()
     delete textObject;
 }
 
+int tst_qquicktext::numberOfNonWhitePixels(int fromX, int toX, const QImage &image)
+{
+    int pixels = 0;
+    for (int x = fromX; x < toX; ++x) {
+        for (int y = 0; y < image.height(); ++y) {
+            if (image.pixel(x, y) != qRgb(255, 255, 255))
+                pixels++;
+        }
+    }
+    return pixels;
+}
+
+void tst_qquicktext::hAlignImplicitWidth()
+{
+    QQuickView view(testFileUrl("hAlignImplicitWidth.qml"));
+    view.show();
+    view.requestActivateWindow();
+    QTest::qWaitForWindowShown(&view);
+
+    QQuickText *text = view.rootObject()->findChild<QQuickText*>("textItem");
+    QVERIFY(text != 0);
+
+    {
+        // Left Align
+        QImage image = view.grabFrameBuffer();
+        int left = numberOfNonWhitePixels(0, image.width() / 3, image);
+        int mid = numberOfNonWhitePixels(image.width() / 3, 2 * image.width() / 3, image);
+        int right = numberOfNonWhitePixels( 2 * image.width() / 3, image.width(), image);
+        QVERIFY(left > mid);
+        QVERIFY(mid > right);
+    }
+    {
+        // HCenter Align
+        text->setHAlign(QQuickText::AlignHCenter);
+        QImage image = view.grabFrameBuffer();
+        int left = numberOfNonWhitePixels(0, image.width() / 3, image);
+        int mid = numberOfNonWhitePixels(image.width() / 3, 2 * image.width() / 3, image);
+        int right = numberOfNonWhitePixels( 2 * image.width() / 3, image.width(), image);
+        QVERIFY(left < mid);
+        QVERIFY(mid > right);
+    }
+    {
+        // Right Align
+        text->setHAlign(QQuickText::AlignRight);
+        QImage image = view.grabFrameBuffer();
+        int left = numberOfNonWhitePixels(0, image.width() / 3, image);
+        int mid = numberOfNonWhitePixels(image.width() / 3, 2 * image.width() / 3, image);
+        int right = numberOfNonWhitePixels( 2 * image.width() / 3, image.width(), image);
+        QVERIFY(left < mid);
+        QVERIFY(mid < right);
+    }
+}
+
 void tst_qquicktext::verticalAlignment()
 {
     //test one align each, and then test if two align fails.