diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index 65850b9a08b147bad91a47ee5a9da9bbd23ed17a..39dcc119e0272268ae9b4c9d6d0c3f5be300d413 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -1299,11 +1299,13 @@ void QQuickTextInput::createCursor()
 QRectF QQuickTextInput::positionToRectangle(int pos) const
 {
     Q_D(const QQuickTextInput);
-    if (pos > d->m_cursor)
+    if (d->m_echoMode == NoEcho)
+        pos = 0;
+    else if (pos > d->m_cursor)
         pos += d->preeditAreaText().length();
-    QTextLine l = d->m_textLayout.lineAt(0);
+    QTextLine l = d->m_textLayout.lineForTextPosition(pos);
     return l.isValid()
-            ? QRectF(l.cursorToX(pos) - d->hscroll, 0.0, d->m_cursorWidth, l.height())
+            ? QRectF(l.cursorToX(pos) - d->hscroll, l.y() - d->vscroll, d->m_cursorWidth, l.height())
             : QRectF();
 }
 
diff --git a/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp
index ee1a3bbd20e1984cf5782847e0a369beddd8915a..1be49a17467cfbaf76f915b31ba90fb990291e88 100644
--- a/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp
@@ -1411,17 +1411,25 @@ void tst_qquicktextinput::verticalAlignment()
 
     QCOMPARE(textInput->vAlign(), QQuickTextInput::AlignTop);
     QVERIFY(textInputPrivate->boundingRect.bottom() - textInputPrivate->vscroll < canvas.height() / 2);
+    QVERIFY(textInput->cursorRectangle().bottom() < canvas.height() / 2);
+    QVERIFY(textInput->positionToRectangle(0).bottom() < canvas.height() / 2);
 
     // bottom aligned
     textInput->setVAlign(QQuickTextInput::AlignBottom);
     QCOMPARE(textInput->vAlign(), QQuickTextInput::AlignBottom);
     QVERIFY(textInputPrivate->boundingRect.top() - textInputPrivate->vscroll > canvas.height() / 2);
+    QVERIFY(textInput->cursorRectangle().top() > canvas.height() / 2);
+    QVERIFY(textInput->positionToRectangle(0).top() > canvas.height() / 2);
 
     // explicitly center aligned
     textInput->setVAlign(QQuickTextInput::AlignVCenter);
     QCOMPARE(textInput->vAlign(), QQuickTextInput::AlignVCenter);
     QVERIFY(textInputPrivate->boundingRect.top() - textInputPrivate->vscroll < canvas.height() / 2);
     QVERIFY(textInputPrivate->boundingRect.bottom() - textInputPrivate->vscroll > canvas.height() / 2);
+    QVERIFY(textInput->cursorRectangle().top() < canvas.height() / 2);
+    QVERIFY(textInput->cursorRectangle().bottom() > canvas.height() / 2);
+    QVERIFY(textInput->positionToRectangle(0).top() < canvas.height() / 2);
+    QVERIFY(textInput->positionToRectangle(0).bottom() > canvas.height() / 2);
 }
 
 void tst_qquicktextinput::boundingRect()
@@ -2374,6 +2382,9 @@ 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()
 {
 
@@ -2413,6 +2424,7 @@ 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);
     }
 
     // Check the cursor rectangle remains within the input bounding rect when auto scrolling.
@@ -2423,6 +2435,7 @@ void tst_qquicktextinput::cursorRectangle()
         input.setCursorPosition(i);
         QCOMPARE(r, input.cursorRectangle());
         QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
+        QCOMPARE(round(input.positionToRectangle(i)), r);
     }
 
     for (int i = text.length() - 2; i >= 0; --i) {
@@ -2431,10 +2444,40 @@ void tst_qquicktextinput::cursorRectangle()
         QCOMPARE(r.top(), 0);
         QVERIFY(r.right() >= 0);
         QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
+        QCOMPARE(round(input.positionToRectangle(i)), r);
     }
 
-    // Check vertical scrolling with word wrap.
+    // Check position with word wrap.
     input.setWrapMode(QQuickTextInput::WordWrap);
+    input.setAutoScroll(false);
+    for (int i = 0; i <= 5; ++i) {
+        input.setCursorPosition(i);
+        r = input.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);
+    }
+
+    input.setCursorPosition(6);
+    r = input.cursorRectangle();
+    QCOMPARE(r.left(), 0);
+    QVERIFY(r.top() > line.height() - error);
+    QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
+    QCOMPARE(round(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);
+    }
+
+    // Check vertical scrolling with word wrap.
+    input.setAutoScroll(true);
     for (int i = 0; i <= 5; ++i) {
         input.setCursorPosition(i);
         r = input.cursorRectangle();
@@ -2443,29 +2486,38 @@ void tst_qquicktextinput::cursorRectangle()
         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);
     }
 
     input.setCursorPosition(6);
     r = input.cursorRectangle();
     QCOMPARE(r.left(), 0);
     QVERIFY(r.bottom() >= input.height() - error);
+    QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
+    QCOMPARE(round(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);
     }
 
     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);
     }
 
     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);
     }
 
     input.setText("Hi!");