/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qquicktext_p.h"
#include "qquicktext_p_p.h"

#include <QtQuick/private/qsgcontext_p.h>
#include <private/qqmlglobal_p.h>
#include <private/qsgadaptationlayer_p.h>
#include "qquicktextnode_p.h"
#include "qquickimage_p_p.h"
#include "qquicktextutil_p.h"
#include "qquicktextdocument_p.h"

#include <QtQuick/private/qsgtexture_p.h>

#include <QtQml/qqmlinfo.h>
#include <QtGui/qevent.h>
#include <QtGui/qabstracttextdocumentlayout.h>
#include <QtGui/qpainter.h>
#include <QtGui/qtextdocument.h>
#include <QtGui/qtextobject.h>
#include <QtGui/qtextcursor.h>
#include <QtGui/qguiapplication.h>
#include <QtGui/qinputmethod.h>

#include <private/qtextengine_p.h>
#include <private/qquickstyledtext_p.h>
#include <QtQuick/private/qquickpixmapcache_p.h>

#include <qmath.h>
#include <limits.h>

QT_BEGIN_NAMESPACE

Q_DECLARE_LOGGING_CATEGORY(DBG_HOVER_TRACE)

const QChar QQuickTextPrivate::elideChar = QChar(0x2026);

QQuickTextPrivate::QQuickTextPrivate()
    : fontInfo(font), elideLayout(nullptr), textLine(nullptr), lineWidth(0)
    , color(0xFF000000), linkColor(0xFF0000FF), styleColor(0xFF000000)
    , lineCount(1), multilengthEos(-1)
    , elideMode(QQuickText::ElideNone), hAlign(QQuickText::AlignLeft), vAlign(QQuickText::AlignTop)
    , format(QQuickText::AutoText), wrapMode(QQuickText::NoWrap)
    , style(QQuickText::Normal)
    , renderType(QQuickTextUtil::textRenderType<QQuickText>())
    , updateType(UpdatePaintNode)
    , maximumLineCountValid(false), updateOnComponentComplete(true), richText(false)
    , styledText(false), widthExceeded(false), heightExceeded(false), internalWidthUpdate(false)
    , requireImplicitSize(false), implicitWidthValid(false), implicitHeightValid(false)
    , truncated(false), hAlignImplicit(true), rightToLeftText(false)
    , layoutTextElided(false), textHasChanged(true), needToUpdateLayout(false), formatModifiesFontSize(false)
    , polishSize(false)
    , updateSizeRecursionGuard(false)
{
    implicitAntialiasing = true;
}

QQuickTextPrivate::ExtraData::ExtraData()
    : padding(0)
    , topPadding(0)
    , leftPadding(0)
    , rightPadding(0)
    , bottomPadding(0)
    , explicitTopPadding(false)
    , explicitLeftPadding(false)
    , explicitRightPadding(false)
    , explicitBottomPadding(false)
    , lineHeight(1.0)
    , doc(nullptr)
    , minimumPixelSize(12)
    , minimumPointSize(12)
    , nbActiveDownloads(0)
    , maximumLineCount(INT_MAX)
    , lineHeightValid(false)
    , lineHeightMode(QQuickText::ProportionalHeight)
    , fontSizeMode(QQuickText::FixedSize)
{
}

void QQuickTextPrivate::init()
{
    Q_Q(QQuickText);
    q->setAcceptedMouseButtons(Qt::LeftButton);
    q->setFlag(QQuickItem::ItemHasContents);
}

QQuickTextPrivate::~QQuickTextPrivate()
{
    delete elideLayout;
    delete textLine; textLine = nullptr;

    if (extra.isAllocated()) {
        qDeleteAll(extra->imgTags);
        extra->imgTags.clear();
    }
}

qreal QQuickTextPrivate::getImplicitWidth() const
{
    if (!requireImplicitSize) {
        // We don't calculate implicitWidth unless it is required.
        // We need to force a size update now to ensure implicitWidth is calculated
        QQuickTextPrivate *me = const_cast<QQuickTextPrivate*>(this);
        me->requireImplicitSize = true;
        me->updateSize();
    }
    return implicitWidth;
}

qreal QQuickTextPrivate::getImplicitHeight() const
{
    if (!requireImplicitSize) {
        QQuickTextPrivate *me = const_cast<QQuickTextPrivate*>(this);
        me->requireImplicitSize = true;
        me->updateSize();
    }
    return implicitHeight;
}

qreal QQuickTextPrivate::availableWidth() const
{
    Q_Q(const QQuickText);
    return q->width() - q->leftPadding() - q->rightPadding();
}

qreal QQuickTextPrivate::availableHeight() const
{
    Q_Q(const QQuickText);
    return q->height() - q->topPadding() - q->bottomPadding();
}

void QQuickTextPrivate::setTopPadding(qreal value, bool reset)
{
    Q_Q(QQuickText);
    qreal oldPadding = q->topPadding();
    if (!reset || extra.isAllocated()) {
        extra.value().topPadding = value;
        extra.value().explicitTopPadding = !reset;
    }
    if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
        updateSize();
        emit q->topPaddingChanged();
    }
}

void QQuickTextPrivate::setLeftPadding(qreal value, bool reset)
{
    Q_Q(QQuickText);
    qreal oldPadding = q->leftPadding();
    if (!reset || extra.isAllocated()) {
        extra.value().leftPadding = value;
        extra.value().explicitLeftPadding = !reset;
    }
    if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
        updateSize();
        emit q->leftPaddingChanged();
    }
}

void QQuickTextPrivate::setRightPadding(qreal value, bool reset)
{
    Q_Q(QQuickText);
    qreal oldPadding = q->rightPadding();
    if (!reset || extra.isAllocated()) {
        extra.value().rightPadding = value;
        extra.value().explicitRightPadding = !reset;
    }
    if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
        updateSize();
        emit q->rightPaddingChanged();
    }
}

void QQuickTextPrivate::setBottomPadding(qreal value, bool reset)
{
    Q_Q(QQuickText);
    qreal oldPadding = q->bottomPadding();
    if (!reset || extra.isAllocated()) {
        extra.value().bottomPadding = value;
        extra.value().explicitBottomPadding = !reset;
    }
    if ((!reset && !qFuzzyCompare(oldPadding, value)) || (reset && !qFuzzyCompare(oldPadding, padding()))) {
        updateSize();
        emit q->bottomPaddingChanged();
    }
}

/*!
    \qmlproperty bool QtQuick::Text::antialiasing

    Used to decide if the Text should use antialiasing or not. Only Text
    with renderType of Text.NativeRendering can disable antialiasing.

    The default is true.
*/

void QQuickText::q_updateLayout()
{
    Q_D(QQuickText);
    d->updateLayout();
}

void QQuickTextPrivate::updateLayout()
{
    Q_Q(QQuickText);
    if (!q->isComponentComplete()) {
        updateOnComponentComplete = true;
        return;
    }
    updateOnComponentComplete = false;
    layoutTextElided = false;

    if (extra.isAllocated())
        extra->visibleImgTags.clear();
    needToUpdateLayout = false;

    // Setup instance of QTextLayout for all cases other than richtext
    if (!richText) {
        if (textHasChanged) {
            if (styledText && !text.isEmpty()) {
                layout.setFont(font);
                // needs temporary bool because formatModifiesFontSize is in a bit-field
                bool fontSizeModified = false;
                QList<QQuickStyledTextImgTag*> someImgTags = extra.isAllocated() ? extra->imgTags : QList<QQuickStyledTextImgTag*>();
                QQuickStyledText::parse(text, layout, someImgTags, q->baseUrl(), qmlContext(q), !maximumLineCountValid, &fontSizeModified);
                if (someImgTags.size() || extra.isAllocated())
                    extra.value().imgTags = someImgTags;
                formatModifiesFontSize = fontSizeModified;
                multilengthEos = -1;
            } else {
                QString tmp = text;
                multilengthEos = tmp.indexOf(QLatin1Char('\x9c'));
                if (multilengthEos != -1)
                    tmp = tmp.mid(0, multilengthEos);
                tmp.replace(QLatin1Char('\n'), QChar::LineSeparator);
                layout.setText(tmp);
            }
            textHasChanged = false;
        }
    } else if (extra.isAllocated() && extra->lineHeightValid) {
        ensureDoc();
        QTextBlockFormat::LineHeightTypes type;
        type = lineHeightMode() == QQuickText::FixedHeight ? QTextBlockFormat::FixedHeight : QTextBlockFormat::ProportionalHeight;
        QTextBlockFormat blockFormat;
        blockFormat.setLineHeight((lineHeightMode() == QQuickText::FixedHeight ? lineHeight() : lineHeight() * 100), type);
        for (QTextBlock it = extra->doc->begin(); it != extra->doc->end(); it = it.next()) {
            QTextCursor cursor(it);
            cursor.mergeBlockFormat(blockFormat);
        }
    }

    updateSize();

    if (needToUpdateLayout) {
        needToUpdateLayout = false;
        textHasChanged = true;
        updateLayout();
    }

    q->polish();
}

void QQuickText::imageDownloadFinished()
{
    Q_D(QQuickText);

    (d->extra->nbActiveDownloads)--;

    // when all the remote images have been downloaded,
    // if one of the sizes was not specified at parsing time
    // we use the implicit size from pixmapcache and re-layout.

    if (d->extra.isAllocated() && d->extra->nbActiveDownloads == 0) {
        bool needToUpdateLayout = false;
        for (QQuickStyledTextImgTag *img : qAsConst(d->extra->visibleImgTags)) {
            if (!img->size.isValid()) {
                img->size = img->pix->implicitSize();
                needToUpdateLayout = true;
            }
        }

        if (needToUpdateLayout) {
            d->textHasChanged = true;
            d->updateLayout();
        } else {
            d->updateType = QQuickTextPrivate::UpdatePaintNode;
            update();
        }
    }
}

void QQuickTextPrivate::updateBaseline(qreal baseline, qreal dy)
{
    Q_Q(QQuickText);

    qreal yoff = 0;

    if (q->heightValid()) {
        if (vAlign == QQuickText::AlignBottom)
            yoff = dy;
        else if (vAlign == QQuickText::AlignVCenter)
            yoff = dy/2;
    }

    q->setBaselineOffset(baseline + yoff + q->topPadding());
}

void QQuickTextPrivate::signalSizeChange(const QSizeF &previousSize)
{
    Q_Q(QQuickText);

    if (layedOutTextRect.size() != previousSize) {
        emit q->contentSizeChanged();
        if (layedOutTextRect.width() != previousSize.width())
            emit q->contentWidthChanged(layedOutTextRect.width());
        if (layedOutTextRect.height() != previousSize.height())
            emit q->contentHeightChanged(layedOutTextRect.height());
    }
}

void QQuickTextPrivate::updateSize()
{
    Q_Q(QQuickText);

    if (!q->isComponentComplete()) {
        updateOnComponentComplete = true;
        return;
    }

    if (!requireImplicitSize) {
        implicitWidthChanged();
        implicitHeightChanged();
        // if the implicitWidth is used, then updateSize() has already been called (recursively)
        if (requireImplicitSize)
            return;
    }

    qreal hPadding = q->leftPadding() + q->rightPadding();
    qreal vPadding = q->topPadding() + q->bottomPadding();

    const QSizeF previousSize = layedOutTextRect.size();

    if (text.isEmpty() && !isLineLaidOutConnected() && fontSizeMode() == QQuickText::FixedSize) {
        // How much more expensive is it to just do a full layout on an empty string here?
        // There may be subtle differences in the height and baseline calculations between
        // QTextLayout and QFontMetrics and the number of variables that can affect the size
        // and position of a line is increasing.
        QFontMetricsF fm(font);
        qreal fontHeight = qCeil(fm.height());  // QScriptLine and therefore QTextLine rounds up
        if (!richText) {                        // line height, so we will as well.
            fontHeight = lineHeightMode() == QQuickText::FixedHeight
                    ? lineHeight()
                    : fontHeight * lineHeight();
        }
        updateBaseline(fm.ascent(), q->height() - fontHeight - vPadding);
        q->setImplicitSize(hPadding, fontHeight + vPadding);
        layedOutTextRect = QRectF(0, 0, 0, fontHeight);
        advance = QSizeF();
        signalSizeChange(previousSize);
        updateType = UpdatePaintNode;
        q->update();
        return;
    }

    QSizeF size(0, 0);

    //setup instance of QTextLayout for all cases other than richtext
    if (!richText) {
        qreal baseline = 0;
        QRectF textRect = setupTextLayout(&baseline);

        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();
        updateBaseline(baseline, q->height() - size.height() - vPadding);
    } else {
        widthExceeded = true; // always relayout rich text on width changes..
        heightExceeded = false; // rich text layout isn't affected by height changes.
        ensureDoc();
        extra->doc->setDefaultFont(font);
        QQuickText::HAlignment horizontalAlignment = q->effectiveHAlign();
        if (rightToLeftText) {
            if (horizontalAlignment == QQuickText::AlignLeft)
                horizontalAlignment = QQuickText::AlignRight;
            else if (horizontalAlignment == QQuickText::AlignRight)
                horizontalAlignment = QQuickText::AlignLeft;
        }
        QTextOption option;
        option.setAlignment((Qt::Alignment)int(horizontalAlignment | vAlign));
        option.setWrapMode(QTextOption::WrapMode(wrapMode));
        option.setUseDesignMetrics(renderType != QQuickText::NativeRendering);
        extra->doc->setDefaultTextOption(option);
        qreal naturalWidth = 0;
        if (requireImplicitSize && q->widthValid()) {
            extra->doc->setTextWidth(-1);
            naturalWidth = extra->doc->idealWidth();
            const bool wasInLayout = internalWidthUpdate;
            internalWidthUpdate = true;
            q->setImplicitWidth(naturalWidth + hPadding);
            internalWidthUpdate = wasInLayout;
        }
        if (internalWidthUpdate)
            return;

        extra->doc->setPageSize(QSizeF(q->width(), -1));
        if (q->widthValid() && (wrapMode != QQuickText::NoWrap || extra->doc->idealWidth() < availableWidth()))
            extra->doc->setTextWidth(availableWidth());
        else
            extra->doc->setTextWidth(extra->doc->idealWidth()); // ### Text does not align if width is not set (QTextDoc bug)

        QSizeF dsize = extra->doc->size();
        layedOutTextRect = QRectF(QPointF(0,0), dsize);
        size = QSizeF(extra->doc->idealWidth(),dsize.height());

        QFontMetricsF fm(font);
        updateBaseline(fm.ascent(), q->height() - size.height() - vPadding);

        //### need to confirm cost of always setting these for richText
        internalWidthUpdate = true;
        qreal oldWidth = q->width();
        qreal iWidth = -1;
        if (!q->widthValid())
            iWidth = size.width();
        if (iWidth > -1)
            q->setImplicitSize(iWidth + hPadding, size.height() + vPadding);
        internalWidthUpdate = false;

        // If the implicit width update caused a recursive change of the width,
        // we will have skipped integral parts of the layout due to the
        // internalWidthUpdate recursion guard. To make sure everything is up
        // to date, we need to run a second pass over the layout when updateSize()
        // is done.
        if (!qFuzzyCompare(q->width(), oldWidth) && !updateSizeRecursionGuard) {
            updateSizeRecursionGuard = true;
            updateSize();
            updateSizeRecursionGuard = false;
        } else {
            if (iWidth == -1)
                q->setImplicitHeight(size.height() + vPadding);

            QTextBlock firstBlock = extra->doc->firstBlock();
            while (firstBlock.layout()->lineCount() == 0)
                firstBlock = firstBlock.next();

            QTextBlock lastBlock = extra->doc->lastBlock();
            while (lastBlock.layout()->lineCount() == 0)
                lastBlock = lastBlock.previous();

            if (firstBlock.lineCount() > 0 && lastBlock.lineCount() > 0) {
                QTextLine firstLine = firstBlock.layout()->lineAt(0);
                QTextLine lastLine = lastBlock.layout()->lineAt(lastBlock.layout()->lineCount() - 1);
                advance = QSizeF(lastLine.horizontalAdvance(),
                                 (lastLine.y() + lastBlock.layout()->position().y()) - (firstLine.y() + firstBlock.layout()->position().y()));
            } else {
                advance = QSizeF();
            }
        }
    }

    signalSizeChange(previousSize);
    updateType = UpdatePaintNode;
    q->update();
}

QQuickTextLine::QQuickTextLine()
    : QObject(), m_line(nullptr), m_height(0), m_lineOffset(0)
{
}

void QQuickTextLine::setLine(QTextLine *line)
{
    m_line = line;
}

void QQuickTextLine::setLineOffset(int offset)
{
    m_lineOffset = offset;
}

int QQuickTextLine::number() const
{
    if (m_line)
        return m_line->lineNumber() + m_lineOffset;
    return 0;
}

qreal QQuickTextLine::width() const
{
    if (m_line)
        return m_line->width();
    return 0;
}

void QQuickTextLine::setWidth(qreal width)
{
    if (m_line)
        m_line->setLineWidth(width);
}

qreal QQuickTextLine::height() const
{
    if (m_height)
        return m_height;
    if (m_line)
        return m_line->height();
    return 0;
}

void QQuickTextLine::setHeight(qreal height)
{
    if (m_line)
        m_line->setPosition(QPointF(m_line->x(), m_line->y() - m_line->height() + height));
    m_height = height;
}

qreal QQuickTextLine::x() const
{
    if (m_line)
        return m_line->x();
    return 0;
}

void QQuickTextLine::setX(qreal x)
{
    if (m_line)
        m_line->setPosition(QPointF(x, m_line->y()));
}

qreal QQuickTextLine::y() const
{
    if (m_line)
        return m_line->y();
    return 0;
}

void QQuickTextLine::setY(qreal y)
{
    if (m_line)
        m_line->setPosition(QPointF(m_line->x(), y));
}

bool QQuickTextPrivate::isLineLaidOutConnected()
{
    Q_Q(QQuickText);
    IS_SIGNAL_CONNECTED(q, QQuickText, lineLaidOut, (QQuickTextLine *));
}

void QQuickTextPrivate::setupCustomLineGeometry(QTextLine &line, qreal &height, int lineOffset)
{
    Q_Q(QQuickText);

    if (!textLine)
        textLine = new QQuickTextLine;
    textLine->setLine(&line);
    textLine->setY(height);
    textLine->setHeight(0);
    textLine->setLineOffset(lineOffset);

    // use the text item's width by default if it has one and wrap is on or text must be aligned
    if (q->widthValid() && (q->wrapMode() != QQuickText::NoWrap ||
                            q->effectiveHAlign() != QQuickText::AlignLeft))
        textLine->setWidth(availableWidth());
    else
        textLine->setWidth(INT_MAX);
    if (lineHeight() != 1.0)
        textLine->setHeight((lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : line.height() * lineHeight());

    emit q->lineLaidOut(textLine);

    height += textLine->height();
}

void QQuickTextPrivate::elideFormats(
        const int start, const int length, int offset, QVector<QTextLayout::FormatRange> *elidedFormats)
{
    const int end = start + length;
    const QVector<QTextLayout::FormatRange> formats = layout.formats();
    for (int i = 0; i < formats.count(); ++i) {
        QTextLayout::FormatRange format = formats.at(i);
        const int formatLength = qMin(format.start + format.length, end) - qMax(format.start, start);
        if (formatLength > 0) {
            format.start = qMax(offset, format.start - start + offset);
            format.length = formatLength;
            elidedFormats->append(format);
        }
    }
}

QString QQuickTextPrivate::elidedText(qreal lineWidth, const QTextLine &line, QTextLine *nextLine) const
{
    if (nextLine) {
        return layout.engine()->elidedText(
                Qt::TextElideMode(elideMode),
                QFixed::fromReal(lineWidth),
                0,
                line.textStart(),
                line.textLength() + nextLine->textLength());
    } else {
        QString elideText = layout.text().mid(line.textStart(), line.textLength());
        if (!styledText) {
            // QFontMetrics won't help eliding styled text.
            elideText[elideText.length() - 1] = elideChar;
            // Appending the elide character may push the line over the maximum width
            // in which case the elided text will need to be elided.
            QFontMetricsF metrics(layout.font());
            if (metrics.horizontalAdvance(elideChar) + line.naturalTextWidth() >= lineWidth)
                elideText = metrics.elidedText(elideText, Qt::TextElideMode(elideMode), lineWidth);
        }
        return elideText;
    }
}

void QQuickTextPrivate::clearFormats()
{
    layout.clearFormats();
    if (elideLayout)
        elideLayout->clearFormats();
}

/*!
    Lays out the QQuickTextPrivate::layout QTextLayout in the constraints of the QQuickText.

    Returns the size of the final text.  This can be used to position the text vertically (the text is
    already absolutely positioned horizontally).
*/

QRectF QQuickTextPrivate::setupTextLayout(qreal *const baseline)
{
    Q_Q(QQuickText);

    bool singlelineElide = elideMode != QQuickText::ElideNone && q->widthValid();
    bool multilineElide = elideMode == QQuickText::ElideRight
            && q->widthValid()
            && (q->heightValid() || maximumLineCountValid);

    if ((!requireImplicitSize || (implicitWidthValid && implicitHeightValid))
            && ((singlelineElide && availableWidth() <= 0.)
                || (multilineElide && q->heightValid() && availableHeight() <= 0.))) {
        // we are elided and we have a zero width or height
        widthExceeded = q->widthValid() && availableWidth() <= 0.;
        heightExceeded = q->heightValid() && availableHeight() <= 0.;

        if (!truncated) {
            truncated = true;
            emit q->truncatedChanged();
        }
        if (lineCount) {
            lineCount = 0;
            emit q->lineCountChanged();
        }

        if (qFuzzyIsNull(q->width())) {
            layout.setText(QString());
            textHasChanged = true;
        }

        QFontMetricsF fm(font);
        qreal height = (lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : qCeil(fm.height()) * lineHeight();
        *baseline = fm.ascent();
        return QRectF(0, 0, 0, height);
    }

    bool shouldUseDesignMetrics = renderType != QQuickText::NativeRendering;
    if (extra.isAllocated())
        extra->visibleImgTags.clear();
    layout.setCacheEnabled(true);
    QTextOption textOption = layout.textOption();
    if (textOption.alignment() != q->effectiveHAlign()
            || textOption.wrapMode() != QTextOption::WrapMode(wrapMode)
            || textOption.useDesignMetrics() != shouldUseDesignMetrics) {
        textOption.setAlignment(Qt::Alignment(q->effectiveHAlign()));
        textOption.setWrapMode(QTextOption::WrapMode(wrapMode));
        textOption.setUseDesignMetrics(shouldUseDesignMetrics);
        layout.setTextOption(textOption);
    }
    if (layout.font() != font)
        layout.setFont(font);

    lineWidth = (q->widthValid() || implicitWidthValid) && q->width() > 0
            ? q->width()
            : FLT_MAX;
    qreal maxHeight = q->heightValid() ? availableHeight() : FLT_MAX;

    const bool customLayout = isLineLaidOutConnected();
    const bool wasTruncated = truncated;

    bool canWrap = wrapMode != QQuickText::NoWrap && q->widthValid();

    bool horizontalFit = fontSizeMode() & QQuickText::HorizontalFit && q->widthValid();
    bool verticalFit = fontSizeMode() & QQuickText::VerticalFit
            && (q->heightValid() || (maximumLineCountValid && canWrap));

    const bool pixelSize = font.pixelSize() != -1;
    QString layoutText = layout.text();

    int largeFont = pixelSize ? font.pixelSize() : font.pointSize();
    int smallFont = fontSizeMode() != QQuickText::FixedSize
            ? qMin(pixelSize ? minimumPixelSize() : minimumPointSize(), largeFont)
            : largeFont;
    int scaledFontSize = largeFont;

    bool widthChanged = false;
    widthExceeded = availableWidth() <= 0 && (singlelineElide || canWrap || horizontalFit);
    heightExceeded = availableHeight() <= 0 && (multilineElide || verticalFit);

    QRectF br;

    QFont scaledFont = font;

    int visibleCount = 0;
    bool elide;
    qreal height = 0;
    QString elideText;
    bool once = true;
    int elideStart = 0;
    int elideEnd = 0;
    bool noBreakLastLine = multilineElide && (wrapMode == QQuickText::Wrap || wrapMode == QQuickText::WordWrap);

    int eos = multilengthEos;

    // Repeated layouts with reduced font sizes or abbreviated strings may be required if the text
    // doesn't fit within the item dimensions,  or a binding to implicitWidth/Height changes
    // the item dimensions.
    for (;;) {
        if (!once) {
            if (pixelSize)
                scaledFont.setPixelSize(scaledFontSize);
            else
                scaledFont.setPointSize(scaledFontSize);
            if (layout.font() != scaledFont)
                layout.setFont(scaledFont);
        }

        layout.beginLayout();

        bool wrapped = false;
        bool truncateHeight = false;
        truncated = false;
        elide = false;
        int unwrappedLineCount = 1;
        int maxLineCount = maximumLineCount();
        height = 0;
        qreal naturalHeight = 0;
        qreal previousHeight = 0;
        br = QRectF();

        QRectF unelidedRect;
        QTextLine line = layout.createLine();
        for (visibleCount = 1; ; ++visibleCount) {
            if (noBreakLastLine && visibleCount == maxLineCount)
                layout.engine()->option.setWrapMode(QTextOption::WrapAnywhere);
            if (customLayout) {
                setupCustomLineGeometry(line, naturalHeight);
            } else {
                setLineGeometry(line, lineWidth, naturalHeight);
            }
            if (noBreakLastLine && visibleCount == maxLineCount)
                layout.engine()->option.setWrapMode(QTextOption::WrapMode(wrapMode));

            unelidedRect = br.united(line.naturalTextRect());

            // Elide the previous line if the accumulated height of the text exceeds the height
            // of the element.
            if (multilineElide && naturalHeight > maxHeight && visibleCount > 1) {
                elide = true;
                heightExceeded = true;
                if (eos != -1)  // There's an abbreviated string available, skip the rest as it's
                    break;      // all going to be discarded.

                truncated = true;
                truncateHeight = true;

                visibleCount -= 1;

                QTextLine previousLine = layout.lineAt(visibleCount - 1);
                elideText = layoutText.at(line.textStart() - 1) != QChar::LineSeparator
                        ? elidedText(line.width(), previousLine, &line)
                        : elidedText(line.width(), previousLine);
                elideStart = previousLine.textStart();
                // elideEnd isn't required for right eliding.

                height = previousHeight;
                break;
            }

            const QTextLine previousLine = line;
            line = layout.createLine();
            if (!line.isValid()) {
                if (singlelineElide && visibleCount == 1 && previousLine.naturalTextWidth() > previousLine.width()) {
                    // Elide a single previousLine of  text if its width exceeds the element width.
                    elide = true;
                    widthExceeded = true;
                    if (eos != -1) // There's an abbreviated string available.
                        break;

                    truncated = true;
                    elideText = layout.engine()->elidedText(
                            Qt::TextElideMode(elideMode),
                            QFixed::fromReal(previousLine.width()),
                            0,
                            previousLine.textStart(),
                            previousLine.textLength());
                    elideStart = previousLine.textStart();
                    elideEnd = elideStart + previousLine.textLength();
                } else {
                    br = unelidedRect;
                    height = naturalHeight;
                }
                break;
            } else {
                const bool wrappedLine = layoutText.at(line.textStart() - 1) != QChar::LineSeparator;
                wrapped |= wrappedLine;

                if (!wrappedLine)
                    ++unwrappedLineCount;

                // Stop if the maximum number of lines has been reached and elide the last line
                // if enabled.
                if (visibleCount == maxLineCount) {
                    truncated = true;
                    heightExceeded |= wrapped;

                    if (multilineElide) {
                        elide = true;
                        if (eos != -1)  // There's an abbreviated string available
                            break;
                        elideText = wrappedLine
                                ? elidedText(previousLine.width(), previousLine, &line)
                                : elidedText(previousLine.width(), previousLine);
                        elideStart = previousLine.textStart();
                        // elideEnd isn't required for right eliding.
                    } else {
                        br = unelidedRect;
                        height = naturalHeight;
                    }
                    break;
                }
            }
            br = unelidedRect;
            previousHeight = height;
            height = naturalHeight;
        }
        widthExceeded |= wrapped;

        // Save the implicit size of the text on the first layout only.
        if (once) {
            once = false;

            // If implicit sizes are required layout any additional lines up to the maximum line
            // count.
            if ((requireImplicitSize) && line.isValid() && unwrappedLineCount < maxLineCount) {
                // Layout the remainder of the wrapped lines up to maxLineCount to get the implicit
                // height.
                for (int lineCount = layout.lineCount(); lineCount < maxLineCount; ++lineCount) {
                    line = layout.createLine();
                    if (!line.isValid())
                        break;
                    if (layoutText.at(line.textStart() - 1) == QChar::LineSeparator)
                        ++unwrappedLineCount;
                    setLineGeometry(line, lineWidth, naturalHeight);
                }

                // Create the remainder of the unwrapped lines up to maxLineCount to get the
                // implicit width.
                const int eol = line.isValid()
                        ? line.textStart() + line.textLength()
                        : layoutText.length();
                if (eol < layoutText.length() && layoutText.at(eol) != QChar::LineSeparator)
                    line = layout.createLine();
                for (; line.isValid() && unwrappedLineCount <= maxLineCount; ++unwrappedLineCount)
                    line = layout.createLine();
            }
            layout.endLayout();

            const qreal naturalWidth = layout.maximumWidth();

            bool wasInLayout = internalWidthUpdate;
            internalWidthUpdate = true;
            q->setImplicitSize(naturalWidth + q->leftPadding() + q->rightPadding(), naturalHeight + q->topPadding() + q->bottomPadding());
            internalWidthUpdate = wasInLayout;

            // Update any variables that are dependent on the validity of the width or height.
            singlelineElide = elideMode != QQuickText::ElideNone && q->widthValid();
            multilineElide = elideMode == QQuickText::ElideRight
                    && q->widthValid()
                    && (q->heightValid() || maximumLineCountValid);
            canWrap = wrapMode != QQuickText::NoWrap && q->widthValid();

            horizontalFit = fontSizeMode() & QQuickText::HorizontalFit && q->widthValid();
            verticalFit = fontSizeMode() & QQuickText::VerticalFit
                    && (q->heightValid() || (maximumLineCountValid && canWrap));

            const qreal oldWidth = lineWidth;
            const qreal oldHeight = maxHeight;

            const qreal availWidth = availableWidth();
            const qreal availHeight = availableHeight();

            lineWidth = q->widthValid() && availWidth > 0 ? availWidth : naturalWidth;
            maxHeight = q->heightValid() ? availHeight : FLT_MAX;

            // If the width of the item has changed and it's possible the result of wrapping,
            // eliding, scaling has changed, or the text is not left aligned do another layout.
            if ((!qFuzzyCompare(lineWidth, oldWidth) || (widthExceeded && lineWidth > oldWidth))
                    && (singlelineElide || multilineElide || canWrap || horizontalFit
                        || q->effectiveHAlign() != QQuickText::AlignLeft)) {
                widthChanged = true;
                widthExceeded = lineWidth >= qMin(oldWidth, naturalWidth);
                heightExceeded = false;
                continue;
            }

            // If the height of the item has changed and it's possible the result of eliding,
            // line count truncation or scaling has changed, do another layout.
            if ((maxHeight < qMin(oldHeight, naturalHeight) || (heightExceeded && maxHeight > oldHeight))
                    && (multilineElide || (canWrap && maximumLineCountValid))) {
                widthExceeded = false;
                heightExceeded = false;
                continue;
            }

            // If the horizontal alignment is not left and the width was not valid we need to relayout
            // now that we know the maximum line width.
            if (!q->widthValid() && !implicitWidthValid && unwrappedLineCount > 1 && q->effectiveHAlign() != QQuickText::AlignLeft) {
                widthExceeded = false;
                heightExceeded = false;
                continue;
            }
        } else if (widthChanged) {
            widthChanged = false;
            if (line.isValid()) {
                for (int lineCount = layout.lineCount(); lineCount < maxLineCount; ++lineCount) {
                    line = layout.createLine();
                    if (!line.isValid())
                        break;
                    setLineGeometry(line, lineWidth, naturalHeight);
                }
            }
            layout.endLayout();

            bool wasInLayout = internalWidthUpdate;
            internalWidthUpdate = true;
            q->setImplicitHeight(naturalHeight + q->topPadding() + q->bottomPadding());
            internalWidthUpdate = wasInLayout;

            multilineElide = elideMode == QQuickText::ElideRight
                    && q->widthValid()
                    && (q->heightValid() || maximumLineCountValid);
            verticalFit = fontSizeMode() & QQuickText::VerticalFit
                    && (q->heightValid() || (maximumLineCountValid && canWrap));

            const qreal oldHeight = maxHeight;
            maxHeight = q->heightValid() ? availableHeight() : FLT_MAX;
            // If the height of the item has changed and it's possible the result of eliding,
            // line count truncation or scaling has changed, do another layout.
            if ((maxHeight < qMin(oldHeight, naturalHeight) || (heightExceeded && maxHeight > oldHeight))
                    && (multilineElide || (canWrap && maximumLineCountValid))) {
                widthExceeded = false;
                heightExceeded = false;
                continue;
            }
        } else {
            layout.endLayout();
        }

        // If the next needs to be elided and there's an abbreviated string available
        // go back and do another layout with the abbreviated string.
        if (eos != -1 && elide) {
            int start = eos + 1;
            eos = text.indexOf(QLatin1Char('\x9c'),  start);
            layoutText = text.mid(start, eos != -1 ? eos - start : -1);
            layoutText.replace(QLatin1Char('\n'), QChar::LineSeparator);
            layout.setText(layoutText);
            textHasChanged = true;
            continue;
        }

        br.moveTop(0);

        // Find the advance of the text layout
        if (layout.lineCount() > 0) {
            QTextLine firstLine = layout.lineAt(0);
            QTextLine lastLine = layout.lineAt(layout.lineCount() - 1);
            advance = QSizeF(lastLine.horizontalAdvance(),
                             lastLine.y() - firstLine.y());
        } else {
            advance = QSizeF();
        }

        if (!horizontalFit && !verticalFit)
            break;

        // Try and find a font size that better fits the dimensions of the element.
        if (horizontalFit) {
            if (unelidedRect.width() > lineWidth || (!verticalFit && wrapped)) {
                widthExceeded = true;
                largeFont = scaledFontSize - 1;
                if (smallFont > largeFont)
                    break;
                scaledFontSize = (smallFont + largeFont) / 2;
                if (pixelSize)
                    scaledFont.setPixelSize(scaledFontSize);
                else
                    scaledFont.setPointSize(scaledFontSize);
                continue;
            } else if (!verticalFit) {
                smallFont = scaledFontSize;
                if (smallFont == largeFont)
                    break;
                scaledFontSize = (smallFont + largeFont + 1) / 2;
            }
        }

        if (verticalFit) {
            if (truncateHeight || unelidedRect.height() > maxHeight) {
                heightExceeded = true;
                largeFont = scaledFontSize - 1;
                if (smallFont > largeFont)
                    break;
                scaledFontSize = (smallFont + largeFont) / 2;

            } else {
                smallFont = scaledFontSize;
                if (smallFont == largeFont)
                    break;
                scaledFontSize = (smallFont + largeFont + 1) / 2;
            }
        }
    }

    implicitWidthValid = true;
    implicitHeightValid = true;

    QFontInfo scaledFontInfo(scaledFont);
    if (fontInfo.weight() != scaledFontInfo.weight()
            || fontInfo.pixelSize() != scaledFontInfo.pixelSize()
            || fontInfo.italic() != scaledFontInfo.italic()
            || !qFuzzyCompare(fontInfo.pointSizeF(), scaledFontInfo.pointSizeF())
            || fontInfo.family() != scaledFontInfo.family()
            || fontInfo.styleName() != scaledFontInfo.styleName()) {
        fontInfo = scaledFontInfo;
        emit q->fontInfoChanged();
    }

    if (eos != multilengthEos)
        truncated = true;

    assignedFont = QFontInfo(font).family();

    if (elide) {
        if (!elideLayout) {
            elideLayout = new QTextLayout;
            elideLayout->setCacheEnabled(true);
        }
        QTextEngine *engine = layout.engine();
        if (engine && engine->hasFormats()) {
            QVector<QTextLayout::FormatRange> formats;
            switch (elideMode) {
            case QQuickText::ElideRight:
                elideFormats(elideStart, elideText.length() - 1, 0, &formats);
                break;
            case QQuickText::ElideLeft:
                elideFormats(elideEnd - elideText.length() + 1, elideText.length() - 1, 1, &formats);
                break;
            case QQuickText::ElideMiddle: {
                const int index = elideText.indexOf(elideChar);
                if (index != -1) {
                    elideFormats(elideStart, index, 0, &formats);
                    elideFormats(
                            elideEnd - elideText.length() + index + 1,
                            elideText.length() - index - 1,
                            index + 1,
                            &formats);
                }
                break;
            }
            default:
                break;
            }
            elideLayout->setFormats(formats);
        }

        elideLayout->setFont(layout.font());
        elideLayout->setTextOption(layout.textOption());
        elideLayout->setText(elideText);
        elideLayout->beginLayout();

        QTextLine elidedLine = elideLayout->createLine();
        elidedLine.setPosition(QPointF(0, height));
        if (customLayout) {
            setupCustomLineGeometry(elidedLine, height, visibleCount - 1);
        } else {
            setLineGeometry(elidedLine, lineWidth, height);
        }
        elideLayout->endLayout();

        br = br.united(elidedLine.naturalTextRect());

        if (visibleCount == 1)
            layout.clearLayout();
    } else {
        delete elideLayout;
        elideLayout = nullptr;
    }

    QTextLine firstLine = visibleCount == 1 && elideLayout
            ? elideLayout->lineAt(0)
            : layout.lineAt(0);
    Q_ASSERT(firstLine.isValid());
    *baseline = firstLine.y() + firstLine.ascent();

    if (!customLayout)
        br.setHeight(height);

    //Update the number of visible lines
    if (lineCount != visibleCount) {
        lineCount = visibleCount;
        emit q->lineCountChanged();
    }

    if (truncated != wasTruncated)
        emit q->truncatedChanged();

    return br;
}

void QQuickTextPrivate::setLineGeometry(QTextLine &line, qreal lineWidth, qreal &height)
{
    Q_Q(QQuickText);
    line.setLineWidth(lineWidth);

    if (extra.isAllocated() && extra->imgTags.isEmpty()) {
        line.setPosition(QPointF(line.position().x(), height));
        height += (lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : line.height() * lineHeight();
        return;
    }

    qreal textTop = 0;
    qreal textHeight = line.height();
    qreal totalLineHeight = textHeight;

    QList<QQuickStyledTextImgTag *> imagesInLine;

    if (extra.isAllocated()) {
        for (QQuickStyledTextImgTag *image : qAsConst(extra->imgTags)) {
            if (image->position >= line.textStart() &&
                image->position < line.textStart() + line.textLength()) {

                if (!image->pix) {
                    QUrl url = q->baseUrl().resolved(image->url);
                    image->pix = new QQuickPixmap(qmlEngine(q), url, image->size);
                    if (image->pix->isLoading()) {
                        image->pix->connectFinished(q, SLOT(imageDownloadFinished()));
                        if (!extra.isAllocated() || !extra->nbActiveDownloads)
                            extra.value().nbActiveDownloads = 0;
                        extra->nbActiveDownloads++;
                    } else if (image->pix->isReady()) {
                        if (!image->size.isValid()) {
                            image->size = image->pix->implicitSize();
                            // if the size of the image was not explicitly set, we need to
                            // call updateLayout() once again.
                            needToUpdateLayout = true;
                        }
                    } else if (image->pix->isError()) {
                        qmlWarning(q) << image->pix->error();
                    }
                }

                qreal ih = qreal(image->size.height());
                if (image->align == QQuickStyledTextImgTag::Top)
                    image->pos.setY(0);
                else if (image->align == QQuickStyledTextImgTag::Middle)
                    image->pos.setY((textHeight / 2.0) - (ih / 2.0));
                else
                    image->pos.setY(textHeight - ih);
                imagesInLine << image;
                textTop = qMax(textTop, qAbs(image->pos.y()));
            }
        }
    }

    for (QQuickStyledTextImgTag *image : qAsConst(imagesInLine)) {
        totalLineHeight = qMax(totalLineHeight, textTop + image->pos.y() + image->size.height());
        const int leadX = line.cursorToX(image->position);
        const int trailX = line.cursorToX(image->position, QTextLine::Trailing);
        const bool rtl = trailX < leadX;
        image->pos.setX(leadX + (rtl ? (-image->offset - image->size.width()) : image->offset));
        image->pos.setY(image->pos.y() + height + textTop);
        extra->visibleImgTags << image;
    }

    line.setPosition(QPointF(line.position().x(), height + textTop));
    height += (lineHeightMode() == QQuickText::FixedHeight) ? lineHeight() : totalLineHeight * lineHeight();
}

/*!
    Returns the y offset when aligning text with a non-1.0 lineHeight
*/
int QQuickTextPrivate::lineHeightOffset() const
{
    QFontMetricsF fm(font);
    qreal fontHeight = qCeil(fm.height());  // QScriptLine and therefore QTextLine rounds up
    return lineHeightMode() == QQuickText::FixedHeight ? fontHeight - lineHeight()
                                                       : (1.0 - lineHeight()) * fontHeight;
}

/*!
    Ensures the QQuickTextPrivate::doc variable is set to a valid text document
*/
void QQuickTextPrivate::ensureDoc()
{
    if (!extra.isAllocated() || !extra->doc) {
        Q_Q(QQuickText);
        extra.value().doc = new QQuickTextDocumentWithImageResources(q);
        extra->doc->setPageSize(QSizeF(0, 0));
        extra->doc->setDocumentMargin(0);
        extra->doc->setBaseUrl(q->baseUrl());
        qmlobject_connect(extra->doc, QQuickTextDocumentWithImageResources, SIGNAL(imagesLoaded()),
                          q, QQuickText, SLOT(q_updateLayout()));
    }
}

/*!
    \qmltype Text
    \instantiates QQuickText
    \inqmlmodule QtQuick
    \ingroup qtquick-visual
    \inherits Item
    \brief Specifies how to add formatted text to a scene.

    Text items can display both plain and rich text. For example, red text with
    a specific font and size can be defined like this:

    \qml
    Text {
        text: "Hello World!"
        font.family: "Helvetica"
        font.pointSize: 24
        color: "red"
    }
    \endqml

    Rich text is defined using HTML-style markup:

    \qml
    Text {
        text: "<b>Hello</b> <i>World!</i>"
    }
    \endqml

    \image declarative-text.png

    If height and width are not explicitly set, Text will attempt to determine how
    much room is needed and set it accordingly. Unless \l wrapMode is set, it will always
    prefer width to height (all text will be placed on a single line).

    The \l elide property can alternatively be used to fit a single line of
    plain text to a set width.

    Note that the \l{Supported HTML Subset} is limited. Also, if the text contains
    HTML img tags that load remote images, the text is reloaded.

    Text provides read-only text. For editable text, see \l TextEdit.

    \sa {Qt Quick Examples - Text#Fonts}{Fonts example}
*/
QQuickText::QQuickText(QQuickItem *parent)
: QQuickImplicitSizeItem(*(new QQuickTextPrivate), parent)
{
    Q_D(QQuickText);
    d->init();
}

QQuickText::QQuickText(QQuickTextPrivate &dd, QQuickItem *parent)
: QQuickImplicitSizeItem(dd, parent)
{
    Q_D(QQuickText);
    d->init();
}

QQuickText::~QQuickText()
{
}

/*!
  \qmlproperty bool QtQuick::Text::clip
  This property holds whether the text is clipped.

  Note that if the text does not fit in the bounding rectangle it will be abruptly chopped.

  If you want to display potentially long text in a limited space, you probably want to use \c elide instead.
*/

/*!
    \qmlsignal QtQuick::Text::lineLaidOut(object line)

    This signal is emitted for each line of text that is laid out during the layout
    process. The specified \a line object provides more details about the line that
    is currently being laid out.

    This gives the opportunity to position and resize a line as it is being laid out.
    It can for example be used to create columns or lay out text around objects.

    The properties of the specified \a line object are:
    \list
    \li number (read-only)
    \li x
    \li y
    \li width
    \li height
    \endlist

    For example, this will move the first 5 lines of a Text item by 100 pixels to the right:
    \code
    onLineLaidOut: {
        if (line.number < 5) {
            line.x = line.x + 100
            line.width = line.width - 100
        }
    }
    \endcode

    The corresponding handler is \c onLineLaidOut.
*/

/*!
    \qmlsignal QtQuick::Text::linkActivated(string link)

    This signal is emitted when the user clicks on a link embedded in the text.
    The link must be in rich text or HTML format and the
    \a link string provides access to the particular link.

    \snippet qml/text/onLinkActivated.qml 0

    The example code will display the text
    "See the \l{http://qt-project.org}{Qt Project website}."

    Clicking on the highlighted link will output
    \tt{http://qt-project.org link activated} to the console.

    The corresponding handler is \c onLinkActivated.
*/

/*!
    \qmlproperty string QtQuick::Text::font.family

    Sets the family name of the font.

    The family name is case insensitive and may optionally include a foundry name, e.g. "Helvetica [Cronyx]".
    If the family is available from more than one foundry and the foundry isn't specified, an arbitrary foundry is chosen.
    If the family isn't available a family will be set using the font matching algorithm.
*/

/*!
    \qmlproperty string QtQuick::Text::font.styleName
    \since 5.6

    Sets the style name of the font.

    The style name is case insensitive. If set, the font will be matched against style name instead
    of the font properties \l font.weight, \l font.bold and \l font.italic.
*/

/*!
    \qmlproperty bool QtQuick::Text::font.bold

    Sets whether the font weight is bold.
*/

/*!
    \qmlproperty enumeration QtQuick::Text::font.weight

    Sets the font's weight.

    The weight can be one of:
    \list
    \li Font.Thin
    \li Font.Light
    \li Font.ExtraLight
    \li Font.Normal - the default
    \li Font.Medium
    \li Font.DemiBold
    \li Font.Bold
    \li Font.ExtraBold
    \li Font.Black
    \endlist

    \qml
    Text { text: "Hello"; font.weight: Font.DemiBold }
    \endqml
*/

/*!
    \qmlproperty bool QtQuick::Text::font.italic

    Sets whether the font has an italic style.
*/

/*!
    \qmlproperty bool QtQuick::Text::font.underline

    Sets whether the text is underlined.
*/

/*!
    \qmlproperty bool QtQuick::Text::font.strikeout

    Sets whether the font has a strikeout style.
*/

/*!
    \qmlproperty real QtQuick::Text::font.pointSize

    Sets the font size in points. The point size must be greater than zero.
*/

/*!
    \qmlproperty int QtQuick::Text::font.pixelSize

    Sets the font size in pixels.

    Using this function makes the font device dependent.
    Use \c pointSize to set the size of the font in a device independent manner.
*/

/*!
    \qmlproperty real QtQuick::Text::font.letterSpacing

    Sets the letter spacing for the font.

    Letter spacing changes the default spacing between individual letters in the font.
    A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing.
*/

/*!
    \qmlproperty real QtQuick::Text::font.wordSpacing

    Sets the word spacing for the font.

    Word spacing changes the default spacing between individual words.
    A positive value increases the word spacing by a corresponding amount of pixels,
    while a negative value decreases the inter-word spacing accordingly.
*/

/*!
    \qmlproperty enumeration QtQuick::Text::font.capitalization

    Sets the capitalization for the text.

    \list
    \li Font.MixedCase - This is the normal text rendering option where no capitalization change is applied.
    \li Font.AllUppercase - This alters the text to be rendered in all uppercase type.
    \li Font.AllLowercase - This alters the text to be rendered in all lowercase type.
    \li Font.SmallCaps - This alters the text to be rendered in small-caps type.
    \li Font.Capitalize - This alters the text to be rendered with the first character of each word as an uppercase character.
    \endlist

    \qml
    Text { text: "Hello"; font.capitalization: Font.AllLowercase }
    \endqml
*/

/*!
    \qmlproperty enumeration QtQuick::Text::font.hintingPreference
    \since 5.8

    Sets the preferred hinting on the text. This is a hint to the underlying text rendering system
    to use a certain level of hinting, and has varying support across platforms. See the table in
    the documentation for QFont::HintingPreference for more details.

    \note This property only has an effect when used together with render type Text.NativeRendering.

    \list
    \value Font.PreferDefaultHinting - Use the default hinting level for the target platform.
    \value Font.PreferNoHinting - If possible, render text without hinting the outlines
           of the glyphs. The text layout will be typographically accurate, using the same metrics
           as are used e.g. when printing.
    \value Font.PreferVerticalHinting - If possible, render text with no horizontal hinting,
           but align glyphs to the pixel grid in the vertical direction. The text will appear
           crisper on displays where the density is too low to give an accurate rendering
           of the glyphs. But since the horizontal metrics of the glyphs are unhinted, the text's
           layout will be scalable to higher density devices (such as printers) without impacting
           details such as line breaks.
    \value Font.PreferFullHinting - If possible, render text with hinting in both horizontal and
           vertical directions. The text will be altered to optimize legibility on the target
           device, but since the metrics will depend on the target size of the text, the positions
           of glyphs, line breaks, and other typographical detail will not scale, meaning that a
           text layout may look different on devices with different pixel densities.
    \endlist

    \qml
    Text { text: "Hello"; renderType: Text.NativeRendering; font.hintingPreference: Font.PreferVerticalHinting }
    \endqml
*/

/*!
    \qmlproperty bool QtQuick::Text::font.kerning
    \since 5.10

    Enables or disables the kerning OpenType feature when shaping the text. Disabling this may
    improve performance when creating or changing the text, at the expense of some cosmetic
    features. The default value is true.

    \qml
    Text { text: "OATS FLAVOUR WAY"; font.kerning: false }
    \endqml
*/

/*!
    \qmlproperty bool QtQuick::Text::font.preferShaping
    \since 5.10

    Sometimes, a font will apply complex rules to a set of characters in order to
    display them correctly. In some writing systems, such as Brahmic scripts, this is
    required in order for the text to be legible, but in e.g. Latin script, it is merely
    a cosmetic feature. Setting the \c preferShaping property to false will disable all
    such features when they are not required, which will improve performance in most cases.

    The default value is true.

    \qml
    Text { text: "Some text"; font.preferShaping: false }
    \endqml
*/
QFont QQuickText::font() const
{
    Q_D(const QQuickText);
    return d->sourceFont;
}

void QQuickText::setFont(const QFont &font)
{
    Q_D(QQuickText);
    if (d->sourceFont == font)
        return;

    d->sourceFont = font;
    QFont oldFont = d->font;
    d->font = font;

    if (!antialiasing())
        d->font.setStyleStrategy(QFont::NoAntialias);

    if (d->font.pointSizeF() != -1) {
        // 0.5pt resolution
        qreal size = qRound(d->font.pointSizeF()*2.0);
        d->font.setPointSizeF(size/2.0);
    }

    if (oldFont != d->font) {
        // if the format changes the size of the text
        // with headings or <font> tag, we need to re-parse
        if (d->formatModifiesFontSize)
            d->textHasChanged = true;
        d->implicitWidthValid = false;
        d->implicitHeightValid = false;
        d->updateLayout();
    }

    emit fontChanged(d->sourceFont);
}

void QQuickText::itemChange(ItemChange change, const ItemChangeData &value)
{
    Q_D(QQuickText);
    Q_UNUSED(value);
    switch (change) {
    case ItemAntialiasingHasChanged:
        if (!antialiasing())
            d->font.setStyleStrategy(QFont::NoAntialias);
        else
            d->font.setStyleStrategy(QFont::PreferAntialias);
        d->implicitWidthValid = false;
        d->implicitHeightValid = false;
        d->updateLayout();
        break;

    case ItemDevicePixelRatioHasChanged:
        if (d->renderType == NativeRendering) {
            // Native rendering optimizes for a given pixel grid, so its results must not be scaled.
            // Text layout code respects the current device pixel ratio automatically, we only need
            // to rerun layout after the ratio changed.
            // Changes of implicit size should be minimal; they are hard to avoid.
            d->implicitWidthValid = false;
            d->implicitHeightValid = false;
            d->updateLayout();
        }
        break;

    default:
        break;
    }
    QQuickItem::itemChange(change, value);
}

/*!
    \qmlproperty string QtQuick::Text::text

    The text to display. Text supports both plain and rich text strings.

    The item will try to automatically determine whether the text should
    be treated as styled text. This determination is made using Qt::mightBeRichText().
*/
QString QQuickText::text() const
{
    Q_D(const QQuickText);
    return d->text;
}

void QQuickText::setText(const QString &n)
{
    Q_D(QQuickText);
    if (d->text == n)
        return;

    d->markdownText = d->format == MarkdownText;
    d->richText = d->format == RichText || d->markdownText;
    d->styledText = d->format == StyledText || (d->format == AutoText && Qt::mightBeRichText(n));
    d->text = n;
    if (isComponentComplete()) {
        if (d->richText) {
            d->ensureDoc();
            if (d->markdownText)
                d->extra->doc->setMarkdownText(n);
            else
                d->extra->doc->setText(n);
            d->rightToLeftText = d->extra->doc->toPlainText().isRightToLeft();
        } else {
            d->clearFormats();
            d->rightToLeftText = d->text.isRightToLeft();
        }
        d->determineHorizontalAlignment();
    }
    d->textHasChanged = true;
    d->implicitWidthValid = false;
    d->implicitHeightValid = false;

    if (d->extra.isAllocated()) {
        qDeleteAll(d->extra->imgTags);
        d->extra->imgTags.clear();
    }
    d->updateLayout();
    setAcceptHoverEvents(d->richText || d->styledText);
    emit textChanged(d->text);
}

/*!
    \qmlproperty color QtQuick::Text::color

    The text color.

    An example of green text defined using hexadecimal notation:
    \qml
    Text {
        color: "#00FF00"
        text: "green text"
    }
    \endqml

    An example of steel blue text defined using an SVG color name:
    \qml
    Text {
        color: "steelblue"
        text: "blue text"
    }
    \endqml
*/
QColor QQuickText::color() const
{
    Q_D(const QQuickText);
    return QColor::fromRgba(d->color);
}

void QQuickText::setColor(const QColor &color)
{
    Q_D(QQuickText);
    QRgb rgb = color.rgba();
    if (d->color == rgb)
        return;

    d->color = rgb;
    if (isComponentComplete())  {
        d->updateType = QQuickTextPrivate::UpdatePaintNode;
        update();
    }
    emit colorChanged();
}

/*!
    \qmlproperty color QtQuick::Text::linkColor

    The color of links in the text.

    This property works with the StyledText \l textFormat, but not with RichText.
    Link color in RichText can be specified by including CSS style tags in the
    text.
*/

QColor QQuickText::linkColor() const
{
    Q_D(const QQuickText);
    return QColor::fromRgba(d->linkColor);
}

void QQuickText::setLinkColor(const QColor &color)
{
    Q_D(QQuickText);
    QRgb rgb = color.rgba();
    if (d->linkColor == rgb)
        return;

    d->linkColor = rgb;
    if (isComponentComplete()) {
        d->updateType = QQuickTextPrivate::UpdatePaintNode;
        update();
    }
    emit linkColorChanged();
}

/*!
    \qmlproperty enumeration QtQuick::Text::style

    Set an additional text style.

    Supported text styles are:
    \list
    \li Text.Normal - the default
    \li Text.Outline
    \li Text.Raised
    \li Text.Sunken
    \endlist

    \qml
    Row {
        Text { font.pointSize: 24; text: "Normal" }
        Text { font.pointSize: 24; text: "Raised"; style: Text.Raised; styleColor: "#AAAAAA" }
        Text { font.pointSize: 24; text: "Outline";style: Text.Outline; styleColor: "red" }
        Text { font.pointSize: 24; text: "Sunken"; style: Text.Sunken; styleColor: "#AAAAAA" }
    }
    \endqml

    \image declarative-textstyle.png
*/
QQuickText::TextStyle QQuickText::style() const
{
    Q_D(const QQuickText);
    return d->style;
}

void QQuickText::setStyle(QQuickText::TextStyle style)
{
    Q_D(QQuickText);
    if (d->style == style)
        return;

    d->style = style;
    if (isComponentComplete()) {
        d->updateType = QQuickTextPrivate::UpdatePaintNode;
        update();
    }
    emit styleChanged(d->style);
}

/*!
    \qmlproperty color QtQuick::Text::styleColor

    Defines the secondary color used by text styles.

    \c styleColor is used as the outline color for outlined text, and as the
    shadow color for raised or sunken text. If no style has been set, it is not
    used at all.

    \qml
    Text { font.pointSize: 18; text: "hello"; style: Text.Raised; styleColor: "gray" }
    \endqml

    \sa style
 */
QColor QQuickText::styleColor() const
{
    Q_D(const QQuickText);
    return QColor::fromRgba(d->styleColor);
}

void QQuickText::setStyleColor(const QColor &color)
{
    Q_D(QQuickText);
    QRgb rgb = color.rgba();
    if (d->styleColor == rgb)
        return;

    d->styleColor = rgb;
    if (isComponentComplete()) {
        d->updateType = QQuickTextPrivate::UpdatePaintNode;
        update();
    }
    emit styleColorChanged();
}

/*!
    \qmlproperty enumeration QtQuick::Text::horizontalAlignment
    \qmlproperty enumeration QtQuick::Text::verticalAlignment
    \qmlproperty enumeration QtQuick::Text::effectiveHorizontalAlignment

    Sets the horizontal and vertical alignment of the text within the Text items
    width and height. By default, the text is vertically aligned to the top. Horizontal
    alignment follows the natural alignment of the text, for example text that is read
    from left to right will be aligned to the left.

    The valid values for \c horizontalAlignment are \c Text.AlignLeft, \c Text.AlignRight, \c Text.AlignHCenter and
    \c Text.AlignJustify.  The valid values for \c verticalAlignment are \c Text.AlignTop, \c Text.AlignBottom
    and \c Text.AlignVCenter.

    Note that for a single line of text, the size of the text is the area of the text. In this common case,
    all alignments are equivalent. If you want the text to be, say, centered in its parent, then you will
    need to either modify the Item::anchors, or set horizontalAlignment to Text.AlignHCenter and bind the width to
    that of the parent.

    When using the attached property LayoutMirroring::enabled to mirror application
    layouts, the horizontal alignment of text will also be mirrored. However, the property
    \c horizontalAlignment will remain unchanged. To query the effective horizontal alignment
    of Text, use the read-only property \c effectiveHorizontalAlignment.
*/
QQuickText::HAlignment QQuickText::hAlign() const
{
    Q_D(const QQuickText);
    return d->hAlign;
}

void QQuickText::setHAlign(HAlignment align)
{
    Q_D(QQuickText);
    bool forceAlign = d->hAlignImplicit && d->effectiveLayoutMirror;
    d->hAlignImplicit = false;
    if (d->setHAlign(align, forceAlign) && isComponentComplete())
        d->updateLayout();
}

void QQuickText::resetHAlign()
{
    Q_D(QQuickText);
    d->hAlignImplicit = true;
    if (isComponentComplete() && d->determineHorizontalAlignment())
        d->updateLayout();
}

QQuickText::HAlignment QQuickText::effectiveHAlign() const
{
    Q_D(const QQuickText);
    QQuickText::HAlignment effectiveAlignment = d->hAlign;
    if (!d->hAlignImplicit && d->effectiveLayoutMirror) {
        switch (d->hAlign) {
        case QQuickText::AlignLeft:
            effectiveAlignment = QQuickText::AlignRight;
            break;
        case QQuickText::AlignRight:
            effectiveAlignment = QQuickText::AlignLeft;
            break;
        default:
            break;
        }
    }
    return effectiveAlignment;
}

bool QQuickTextPrivate::setHAlign(QQuickText::HAlignment alignment, bool forceAlign)
{
    Q_Q(QQuickText);
    if (hAlign != alignment || forceAlign) {
        QQuickText::HAlignment oldEffectiveHAlign = q->effectiveHAlign();
        hAlign = alignment;

        emit q->horizontalAlignmentChanged(hAlign);
        if (oldEffectiveHAlign != q->effectiveHAlign())
            emit q->effectiveHorizontalAlignmentChanged();
        return true;
    }
    return false;
}

bool QQuickTextPrivate::determineHorizontalAlignment()
{
    if (hAlignImplicit) {
#if QT_CONFIG(im)
        bool alignToRight = text.isEmpty() ? QGuiApplication::inputMethod()->inputDirection() == Qt::RightToLeft : rightToLeftText;
#else
        bool alignToRight = rightToLeftText;
#endif
        return setHAlign(alignToRight ? QQuickText::AlignRight : QQuickText::AlignLeft);
    }
    return false;
}

void QQuickTextPrivate::mirrorChange()
{
    Q_Q(QQuickText);
    if (q->isComponentComplete()) {
        if (!hAlignImplicit && (hAlign == QQuickText::AlignRight || hAlign == QQuickText::AlignLeft)) {
            updateLayout();
            emit q->effectiveHorizontalAlignmentChanged();
        }
    }
}

QQuickText::VAlignment QQuickText::vAlign() const
{
    Q_D(const QQuickText);
    return d->vAlign;
}

void QQuickText::setVAlign(VAlignment align)
{
    Q_D(QQuickText);
    if (d->vAlign == align)
        return;

    d->vAlign = align;

    if (isComponentComplete())
        d->updateLayout();

    emit verticalAlignmentChanged(align);
}

/*!
    \qmlproperty enumeration QtQuick::Text::wrapMode

    Set this property to wrap the text to the Text item's width.  The text will only
    wrap if an explicit width has been set.  wrapMode can be one of:

    \list
    \li Text.NoWrap (default) - no wrapping will be performed. If the text contains insufficient newlines, then \l contentWidth will exceed a set width.
    \li Text.WordWrap - wrapping is done on word boundaries only. If a word is too long, \l contentWidth will exceed a set width.
    \li Text.WrapAnywhere - wrapping is done at any point on a line, even if it occurs in the middle of a word.
    \li Text.Wrap - if possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word.
    \endlist
*/
QQuickText::WrapMode QQuickText::wrapMode() const
{
    Q_D(const QQuickText);
    return d->wrapMode;
}

void QQuickText::setWrapMode(WrapMode mode)
{
    Q_D(QQuickText);
    if (mode == d->wrapMode)
        return;

    d->wrapMode = mode;
    d->updateLayout();

    emit wrapModeChanged();
}

/*!
    \qmlproperty int QtQuick::Text::lineCount

    Returns the number of lines visible in the text item.

    This property is not supported for rich text.

    \sa maximumLineCount
*/
int QQuickText::lineCount() const
{
    Q_D(const QQuickText);
    return d->lineCount;
}

/*!
    \qmlproperty bool QtQuick::Text::truncated

    Returns true if the text has been truncated due to \l maximumLineCount
    or \l elide.

    This property is not supported for rich text.

    \sa maximumLineCount, elide
*/
bool QQuickText::truncated() const
{
    Q_D(const QQuickText);
    return d->truncated;
}

/*!
    \qmlproperty int QtQuick::Text::maximumLineCount

    Set this property to limit the number of lines that the text item will show.
    If elide is set to Text.ElideRight, the text will be elided appropriately.
    By default, this is the value of the largest possible integer.

    This property is not supported for rich text.

    \sa lineCount, elide
*/
int QQuickText::maximumLineCount() const
{
    Q_D(const QQuickText);
    return d->maximumLineCount();
}

void QQuickText::setMaximumLineCount(int lines)
{
    Q_D(QQuickText);

    d->maximumLineCountValid = lines==INT_MAX ? false : true;
    if (d->maximumLineCount() != lines) {
        d->extra.value().maximumLineCount = lines;
        d->implicitHeightValid = false;
        d->updateLayout();
        emit maximumLineCountChanged();
    }
}

void QQuickText::resetMaximumLineCount()
{
    Q_D(QQuickText);
    setMaximumLineCount(INT_MAX);
    if (d->truncated != false) {
        d->truncated = false;
        emit truncatedChanged();
    }
}

/*!
    \qmlproperty enumeration QtQuick::Text::textFormat

    The way the text property should be displayed.

    Supported text formats are:

    \list
    \li Text.AutoText (default)
    \li Text.PlainText
    \li Text.StyledText
    \li Text.RichText
    \endlist

    If the text format is \c Text.AutoText the Text item
    will automatically determine whether the text should be treated as
    styled text.  This determination is made using Qt::mightBeRichText()
    which uses a fast and therefore simple heuristic. It mainly checks
    whether there is something that looks like a tag before the first
    line break. Although the result may be correct for common cases,
    there is no guarantee.

    Text.StyledText is an optimized format supporting some basic text
    styling markup, in the style of HTML 3.2:

    \code
    <b></b> - bold
    <del></del> - strike out (removed content)
    <s></s> - strike out (no longer accurate or no longer relevant content)
    <strong></strong> - bold
    <i></i> - italic
    <br> - new line
    <p> - paragraph
    <u> - underlined text
    <font color="color_name" size="1-7"></font>
    <h1> to <h6> - headers
    <a href=""> - anchor
    <img src="" align="top,middle,bottom" width="" height=""> - inline images
    <ol type="">, <ul type=""> and <li> - ordered and unordered lists
    <pre></pre> - preformatted
    &gt; &lt; &amp;
    \endcode

    \c Text.StyledText parser is strict, requiring tags to be correctly nested.

    \table
    \row
    \li
    \qml
Column {
    Text {
        font.pointSize: 24
        text: "<b>Hello</b> <i>World!</i>"
    }
    Text {
        font.pointSize: 24
        textFormat: Text.RichText
        text: "<b>Hello</b> <i>World!</i>"
    }
    Text {
        font.pointSize: 24
        textFormat: Text.PlainText
        text: "<b>Hello</b> <i>World!</i>"
    }
}
    \endqml
    \li \image declarative-textformat.png
    \endtable

    Text.RichText supports a larger subset of HTML 4, as described on the
    \l {Supported HTML Subset} page. You should prefer using Text.PlainText
    or Text.StyledText instead, as they offer better performance.
*/
QQuickText::TextFormat QQuickText::textFormat() const
{
    Q_D(const QQuickText);
    return d->format;
}

void QQuickText::setTextFormat(TextFormat format)
{
    Q_D(QQuickText);
    if (format == d->format)
        return;
    d->format = format;
    bool wasRich = d->richText;
    d->markdownText = format == MarkdownText;
    d->richText = format == RichText || d->markdownText;
    d->styledText = format == StyledText || (format == AutoText && Qt::mightBeRichText(d->text));

    if (isComponentComplete()) {
        if (!wasRich && d->richText) {
            d->ensureDoc();
            d->extra->doc->setText(d->text);
            d->rightToLeftText = d->extra->doc->toPlainText().isRightToLeft();
        } else {
            d->clearFormats();
            d->rightToLeftText = d->text.isRightToLeft();
            d->textHasChanged = true;
        }
        d->determineHorizontalAlignment();
    }
    d->updateLayout();
    setAcceptHoverEvents(d->richText || d->styledText);
    setAcceptedMouseButtons(d->richText || d->styledText ? Qt::LeftButton : Qt::NoButton);

    emit textFormatChanged(d->format);
}

/*!
    \qmlproperty enumeration QtQuick::Text::elide

    Set this property to elide parts of the text fit to the Text item's width.
    The text will only elide if an explicit width has been set.

    This property cannot be used with rich text.

    Eliding can be:
    \list
    \li Text.ElideNone  - the default
    \li Text.ElideLeft
    \li Text.ElideMiddle
    \li Text.ElideRight
    \endlist

    If this property is set to Text.ElideRight, it can be used with \l {wrapMode}{wrapped}
    text. The text will only elide if \c maximumLineCount, or \c height has been set.
    If both \c maximumLineCount and \c height are set, \c maximumLineCount will
    apply unless the lines do not fit in the height allowed.

    If the text is a multi-length string, and the mode is not \c Text.ElideNone,
    the first string that fits will be used, otherwise the last will be elided.

    Multi-length strings are ordered from longest to shortest, separated by the
    Unicode "String Terminator" character \c U009C (write this in QML with \c{"\u009C"} or \c{"\x9C"}).
*/
QQuickText::TextElideMode QQuickText::elideMode() const
{
    Q_D(const QQuickText);
    return d->elideMode;
}

void QQuickText::setElideMode(QQuickText::TextElideMode mode)
{
    Q_D(QQuickText);
    if (mode == d->elideMode)
        return;

    d->elideMode = mode;
    d->updateLayout();

    emit elideModeChanged(mode);
}

/*!
    \qmlproperty url QtQuick::Text::baseUrl

    This property specifies a base URL which is used to resolve relative URLs
    within the text.

    Urls are resolved to be within the same directory as the target of the base
    URL meaning any portion of the path after the last '/' will be ignored.

    \table
    \header \li Base URL \li Relative URL \li Resolved URL
    \row \li http://qt-project.org/ \li images/logo.png \li http://qt-project.org/images/logo.png
    \row \li http://qt-project.org/index.html \li images/logo.png \li http://qt-project.org/images/logo.png
    \row \li http://qt-project.org/content \li images/logo.png \li http://qt-project.org/content/images/logo.png
    \row \li http://qt-project.org/content/ \li images/logo.png \li http://qt-project.org/content/images/logo.png
    \row \li http://qt-project.org/content/index.html \li images/logo.png \li http://qt-project.org/content/images/logo.png
    \row \li http://qt-project.org/content/index.html \li ../images/logo.png \li http://qt-project.org/images/logo.png
    \row \li http://qt-project.org/content/index.html \li /images/logo.png \li http://qt-project.org/images/logo.png
    \endtable

    The default value is the url of the QML file instantiating the Text item.
*/

QUrl QQuickText::baseUrl() const
{
    Q_D(const QQuickText);
    if (!d->extra.isAllocated() || d->extra->baseUrl.isEmpty()) {
        if (QQmlContext *context = qmlContext(this))
            return context->baseUrl();
        else
            return QUrl();
    } else {
        return d->extra->baseUrl;
    }
}

void QQuickText::setBaseUrl(const QUrl &url)
{
    Q_D(QQuickText);
    if (baseUrl() != url) {
        d->extra.value().baseUrl = url;

        if (d->richText) {
            d->ensureDoc();
            d->extra->doc->setBaseUrl(url);
        }
        if (d->styledText) {
            d->textHasChanged = true;
            if (d->extra.isAllocated()) {
                qDeleteAll(d->extra->imgTags);
                d->extra->imgTags.clear();
            }
            d->updateLayout();
        }
        emit baseUrlChanged();
    }
}

void QQuickText::resetBaseUrl()
{
    if (QQmlContext *context = qmlContext(this))
        setBaseUrl(context->baseUrl());
    else
        setBaseUrl(QUrl());
}

/*! \internal */
QRectF QQuickText::boundingRect() const
{
    Q_D(const QQuickText);

    QRectF rect = d->layedOutTextRect;
    rect.moveLeft(QQuickTextUtil::alignedX(rect.width(), width(), effectiveHAlign()));
    rect.moveTop(QQuickTextUtil::alignedY(rect.height() + d->lineHeightOffset(), height(), d->vAlign));

    if (d->style != Normal)
        rect.adjust(-1, 0, 1, 2);
    // Could include font max left/right bearings to either side of rectangle.

    return rect;
}

QRectF QQuickText::clipRect() const
{
    Q_D(const QQuickText);

    QRectF rect = QQuickImplicitSizeItem::clipRect();
    if (d->style != Normal)
        rect.adjust(-1, 0, 1, 2);
    return rect;
}

/*! \internal */
void QQuickText::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry)
{
    Q_D(QQuickText);
    if (d->text.isEmpty()) {
        QQuickItem::geometryChanged(newGeometry, oldGeometry);
        return;
    }

    bool widthChanged = newGeometry.width() != oldGeometry.width();
    bool heightChanged = newGeometry.height() != oldGeometry.height();
    bool wrapped = d->wrapMode != QQuickText::NoWrap;
    bool elide = d->elideMode != QQuickText::ElideNone;
    bool scaleFont = d->fontSizeMode() != QQuickText::FixedSize && (widthValid() || heightValid());
    bool verticalScale = (d->fontSizeMode() & QQuickText::VerticalFit) && heightValid();

    bool widthMaximum = newGeometry.width() >= oldGeometry.width() && !d->widthExceeded;
    bool heightMaximum = newGeometry.height() >= oldGeometry.height() && !d->heightExceeded;

    bool verticalPositionChanged = heightChanged && d->vAlign != AlignTop;

    if ((!widthChanged && !heightChanged) || d->internalWidthUpdate)
        goto geomChangeDone;

    if ((effectiveHAlign() != QQuickText::AlignLeft && widthChanged) || verticalPositionChanged) {
        // If the width has changed and we're not left aligned do an update so the text is
        // repositioned even if a full layout isn't required. And the same for vertical.
        d->updateType = QQuickTextPrivate::UpdatePaintNode;
        update();
    }

    if (!wrapped && !elide && !scaleFont && !verticalPositionChanged)
        goto geomChangeDone; // left aligned unwrapped text without eliding never needs relayout

    if (elide // eliding and dimensions were and remain invalid;
            && ((widthValid() && oldGeometry.width() <= 0 && newGeometry.width() <= 0)
            || (heightValid() && oldGeometry.height() <= 0 && newGeometry.height() <= 0))) {
        goto geomChangeDone;
    }

    if (widthMaximum && heightMaximum && !d->isLineLaidOutConnected() && !verticalPositionChanged)  // Size is sufficient and growing.
        goto geomChangeDone;

    if (!(widthChanged || widthMaximum) && !d->isLineLaidOutConnected()) { // only height has changed
        if (newGeometry.height() > oldGeometry.height()) {
            if (!d->heightExceeded && !qFuzzyIsNull(oldGeometry.height())) {
                // Height is adequate and growing, and it wasn't 0 previously.
                goto geomChangeDone;
            }
            if (d->lineCount == d->maximumLineCount())  // Reached maximum line and height is growing.
                goto geomChangeDone;
        } else if (newGeometry.height() < oldGeometry.height()) {
            if (d->lineCount < 2 && !verticalScale && newGeometry.height() > 0)  // A single line won't be truncated until the text is 0 height.
                goto geomChangeDone;

            if (!verticalScale // no scaling, no eliding, and either unwrapped, or no maximum line count.
                    && d->elideMode != QQuickText::ElideRight
                    && !(d->maximumLineCountValid && d->widthExceeded)) {
                goto geomChangeDone;
            }
        }
    } else if (!heightChanged && widthMaximum) {
        goto geomChangeDone;
    }

    if (d->updateOnComponentComplete || d->textHasChanged) {
        // We need to re-elide
        d->updateLayout();
    } else {
        // We just need to re-layout
        d->updateSize();
    }

geomChangeDone:
    QQuickItem::geometryChanged(newGeometry, oldGeometry);
}

void QQuickText::triggerPreprocess()
{
    Q_D(QQuickText);
    if (d->updateType == QQuickTextPrivate::UpdateNone)
        d->updateType = QQuickTextPrivate::UpdatePreprocess;
    update();
}

QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
{
    Q_UNUSED(data);
    Q_D(QQuickText);

    if (d->text.isEmpty()) {
        delete oldNode;
        return nullptr;
    }

    if (d->updateType != QQuickTextPrivate::UpdatePaintNode && oldNode != nullptr) {
        // Update done in preprocess() in the nodes
        d->updateType = QQuickTextPrivate::UpdateNone;
        return oldNode;
    }

    d->updateType = QQuickTextPrivate::UpdateNone;

    const qreal dy = QQuickTextUtil::alignedY(d->layedOutTextRect.height() + d->lineHeightOffset(), d->availableHeight(), d->vAlign) + topPadding();

    QQuickTextNode *node = nullptr;
    if (!oldNode)
        node = new QQuickTextNode(this);
    else
        node = static_cast<QQuickTextNode *>(oldNode);

    node->setUseNativeRenderer(d->renderType == NativeRendering);
    node->deleteContent();
    node->setMatrix(QMatrix4x4());

    const QColor color = QColor::fromRgba(d->color);
    const QColor styleColor = QColor::fromRgba(d->styleColor);
    const QColor linkColor = QColor::fromRgba(d->linkColor);

    if (d->richText) {
        const qreal dx = QQuickTextUtil::alignedX(d->layedOutTextRect.width(), d->availableWidth(), effectiveHAlign()) + leftPadding();
        d->ensureDoc();
        node->addTextDocument(QPointF(dx, dy), d->extra->doc, color, d->style, styleColor, linkColor);
    } else if (d->layedOutTextRect.width() > 0) {
        const qreal dx = QQuickTextUtil::alignedX(d->lineWidth, d->availableWidth(), effectiveHAlign()) + leftPadding();
        int unelidedLineCount = d->lineCount;
        if (d->elideLayout)
            unelidedLineCount -= 1;
        if (unelidedLineCount > 0) {
            node->addTextLayout(
                        QPointF(dx, dy),
                        &d->layout,
                        color, d->style, styleColor, linkColor,
                        QColor(), QColor(), -1, -1,
                        0, unelidedLineCount);
        }
        if (d->elideLayout)
            node->addTextLayout(QPointF(dx, dy), d->elideLayout, color, d->style, styleColor, linkColor);

        if (d->extra.isAllocated()) {
            for (QQuickStyledTextImgTag *img : qAsConst(d->extra->visibleImgTags)) {
                QQuickPixmap *pix = img->pix;
                if (pix && pix->isReady())
                    node->addImage(QRectF(img->pos.x() + dx, img->pos.y() + dy, pix->width(), pix->height()), pix->image());
            }
        }
    }

    // The font caches have now been initialized on the render thread, so they have to be
    // invalidated before we can use them from the main thread again.
    invalidateFontCaches();

    return node;
}

void QQuickText::updatePolish()
{
    Q_D(QQuickText);
    // If the fonts used for rendering are different from the ones used in the GUI thread,
    // it means we will get warnings and corrupted text. If this case is detected, we need
    // to update the text layout before creating the scenegraph nodes.
    if (!d->assignedFont.isEmpty() && QFontInfo(d->font).family() != d->assignedFont)
        d->polishSize = true;

    if (d->polishSize) {
        d->updateSize();
        d->polishSize = false;
    }
    invalidateFontCaches();
}

/*!
    \qmlproperty real QtQuick::Text::contentWidth

    Returns the width of the text, including width past the width
    which is covered due to insufficient wrapping if WrapMode is set.
*/
qreal QQuickText::contentWidth() const
{
    Q_D(const QQuickText);
    return d->layedOutTextRect.width();
}

/*!
    \qmlproperty real QtQuick::Text::contentHeight

    Returns the height of the text, including height past the height
    which is covered due to there being more text than fits in the set height.
*/
qreal QQuickText::contentHeight() const
{
    Q_D(const QQuickText);
    return d->layedOutTextRect.height();
}

/*!
    \qmlproperty real QtQuick::Text::lineHeight

    Sets the line height for the text.
    The value can be in pixels or a multiplier depending on lineHeightMode.

    The default value is a multiplier of 1.0.
    The line height must be a positive value.
*/
qreal QQuickText::lineHeight() const
{
    Q_D(const QQuickText);
    return d->lineHeight();
}

void QQuickText::setLineHeight(qreal lineHeight)
{
    Q_D(QQuickText);

    if ((d->lineHeight() == lineHeight) || (lineHeight < 0.0))
        return;

    d->extra.value().lineHeightValid = true;
    d->extra.value().lineHeight = lineHeight;
    d->implicitHeightValid = false;
    d->updateLayout();
    emit lineHeightChanged(lineHeight);
}

/*!
    \qmlproperty enumeration QtQuick::Text::lineHeightMode

    This property determines how the line height is specified.
    The possible values are:

    \list
    \li Text.ProportionalHeight (default) - this sets the spacing proportional to the
       line (as a multiplier). For example, set to 2 for double spacing.
    \li Text.FixedHeight - this sets the line height to a fixed line height (in pixels).
    \endlist
*/
QQuickText::LineHeightMode QQuickText::lineHeightMode() const
{
    Q_D(const QQuickText);
    return d->lineHeightMode();
}

void QQuickText::setLineHeightMode(LineHeightMode mode)
{
    Q_D(QQuickText);
    if (mode == d->lineHeightMode())
        return;

    d->implicitHeightValid = false;
    d->extra.value().lineHeightValid = true;
    d->extra.value().lineHeightMode = mode;
    d->updateLayout();

    emit lineHeightModeChanged(mode);
}

/*!
    \qmlproperty enumeration QtQuick::Text::fontSizeMode

    This property specifies how the font size of the displayed text is determined.
    The possible values are:

    \list
    \li Text.FixedSize (default) - The size specified by \l font.pixelSize
    or \l font.pointSize is used.
    \li Text.HorizontalFit - The largest size up to the size specified that fits
    within the width of the item without wrapping is used.
    \li Text.VerticalFit - The largest size up to the size specified that fits
    the height of the item is used.
    \li Text.Fit - The largest size up to the size specified that fits within the
    width and height of the item is used.
    \endlist

    The font size of fitted text has a minimum bound specified by the
    minimumPointSize or minimumPixelSize property and maximum bound specified
    by either the \l font.pointSize or \l font.pixelSize properties.

    \qml
    Text { text: "Hello"; fontSizeMode: Text.Fit; minimumPixelSize: 10; font.pixelSize: 72 }
    \endqml

    If the text does not fit within the item bounds with the minimum font size
    the text will be elided as per the \l elide property.
*/

QQuickText::FontSizeMode QQuickText::fontSizeMode() const
{
    Q_D(const QQuickText);
    return d->fontSizeMode();
}

void QQuickText::setFontSizeMode(FontSizeMode mode)
{
    Q_D(QQuickText);
    if (d->fontSizeMode() == mode)
        return;

    d->polishSize = true;
    polish();

    d->extra.value().fontSizeMode = mode;
    emit fontSizeModeChanged();
}

/*!
    \qmlproperty int QtQuick::Text::minimumPixelSize

    This property specifies the minimum font pixel size of text scaled by the
    fontSizeMode property.

    If the fontSizeMode is Text.FixedSize or the \l font.pixelSize is -1 this
    property is ignored.
*/

int QQuickText::minimumPixelSize() const
{
    Q_D(const QQuickText);
    return d->minimumPixelSize();
}

void QQuickText::setMinimumPixelSize(int size)
{
    Q_D(QQuickText);
    if (d->minimumPixelSize() == size)
        return;

    if (d->fontSizeMode() != FixedSize && (widthValid() || heightValid())) {
        d->polishSize = true;
        polish();
    }
    d->extra.value().minimumPixelSize = size;
    emit minimumPixelSizeChanged();
}

/*!
    \qmlproperty int QtQuick::Text::minimumPointSize

    This property specifies the minimum font point \l size of text scaled by
    the fontSizeMode property.

    If the fontSizeMode is Text.FixedSize or the \l font.pointSize is -1 this
    property is ignored.
*/

int QQuickText::minimumPointSize() const
{
    Q_D(const QQuickText);
    return d->minimumPointSize();
}

void QQuickText::setMinimumPointSize(int size)
{
    Q_D(QQuickText);
    if (d->minimumPointSize() == size)
        return;

    if (d->fontSizeMode() != FixedSize && (widthValid() || heightValid())) {
        d->polishSize = true;
        polish();
    }
    d->extra.value().minimumPointSize = size;
    emit minimumPointSizeChanged();
}

/*!
    Returns the number of resources (images) that are being loaded asynchronously.
*/
int QQuickText::resourcesLoading() const
{
    Q_D(const QQuickText);
    if (d->richText && d->extra.isAllocated() && d->extra->doc)
        return d->extra->doc->resourcesLoading();
    return 0;
}

/*! \internal */
void QQuickText::componentComplete()
{
    Q_D(QQuickText);
    if (d->updateOnComponentComplete) {
        if (d->richText) {
            d->ensureDoc();
            if (d->markdownText)
                d->extra->doc->setMarkdownText(d->text);
            else
                d->extra->doc->setText(d->text);
            d->rightToLeftText = d->extra->doc->toPlainText().isRightToLeft();
        } else {
            d->rightToLeftText = d->text.isRightToLeft();
        }
        d->determineHorizontalAlignment();
    }
    QQuickItem::componentComplete();
    if (d->updateOnComponentComplete)
        d->updateLayout();
}

QString QQuickTextPrivate::anchorAt(const QTextLayout *layout, const QPointF &mousePos)
{
    for (int i = 0; i < layout->lineCount(); ++i) {
        QTextLine line = layout->lineAt(i);
        if (line.naturalTextRect().contains(mousePos)) {
            int charPos = line.xToCursor(mousePos.x(), QTextLine::CursorOnCharacter);
            const auto formats = layout->formats();
            for (const QTextLayout::FormatRange &formatRange : formats) {
                if (formatRange.format.isAnchor()
                        && charPos >= formatRange.start
                        && charPos < formatRange.start + formatRange.length) {
                    return formatRange.format.anchorHref();
                }
            }
            break;
        }
    }
    return QString();
}

QString QQuickTextPrivate::anchorAt(const QPointF &mousePos) const
{
    Q_Q(const QQuickText);
    QPointF translatedMousePos = mousePos;
    translatedMousePos.rx() -= q->leftPadding();
    translatedMousePos.ry() -= q->topPadding() + QQuickTextUtil::alignedY(layedOutTextRect.height() + lineHeightOffset(), availableHeight(), vAlign);
    if (styledText) {
        QString link = anchorAt(&layout, translatedMousePos);
        if (link.isEmpty() && elideLayout)
            link = anchorAt(elideLayout, translatedMousePos);
        return link;
    } else if (richText && extra.isAllocated() && extra->doc) {
        translatedMousePos.rx() -= QQuickTextUtil::alignedX(layedOutTextRect.width(), availableWidth(), q->effectiveHAlign());
        return extra->doc->documentLayout()->anchorAt(translatedMousePos);
    }
    return QString();
}

bool QQuickTextPrivate::isLinkActivatedConnected()
{
    Q_Q(QQuickText);
    IS_SIGNAL_CONNECTED(q, QQuickText, linkActivated, (const QString &));
}

/*!  \internal */
void QQuickText::mousePressEvent(QMouseEvent *event)
{
    Q_D(QQuickText);

    QString link;
    if (d->isLinkActivatedConnected())
        link = d->anchorAt(event->localPos());

    if (link.isEmpty()) {
        event->setAccepted(false);
    } else {
        d->extra.value().activeLink = link;
    }

    // ### may malfunction if two of the same links are clicked & dragged onto each other)

    if (!event->isAccepted())
        QQuickItem::mousePressEvent(event);
}


/*! \internal */
void QQuickText::mouseReleaseEvent(QMouseEvent *event)
{
    Q_D(QQuickText);

    // ### confirm the link, and send a signal out

    QString link;
    if (d->isLinkActivatedConnected())
        link = d->anchorAt(event->localPos());

    if (!link.isEmpty() && d->extra.isAllocated() && d->extra->activeLink == link)
        emit linkActivated(d->extra->activeLink);
    else
        event->setAccepted(false);

    if (!event->isAccepted())
        QQuickItem::mouseReleaseEvent(event);
}

bool QQuickTextPrivate::isLinkHoveredConnected()
{
    Q_Q(QQuickText);
    IS_SIGNAL_CONNECTED(q, QQuickText, linkHovered, (const QString &));
}

/*!
    \qmlsignal QtQuick::Text::linkHovered(string link)
    \since 5.2

    This signal is emitted when the user hovers a link embedded in the
    text. The link must be in rich text or HTML format and the \a link
    string provides access to the particular link.

    The corresponding handler is \c onLinkHovered.

    \sa hoveredLink, linkAt()
*/

/*!
    \qmlproperty string QtQuick::Text::hoveredLink
    \since 5.2

    This property contains the link string when the user hovers a link
    embedded in the text. The link must be in rich text or HTML format
    and the \a hoveredLink string provides access to the particular link.

    \sa linkHovered, linkAt()
*/

QString QQuickText::hoveredLink() const
{
    Q_D(const QQuickText);
    if (const_cast<QQuickTextPrivate *>(d)->isLinkHoveredConnected()) {
        if (d->extra.isAllocated())
            return d->extra->hoveredLink;
    } else {
#if QT_CONFIG(cursor)
        if (QQuickWindow *wnd = window()) {
            QPointF pos = QCursor::pos(wnd->screen()) - wnd->position() - mapToScene(QPointF(0, 0));
            return d->anchorAt(pos);
        }
#endif // cursor
    }
    return QString();
}

void QQuickTextPrivate::processHoverEvent(QHoverEvent *event)
{
    Q_Q(QQuickText);
    qCDebug(DBG_HOVER_TRACE) << q;
    QString link;
    if (isLinkHoveredConnected()) {
        if (event->type() != QEvent::HoverLeave)
            link = anchorAt(event->posF());

        if ((!extra.isAllocated() && !link.isEmpty()) || (extra.isAllocated() && extra->hoveredLink != link)) {
            extra.value().hoveredLink = link;
            emit q->linkHovered(extra->hoveredLink);
        }
    }
    event->setAccepted(!link.isEmpty());
}

void QQuickText::hoverEnterEvent(QHoverEvent *event)
{
    Q_D(QQuickText);
    d->processHoverEvent(event);
}

void QQuickText::hoverMoveEvent(QHoverEvent *event)
{
    Q_D(QQuickText);
    d->processHoverEvent(event);
}

void QQuickText::hoverLeaveEvent(QHoverEvent *event)
{
    Q_D(QQuickText);
    d->processHoverEvent(event);
}

/*!
    \qmlproperty enumeration QtQuick::Text::renderType

    Override the default rendering type for this component.

    Supported render types are:
    \list
    \li Text.QtRendering
    \li Text.NativeRendering
    \endlist

    Select Text.NativeRendering if you prefer text to look native on the target platform and do
    not require advanced features such as transformation of the text. Using such features in
    combination with the NativeRendering render type will lend poor and sometimes pixelated
    results.

    The default rendering type is determined by \l QQuickWindow::textRenderType().
*/
QQuickText::RenderType QQuickText::renderType() const
{
    Q_D(const QQuickText);
    return d->renderType;
}

void QQuickText::setRenderType(QQuickText::RenderType renderType)
{
    Q_D(QQuickText);
    if (d->renderType == renderType)
        return;

    d->renderType = renderType;
    emit renderTypeChanged();

    if (isComponentComplete())
        d->updateLayout();
}

/*!
    \qmlmethod QtQuick::Text::doLayout()
    \deprecated

    Use \l forceLayout() instead.
*/
void QQuickText::doLayout()
{
    forceLayout();
}

/*!
    \qmlmethod QtQuick::Text::forceLayout()
    \since 5.9

    Triggers a re-layout of the displayed text.
*/
void QQuickText::forceLayout()
{
    Q_D(QQuickText);
    d->updateSize();
}

/*!
    \qmlmethod QtQuick::Text::linkAt(real x, real y)
    \since 5.3

    Returns the link string at point \a x, \a y in content coordinates,
    or an empty string if no link exists at that point.

    \sa hoveredLink
*/
QString QQuickText::linkAt(qreal x, qreal y) const
{
    Q_D(const QQuickText);
    return d->anchorAt(QPointF(x, y));
}

/*!
 * \internal
 *
 * Invalidates font caches owned by the text objects owned by the element
 * to work around the fact that text objects cannot be used from multiple threads.
 */
void QQuickText::invalidateFontCaches()
{
    Q_D(QQuickText);

    if (d->richText && d->extra.isAllocated() && d->extra->doc != nullptr) {
        QTextBlock block;
        for (block = d->extra->doc->firstBlock(); block.isValid(); block = block.next()) {
            if (block.layout() != nullptr && block.layout()->engine() != nullptr)
                block.layout()->engine()->resetFontEngineCache();
        }
    } else {
        if (d->layout.engine() != nullptr)
            d->layout.engine()->resetFontEngineCache();
    }
}

/*!
    \since 5.6
    \qmlproperty real QtQuick::Text::padding
    \qmlproperty real QtQuick::Text::topPadding
    \qmlproperty real QtQuick::Text::leftPadding
    \qmlproperty real QtQuick::Text::bottomPadding
    \qmlproperty real QtQuick::Text::rightPadding

    These properties hold the padding around the content. This space is reserved
    in addition to the contentWidth and contentHeight.
*/
qreal QQuickText::padding() const
{
    Q_D(const QQuickText);
    return d->padding();
}

void QQuickText::setPadding(qreal padding)
{
    Q_D(QQuickText);
    if (qFuzzyCompare(d->padding(), padding))
        return;

    d->extra.value().padding = padding;
    d->updateSize();
    emit paddingChanged();
    if (!d->extra.isAllocated() || !d->extra->explicitTopPadding)
        emit topPaddingChanged();
    if (!d->extra.isAllocated() || !d->extra->explicitLeftPadding)
        emit leftPaddingChanged();
    if (!d->extra.isAllocated() || !d->extra->explicitRightPadding)
        emit rightPaddingChanged();
    if (!d->extra.isAllocated() || !d->extra->explicitBottomPadding)
        emit bottomPaddingChanged();
}

void QQuickText::resetPadding()
{
    setPadding(0);
}

qreal QQuickText::topPadding() const
{
    Q_D(const QQuickText);
    if (d->extra.isAllocated() && d->extra->explicitTopPadding)
        return d->extra->topPadding;
    return d->padding();
}

void QQuickText::setTopPadding(qreal padding)
{
    Q_D(QQuickText);
    d->setTopPadding(padding);
}

void QQuickText::resetTopPadding()
{
    Q_D(QQuickText);
    d->setTopPadding(0, true);
}

qreal QQuickText::leftPadding() const
{
    Q_D(const QQuickText);
    if (d->extra.isAllocated() && d->extra->explicitLeftPadding)
        return d->extra->leftPadding;
    return d->padding();
}

void QQuickText::setLeftPadding(qreal padding)
{
    Q_D(QQuickText);
    d->setLeftPadding(padding);
}

void QQuickText::resetLeftPadding()
{
    Q_D(QQuickText);
    d->setLeftPadding(0, true);
}

qreal QQuickText::rightPadding() const
{
    Q_D(const QQuickText);
    if (d->extra.isAllocated() && d->extra->explicitRightPadding)
        return d->extra->rightPadding;
    return d->padding();
}

void QQuickText::setRightPadding(qreal padding)
{
    Q_D(QQuickText);
    d->setRightPadding(padding);
}

void QQuickText::resetRightPadding()
{
    Q_D(QQuickText);
    d->setRightPadding(0, true);
}

qreal QQuickText::bottomPadding() const
{
    Q_D(const QQuickText);
    if (d->extra.isAllocated() && d->extra->explicitBottomPadding)
        return d->extra->bottomPadding;
    return d->padding();
}

void QQuickText::setBottomPadding(qreal padding)
{
    Q_D(QQuickText);
    d->setBottomPadding(padding);
}

void QQuickText::resetBottomPadding()
{
    Q_D(QQuickText);
    d->setBottomPadding(0, true);
}

/*!
    \qmlproperty string QtQuick::Text::fontInfo.family
    \since 5.9

    The family name of the font that has been resolved for the current font
    and fontSizeMode.
*/

/*!
    \qmlproperty string QtQuick::Text::fontInfo.styleName
    \since 5.9

    The style name of the font info that has been resolved for the current font
    and fontSizeMode.
*/

/*!
    \qmlproperty bool QtQuick::Text::fontInfo.bold
    \since 5.9

    The bold state of the font info that has been resolved for the current font
    and fontSizeMode. This is true if the weight of the resolved font is bold or higher.
*/

/*!
    \qmlproperty int QtQuick::Text::fontInfo.weight
    \since 5.9

    The weight of the font info that has been resolved for the current font
    and fontSizeMode.
*/

/*!
    \qmlproperty bool QtQuick::Text::fontInfo.italic
    \since 5.9

    The italic state of the font info that has been resolved for the current font
    and fontSizeMode.
*/

/*!
    \qmlproperty real QtQuick::Text::fontInfo.pointSize
    \since 5.9

    The pointSize of the font info that has been resolved for the current font
    and fontSizeMode.
*/

/*!
    \qmlproperty string QtQuick::Text::fontInfo.pixelSize
    \since 5.9

    The pixel size of the font info that has been resolved for the current font
    and fontSizeMode.
*/
QJSValue QQuickText::fontInfo() const
{
    Q_D(const QQuickText);

    QJSEngine *engine = qjsEngine(this);
    if (!engine) {
        qmlWarning(this) << "fontInfo: item has no JS engine";
        return QJSValue();
    }

    QJSValue value = engine->newObject();
    value.setProperty(QStringLiteral("family"), d->fontInfo.family());
    value.setProperty(QStringLiteral("styleName"), d->fontInfo.styleName());
    value.setProperty(QStringLiteral("bold"), d->fontInfo.bold());
    value.setProperty(QStringLiteral("weight"), d->fontInfo.weight());
    value.setProperty(QStringLiteral("italic"), d->fontInfo.italic());
    value.setProperty(QStringLiteral("pointSize"), d->fontInfo.pointSizeF());
    value.setProperty(QStringLiteral("pixelSize"), d->fontInfo.pixelSize());
    return value;
}

/*!
    \qmlproperty size QtQuick::Text::advance
    \since 5.10

    The distance, in pixels, from the baseline origin of the first
    character of the text item, to the baseline origin of the first
    character in a text item occurring directly after this one
    in a text flow.

    Note that the advance can be negative if the text flows from
    the right to the left.
*/
QSizeF QQuickText::advance() const
{
    Q_D(const QQuickText);
    return d->advance;
}

QT_END_NAMESPACE

#include "moc_qquicktext_p.cpp"
