diff options
-rw-r--r-- | src/gui/text/qtextlayout.cpp | 35 | ||||
-rw-r--r-- | tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp | 54 |
2 files changed, 63 insertions, 26 deletions
diff --git a/src/gui/text/qtextlayout.cpp b/src/gui/text/qtextlayout.cpp index 5b9c10ee52..845642bb6e 100644 --- a/src/gui/text/qtextlayout.cpp +++ b/src/gui/text/qtextlayout.cpp @@ -2909,18 +2909,10 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const bool visual = eng->visualCursorMovement(); if (x <= 0) { // left of first item - int item = visualOrder[0]+firstItem; - QScriptItem &si = eng->layoutData->items[item]; - if (!si.num_glyphs) - eng->shape(item); - int pos = si.position; - if (si.analysis.bidiLevel % 2) - pos += eng->length(item); - pos = qMax(line.from, pos); - pos = qMin(line.from + line_length, pos); - return pos; - } else if (x < line.textWidth - || (line.justified && x < line.width)) { + if (eng->isRightToLeft()) + return line.from + line_length; + return line.from; + } else if (x < line.textWidth || (line.justified && x < line.width)) { // has to be in one of the runs QFixed pos; bool rtl = eng->isRightToLeft(); @@ -3070,26 +3062,17 @@ int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const } } // right of last item -// qDebug("right of last"); - int item = visualOrder[nItems-1]+firstItem; - QScriptItem &si = eng->layoutData->items[item]; - if (!si.num_glyphs) - eng->shape(item); - int pos = si.position; - if (!(si.analysis.bidiLevel % 2)) - pos += eng->length(item); - pos = qMax(line.from, pos); - - int maxPos = line.from + line_length; + int pos = line.from; + if (!eng->isRightToLeft()) + pos += line_length; // except for the last line we assume that the // character between lines is a space and we want // to position the cursor to the left of that // character. - if (this->index < eng->lines.count() - 1) - maxPos = eng->previousLogicalPosition(maxPos); + if (index < eng->lines.count() - 1) + pos = qMin(eng->previousLogicalPosition(pos), pos); - pos = qMin(pos, maxPos); return pos; } diff --git a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp index 4b8ba98d04..a4c848c1ec 100644 --- a/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp +++ b/tests/auto/gui/text/qtextlayout/tst_qtextlayout.cpp @@ -68,11 +68,13 @@ private slots: void forcedBreaks(); void breakAny(); void noWrap(); + void cursorToXForInlineObjects(); void cursorToXForSetColumns(); void cursorToXForTrailingSpaces_data(); void cursorToXForTrailingSpaces(); void cursorToXInvalidInput(); + void horizontalAlignment_data(); void horizontalAlignment(); void horizontalAlignmentMultiline_data(); @@ -86,6 +88,8 @@ private slots: #ifdef QT_BUILD_INTERNAL void xToCursorAtEndOfLine(); #endif + void xToCursorForBidiEnds_data(); + void xToCursorForBidiEnds(); void boundingRectTopLeft(); void graphemeBoundaryForSurrogatePairs(); void tabStops(); @@ -1126,6 +1130,56 @@ void tst_QTextLayout::xToCursorAtEndOfLine() } #endif + +void tst_QTextLayout::xToCursorForBidiEnds_data() +{ + QTest::addColumn<Qt::LayoutDirection>("textDirection"); + QTest::addColumn<QString>("text"); + QTest::addColumn<int>("leftPosition"); + QTest::addColumn<int>("rightPosition"); + + QTest::addRow("LTR, abcشزذ") << Qt::LeftToRight << "abcشزذ" + << 0 << 6; + QTest::addRow("RTL, abcشزذ") << Qt::RightToLeft << "abcشزذ" + << 6 << 0; + QTest::addRow("LTR, شزذabc") << Qt::LeftToRight << "شزذabc" + << 0 << 6; + QTest::addRow("RTL, شزذabc") << Qt::RightToLeft << "شزذabc" + << 6 << 0; + + QTest::addRow("LTR, abcشزذabc") << Qt::LeftToRight << "abcشزذabc" + << 0 << 9; + QTest::addRow("RTL, abcشزذabc") << Qt::RightToLeft << "abcشزذabc" + << 9 << 0; + QTest::addRow("LTR, شزذabcشزذ") << Qt::LeftToRight << "شزذabcشزذ" + << 0 << 9; + QTest::addRow("RTL, شزذabcشزذ") << Qt::RightToLeft << "شزذabcشزذ" + << 9 << 0; +} + +void tst_QTextLayout::xToCursorForBidiEnds() +{ + QFETCH(Qt::LayoutDirection, textDirection); + QFETCH(QString, text); + QFETCH(int, leftPosition); + QFETCH(int, rightPosition); + + QTextOption option; + option.setTextDirection(textDirection); + + QTextLayout layout(text, testFont); + layout.setTextOption(option); + layout.beginLayout(); + + QTextLine line = layout.createLine(); + line.setLineWidth(0x10000); + + QCOMPARE(line.xToCursor(0), leftPosition); + QCOMPARE(line.xToCursor(line.width()), rightPosition); + + layout.endLayout(); +} + void tst_QTextLayout::boundingRectTopLeft() { QString text = "FirstLine\nSecondLine"; |