diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index 9f22dfdd081dcf1779a1281c7beefbc16dd0039f..d7303352c50ba7f7ad5235fdb2cf769b1ce6ae42 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -421,6 +421,10 @@ void QQuickTextPrivate::updateSize()
     //setup instance of QTextLayout for all cases other than richtext
     if (!richText) {
         QRectF textRect = setupTextLayout(&naturalWidth);
+
+        if (internalWidthUpdate)    // probably the result of a binding loop, but by letting it
+            return;      // get this far we'll get a warning to that effect if it is.
+
         layedOutTextRect = textRect;
         size = textRect.size();
         dy -= size.height();
@@ -443,7 +447,13 @@ void QQuickTextPrivate::updateSize()
         if (requireImplicitWidth && q->widthValid()) {
             extra->doc->setTextWidth(-1);
             naturalWidth = extra->doc->idealWidth();
+            const bool wasInLayout = internalWidthUpdate;
+            internalWidthUpdate = true;
+            q->setImplicitWidth(naturalWidth);
+            internalWidthUpdate = wasInLayout;
         }
+        if (internalWidthUpdate)
+            return;
         if (wrapMode != QQuickText::NoWrap && q->widthValid())
             extra->doc->setTextWidth(q->width());
         else
@@ -468,8 +478,6 @@ void QQuickTextPrivate::updateSize()
     qreal iWidth = -1;
     if (!q->widthValid())
         iWidth = size.width();
-    else if (requireImplicitWidth)
-        iWidth = naturalWidth;
     if (iWidth > -1)
         q->setImplicitSize(iWidth, size.height());
     internalWidthUpdate = false;
@@ -697,6 +705,11 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
             layout.endLayout();
             *naturalWidth = layout.maximumWidth();
             layout.clearLayout();
+
+            bool wasInLayout = internalWidthUpdate;
+            internalWidthUpdate = true;
+            q->setImplicitWidth(*naturalWidth);
+            internalWidthUpdate = wasInLayout;
         }
 
         QFontMetrics fm(font);
@@ -704,7 +717,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
         return QRect(0, 0, 0, height);
     }
 
-    const qreal lineWidth = q->widthValid() ? q->width() : FLT_MAX;
+    qreal lineWidth = q->widthValid() && q->width() > 0 ? q->width() : FLT_MAX;
     const qreal maxHeight = q->heightValid() ? q->height() : FLT_MAX;
 
     const bool customLayout = isLineLaidOutConnected();
@@ -735,6 +748,7 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
     QTextLine line;
     int visibleCount = 0;
     bool elide;
+    bool widthChanged;
     qreal height = 0;
     QString elideText;
     bool once = true;
@@ -755,13 +769,14 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
                 scaledFont.setPointSize(scaledFontSize);
             layout.setFont(scaledFont);
         }
-        layout.beginLayout();
 
+        layout.beginLayout();
 
         bool wrapped = false;
         bool truncateHeight = false;
         truncated = false;
         elide = false;
+        widthChanged = false;
         int characterCount = 0;
         int unwrappedLineCount = 1;
         int maxLineCount = maximumLineCount();
@@ -864,7 +879,6 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
             br = br.united(line.naturalTextRect());
             line = nextLine;
         }
-
         layout.endLayout();
         br.moveTop(0);
 
@@ -886,8 +900,21 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
                     if (!line.isValid())
                         break;
                 }
+
                 *naturalWidth = qMax(*naturalWidth, widthLayout.maximumWidth());
             }
+
+            bool wasInLayout = internalWidthUpdate;
+            internalWidthUpdate = true;
+            q->setImplicitWidth(*naturalWidth);
+            internalWidthUpdate = wasInLayout;
+
+            const qreal oldWidth = lineWidth;
+            lineWidth = q->widthValid() && q->width() > 0 ? q->width() : FLT_MAX;
+            if (lineWidth != oldWidth && (singlelineElide || multilineElide || canWrap || horizontalFit)) {
+                widthChanged = true;
+                continue;
+            }
         }
 
         // If the next needs to be elided and there's an abbreviated string available
@@ -911,32 +938,36 @@ QRectF QQuickTextPrivate::setupTextLayout(qreal *const naturalWidth)
         if (horizontalFit) {
             if (unelidedRect.width() > lineWidth || (!verticalFit && wrapped)) {
                 largeFont = scaledFontSize - 1;
-                scaledFontSize = (smallFont + largeFont) / 2;
                 if (smallFont > largeFont)
                     break;
+                scaledFontSize = (smallFont + largeFont) / 2;
+                if (pixelSize)
+                    scaledFont.setPixelSize(scaledFontSize);
+                else
+                    scaledFont.setPointSize(scaledFontSize);
                 continue;
             } else if (!verticalFit) {
                 smallFont = scaledFontSize;
-                scaledFontSize = (smallFont + largeFont + 1) / 2;
                 if (smallFont == largeFont)
                     break;
+                scaledFontSize = (smallFont + largeFont + 1) / 2;
             }
         }
 
         if (verticalFit) {
             if (truncateHeight || unelidedRect.height() > maxHeight) {
                 largeFont = scaledFontSize - 1;
-                scaledFontSize = (smallFont + largeFont + 1) / 2;
                 if (smallFont > largeFont)
                     break;
+                scaledFontSize = (smallFont + largeFont) / 2;
+
             } else {
                 smallFont = scaledFontSize;
-                scaledFontSize = (smallFont + largeFont + 1) / 2;
                 if (smallFont == largeFont)
                     break;
+                scaledFontSize = (smallFont + largeFont + 1) / 2;
             }
         }
-
     }
 
     if (eos != multilengthEos)
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index 79df5abd1131feca31e095c73a2ffc6a52c2d56d..4fa5233b9a42250f56035c1eec67e3d5129571df 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -1143,7 +1143,8 @@ void QQuickTextEdit::setInputMethodHints(Qt::InputMethodHints hints)
 void QQuickTextEdit::geometryChanged(const QRectF &newGeometry,
                                   const QRectF &oldGeometry)
 {
-    if (newGeometry.width() != oldGeometry.width())
+    Q_D(QQuickTextEdit);
+    if (newGeometry.width() != oldGeometry.width() && d->wrapMode != NoWrap && !d->inLayout)
         updateSize();
     QQuickImplicitSizeItem::geometryChanged(newGeometry, oldGeometry);
 }
@@ -1857,6 +1858,13 @@ void QQuickTextEdit::updateSize()
             if (d->requireImplicitWidth) {
                 d->document->setTextWidth(-1);
                 naturalWidth = d->document->idealWidth();
+
+                const bool wasInLayout = d->inLayout;
+                d->inLayout = true;
+                setImplicitWidth(naturalWidth);
+                d->inLayout = wasInLayout;
+                if (d->inLayout)    // probably the result of a binding loop, but by letting it
+                    return;         // get this far we'll get a warning to that effect.
             }
             if (d->document->textWidth() != width())
                 d->document->setTextWidth(width());
@@ -1888,11 +1896,11 @@ void QQuickTextEdit::updateSize()
             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.
         qreal iWidth = -1;
-        if (!widthValid())
+        if (!widthValid() && !d->requireImplicitWidth)
             iWidth = newWidth;
-        else if (d->requireImplicitWidth)
-            iWidth = naturalWidth;
+
         qreal newHeight = d->document->isEmpty() ? fm.height() : d->document->size().height();
+
         if (iWidth > -1)
             setImplicitSize(iWidth, newHeight);
         else
diff --git a/src/quick/items/qquicktextedit_p_p.h b/src/quick/items/qquicktextedit_p_p.h
index 055b5c7929fd558922aec35db225dfc2e706f4e9..f0a35d5266ea96e586b51bd9c1fb9509b2f20b06 100644
--- a/src/quick/items/qquicktextedit_p_p.h
+++ b/src/quick/items/qquicktextedit_p_p.h
@@ -78,7 +78,7 @@ public:
         , documentDirty(true), dirty(false), richText(false), cursorVisible(false)
         , focusOnPress(true), persistentSelection(false), requireImplicitWidth(false)
         , selectByMouse(false), canPaste(false), canPasteValid(false), hAlignImplicit(true)
-        , rightToLeftText(false), textCached(false)
+        , rightToLeftText(false), textCached(false), inLayout(false)
     {
     }
 
@@ -144,6 +144,7 @@ public:
     bool hAlignImplicit:1;
     bool rightToLeftText:1;
     bool textCached:1;
+    bool inLayout:1;
 };
 
 QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index c9b2e7b41ea3f3775ae4116611a16d3d776afbc5..7d7fe851b33f32fee113458bcaa1f2c3d31ebaf7 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -1604,9 +1604,11 @@ void QQuickTextInput::geometryChanged(const QRectF &newGeometry,
                                   const QRectF &oldGeometry)
 {
     Q_D(QQuickTextInput);
-    if (newGeometry.width() != oldGeometry.width())
-        d->updateLayout();
-    updateCursorRectangle();
+    if (!d->inLayout) {
+        if (newGeometry.width() != oldGeometry.width() && d->wrapMode != NoWrap)
+            d->updateLayout();
+        updateCursorRectangle();
+    }
     QQuickImplicitSizeItem::geometryChanged(newGeometry, oldGeometry);
 }
 
@@ -2699,6 +2701,38 @@ void QQuickTextInputPrivate::updateDisplayText(bool forceUpdate)
     }
 }
 
+qreal QQuickTextInputPrivate::getImplicitWidth() const
+{
+    Q_Q(const QQuickTextInput);
+    if (!requireImplicitWidth) {
+        QQuickTextInputPrivate *d = const_cast<QQuickTextInputPrivate *>(this);
+        d->requireImplicitWidth = true;
+
+        if (q->isComponentComplete()) {
+            // One time cost, only incurred if implicitWidth is first requested after
+            // componentComplete.
+            QTextLayout layout(m_text);
+
+            QTextOption option = m_textLayout.textOption();
+            option.setTextDirection(m_layoutDirection);
+            option.setFlags(QTextOption::IncludeTrailingSpaces);
+            option.setWrapMode(QTextOption::WrapMode(wrapMode));
+            option.setAlignment(Qt::Alignment(q->effectiveHAlign()));
+            layout.setTextOption(option);
+            layout.setFont(font);
+            layout.setPreeditArea(m_textLayout.preeditAreaPosition(), m_textLayout.preeditAreaText());
+            layout.beginLayout();
+
+            QTextLine line = layout.createLine();
+            line.setLineWidth(INT_MAX);
+            d->implicitWidth = qCeil(line.naturalTextWidth());
+
+            layout.endLayout();
+        }
+    }
+    return implicitWidth;
+}
+
 void QQuickTextInputPrivate::updateLayout()
 {
     Q_Q(QQuickTextInput);
@@ -2718,6 +2752,15 @@ void QQuickTextInputPrivate::updateLayout()
     boundingRect = QRectF();
     m_textLayout.beginLayout();
     QTextLine line = m_textLayout.createLine();
+    if (requireImplicitWidth) {
+        line.setLineWidth(INT_MAX);
+        const bool wasInLayout = inLayout;
+        inLayout = true;
+        q->setImplicitWidth(qCeil(line.naturalTextWidth()));
+        inLayout = wasInLayout;
+        if (inLayout)       // probably the result of a binding loop, but by letting it
+            return;         // get this far we'll get a warning to that effect.
+    }
     qreal lineWidth = q->widthValid() ? q->width() : INT_MAX;
     qreal height = 0;
     do {
@@ -2737,7 +2780,11 @@ void QQuickTextInputPrivate::updateLayout()
 
     updateType = UpdatePaintNode;
     q->update();
-    q->setImplicitSize(boundingRect.width(), boundingRect.height());
+
+    if (!requireImplicitWidth && !q->widthValid())
+        q->setImplicitSize(qCeil(boundingRect.width()), qCeil(boundingRect.height()));
+    else
+        q->setImplicitHeight(qCeil(boundingRect.height()));
 
     if (previousRect != boundingRect)
         emit q->contentSizeChanged();
diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h
index bb00600661c1bf874eebdc555b41eabc3023c330..165155acd03723aee2ae247aa263ba16c53f4b75 100644
--- a/src/quick/items/qquicktextinput_p_p.h
+++ b/src/quick/items/qquicktextinput_p_p.h
@@ -125,6 +125,8 @@ public:
         , m_acceptableInput(1)
         , m_blinkStatus(0)
         , m_passwordEchoEditing(false)
+        , inLayout(false)
+        , requireImplicitWidth(false)
     {
     }
 
@@ -256,7 +258,8 @@ public:
     bool m_acceptableInput : 1;
     bool m_blinkStatus : 1;
     bool m_passwordEchoEditing : 1;
-
+    bool inLayout:1;
+    bool requireImplicitWidth:1;
 
     static inline QQuickTextInputPrivate *get(QQuickTextInput *t) {
         return t->d_func();
@@ -404,6 +407,8 @@ public:
 
     void updateLayout();
 
+    qreal getImplicitWidth() const;
+
 private:
     void removeSelectedText();
     void internalSetText(const QString &txt, int pos = -1, bool edited = true);
diff --git a/tests/auto/quick/qquicktext/tst_qquicktext.cpp b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
index 92e8528a0d1f0d8978e49f49942b25dfb4c54239..45d09bc866d2b96094e4d8c80ae668ad6148aaac 100644
--- a/tests/auto/quick/qquicktext/tst_qquicktext.cpp
+++ b/tests/auto/quick/qquicktext/tst_qquicktext.cpp
@@ -107,6 +107,8 @@ private slots:
     void implicitSize_data();
     void implicitSize();
     void contentSize();
+    void implicitSizeBinding_data();
+    void implicitSizeBinding();
 
     void lineLaidOut();
 
@@ -1548,29 +1550,36 @@ void tst_qquicktext::implicitSize_data()
     QTest::addColumn<QString>("width");
     QTest::addColumn<QString>("wrap");
     QTest::addColumn<QString>("elide");
-    QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.NoWrap" << "Text.ElideNone";
-    QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" <<" 50" << "Text.NoWrap" << "Text.ElideNone";
-    QTest::newRow("plain, 0 width") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.NoWrap" << "Text.ElideNone";
-    QTest::newRow("plain, elide") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.NoWrap" << "Text.ElideRight";
-    QTest::newRow("plain, 0 width, elide") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.NoWrap" << "Text.ElideRight";
-    QTest::newRow("richtext, 0 width") << "<b>The quick red fox jumped over the lazy brown dog</b>" <<" 0" << "Text.NoWrap" << "Text.ElideNone";
-    QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.Wrap" << "Text.ElideNone";
-    QTest::newRow("richtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "50" << "Text.Wrap" << "Text.ElideNone";
-    QTest::newRow("plain_wrap, 0 width") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.Wrap" << "Text.ElideNone";
-    QTest::newRow("plain_wrap, elide") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.Wrap" << "Text.ElideRight";
-    QTest::newRow("plain_wrap, 0 width, elide") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.Wrap" << "Text.ElideRight";
-    QTest::newRow("richtext_wrap, 0 width") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "0" << "Text.Wrap" << "Text.ElideNone";
+    QTest::addColumn<QString>("format");
+    QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.NoWrap" << "Text.ElideNone" << "Text.PlainText";
+    QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" <<" 50" << "Text.NoWrap" << "Text.ElideNone" << "Text.RichText";
+    QTest::newRow("styledtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" <<" 50" << "Text.NoWrap" << "Text.ElideNone" << "Text.StyledText";
+    QTest::newRow("plain, 0 width") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.NoWrap" << "Text.ElideNone" << "Text.PlainText";
+    QTest::newRow("plain, elide") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.NoWrap" << "Text.ElideRight" << "Text.PlainText";
+    QTest::newRow("plain, 0 width, elide") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.NoWrap" << "Text.ElideRight" << "Text.PlainText";
+    QTest::newRow("richtext, 0 width") << "<b>The quick red fox jumped over the lazy brown dog</b>" <<" 0" << "Text.NoWrap" << "Text.ElideNone" << "Text.RichText";
+    QTest::newRow("styledtext, 0 width") << "<b>The quick red fox jumped over the lazy brown dog</b>" <<" 0" << "Text.NoWrap" << "Text.ElideNone" << "Text.StyledText";
+    QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.Wrap" << "Text.ElideNone" << "Text.PlainText";
+    QTest::newRow("richtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "50" << "Text.Wrap" << "Text.ElideNone" << "Text.RichText";
+    QTest::newRow("styledtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "50" << "Text.Wrap" << "Text.ElideNone" << "Text.StyledText";
+    QTest::newRow("plain_wrap, 0 width") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.Wrap" << "Text.ElideNone" << "Text.PlainText";
+    QTest::newRow("plain_wrap, elide") << "The quick red fox jumped over the lazy brown dog" << "50" << "Text.Wrap" << "Text.ElideRight" << "Text.PlainText";
+    QTest::newRow("plain_wrap, 0 width, elide") << "The quick red fox jumped over the lazy brown dog" << "0" << "Text.Wrap" << "Text.ElideRight" << "Text.PlainText";
+    QTest::newRow("richtext_wrap, 0 width") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "0" << "Text.Wrap" << "Text.ElideNone" << "Text.RichText";
+    QTest::newRow("styledtext_wrap, 0 width") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "0" << "Text.Wrap" << "Text.ElideNone" << "Text.StyledText";
 }
 
 void tst_qquicktext::implicitSize()
 {
     QFETCH(QString, text);
     QFETCH(QString, width);
+    QFETCH(QString, format);
     QFETCH(QString, wrap);
     QFETCH(QString, elide);
     QString componentStr = "import QtQuick 2.0\nText { "
             "text: \"" + text + "\"; "
             "width: " + width + "; "
+            "textFormat: " + format + "; "
             "wrapMode: " + wrap + "; "
             "elide: " + elide + "; "
             "maximumLineCount: 1 }";
@@ -1631,6 +1640,35 @@ void tst_qquicktext::contentSize()
     QCOMPARE(spy.count(), ++spyCount);
 }
 
+void tst_qquicktext::implicitSizeBinding_data()
+{
+    implicitSize_data();
+}
+
+void tst_qquicktext::implicitSizeBinding()
+{
+    QFETCH(QString, text);
+    QFETCH(QString, wrap);
+    QFETCH(QString, format);
+    QString componentStr = "import QtQuick 2.0\nText { text: \"" + text + "\"; width: implicitWidth; height: implicitHeight; wrapMode: " + wrap + "; textFormat: " + format + " }";
+
+    QDeclarativeComponent textComponent(&engine);
+    textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QScopedPointer<QObject> object(textComponent.create());
+    QQuickText *textObject = qobject_cast<QQuickText *>(object.data());
+
+    QCOMPARE(textObject->width(), textObject->implicitWidth());
+    QCOMPARE(textObject->height(), textObject->implicitHeight());
+
+    textObject->resetWidth();
+    QCOMPARE(textObject->width(), textObject->implicitWidth());
+    QCOMPARE(textObject->height(), textObject->implicitHeight());
+
+    textObject->resetHeight();
+    QCOMPARE(textObject->width(), textObject->implicitWidth());
+    QCOMPARE(textObject->height(), textObject->implicitHeight());
+}
+
 void tst_qquicktext::lineLaidOut()
 {
     QQuickView *canvas = createView(testFile("lineLayout.qml"));
diff --git a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
index 46a4ea46ddaabdac49fc01312e26fcf2cdd29c71..83e7e788662db882665e68a4a03989f0bcbcd264 100644
--- a/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
+++ b/tests/auto/quick/qquicktextedit/tst_qquicktextedit.cpp
@@ -152,6 +152,8 @@ private slots:
     void implicitSize_data();
     void implicitSize();
     void contentSize();
+    void implicitSizeBinding_data();
+    void implicitSizeBinding();
 
     void preeditCursorRectangle();
     void inputMethodComposing();
@@ -2512,17 +2514,19 @@ void tst_qquicktextedit::implicitSize_data()
 {
     QTest::addColumn<QString>("text");
     QTest::addColumn<QString>("wrap");
-    QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap";
-    QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.NoWrap";
-    QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap";
-    QTest::newRow("richtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.Wrap";
+    QTest::addColumn<QString>("format");
+    QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.NoWrap" << "TextEdit.PlainText";
+    QTest::newRow("richtext") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.NoWrap" << "TextEdit.RichText";
+    QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextEdit.Wrap" << "TextEdit.PlainText";
+    QTest::newRow("richtext_wrap") << "<b>The quick red fox jumped over the lazy brown dog</b>" << "TextEdit.Wrap" << "TextEdit.RichText";
 }
 
 void tst_qquicktextedit::implicitSize()
 {
     QFETCH(QString, text);
     QFETCH(QString, wrap);
-    QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + " }";
+    QFETCH(QString, format);
+    QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + "; textFormat: " + format + " }";
     QQmlComponent textComponent(&engine);
     textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
     QQuickTextEdit *textObject = qobject_cast<QQuickTextEdit*>(textComponent.create());
@@ -2563,6 +2567,34 @@ void tst_qquicktextedit::contentSize()
     QCOMPARE(spy.count(), 3);
 }
 
+void tst_qquicktextedit::implicitSizeBinding_data()
+{
+    implicitSize_data();
+}
+
+void tst_qquicktextedit::implicitSizeBinding()
+{
+    QFETCH(QString, text);
+    QFETCH(QString, wrap);
+    QFETCH(QString, format);
+    QString componentStr = "import QtQuick 2.0\nTextEdit { text: \"" + text + "\"; width: implicitWidth; height: implicitHeight; wrapMode: " + wrap + "; textFormat: " + format + " }";
+    QDeclarativeComponent textComponent(&engine);
+    textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QScopedPointer<QObject> object(textComponent.create());
+    QQuickTextEdit *textObject = qobject_cast<QQuickTextEdit *>(object.data());
+
+    QCOMPARE(textObject->width(), textObject->implicitWidth());
+    QCOMPARE(textObject->height(), textObject->implicitHeight());
+
+    textObject->resetWidth();
+    QCOMPARE(textObject->width(), textObject->implicitWidth());
+    QCOMPARE(textObject->height(), textObject->implicitHeight());
+
+    textObject->resetHeight();
+    QCOMPARE(textObject->width(), textObject->implicitWidth());
+    QCOMPARE(textObject->height(), textObject->implicitHeight());
+}
+
 void tst_qquicktextedit::preeditCursorRectangle()
 {
     QString preeditText = "super";
diff --git a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
index e3a9bfcea1b49365f3f987e914c4160b9e18761b..8467a171a68b6bff7b92a09ad45932e74ad6d220 100644
--- a/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
+++ b/tests/auto/quick/qquicktextinput/tst_qquicktextinput.cpp
@@ -192,6 +192,11 @@ private slots:
     void QTBUG_19956_data();
     void QTBUG_19956_regexp();
 
+    void implicitSize_data();
+    void implicitSize();
+    void implicitSizeBinding_data();
+    void implicitSizeBinding();
+
     void negativeDimensions();
 
 private:
@@ -4940,6 +4945,58 @@ void tst_qquicktextinput::QTBUG_19956_regexp()
     QVERIFY(canvas.rootObject()->property("acceptableInput").toBool());
 }
 
+void tst_qquicktextinput::implicitSize_data()
+{
+    QTest::addColumn<QString>("text");
+    QTest::addColumn<QString>("wrap");
+    QTest::newRow("plain") << "The quick red fox jumped over the lazy brown dog" << "TextInput.NoWrap";
+    QTest::newRow("plain_wrap") << "The quick red fox jumped over the lazy brown dog" << "TextInput.Wrap";
+}
+
+void tst_qquicktextinput::implicitSize()
+{
+    QFETCH(QString, text);
+    QFETCH(QString, wrap);
+    QString componentStr = "import QtQuick 2.0\nTextInput { text: \"" + text + "\"; width: 50; wrapMode: " + wrap + " }";
+    QDeclarativeComponent textComponent(&engine);
+    textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QQuickTextInput *textObject = qobject_cast<QQuickTextInput*>(textComponent.create());
+
+    QVERIFY(textObject->width() < textObject->implicitWidth());
+    QVERIFY(textObject->height() == textObject->implicitHeight());
+
+    textObject->resetWidth();
+    QVERIFY(textObject->width() == textObject->implicitWidth());
+    QVERIFY(textObject->height() == textObject->implicitHeight());
+}
+
+void tst_qquicktextinput::implicitSizeBinding_data()
+{
+    implicitSize_data();
+}
+
+void tst_qquicktextinput::implicitSizeBinding()
+{
+    QFETCH(QString, text);
+    QFETCH(QString, wrap);
+    QString componentStr = "import QtQuick 2.0\nTextInput { text: \"" + text + "\"; width: implicitWidth; height: implicitHeight; wrapMode: " + wrap + " }";
+    QDeclarativeComponent textComponent(&engine);
+    textComponent.setData(componentStr.toLatin1(), QUrl::fromLocalFile(""));
+    QScopedPointer<QObject> object(textComponent.create());
+    QQuickTextInput *textObject = qobject_cast<QQuickTextInput *>(object.data());
+
+    QCOMPARE(textObject->width(), textObject->implicitWidth());
+    QCOMPARE(textObject->height(), textObject->implicitHeight());
+
+    textObject->resetWidth();
+    QCOMPARE(textObject->width(), textObject->implicitWidth());
+    QCOMPARE(textObject->height(), textObject->implicitHeight());
+
+    textObject->resetHeight();
+    QCOMPARE(textObject->width(), textObject->implicitWidth());
+    QCOMPARE(textObject->height(), textObject->implicitHeight());
+}
+
 
 void tst_qquicktextinput::negativeDimensions()
 {