summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Jones <martin.jones@nokia.com>2011-03-04 04:33:30 (GMT)
committerMartin Jones <martin.jones@nokia.com>2011-03-04 07:00:44 (GMT)
commit7cdd849b50f0314d0eb227e1d0c92627f2be555b (patch)
tree7afd7de1664dad1db3898a749c9ea8eda1a53fbf
parent9f674617daf03026d78f8ce18328cbe6c31b689d (diff)
downloadQt-7cdd849b50f0314d0eb227e1d0c92627f2be555b.zip
Qt-7cdd849b50f0314d0eb227e1d0c92627f2be555b.tar.gz
Qt-7cdd849b50f0314d0eb227e1d0c92627f2be555b.tar.bz2
Fix RTL multiline Text drawing
We handled horizontal alignment ourselves, but this neglected some RTL layouting issues (e.g. trailing spaces). Allow QTextLayout to do the aligning for us. Also fix eliding of multiline text for RTL language - in this case the eliding should be to the left. Change-Id: I487137b123ae66c1f5fc358a8d8a013049d05818 Reviewed-by: Joona Petrell
-rw-r--r--src/declarative/graphicsitems/qdeclarativetext.cpp75
-rw-r--r--tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp12
2 files changed, 26 insertions, 61 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativetext.cpp b/src/declarative/graphicsitems/qdeclarativetext.cpp
index 3988f7f..890e481 100644
--- a/src/declarative/graphicsitems/qdeclarativetext.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetext.cpp
@@ -364,19 +364,16 @@ QSize QDeclarativeTextPrivate::setupTextLayout()
Q_Q(QDeclarativeText);
layout.setCacheEnabled(true);
- qreal height = 0;
qreal widthUsed = 0;
qreal lineWidth = 0;
- int visibleTextLength = 0;
int visibleCount = 0;
//set manual width
- if ((wrapMode != QDeclarativeText::NoWrap || elideMode != QDeclarativeText::ElideNone) && q->widthValid())
+ if (q->widthValid())
lineWidth = q->width();
QTextOption textOption = layout.textOption();
- if (hAlign == QDeclarativeText::AlignJustify)
- textOption.setAlignment(Qt::Alignment(hAlign));
+ textOption.setAlignment(Qt::Alignment(hAlign));
textOption.setWrapMode(QTextOption::WrapMode(wrapMode));
layout.setTextOption(textOption);
@@ -384,7 +381,6 @@ QSize QDeclarativeTextPrivate::setupTextLayout()
bool truncate = false;
QFontMetrics fm(layout.font());
- qreal elideWidth = fm.width(elideChar);
elidePos = QPointF();
if (requireImplicitWidth && q->widthValid()) {
@@ -407,36 +403,35 @@ QSize QDeclarativeTextPrivate::setupTextLayout()
layout.beginLayout();
if (!lineWidth)
lineWidth = INT_MAX;
- int y = 0;
int linesLeft = maximumLineCount;
+ int visibleTextLength = 0;
while (linesLeft > 0) {
QTextLine line = layout.createLine();
if (!line.isValid())
break;
visibleCount++;
- line.setLineWidth(lineWidth);
+ if (lineWidth)
+ line.setLineWidth(lineWidth);
visibleTextLength += line.textLength();
if (--linesLeft == 0) {
if (visibleTextLength < text.length()) {
truncate = true;
if (elideMode==QDeclarativeText::ElideRight && q->widthValid()) {
+ qreal elideWidth = fm.width(elideChar);
// Need to correct for alignment
line.setLineWidth(lineWidth-elideWidth);
- int x = line.naturalTextWidth();
- if (hAlign == QDeclarativeText::AlignRight) {
- x = q->width()-elideWidth;
- } else if (hAlign == QDeclarativeText::AlignHCenter) {
- x = (q->width()+line.naturalTextWidth() - elideWidth)/2;
+ if (layout.text().mid(line.textStart(), line.textLength()).isRightToLeft()) {
+ line.setPosition(QPointF(line.position().x() + elideWidth, line.position().y()));
+ elidePos.setX(line.naturalTextRect().left() - elideWidth);
+ } else {
+ elidePos.setX(line.naturalTextRect().right());
}
- elidePos = QPointF(x, y + fm.ascent());
elideText = true;
}
}
}
-
- y += line.height();
}
layout.endLayout();
@@ -458,36 +453,20 @@ QSize QDeclarativeTextPrivate::setupTextLayout()
layout.endLayout();
}
+ qreal height = 0;
for (int i = 0; i < layout.lineCount(); ++i) {
QTextLine line = layout.lineAt(i);
- widthUsed = qMax(widthUsed, line.naturalTextWidth());
+ // calc width
+ widthUsed = qMax(widthUsed, line.naturalTextRect().right());
+ // set line spacing
+ line.setPosition(QPointF(line.position().x(), height));
+ if (elideText && i == layout.lineCount()-1)
+ elidePos.setY(height + fm.ascent());
+ height += (lineHeightMode == QDeclarativeText::FixedHeight) ? lineHeight : line.height() * lineHeight;
}
- qreal layoutWidth = q->widthValid() ? q->width() : widthUsed;
if (!q->widthValid())
- naturalWidth = layoutWidth;
-
- qreal x = 0;
- for (int i = 0; i < layout.lineCount(); ++i) {
- QTextLine line = layout.lineAt(i);
- line.setPosition(QPointF(0, height));
- height += (lineHeightMode == QDeclarativeText::FixedHeight) ? lineHeight : line.height() * lineHeight;
-
- if (!cacheAllTextAsImage) {
- if ((hAlign == QDeclarativeText::AlignLeft) || (hAlign == QDeclarativeText::AlignJustify)) {
- x = 0;
- } else if (hAlign == QDeclarativeText::AlignRight) {
- x = layoutWidth - line.naturalTextWidth();
- if (elideText && i == layout.lineCount()-1)
- x -= elideWidth; // Correct for when eliding multilines
- } else if (hAlign == QDeclarativeText::AlignHCenter) {
- x = (layoutWidth - line.naturalTextWidth()) / 2;
- if (elideText && i == layout.lineCount()-1)
- x -= elideWidth/2; // Correct for when eliding multilines
- }
- line.setPosition(QPointF(x, line.y()));
- }
- }
+ naturalWidth = widthUsed;
//Update the number of visible lines
if (lineCount != visibleCount) {
@@ -506,20 +485,6 @@ QPixmap QDeclarativeTextPrivate::textLayoutImage(bool drawStyle)
{
//do layout
QSize size = layedOutTextSize;
-
- qreal x = 0;
- for (int i = 0; i < layout.lineCount(); ++i) {
- QTextLine line = layout.lineAt(i);
- if ((hAlign == QDeclarativeText::AlignLeft) || (hAlign == QDeclarativeText::AlignJustify)) {
- x = 0;
- } else if (hAlign == QDeclarativeText::AlignRight) {
- x = size.width() - line.naturalTextWidth();
- } else if (hAlign == QDeclarativeText::AlignHCenter) {
- x = (size.width() - line.naturalTextWidth()) / 2;
- }
- line.setPosition(QPointF(x, line.y()));
- }
-
//paint text
QPixmap img(size);
if (!size.isEmpty()) {
diff --git a/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp b/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp
index 2aeb425..f27fc07 100644
--- a/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp
+++ b/tests/auto/declarative/qdeclarativetext/tst_qdeclarativetext.cpp
@@ -520,32 +520,32 @@ void tst_qdeclarativetext::horizontalAlignment_RightToLeft()
// implicit alignment should follow the reading direction of RTL text
QCOMPARE(text->hAlign(), QDeclarativeText::AlignRight);
- QVERIFY(textPrivate->layout.lineAt(0).x() > canvas->width()/2);
+ QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
// explicitly left aligned
text->setHAlign(QDeclarativeText::AlignLeft);
QCOMPARE(text->hAlign(), QDeclarativeText::AlignLeft);
- QVERIFY(textPrivate->layout.lineAt(0).x() < canvas->width()/2);
+ QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
// explicitly right aligned
text->setHAlign(QDeclarativeText::AlignRight);
QCOMPARE(text->hAlign(), QDeclarativeText::AlignRight);
- QVERIFY(textPrivate->layout.lineAt(0).x() > canvas->width()/2);
+ QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
// explicitly center aligned
text->setHAlign(QDeclarativeText::AlignHCenter);
QCOMPARE(text->hAlign(), QDeclarativeText::AlignHCenter);
- QVERIFY(textPrivate->layout.lineAt(0).x() < canvas->width()/2);
+ QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
// reseted alignment should go back to following the text reading direction
text->resetHAlign();
QCOMPARE(text->hAlign(), QDeclarativeText::AlignRight);
- QVERIFY(textPrivate->layout.lineAt(0).x() > canvas->width()/2);
+ QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() > canvas->width()/2);
// English text should be implicitly left aligned
text->setText("Hello world!");
QCOMPARE(text->hAlign(), QDeclarativeText::AlignLeft);
- QVERIFY(textPrivate->layout.lineAt(0).x() < canvas->width()/2);
+ QVERIFY(textPrivate->layout.lineAt(0).naturalTextRect().left() < canvas->width()/2);
// empty text is also implicitly left aligned
text->setText("");