Fix horizontal alignment bug with rich text
authorYann Bodson <yann.bodson@nokia.com>
Mon, 26 Mar 2012 06:04:52 +0000 (16:04 +1000)
committerQt by Nokia <qt-info@nokia.com>
Mon, 26 Mar 2012 07:25:32 +0000 (09:25 +0200)
Task-number: QTBUG-21473
Change-Id: I3542d7fb49ec1ea370709c799167ec01cf5ed19c
Reviewed-by: Andrew den Exter <andrew.den-exter@nokia.com>
src/quick/items/qquicktext.cpp
tests/auto/quick/qquicktext/tst_qquicktext.cpp

index d730335..e1a28a4 100644 (file)
@@ -402,7 +402,7 @@ void QQuickTextPrivate::updateSize()
     if (text.isEmpty()) {
         qreal fontHeight = fm.height();
         q->setImplicitSize(0, fontHeight);
-        layedOutTextRect = QRect(0, 0, 0, fontHeight);
+        layedOutTextRect = QRectF(0, 0, 0, fontHeight);
         emit q->contentSizeChanged();
         updateType = UpdatePaintNode;
         q->update();
@@ -2001,7 +2001,20 @@ QRectF QQuickText::boundingRect() const
 
     // Could include font max left/right bearings to either side of rectangle.
 
-    int h = height();
+    qreal w = width();
+    switch (d->hAlign) {
+    case AlignLeft:
+    case AlignJustify:
+        break;
+    case AlignRight:
+        rect.moveLeft(w - rect.width());
+        break;
+    case AlignHCenter:
+        rect.moveLeft((w - rect.width()) / 2);
+        break;
+    }
+
+    qreal h = height();
     switch (d->vAlign) {
     case AlignTop:
         break;
index 81020ad..5d7d602 100644 (file)
@@ -110,6 +110,8 @@ private slots:
     void implicitSizeBinding_data();
     void implicitSizeBinding();
 
+    void boundingRect_data();
+    void boundingRect();
     void lineLaidOut();
 
     void imgTagsBaseUrl_data();
@@ -1669,6 +1671,80 @@ void tst_qquicktext::implicitSizeBinding()
     QCOMPARE(textObject->height(), textObject->implicitHeight());
 }
 
+void tst_qquicktext::boundingRect_data()
+{
+    QTest::addColumn<QString>("format");
+    QTest::newRow("PlainText") << "Text.PlainText";
+    QTest::newRow("StyledText") << "Text.StyledText";
+    QTest::newRow("RichText") << "Text.RichText";
+}
+
+void tst_qquicktext::boundingRect()
+{
+    QFETCH(QString, format);
+
+    QDeclarativeComponent component(&engine);
+    component.setData("import QtQuick 2.0\n Text { textFormat:" + format.toUtf8() + "}", QUrl());
+    QScopedPointer<QObject> object(component.create());
+    QQuickText *text = qobject_cast<QQuickText *>(object.data());
+    QVERIFY(text);
+
+    QCOMPARE(text->boundingRect().x(), qreal(0));
+    QCOMPARE(text->boundingRect().y(), qreal(0));
+    QCOMPARE(text->boundingRect().width(), qreal(0));
+    QCOMPARE(text->boundingRect().height(), QFontMetricsF(text->font()).height());
+
+    text->setText("Hello World");
+
+    QTextLayout layout(text->text());
+    layout.setFont(text->font());
+
+    if (!qmlDisableDistanceField()) {
+        QTextOption option;
+        option.setUseDesignMetrics(true);
+        layout.setTextOption(option);
+    }
+    layout.beginLayout();
+    QTextLine line = layout.createLine();
+    layout.endLayout();
+
+    QCOMPARE(text->boundingRect().x(), qreal(0));
+    QCOMPARE(text->boundingRect().y(), qreal(0));
+    QCOMPARE(text->boundingRect().width(), line.naturalTextWidth());
+    QCOMPARE(text->boundingRect().height(), line.height());
+
+    // the size of the bounding rect shouldn't be bounded by the size of item.
+    text->setWidth(text->width() / 2);
+    QCOMPARE(text->boundingRect().x(), qreal(0));
+    QCOMPARE(text->boundingRect().y(), qreal(0));
+    QCOMPARE(text->boundingRect().width(), line.naturalTextWidth());
+    QCOMPARE(text->boundingRect().height(), line.height());
+
+    text->setHeight(text->height() * 2);
+    QCOMPARE(text->boundingRect().x(), qreal(0));
+    QCOMPARE(text->boundingRect().y(), qreal(0));
+    QCOMPARE(text->boundingRect().width(), line.naturalTextWidth());
+    QCOMPARE(text->boundingRect().height(), line.height());
+
+    text->setHAlign(QQuickText::AlignRight);
+    QCOMPARE(text->boundingRect().x(), text->width() - line.naturalTextWidth());
+    QCOMPARE(text->boundingRect().y(), qreal(0));
+    QCOMPARE(text->boundingRect().width(), line.naturalTextWidth());
+    QCOMPARE(text->boundingRect().height(), line.height());
+
+    text->setWrapMode(QQuickText::Wrap);
+    QCOMPARE(text->boundingRect().right(), text->width());
+    QCOMPARE(text->boundingRect().y(), qreal(0));
+    QVERIFY(text->boundingRect().width() < line.naturalTextWidth());
+    QVERIFY(text->boundingRect().height() > line.height());
+
+    text->setVAlign(QQuickText::AlignBottom);
+    QCOMPARE(text->boundingRect().right(), text->width());
+    QCOMPARE(text->boundingRect().bottom(), text->height());
+    QVERIFY(text->boundingRect().width() < line.naturalTextWidth());
+    QVERIFY(text->boundingRect().height() > line.height());
+}
+
 void tst_qquicktext::lineLaidOut()
 {
     QQuickView *canvas = createView(testFile("lineLayout.qml"));