From 5fee1e79cc1c18acf58f9171a73a7525154a65cd Mon Sep 17 00:00:00 2001 From: Andrew den Exter Date: Thu, 23 Feb 2012 14:11:48 +1000 Subject: [PATCH] Use floating point types for position offsets and cursorRectangle. Rounding to align painting to pixel boundaries is no longer necessary are largely removed. Correct the few instances remaining in TextEdit and TextInput. Change-Id: Ic6ec57092d74ec43b23d85cd8868e0190acc3e09 Reviewed-by: Yann Bodson --- src/quick/items/qquicktextedit.cpp | 22 +++--- src/quick/items/qquicktextedit_p.h | 6 +- src/quick/items/qquicktextedit_p_p.h | 8 +- src/quick/items/qquicktextinput.cpp | 42 +++++------ src/quick/items/qquicktextinput_p.h | 4 +- src/quick/items/qquicktextinput_p_p.h | 13 ++-- .../qtquick2/qquicktextedit/tst_qquicktextedit.cpp | 38 +++++----- .../qquicktextinput/tst_qquicktextinput.cpp | 77 ++++++++++---------- 8 files changed, 102 insertions(+), 108 deletions(-) diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index 0626471..66285fc 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -732,10 +732,10 @@ QRectF QQuickTextEdit::positionToRectangle(int pos) const Position 0 is before the first character, position 1 is after the first character but before the second, and so on until position \l {text}.length, which is after all characters. */ -int QQuickTextEdit::positionAt(int x, int y) const +int QQuickTextEdit::positionAt(qreal x, qreal y) const { Q_D(const QQuickTextEdit); - int r = d->document->documentLayout()->hitTest(QPoint(x,y-d->yoff), Qt::FuzzyHit); + int r = d->document->documentLayout()->hitTest(QPointF(x,y-d->yoff), Qt::FuzzyHit); QTextCursor cursor = d->control->textCursor(); if (r > cursor.position()) { // The cursor position includes positions within the preedit text, but only positions in the @@ -1290,10 +1290,10 @@ Qt::TextInteractionFlags QQuickTextEdit::textInteractionFlags() const automatically when it changes. The width of the delegate is unaffected by changes in the cursor rectangle. */ -QRect QQuickTextEdit::cursorRectangle() const +QRectF QQuickTextEdit::cursorRectangle() const { Q_D(const QQuickTextEdit); - return d->control->cursorRect().toRect().translated(0,d->yoff); + return d->control->cursorRect().translated(0, d->yoff); } bool QQuickTextEdit::event(QEvent *event) @@ -1863,11 +1863,11 @@ void QQuickTextEdit::updateSize() } else { d->document->setTextWidth(-1); } - QFontMetrics fm = QFontMetrics(d->font); - int dy = height(); - dy -= (int)d->document->size().height(); + QFontMetricsF fm(d->font); + qreal dy = height(); + dy -= d->document->size().height(); - int nyoff; + qreal nyoff; if (heightValid()) { if (d->vAlign == AlignBottom) nyoff = dy; @@ -1883,7 +1883,7 @@ void QQuickTextEdit::updateSize() setBaselineOffset(fm.ascent() + d->yoff + d->textMargin); //### need to comfirm cost of always setting these - int newWidth = qCeil(d->document->idealWidth()); + qreal newWidth = d->document->idealWidth(); if (!widthValid() && d->document->textWidth() != newWidth) d->document->setTextWidth(newWidth); // ### Text does not align if width is not set (QTextDoc bug) // ### Setting the implicitWidth triggers another updateSize(), and unless there are bindings nothing has changed. @@ -1892,13 +1892,13 @@ void QQuickTextEdit::updateSize() iWidth = newWidth; else if (d->requireImplicitWidth) iWidth = naturalWidth; - qreal newHeight = d->document->isEmpty() ? fm.height() : (int)d->document->size().height(); + qreal newHeight = d->document->isEmpty() ? fm.height() : d->document->size().height(); if (iWidth > -1) setImplicitSize(iWidth, newHeight); else setImplicitHeight(newHeight); - QSize size(newWidth, newHeight); + QSizeF size(newWidth, newHeight); if (d->contentSize != size) { d->contentSize = size; emit contentSizeChanged(); diff --git a/src/quick/items/qquicktextedit_p.h b/src/quick/items/qquicktextedit_p.h index 5f6317a..b3fd32a 100644 --- a/src/quick/items/qquicktextedit_p.h +++ b/src/quick/items/qquicktextedit_p.h @@ -79,7 +79,7 @@ class Q_AUTOTEST_EXPORT QQuickTextEdit : public QQuickImplicitSizeItem Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged) Q_PROPERTY(bool cursorVisible READ isCursorVisible WRITE setCursorVisible NOTIFY cursorVisibleChanged) Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged) - Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged) + Q_PROPERTY(QRectF cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged) Q_PROPERTY(QDeclarativeComponent* cursorDelegate READ cursorDelegate WRITE setCursorDelegate NOTIFY cursorDelegateChanged) Q_PROPERTY(int selectionStart READ selectionStart NOTIFY selectionStartChanged) Q_PROPERTY(int selectionEnd READ selectionEnd NOTIFY selectionEndChanged) @@ -212,7 +212,7 @@ public: void setTextInteractionFlags(Qt::TextInteractionFlags flags); Qt::TextInteractionFlags textInteractionFlags() const; - QRect cursorRectangle() const; + QRectF cursorRectangle() const; QVariant inputMethodQuery(Qt::InputMethodQuery property) const; @@ -224,7 +224,7 @@ public: void resetBaseUrl(); Q_INVOKABLE QRectF positionToRectangle(int) const; - Q_INVOKABLE int positionAt(int x, int y) const; + Q_INVOKABLE int positionAt(qreal x, qreal y) const; Q_INVOKABLE void moveCursorSelection(int pos); Q_INVOKABLE void moveCursorSelection(int pos, SelectionMode mode); diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h index 1497c20..8ec589d 100644 --- a/src/quick/items/qquicktextedit_p_p.h +++ b/src/quick/items/qquicktextedit_p_p.h @@ -69,8 +69,8 @@ class QQuickTextEditPrivate : public QQuickImplicitSizeItemPrivate public: QQuickTextEditPrivate() : color(QRgb(0xFF000000)), selectionColor(QRgb(0xFF000080)), selectedTextColor(QRgb(0xFFFFFFFF)) - , textMargin(0.0), font(sourceFont), cursorComponent(0), cursor(0), document(0), control(0) - , lastSelectionStart(0), lastSelectionEnd(0), lineCount(0), yoff(0) + , textMargin(0.0), yoff(0), font(sourceFont), cursorComponent(0), cursor(0), document(0), control(0) + , lastSelectionStart(0), lastSelectionEnd(0), lineCount(0) , hAlign(QQuickTextEdit::AlignLeft), vAlign(QQuickTextEdit::AlignTop) , format(QQuickTextEdit::PlainText), wrapMode(QQuickTextEdit::NoWrap) , mouseSelectionMode(QQuickTextEdit::SelectCharacters), inputMethodHints(Qt::ImhNone) @@ -98,9 +98,10 @@ public: QColor selectionColor; QColor selectedTextColor; - QSize contentSize; + QSizeF contentSize; qreal textMargin; + qreal yoff; QString text; QUrl baseUrl; @@ -115,7 +116,6 @@ public: int lastSelectionStart; int lastSelectionEnd; int lineCount; - int yoff; enum UpdateType { UpdateNone, diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index 9b11e2e..6f079dc 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -677,7 +677,7 @@ void QQuickTextInput::setCursorPosition(int cp) cursor rectangle. */ -QRect QQuickTextInput::cursorRectangle() const +QRectF QQuickTextInput::cursorRectangle() const { Q_D(const QQuickTextInput); @@ -688,12 +688,8 @@ QRect QQuickTextInput::cursorRectangle() const c = 0; QTextLine l = d->m_textLayout.lineForTextPosition(c); if (!l.isValid()) - return QRect(); - return QRect( - qRound(l.cursorToX(c) - d->hscroll), - qRound(l.y() - d->vscroll), - 1, - qCeil(l.height())); + return QRectF(); + return QRectF(l.cursorToX(c) - d->hscroll, l.y() - d->vscroll, 1, l.height()); } /*! @@ -1368,7 +1364,7 @@ void QQuickTextInput::positionAt(QDeclarativeV8Function *args) const args->returnValue(v8::Int32::New(pos)); } -int QQuickTextInputPrivate::positionAt(int x, int y, QTextLine::CursorPosition position) const +int QQuickTextInputPrivate::positionAt(qreal x, qreal y, QTextLine::CursorPosition position) const { x += hscroll; y += vscroll; @@ -1432,7 +1428,7 @@ void QQuickTextInput::mouseDoubleClickEvent(QMouseEvent *event) d->selectWordAtPos(cursor); event->setAccepted(true); if (!d->hasPendingTripleClick()) { - d->tripleClickStartPoint = event->localPos().toPoint(); + d->tripleClickStartPoint = event->localPos(); d->tripleClickTimer.start(); } } else { @@ -1617,15 +1613,15 @@ void QQuickTextInputPrivate::updateHorizontalScroll() Q_Q(QQuickTextInput); QTextLine currentLine = m_textLayout.lineForTextPosition(m_cursor + m_preeditCursor); const int preeditLength = m_textLayout.preeditAreaText().length(); - const int width = qMax(0, qFloor(q->width())); - int widthUsed = currentLine.isValid() ? qRound(currentLine.naturalTextWidth()) : 0; + const qreal width = qMax(0, q->width()); + qreal widthUsed = currentLine.isValid() ? currentLine.naturalTextWidth() : 0; int previousScroll = hscroll; if (!autoScroll || widthUsed <= width || m_echoMode == QQuickTextInput::NoEcho) { hscroll = 0; } else { Q_ASSERT(currentLine.isValid()); - int cix = qRound(currentLine.cursorToX(m_cursor + preeditLength)); + qreal cix = currentLine.cursorToX(m_cursor + preeditLength); if (cix - hscroll >= width) { // text doesn't fit, cursor is to the right of br (scroll right) hscroll = cix - width; @@ -1640,7 +1636,7 @@ void QQuickTextInputPrivate::updateHorizontalScroll() if (preeditLength > 0) { // check to ensure long pre-edit text doesn't push the cursor // off to the left - cix = qRound(currentLine.cursorToX(m_cursor + qMax(0, m_preeditCursor - 1))); + cix = currentLine.cursorToX(m_cursor + qMax(0, m_preeditCursor - 1)); if (cix < hscroll) hscroll = cix; } @@ -1653,9 +1649,9 @@ void QQuickTextInputPrivate::updateVerticalScroll() { Q_Q(QQuickTextInput); const int preeditLength = m_textLayout.preeditAreaText().length(); - const int height = qMax(0, qFloor(q->height())); - int heightUsed = boundingRect.height(); - int previousScroll = vscroll; + const qreal height = qMax(0, q->height()); + qreal heightUsed = boundingRect.height(); + qreal previousScroll = vscroll; if (!autoScroll || heightUsed <= height) { // text fits in br; use vscroll for alignment @@ -1674,8 +1670,8 @@ void QQuickTextInputPrivate::updateVerticalScroll() } else { QTextLine currentLine = m_textLayout.lineForTextPosition(m_cursor + preeditLength); QRectF r = currentLine.isValid() ? currentLine.rect() : QRectF(); - int top = qFloor(r.top()); - int bottom = qCeil(r.bottom()); + qreal top = r.top(); + int bottom = r.bottom(); if (bottom - vscroll >= height) { // text doesn't fit, cursor is to the below the br (scroll down) @@ -1692,7 +1688,7 @@ void QQuickTextInputPrivate::updateVerticalScroll() // check to ensure long pre-edit text doesn't push the cursor // off the top currentLine = m_textLayout.lineForTextPosition(m_cursor + qMax(0, m_preeditCursor - 1)); - top = currentLine.isValid() ? qRound(currentLine.rect().top()) : 0; + top = currentLine.isValid() ? currentLine.rect().top() : 0; if (top < vscroll) vscroll = top; } @@ -1742,11 +1738,11 @@ QSGNode *QQuickTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData node->deleteContent(); node->setMatrix(QMatrix4x4()); - QPoint offset = QPoint(0,0); + QPointF offset(0, 0); if (d->autoScroll && d->m_textLayout.lineCount() > 0) { - QFontMetrics fm = QFontMetrics(d->font); + QFontMetricsF fm(d->font); // the y offset is there to keep the baseline constant in case we have script changes in the text. - offset = -QPoint(d->hscroll, d->vscroll + qRound(d->m_textLayout.lineAt(0).ascent()) - fm.ascent()); + offset = -QPoint(d->hscroll, d->vscroll + d->m_textLayout.lineAt(0).ascent() - fm.ascent()); } else { offset = -QPoint(d->hscroll, d->vscroll); } @@ -2732,7 +2728,7 @@ void QQuickTextInputPrivate::updateLayout() updateType = UpdatePaintNode; q->update(); - q->setImplicitSize(qCeil(boundingRect.width()), qCeil(boundingRect.height())); + q->setImplicitSize(boundingRect.width(), boundingRect.height()); if (previousRect != boundingRect) emit q->contentSizeChanged(); diff --git a/src/quick/items/qquicktextinput_p.h b/src/quick/items/qquicktextinput_p.h index 0e60cf6..ebd3d58 100644 --- a/src/quick/items/qquicktextinput_p.h +++ b/src/quick/items/qquicktextinput_p.h @@ -76,7 +76,7 @@ class Q_AUTOTEST_EXPORT QQuickTextInput : public QQuickImplicitSizeItem Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged) Q_PROPERTY(bool cursorVisible READ isCursorVisible WRITE setCursorVisible NOTIFY cursorVisibleChanged) Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged) - Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged) + Q_PROPERTY(QRectF cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged) Q_PROPERTY(QDeclarativeComponent *cursorDelegate READ cursorDelegate WRITE setCursorDelegate NOTIFY cursorDelegateChanged) Q_PROPERTY(int selectionStart READ selectionStart NOTIFY selectionStartChanged) Q_PROPERTY(int selectionEnd READ selectionEnd NOTIFY selectionEndChanged) @@ -195,7 +195,7 @@ public: int cursorPosition() const; void setCursorPosition(int cp); - QRect cursorRectangle() const; + QRectF cursorRectangle() const; int selectionStart() const; int selectionEnd() const; diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h index e48b000..1921451 100644 --- a/src/quick/items/qquicktextinput_p_p.h +++ b/src/quick/items/qquicktextinput_p_p.h @@ -77,14 +77,14 @@ class Q_AUTOTEST_EXPORT QQuickTextInputPrivate : public QQuickImplicitSizeItemPr Q_DECLARE_PUBLIC(QQuickTextInput) public: QQuickTextInputPrivate() - : cursorItem(0) + : hscroll(0) + , vscroll(0) + , cursorItem(0) , textNode(0) , m_maskData(0) , color(QRgb(0xFF000000)) , selectionColor(QRgb(0xFF000080)) , selectedTextColor(QRgb(0xFFFFFFFF)) - , hscroll(0) - , vscroll(0) , m_cursor(0) , m_preeditCursor(0) , m_blinkPeriod(0) @@ -179,6 +179,9 @@ public: QDeclarativeGuard m_validator; #endif + qreal hscroll; + qreal vscroll; + QTextLayout m_textLayout; QString m_text; QString m_inputMask; @@ -203,8 +206,6 @@ public: #endif int lastSelectionStart; int lastSelectionEnd; - int hscroll; - int vscroll; int m_cursor; int m_preeditCursor; int m_blinkPeriod; // 0 for non-blinking cursor @@ -295,7 +296,7 @@ public: int selectionStart() const { return hasSelectedText() ? m_selstart : -1; } int selectionEnd() const { return hasSelectedText() ? m_selend : -1; } - int positionAt(int x, int y, QTextLine::CursorPosition position) const; + int positionAt(qreal x, qreal y, QTextLine::CursorPosition position) const; int positionAt(const QPointF &point, QTextLine::CursorPosition position = QTextLine::CursorBetweenCharacters) const { return positionAt(point.x(), point.y(), position); } diff --git a/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp index 62b85b8..e2673c1 100644 --- a/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp +++ b/tests/auto/qtquick2/qquicktextedit/tst_qquicktextedit.cpp @@ -461,10 +461,10 @@ void tst_qquicktextedit::width() layout.endLayout(); - qreal metricWidth = ceil(layout.boundingRect().width()); + qreal metricWidth = layout.boundingRect().width(); QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->width(), qreal(metricWidth)); + QCOMPARE(textEditObject->width(), metricWidth); } for (int i = 0; i < richText.size(); i++) @@ -475,7 +475,7 @@ void tst_qquicktextedit::width() if (requiresUnhintedMetrics) document.setUseDesignMetrics(true); - int documentWidth = ceil(document.idealWidth()); + qreal documentWidth = document.idealWidth(); QString componentStr = "import QtQuick 2.0\nTextEdit { textFormat: TextEdit.RichText; text: \"" + richText.at(i) + "\" }"; QDeclarativeComponent texteditComponent(&engine); @@ -483,7 +483,7 @@ void tst_qquicktextedit::width() QQuickTextEdit *textEditObject = qobject_cast(texteditComponent.create()); QVERIFY(textEditObject != 0); - QCOMPARE(textEditObject->width(), qreal(documentWidth)); + QCOMPARE(textEditObject->width(), documentWidth); } } @@ -1843,8 +1843,8 @@ void tst_qquicktextedit::cursorDelegate() //Test Delegate gets moved for (int i=0; i<= textEditObject->text().length(); i++) { textEditObject->setCursorPosition(i); - QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + QCOMPARE(textEditObject->cursorRectangle().x(), delegateObject->x()); + QCOMPARE(textEditObject->cursorRectangle().y(), delegateObject->y()); } // Clear preedit text; QInputMethodEvent event; @@ -1858,8 +1858,8 @@ void tst_qquicktextedit::cursorDelegate() QTest::mouseClick(&view, Qt::LeftButton, 0, point1); QTest::qWait(50); QTRY_VERIFY(textEditObject->cursorPosition() != 0); - QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + QCOMPARE(textEditObject->cursorRectangle().x(), delegateObject->x()); + QCOMPARE(textEditObject->cursorRectangle().y(), delegateObject->y()); // Test delegate gets moved on mouse drag textEditObject->setCursorPosition(0); @@ -1869,27 +1869,27 @@ void tst_qquicktextedit::cursorDelegate() QGuiApplication::sendEvent(&view, &mv); QTest::mouseRelease(&view, Qt::LeftButton, 0, point2); QTest::qWait(50); - QTRY_COMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + QTRY_COMPARE(textEditObject->cursorRectangle().x(), delegateObject->x()); + QCOMPARE(textEditObject->cursorRectangle().y(), delegateObject->y()); textEditObject->setReadOnly(true); textEditObject->setCursorPosition(0); QTest::mouseClick(&view, Qt::LeftButton, 0, textEditObject->positionToRectangle(5).center().toPoint()); QTest::qWait(50); QTRY_VERIFY(textEditObject->cursorPosition() != 0); - QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + QCOMPARE(textEditObject->cursorRectangle().x(), delegateObject->x()); + QCOMPARE(textEditObject->cursorRectangle().y(), delegateObject->y()); textEditObject->setCursorPosition(0); QTest::mouseClick(&view, Qt::LeftButton, 0, textEditObject->positionToRectangle(5).center().toPoint()); QTest::qWait(50); QTRY_VERIFY(textEditObject->cursorPosition() != 0); - QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + QCOMPARE(textEditObject->cursorRectangle().x(), delegateObject->x()); + QCOMPARE(textEditObject->cursorRectangle().y(), delegateObject->y()); textEditObject->setCursorPosition(0); - QCOMPARE(textEditObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textEditObject->cursorRectangle().y(), qRound(delegateObject->y())); + QCOMPARE(textEditObject->cursorRectangle().x(), delegateObject->x()); + QCOMPARE(textEditObject->cursorRectangle().y(), delegateObject->y()); //Test Delegate gets deleted textEditObject->setCursorDelegate(0); QVERIFY(!textEditObject->findChild("cursorInstance")); @@ -2582,14 +2582,14 @@ void tst_qquicktextedit::cursorRectangleSize() qApp->sendEvent(qApp->focusObject(), &event); QRectF cursorRectFromQuery = event.value(Qt::ImCursorRectangle).toRectF(); - QRect cursorRectFromItem = textEdit->cursorRectangle(); + QRectF cursorRectFromItem = textEdit->cursorRectangle(); QRectF cursorRectFromPositionToRectangle = textEdit->positionToRectangle(textEdit->cursorPosition()); // item and input query cursor rectangles match - QCOMPARE(cursorRectFromItem, cursorRectFromQuery.toRect()); + QCOMPARE(cursorRectFromItem, cursorRectFromQuery); // item cursor rectangle and positionToRectangle calculations match - QCOMPARE(cursorRectFromItem, cursorRectFromPositionToRectangle.toRect()); + QCOMPARE(cursorRectFromItem, cursorRectFromPositionToRectangle); // item-canvas transform and input item transform match QCOMPARE(QQuickItemPrivate::get(textEdit)->itemToCanvasTransform(), qApp->inputMethod()->inputItemTransform()); diff --git a/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp index c1768bd..236b120 100644 --- a/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp @@ -2341,12 +2341,12 @@ void tst_qquicktextinput::cursorDelegate() //Test Delegate gets moved for (int i=0; i<= textInputObject->text().length(); i++) { textInputObject->setCursorPosition(i); - QCOMPARE(textInputObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textInputObject->cursorRectangle().y(), qRound(delegateObject->y())); + QCOMPARE(textInputObject->cursorRectangle().x(), delegateObject->x()); + QCOMPARE(textInputObject->cursorRectangle().y(), delegateObject->y()); } textInputObject->setCursorPosition(0); - QCOMPARE(textInputObject->cursorRectangle().x(), qRound(delegateObject->x())); - QCOMPARE(textInputObject->cursorRectangle().y(), qRound(delegateObject->y())); + QCOMPARE(textInputObject->cursorRectangle().x(), delegateObject->x()); + QCOMPARE(textInputObject->cursorRectangle().y(), delegateObject->y()); //Test Delegate gets deleted textInputObject->setCursorDelegate(0); QVERIFY(!textInputObject->findChild("cursorInstance")); @@ -2404,9 +2404,6 @@ void tst_qquicktextinput::cursorVisible() QCOMPARE(spy.count(), 7); } -static QRect round(const QRectF &r) { - return QRect(qRound(r.left()), qRound(r.top()), qCeil(r.width()), qCeil(r.height())); } - void tst_qquicktextinput::cursorRectangle() { @@ -2430,7 +2427,7 @@ void tst_qquicktextinput::cursorRectangle() input.setWidth(line.cursorToX(5, QTextLine::Leading)); input.setHeight(qCeil(line.height() * 3 / 2)); - QRect r; + QRectF r; // some tolerance for different fonts. #ifdef Q_OS_LINUX @@ -2445,28 +2442,28 @@ void tst_qquicktextinput::cursorRectangle() QVERIFY(r.left() < qCeil(line.cursorToX(i, QTextLine::Trailing))); QVERIFY(r.right() >= qFloor(line.cursorToX(i , QTextLine::Leading))); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(i)), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(i), r); } // Check the cursor rectangle remains within the input bounding rect when auto scrolling. - QVERIFY(r.left() < input.width()); + QVERIFY(r.left() < input.width() + error); QVERIFY(r.right() >= input.width() - error); for (int i = 6; i < text.length(); ++i) { input.setCursorPosition(i); QCOMPARE(r, input.cursorRectangle()); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(i)), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(i), r); } for (int i = text.length() - 2; i >= 0; --i) { input.setCursorPosition(i); r = input.cursorRectangle(); - QCOMPARE(r.top(), 0); + QCOMPARE(r.top(), 0.); QVERIFY(r.right() >= 0); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(i)), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(i), r); } // Check position with word wrap. @@ -2478,24 +2475,24 @@ void tst_qquicktextinput::cursorRectangle() QVERIFY(r.left() < qCeil(line.cursorToX(i, QTextLine::Trailing))); QVERIFY(r.right() >= qFloor(line.cursorToX(i , QTextLine::Leading))); - QCOMPARE(r.top(), 0); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(i)), r); + QCOMPARE(r.top(), 0.); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(i), r); } input.setCursorPosition(6); r = input.cursorRectangle(); - QCOMPARE(r.left(), 0); + QCOMPARE(r.left(), 0.); QVERIFY(r.top() > line.height() - error); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(6)), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(6), r); for (int i = 7; i < text.length(); ++i) { input.setCursorPosition(i); r = input.cursorRectangle(); QVERIFY(r.top() > line.height() - error); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(i)), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(i), r); } // Check vertical scrolling with word wrap. @@ -2506,40 +2503,40 @@ void tst_qquicktextinput::cursorRectangle() QVERIFY(r.left() < qCeil(line.cursorToX(i, QTextLine::Trailing))); QVERIFY(r.right() >= qFloor(line.cursorToX(i , QTextLine::Leading))); - QCOMPARE(r.top(), 0); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(round(input.positionToRectangle(i))), r); + QCOMPARE(r.top(), 0.); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(i), r); } input.setCursorPosition(6); r = input.cursorRectangle(); - QCOMPARE(r.left(), 0); + QCOMPARE(r.left(), 0.); QVERIFY(r.bottom() >= input.height() - error); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(6)), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(6), r); for (int i = 7; i < text.length(); ++i) { input.setCursorPosition(i); r = input.cursorRectangle(); QVERIFY(r.bottom() >= input.height() - error); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(i)), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(i), r); } for (int i = text.length() - 2; i >= 6; --i) { input.setCursorPosition(i); r = input.cursorRectangle(); QVERIFY(r.bottom() >= input.height() - error); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(i)), r); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(i), r); } for (int i = 5; i >= 0; --i) { input.setCursorPosition(i); r = input.cursorRectangle(); - QCOMPARE(r.top(), 0); - QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r); - QCOMPARE(round(input.positionToRectangle(i)), r); + QCOMPARE(r.top(), 0.); + QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRectF(), r); + QCOMPARE(input.positionToRectangle(i), r); } input.setText("Hi!"); @@ -3228,14 +3225,14 @@ void tst_qquicktextinput::cursorRectangleSize() qApp->sendEvent(qApp->focusObject(), &event); QRectF cursorRectFromQuery = event.value(Qt::ImCursorRectangle).toRectF(); - QRect cursorRectFromItem = textInput->cursorRectangle(); + QRectF cursorRectFromItem = textInput->cursorRectangle(); QRectF cursorRectFromPositionToRectangle = textInput->positionToRectangle(textInput->cursorPosition()); // item and input query cursor rectangles match - QCOMPARE(cursorRectFromItem, cursorRectFromQuery.toRect()); + QCOMPARE(cursorRectFromItem, cursorRectFromQuery); // item cursor rectangle and positionToRectangle calculations match - QCOMPARE(cursorRectFromItem, cursorRectFromPositionToRectangle.toRect()); + QCOMPARE(cursorRectFromItem, cursorRectFromPositionToRectangle); // item-canvas transform and input item transform match QCOMPARE(QQuickItemPrivate::get(textInput)->itemToCanvasTransform(), qApp->inputMethod()->inputItemTransform()); -- 1.7.2.5