From faebec95f12f2db4cc105738c064e12bd0bcf988 Mon Sep 17 00:00:00 2001
From: Warwick Allison <warwick.allison@nokia.com>
Date: Wed, 23 Jun 2010 16:50:48 +1000
Subject: Fix and better test Text / TextEdit alignments. Various clipping and
 refresh bugs.

Task-number: QTBUG-11492
---
 .../graphicsitems/qdeclarativepainteditem.cpp      |   4 +-
 src/declarative/graphicsitems/qdeclarativetext.cpp | 142 +++++++++++++--------
 src/declarative/graphicsitems/qdeclarativetext_p.h |   2 +
 .../graphicsitems/qdeclarativetextedit.cpp         |  28 +++-
 .../graphicsitems/qdeclarativetextedit_p.h         |   2 +
 .../qdeclarativetext/data/alignments.qml           |  42 ++++++
 .../qdeclarativetext/data/alignments_cb.png        | Bin 0 -> 1184 bytes
 .../qdeclarativetext/data/alignments_cc.png        | Bin 0 -> 1293 bytes
 .../qdeclarativetext/data/alignments_ct.png        | Bin 0 -> 1237 bytes
 .../qdeclarativetext/data/alignments_lb.png        | Bin 0 -> 1208 bytes
 .../qdeclarativetext/data/alignments_lc.png        | Bin 0 -> 1303 bytes
 .../qdeclarativetext/data/alignments_lt.png        | Bin 0 -> 1241 bytes
 .../qdeclarativetext/data/alignments_rb.png        | Bin 0 -> 1178 bytes
 .../qdeclarativetext/data/alignments_rc.png        | Bin 0 -> 1274 bytes
 .../qdeclarativetext/data/alignments_rt.png        | Bin 0 -> 1221 bytes
 .../qdeclarativetext/tst_qdeclarativetext.cpp      |  66 ++++++++++
 .../qdeclarativetextedit/data/alignments.qml       |  42 ++++++
 .../qdeclarativetextedit/data/alignments_cb.png    | Bin 0 -> 1411 bytes
 .../qdeclarativetextedit/data/alignments_cc.png    | Bin 0 -> 1501 bytes
 .../qdeclarativetextedit/data/alignments_ct.png    | Bin 0 -> 1457 bytes
 .../qdeclarativetextedit/data/alignments_lb.png    | Bin 0 -> 1420 bytes
 .../qdeclarativetextedit/data/alignments_lc.png    | Bin 0 -> 1508 bytes
 .../qdeclarativetextedit/data/alignments_lt.png    | Bin 0 -> 1447 bytes
 .../qdeclarativetextedit/data/alignments_rb.png    | Bin 0 -> 1421 bytes
 .../qdeclarativetextedit/data/alignments_rc.png    | Bin 0 -> 1485 bytes
 .../qdeclarativetextedit/data/alignments_rt.png    | Bin 0 -> 1439 bytes
 .../tst_qdeclarativetextedit.cpp                   |  54 ++++++++
 27 files changed, 326 insertions(+), 56 deletions(-)
 create mode 100644 tests/auto/declarative/qdeclarativetext/data/alignments.qml
 create mode 100644 tests/auto/declarative/qdeclarativetext/data/alignments_cb.png
 create mode 100644 tests/auto/declarative/qdeclarativetext/data/alignments_cc.png
 create mode 100644 tests/auto/declarative/qdeclarativetext/data/alignments_ct.png
 create mode 100644 tests/auto/declarative/qdeclarativetext/data/alignments_lb.png
 create mode 100644 tests/auto/declarative/qdeclarativetext/data/alignments_lc.png
 create mode 100644 tests/auto/declarative/qdeclarativetext/data/alignments_lt.png
 create mode 100644 tests/auto/declarative/qdeclarativetext/data/alignments_rb.png
 create mode 100644 tests/auto/declarative/qdeclarativetext/data/alignments_rc.png
 create mode 100644 tests/auto/declarative/qdeclarativetext/data/alignments_rt.png
 create mode 100644 tests/auto/declarative/qdeclarativetextedit/data/alignments.qml
 create mode 100644 tests/auto/declarative/qdeclarativetextedit/data/alignments_cb.png
 create mode 100644 tests/auto/declarative/qdeclarativetextedit/data/alignments_cc.png
 create mode 100644 tests/auto/declarative/qdeclarativetextedit/data/alignments_ct.png
 create mode 100644 tests/auto/declarative/qdeclarativetextedit/data/alignments_lb.png
 create mode 100644 tests/auto/declarative/qdeclarativetextedit/data/alignments_lc.png
 create mode 100644 tests/auto/declarative/qdeclarativetextedit/data/alignments_lt.png
 create mode 100644 tests/auto/declarative/qdeclarativetextedit/data/alignments_rb.png
 create mode 100644 tests/auto/declarative/qdeclarativetextedit/data/alignments_rc.png
 create mode 100644 tests/auto/declarative/qdeclarativetextedit/data/alignments_rt.png

diff --git a/src/declarative/graphicsitems/qdeclarativepainteditem.cpp b/src/declarative/graphicsitems/qdeclarativepainteditem.cpp
index 13d1b61..3b9b8df 100644
--- a/src/declarative/graphicsitems/qdeclarativepainteditem.cpp
+++ b/src/declarative/graphicsitems/qdeclarativepainteditem.cpp
@@ -151,6 +151,7 @@ void QDeclarativePaintedItem::setContentsSize(const QSize &size)
 {
     Q_D(QDeclarativePaintedItem);
     if (d->contentsSize == size) return;
+    prepareGeometryChange();
     d->contentsSize = size;
     clearCache();
     update();
@@ -247,8 +248,7 @@ QRectF QDeclarativePaintedItem::boundingRect() const
 void QDeclarativePaintedItem::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWidget *)
 {
     Q_D(QDeclarativePaintedItem);
-    const QRect content(0,0,qCeil(d->contentsSize.width()*d->contentsScale),
-                            qCeil(d->contentsSize.height()*d->contentsScale));
+    const QRect content = boundingRect().toRect();
     if (content.width() <= 0 || content.height() <= 0)
         return;
 
diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp
index c2e0d67..2ba680d 100644
--- a/src/declarative/graphicsitems/qdeclarativetext.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetext.cpp
@@ -663,6 +663,71 @@ void QDeclarativeText::setElideMode(QDeclarativeText::TextElideMode mode)
     emit elideModeChanged(d->elideMode);
 }
 
+QRectF QDeclarativeText::boundingRect() const
+{
+    Q_D(const QDeclarativeText);
+
+    int w = width();
+    int h = height();
+
+    int x = 0;
+    int y = 0;
+
+    if (d->cache || d->style != Normal) {
+        switch (d->hAlign) {
+        case AlignLeft:
+            x = 0;
+            break;
+        case AlignRight:
+            x = w - d->imgCache.width();
+            break;
+        case AlignHCenter:
+            x = (w - d->imgCache.width()) / 2;
+            break;
+        }
+
+        switch (d->vAlign) {
+        case AlignTop:
+            y = 0;
+            break;
+        case AlignBottom:
+            y = h - d->imgCache.height();
+            break;
+        case AlignVCenter:
+            y = (h - d->imgCache.height()) / 2;
+            break;
+        }
+
+        return QRectF(x,y,d->imgCache.width(),d->imgCache.height());
+    } else {
+        switch (d->hAlign) {
+        case AlignLeft:
+            x = 0;
+            break;
+        case AlignRight:
+            x = w - d->cachedLayoutSize.width();
+            break;
+        case AlignHCenter:
+            x = (w - d->cachedLayoutSize.width()) / 2;
+            break;
+        }
+
+        switch (d->vAlign) {
+        case AlignTop:
+            y = 0;
+            break;
+        case AlignBottom:
+            y = h - d->cachedLayoutSize.height();
+            break;
+        case AlignVCenter:
+            y = (h - d->cachedLayoutSize.height()) / 2;
+            break;
+        }
+
+        return QRectF(x,y,d->cachedLayoutSize.width(),d->cachedLayoutSize.height());
+    }
+}
+
 void QDeclarativeText::geometryChanged(const QRectF &newGeometry,
                               const QRectF &oldGeometry)
 {
@@ -713,6 +778,7 @@ void QDeclarativeTextPrivate::updateLayout()
     }
 }
 
+
 void QDeclarativeTextPrivate::updateSize()
 {
     Q_Q(QDeclarativeText);
@@ -730,7 +796,10 @@ void QDeclarativeTextPrivate::updateSize()
         //setup instance of QTextLayout for all cases other than richtext
         if (!richText) {
             size = setupTextLayout(&layout);
-            cachedLayoutSize = size;
+            if (cachedLayoutSize != size) {
+                q->prepareGeometryChange();
+                cachedLayoutSize = size;
+            }
             dy -= size.height();
         } else {
             singleline = false; // richtext can't elide or be optimized for single-line case
@@ -744,7 +813,13 @@ void QDeclarativeTextPrivate::updateSize()
             else
                 doc->setTextWidth(doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug)
             dy -= (int)doc->size().height();
-            cachedLayoutSize = doc->size().toSize();
+                q->prepareGeometryChange();
+            QSize dsize = doc->size().toSize();
+            if (dsize != cachedLayoutSize) {
+                q->prepareGeometryChange();
+                cachedLayoutSize = dsize;
+            }
+            size = QSize(int(doc->idealWidth()),dsize.height());
         }
         int yoff = 0;
 
@@ -757,8 +832,8 @@ void QDeclarativeTextPrivate::updateSize()
         q->setBaselineOffset(fm.ascent() + yoff);
 
         //### need to comfirm cost of always setting these for richText
-        q->setImplicitWidth(richText ? (int)doc->idealWidth() : size.width());
-        q->setImplicitHeight(richText ? (int)doc->size().height() : size.height());
+        q->setImplicitWidth(size.width());
+        q->setImplicitHeight(size.height());
         emit q->paintedSizeChanged();
     } else {
         dirty = true;
@@ -813,6 +888,8 @@ void QDeclarativeTextPrivate::drawOutline()
     ppm.drawPixmap(pos, imgCache);
     ppm.end();
 
+    if (imgCache.size() != img.size())
+        q_func()->prepareGeometryChange();
     imgCache = img;
 }
 
@@ -831,6 +908,8 @@ void QDeclarativeTextPrivate::drawOutline(int yOffset)
     ppm.drawPixmap(pos, imgCache);
     ppm.end();
 
+    if (imgCache.size() != img.size())
+        q_func()->prepareGeometryChange();
     imgCache = img;
 }
 
@@ -955,18 +1034,21 @@ void QDeclarativeTextPrivate::checkImgCache()
         return;
 
     bool empty = text.isEmpty();
+    QPixmap newImgCache;
     if (empty) {
-        imgCache = QPixmap();
         imgStyleCache = QPixmap();
     } else if (richText) {
-        imgCache = richTextImage(false);
+        newImgCache = richTextImage(false);
         if (style != QDeclarativeText::Normal)
             imgStyleCache = richTextImage(true); //### should use styleColor
     } else {
-        imgCache = wrappedTextImage(false);
+        newImgCache = wrappedTextImage(false);
         if (style != QDeclarativeText::Normal)
             imgStyleCache = wrappedTextImage(true); //### should use styleColor
     }
+    if (imgCache.size() != newImgCache.size())
+        q_func()->prepareGeometryChange();
+    imgCache = newImgCache;
     if (!empty)
         switch (style) {
         case QDeclarativeText::Outline:
@@ -1031,35 +1113,7 @@ void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWid
         if (d->smooth)
             p->setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform, d->smooth);
 
-        int w = width();
-        int h = height();
-
-        int x = 0;
-        int y = 0;
-
-        switch (d->hAlign) {
-        case AlignLeft:
-            x = 0;
-            break;
-        case AlignRight:
-            x = w - d->imgCache.width();
-            break;
-        case AlignHCenter:
-            x = (w - d->imgCache.width()) / 2;
-            break;
-        }
-
-        switch (d->vAlign) {
-        case AlignTop:
-            y = 0;
-            break;
-        case AlignBottom:
-            y = h - d->imgCache.height();
-            break;
-        case AlignVCenter:
-            y = (h - d->imgCache.height()) / 2;
-            break;
-        }
+        QRect br = boundingRect().toRect();
 
         bool needClip = clip() && (d->imgCache.width() > width() ||
                                    d->imgCache.height() > height());
@@ -1068,7 +1122,7 @@ void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWid
             p->save();
             p->setClipRect(boundingRect(), Qt::IntersectClip);
         }
-        p->drawPixmap(x, y, d->imgCache);
+        p->drawPixmap(br.x(), br.y(), d->imgCache);
         if (needClip)
             p->restore();
 
@@ -1077,20 +1131,8 @@ void QDeclarativeText::paint(QPainter *p, const QStyleOptionGraphicsItem *, QWid
             p->setRenderHint(QPainter::SmoothPixmapTransform, oldSmooth);
         }
     } else {
-        int h = height();
-        int y = 0;
+        qreal y = boundingRect().y();
 
-        switch (d->vAlign) {
-        case AlignTop:
-            y = 0;
-            break;
-        case AlignBottom:
-            y = h - d->cachedLayoutSize.height();
-            break;
-        case AlignVCenter:
-            y = (h - d->cachedLayoutSize.height()) / 2;
-            break;
-        }
         bool needClip = !clip() && (d->cachedLayoutSize.width() > width() ||
                                     d->cachedLayoutSize.height() > height());
 
diff --git a/src/declarative/graphicsitems/qdeclarativetext_p.h b/src/declarative/graphicsitems/qdeclarativetext_p.h
index db21140..cd97df3 100644
--- a/src/declarative/graphicsitems/qdeclarativetext_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetext_p.h
@@ -143,6 +143,8 @@ public:
     qreal paintedWidth() const;
     qreal paintedHeight() const;
 
+    QRectF boundingRect() const;
+
 Q_SIGNALS:
     void textChanged(const QString &text);
     void linkActivated(const QString &link);
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
index 3106daf..7db21f2 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
@@ -1231,8 +1231,13 @@ void QDeclarativeTextEdit::updateImgCache(const QRectF &rf)
         r = QRect(0,0,INT_MAX,INT_MAX);
     } else {
         r = rf.toRect();
-        if (r != QRect(0,0,INT_MAX,INT_MAX)) // Don't translate "everything"
+        if (r.height() > INT_MAX/2) {
+            // Take care of overflow when translating "everything"
+            r.setTop(r.y() + d->yoff);
+            r.setBottom(INT_MAX/2);
+        } else {
             r = r.translated(0,d->yoff);
+        }
     }
     dirtyCache(r);
     emit update();
@@ -1327,6 +1332,14 @@ void QDeclarativeTextEdit::updateSelectionMarkers()
     }
 }
 
+QRectF QDeclarativeTextEdit::boundingRect() const
+{
+    Q_D(const QDeclarativeTextEdit);
+    QRectF r = QDeclarativePaintedItem::boundingRect();
+    return r.translated(0,d->yoff);
+}
+
+
 //### we should perhaps be a bit smarter here -- depending on what has changed, we shouldn't
 //    need to do all the calculations each time
 void QDeclarativeTextEdit::updateSize()
@@ -1341,13 +1354,20 @@ void QDeclarativeTextEdit::updateSize()
             d->document->setTextWidth(width());
         dy -= (int)d->document->size().height();
 
+        int nyoff;
         if (heightValid()) {
             if (d->vAlign == AlignBottom)
-                d->yoff = dy;
+                nyoff = dy;
             else if (d->vAlign == AlignVCenter)
-                d->yoff = dy/2;
+                nyoff = dy/2;
+            else
+                nyoff = 0;
         } else {
-            d->yoff = 0;
+            nyoff = 0;
+        }
+        if (nyoff != d->yoff) {
+            prepareGeometryChange();
+            d->yoff = nyoff;
         }
         setBaselineOffset(fm.ascent() + d->yoff + d->textMargin);
 
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p.h
index d08f607..a6dd4a4 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextedit_p.h
@@ -195,6 +195,8 @@ public:
     Q_INVOKABLE int positionAt(int x, int y) const;
     Q_INVOKABLE void moveCursorSelection(int pos);
 
+    QRectF boundingRect() const;
+
 Q_SIGNALS:
     void textChanged(const QString &);
     void paintedSizeChanged();
diff --git a/tests/auto/declarative/qdeclarativetext/data/alignments.qml b/tests/auto/declarative/qdeclarativetext/data/alignments.qml
new file mode 100644
index 0000000..6a98a4d
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativetext/data/alignments.qml
@@ -0,0 +1,42 @@
+import Qt 4.7
+
+Rectangle {
+    id: top
+    width: 70; height: 70;
+
+    property alias horizontalAlignment: t.horizontalAlignment
+    property alias verticalAlignment: t.verticalAlignment
+    property alias wrapMode: t.wrapMode
+    property alias running: timer.running
+    property string txt: "Test"
+
+    Rectangle {
+        anchors.centerIn: parent
+        width: 40
+        height: 40
+        color: "green"
+
+        Text {
+            id: t
+
+            anchors.fill: parent
+            font.pixelSize: 8
+            horizontalAlignment: TextEdit.AlignRight
+            verticalAlignment: TextEdit.AlignBottom
+            wrapMode: TextEdit.WordWrap
+            text: top.txt
+        }
+        Timer {
+            id: timer
+
+            interval: 1
+            running: true
+            repeat: true
+            onTriggered: {
+                top.txt = top.txt + "<br>more " + top.txt.length;
+                if (top.txt.length > 50)
+                    running = false
+            }
+        }
+    }
+}
diff --git a/tests/auto/declarative/qdeclarativetext/data/alignments_cb.png b/tests/auto/declarative/qdeclarativetext/data/alignments_cb.png
new file mode 100644
index 0000000..5cdb1e5
Binary files /dev/null and b/tests/auto/declarative/qdeclarativetext/data/alignments_cb.png differ
diff --git a/tests/auto/declarative/qdeclarativetext/data/alignments_cc.png b/tests/auto/declarative/qdeclarativetext/data/alignments_cc.png
new file mode 100644
index 0000000..6b6862c
Binary files /dev/null and b/tests/auto/declarative/qdeclarativetext/data/alignments_cc.png differ
diff --git a/tests/auto/declarative/qdeclarativetext/data/alignments_ct.png b/tests/auto/declarative/qdeclarativetext/data/alignments_ct.png
new file mode 100644
index 0000000..7bfd281
Binary files /dev/null and b/tests/auto/declarative/qdeclarativetext/data/alignments_ct.png differ
diff --git a/tests/auto/declarative/qdeclarativetext/data/alignments_lb.png b/tests/auto/declarative/qdeclarativetext/data/alignments_lb.png
new file mode 100644
index 0000000..a8c16a0
Binary files /dev/null and b/tests/auto/declarative/qdeclarativetext/data/alignments_lb.png differ
diff --git a/tests/auto/declarative/qdeclarativetext/data/alignments_lc.png b/tests/auto/declarative/qdeclarativetext/data/alignments_lc.png
new file mode 100644
index 0000000..1f6e28d
Binary files /dev/null and b/tests/auto/declarative/qdeclarativetext/data/alignments_lc.png differ
diff --git a/tests/auto/declarative/qdeclarativetext/data/alignments_lt.png b/tests/auto/declarative/qdeclarativetext/data/alignments_lt.png
new file mode 100644
index 0000000..e529880
Binary files /dev/null and b/tests/auto/declarative/qdeclarativetext/data/alignments_lt.png differ
diff --git a/tests/auto/declarative/qdeclarativetext/data/alignments_rb.png b/tests/auto/declarative/qdeclarativetext/data/alignments_rb.png
new file mode 100644
index 0000000..c1ce274
Binary files /dev/null and b/tests/auto/declarative/qdeclarativetext/data/alignments_rb.png differ
diff --git a/tests/auto/declarative/qdeclarativetext/data/alignments_rc.png b/tests/auto/declarative/qdeclarativetext/data/alignments_rc.png
new file mode 100644
index 0000000..4f8a4a7
Binary files /dev/null and b/tests/auto/declarative/qdeclarativetext/data/alignments_rc.png differ
diff --git a/tests/auto/declarative/qdeclarativetext/data/alignments_rt.png b/tests/auto/declarative/qdeclarativetext/data/alignments_rt.png
new file mode 100644
index 0000000..643bd18
Binary files /dev/null and b/tests/auto/declarative/qdeclarativetext/data/alignments_rt.png differ
diff --git a/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp b/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp
index 01120b1..91b3ca0 100644
--- a/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp
+++ b/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp
@@ -47,6 +47,7 @@
 #include <QFontMetrics>
 #include <QGraphicsSceneMouseEvent>
 #include <qmath.h>
+#include <QDeclarativeView>
 
 #include "../../../shared/util.h"
 #include "testhttpserver.h"
@@ -70,6 +71,9 @@ private slots:
     void elide();
     void textFormat();
 
+    void alignments_data();
+    void alignments();
+
     void embeddedImages_data();
     void embeddedImages();
 
@@ -108,6 +112,8 @@ private:
     QStringList colorStrings;
 
     QDeclarativeEngine engine;
+
+    QDeclarativeView *createView(const QString &filename);
 };
 
 tst_qdeclarativetext::tst_qdeclarativetext()
@@ -163,6 +169,14 @@ tst_qdeclarativetext::tst_qdeclarativetext()
     //
 }
 
+QDeclarativeView *tst_qdeclarativetext::createView(const QString &filename)
+{
+    QDeclarativeView *canvas = new QDeclarativeView(0);
+
+    canvas->setSource(QUrl::fromLocalFile(filename));
+    return canvas;
+}
+
 void tst_qdeclarativetext::text()
 {
     {
@@ -383,6 +397,58 @@ void tst_qdeclarativetext::textFormat()
     }
 }
 
+
+void tst_qdeclarativetext::alignments_data()
+{
+    QTest::addColumn<int>("hAlign");
+    QTest::addColumn<int>("vAlign");
+    QTest::addColumn<QString>("expectfile");
+
+    QTest::newRow("LT") << int(Qt::AlignLeft) << int(Qt::AlignTop) << SRCDIR "/data/alignments_lt.png";
+    QTest::newRow("RT") << int(Qt::AlignRight) << int(Qt::AlignTop) << SRCDIR "/data/alignments_rt.png";
+    QTest::newRow("CT") << int(Qt::AlignHCenter) << int(Qt::AlignTop) << SRCDIR "/data/alignments_ct.png";
+
+    QTest::newRow("LB") << int(Qt::AlignLeft) << int(Qt::AlignBottom) << SRCDIR "/data/alignments_lb.png";
+    QTest::newRow("RB") << int(Qt::AlignRight) << int(Qt::AlignBottom) << SRCDIR "/data/alignments_rb.png";
+    QTest::newRow("CB") << int(Qt::AlignHCenter) << int(Qt::AlignBottom) << SRCDIR "/data/alignments_cb.png";
+
+    QTest::newRow("LC") << int(Qt::AlignLeft) << int(Qt::AlignVCenter) << SRCDIR "/data/alignments_lc.png";
+    QTest::newRow("RC") << int(Qt::AlignRight) << int(Qt::AlignVCenter) << SRCDIR "/data/alignments_rc.png";
+    QTest::newRow("CC") << int(Qt::AlignHCenter) << int(Qt::AlignVCenter) << SRCDIR "/data/alignments_cc.png";
+}
+
+
+void tst_qdeclarativetext::alignments()
+{
+    QFETCH(int, hAlign);
+    QFETCH(int, vAlign);
+    QFETCH(QString, expectfile);
+
+    QDeclarativeView *canvas = createView(SRCDIR "/data/alignments.qml");
+
+    canvas->show();
+    QApplication::setActiveWindow(canvas);
+    QTest::qWaitForWindowShown(canvas);
+    QTRY_COMPARE(QApplication::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);
+
+#ifdef Q_OS_LINUX
+    // Font-specific, but not likely platform-specific, so only test on one platform
+    QCOMPARE(actual,expect);
+#endif
+}
+
 //the alignment tests may be trivial o.oa
 void tst_qdeclarativetext::horizontalAlignment()
 {
diff --git a/tests/auto/declarative/qdeclarativetextedit/data/alignments.qml b/tests/auto/declarative/qdeclarativetextedit/data/alignments.qml
new file mode 100644
index 0000000..6a98a4d
--- /dev/null
+++ b/tests/auto/declarative/qdeclarativetextedit/data/alignments.qml
@@ -0,0 +1,42 @@
+import Qt 4.7
+
+Rectangle {
+    id: top
+    width: 70; height: 70;
+
+    property alias horizontalAlignment: t.horizontalAlignment
+    property alias verticalAlignment: t.verticalAlignment
+    property alias wrapMode: t.wrapMode
+    property alias running: timer.running
+    property string txt: "Test"
+
+    Rectangle {
+        anchors.centerIn: parent
+        width: 40
+        height: 40
+        color: "green"
+
+        Text {
+            id: t
+
+            anchors.fill: parent
+            font.pixelSize: 8
+            horizontalAlignment: TextEdit.AlignRight
+            verticalAlignment: TextEdit.AlignBottom
+            wrapMode: TextEdit.WordWrap
+            text: top.txt
+        }
+        Timer {
+            id: timer
+
+            interval: 1
+            running: true
+            repeat: true
+            onTriggered: {
+                top.txt = top.txt + "<br>more " + top.txt.length;
+                if (top.txt.length > 50)
+                    running = false
+            }
+        }
+    }
+}
diff --git a/tests/auto/declarative/qdeclarativetextedit/data/alignments_cb.png b/tests/auto/declarative/qdeclarativetextedit/data/alignments_cb.png
new file mode 100644
index 0000000..0e40444
Binary files /dev/null and b/tests/auto/declarative/qdeclarativetextedit/data/alignments_cb.png differ
diff --git a/tests/auto/declarative/qdeclarativetextedit/data/alignments_cc.png b/tests/auto/declarative/qdeclarativetextedit/data/alignments_cc.png
new file mode 100644
index 0000000..a5c83a8
Binary files /dev/null and b/tests/auto/declarative/qdeclarativetextedit/data/alignments_cc.png differ
diff --git a/tests/auto/declarative/qdeclarativetextedit/data/alignments_ct.png b/tests/auto/declarative/qdeclarativetextedit/data/alignments_ct.png
new file mode 100644
index 0000000..8177c20
Binary files /dev/null and b/tests/auto/declarative/qdeclarativetextedit/data/alignments_ct.png differ
diff --git a/tests/auto/declarative/qdeclarativetextedit/data/alignments_lb.png b/tests/auto/declarative/qdeclarativetextedit/data/alignments_lb.png
new file mode 100644
index 0000000..c0e1774
Binary files /dev/null and b/tests/auto/declarative/qdeclarativetextedit/data/alignments_lb.png differ
diff --git a/tests/auto/declarative/qdeclarativetextedit/data/alignments_lc.png b/tests/auto/declarative/qdeclarativetextedit/data/alignments_lc.png
new file mode 100644
index 0000000..d61aaf2
Binary files /dev/null and b/tests/auto/declarative/qdeclarativetextedit/data/alignments_lc.png differ
diff --git a/tests/auto/declarative/qdeclarativetextedit/data/alignments_lt.png b/tests/auto/declarative/qdeclarativetextedit/data/alignments_lt.png
new file mode 100644
index 0000000..599f4c6
Binary files /dev/null and b/tests/auto/declarative/qdeclarativetextedit/data/alignments_lt.png differ
diff --git a/tests/auto/declarative/qdeclarativetextedit/data/alignments_rb.png b/tests/auto/declarative/qdeclarativetextedit/data/alignments_rb.png
new file mode 100644
index 0000000..83ec990
Binary files /dev/null and b/tests/auto/declarative/qdeclarativetextedit/data/alignments_rb.png differ
diff --git a/tests/auto/declarative/qdeclarativetextedit/data/alignments_rc.png b/tests/auto/declarative/qdeclarativetextedit/data/alignments_rc.png
new file mode 100644
index 0000000..53e30b7
Binary files /dev/null and b/tests/auto/declarative/qdeclarativetextedit/data/alignments_rc.png differ
diff --git a/tests/auto/declarative/qdeclarativetextedit/data/alignments_rt.png b/tests/auto/declarative/qdeclarativetextedit/data/alignments_rt.png
new file mode 100644
index 0000000..61a112f
Binary files /dev/null and b/tests/auto/declarative/qdeclarativetextedit/data/alignments_rt.png differ
diff --git a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
index f7ba7a1..009d354 100644
--- a/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
+++ b/tests/auto/declarative/qdeclarativetextedit/tst_qdeclarativetextedit.cpp
@@ -73,6 +73,8 @@ private slots:
     void width();
     void wrap();
     void textFormat();
+    void alignments();
+    void alignments_data();
 
     // ### these tests may be trivial    
     void hAlign();
@@ -297,6 +299,58 @@ void tst_qdeclarativetextedit::textFormat()
     }
 }
 
+void tst_qdeclarativetextedit::alignments_data()
+{
+    QTest::addColumn<int>("hAlign");
+    QTest::addColumn<int>("vAlign");
+    QTest::addColumn<QString>("expectfile");
+
+    QTest::newRow("LT") << int(Qt::AlignLeft) << int(Qt::AlignTop) << SRCDIR "/data/alignments_lt.png";
+    QTest::newRow("RT") << int(Qt::AlignRight) << int(Qt::AlignTop) << SRCDIR "/data/alignments_rt.png";
+    QTest::newRow("CT") << int(Qt::AlignHCenter) << int(Qt::AlignTop) << SRCDIR "/data/alignments_ct.png";
+
+    QTest::newRow("LB") << int(Qt::AlignLeft) << int(Qt::AlignBottom) << SRCDIR "/data/alignments_lb.png";
+    QTest::newRow("RB") << int(Qt::AlignRight) << int(Qt::AlignBottom) << SRCDIR "/data/alignments_rb.png";
+    QTest::newRow("CB") << int(Qt::AlignHCenter) << int(Qt::AlignBottom) << SRCDIR "/data/alignments_cb.png";
+
+    QTest::newRow("LC") << int(Qt::AlignLeft) << int(Qt::AlignVCenter) << SRCDIR "/data/alignments_lc.png";
+    QTest::newRow("RC") << int(Qt::AlignRight) << int(Qt::AlignVCenter) << SRCDIR "/data/alignments_rc.png";
+    QTest::newRow("CC") << int(Qt::AlignHCenter) << int(Qt::AlignVCenter) << SRCDIR "/data/alignments_cc.png";
+}
+
+
+void tst_qdeclarativetextedit::alignments()
+{
+    QFETCH(int, hAlign);
+    QFETCH(int, vAlign);
+    QFETCH(QString, expectfile);
+
+    QDeclarativeView *canvas = createView(SRCDIR "/data/alignments.qml");
+
+    canvas->show();
+    QApplication::setActiveWindow(canvas);
+    QTest::qWaitForWindowShown(canvas);
+    QTRY_COMPARE(QApplication::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);
+
+#ifdef Q_OS_LINUX
+    // Font-specific, but not likely platform-specific, so only test on one platform
+    QCOMPARE(actual,expect);
+#endif
+}
+
+
 //the alignment tests may be trivial o.oa
 void tst_qdeclarativetextedit::hAlign()
 {
-- 
cgit v0.12