diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index 2d5f5af49d49e12d1df4e305aed2f1157c40c4de..b4f31e37ef6e0de626da0f625f0dcbd3d7e2c750 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -1412,13 +1412,14 @@ 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 = q->width(); + const int width = qMax(0, qFloor(q->width())); int widthUsed = currentLine.isValid() ? qRound(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)); if (cix - hscroll >= width) { // text doesn't fit, cursor is to the right of br (scroll right) @@ -1447,7 +1448,7 @@ void QQuickTextInputPrivate::updateVerticalScroll() { Q_Q(QQuickTextInput); const int preeditLength = m_textLayout.preeditAreaText().length(); - const int height = q->height(); + const int height = qMax(0, qFloor(q->height())); int heightUsed = boundingRect.height(); int previousScroll = vscroll; @@ -1466,7 +1467,8 @@ void QQuickTextInputPrivate::updateVerticalScroll() break; } } else { - QRectF r = m_textLayout.lineForTextPosition(m_cursor + preeditLength).rect(); + 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()); @@ -1484,10 +1486,10 @@ void QQuickTextInputPrivate::updateVerticalScroll() if (preeditLength > 0) { // check to ensure long pre-edit text doesn't push the cursor // off the top - top = qRound(m_textLayout.lineForTextPosition( - m_cursor + qMax(0, m_preeditCursor - 1)).rect().top()); - if (top < vscroll) - vscroll = top; + currentLine = m_textLayout.lineForTextPosition(m_cursor + qMax(0, m_preeditCursor - 1)); + top = currentLine.isValid() ? qRound(currentLine.rect().top()) : 0; + if (top < vscroll) + vscroll = top; } } if (previousScroll != vscroll) diff --git a/tests/auto/qtquick2/qquicktextinput/data/negativeDimensions.qml b/tests/auto/qtquick2/qquicktextinput/data/negativeDimensions.qml new file mode 100644 index 0000000000000000000000000000000000000000..7a58c85b1dae44bc650fd7286054f05c226231a0 --- /dev/null +++ b/tests/auto/qtquick2/qquicktextinput/data/negativeDimensions.qml @@ -0,0 +1,19 @@ +import QtQuick 2.0 + +Item { + TextInput { + objectName: "input" + + focus: true + width: -1 + height: -1 + text: "sushi" + + anchors { + left: parent.left; + leftMargin: 5 + top: parent.top + topMargin: font.pixelSize + } + } +} diff --git a/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp index 3319936616faf5f7675cdafad9cb6495c71ae9b0..0286cea343dc4d345fe0f3b8ad31974007676c08 100644 --- a/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp +++ b/tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp @@ -176,6 +176,8 @@ private slots: void QTBUG_19956_data(); void QTBUG_19956_regexp(); + void negativeDimensions(); + private: void simulateKey(QQuickView *, int key); @@ -3390,6 +3392,19 @@ void tst_qquicktextinput::QTBUG_19956_regexp() QVERIFY(canvas.rootObject()->property("acceptableInput").toBool()); } + +void tst_qquicktextinput::negativeDimensions() +{ + // Verify this doesn't assert during initialization. + QDeclarativeComponent component(&engine, testFileUrl("negativeDimensions.qml")); + QScopedPointer<QObject> o(component.create()); + QVERIFY(o); + QQuickTextInput *input = o->findChild<QQuickTextInput *>("input"); + QVERIFY(input); + QCOMPARE(input->width(), qreal(-1)); + QCOMPARE(input->height(), qreal(-1)); +} + QTEST_MAIN(tst_qquicktextinput) #include "tst_qquicktextinput.moc"