/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui 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 "qtextlayout.h"
#include "qtextengine_p.h"

#include <qthread.h>
#include <qfont.h>
#include <qmath.h>
#include <qpainter.h>
#include <qvarlengtharray.h>
#include <qtextformat.h>
#include <qabstracttextdocumentlayout.h>
#include "qtextdocument_p.h"
#include "qtextformat_p.h"
#include "qpainterpath.h"
#include "qglyphrun.h"
#include "qglyphrun_p.h"
#include "qrawfont.h"
#include "qrawfont_p.h"
#include <limits.h>

#include <qdebug.h>

#include "qfontengine_p.h"
#include <private/qpainter_p.h>

QT_BEGIN_NAMESPACE

#define ObjectSelectionBrush (QTextFormat::ForegroundBrush + 1)
#define SuppressText 0x5012
#define SuppressBackground 0x513

/*!
    \class QTextLayout::FormatRange
    \reentrant

    \brief The QTextLayout::FormatRange structure is used to apply extra formatting information
    for a specified area in the text layout's content.
    \inmodule QtGui

    \sa QTextLayout::setFormats(), QTextLayout::draw()
*/

/*!
    \variable QTextLayout::FormatRange::start
    Specifies the beginning of the format range within the text layout's text.
*/

/*!
    \variable QTextLayout::FormatRange::length
    Specifies the numer of characters the format range spans.
*/

/*!
    \variable QTextLayout::FormatRange::format
    Specifies the format to apply.
*/

/*! \fn bool operator==(const QTextLayout::FormatRange &lhs, const QTextLayout::FormatRange &rhs)
  \relates QTextLayout::FormatRange

  Returns true if the \c {start}, \c {length}, and \c {format} fields
  in \a lhs and \a rhs contain the same values respectively.
 */

/*! \fn bool operator!=(const QTextLayout::FormatRange &lhs, const QTextLayout::FormatRange &rhs)
  \relates QTextLayout::FormatRange

  Returns true if any of the \c {start}, \c {length}, or \c {format} fields
  in \a lhs and \a rhs contain different values respectively.
 */

/*!
    \class QTextInlineObject
    \reentrant

    \brief The QTextInlineObject class represents an inline object in
    a QAbstractTextDocumentLayout and its implementations.
    \inmodule QtGui

    \ingroup richtext-processing

    Normally, you do not need to create a QTextInlineObject. It is
    used by QAbstractTextDocumentLayout to handle inline objects when
    implementing a custom layout.

    The inline object has various attributes that can be set, for
    example using, setWidth(), setAscent(), and setDescent(). The
    rectangle it occupies is given by rect(), and its direction by
    textDirection(). Its position in the text layout is given by
    textPosition(), and its format is given by format().
*/

/*!
    \fn QTextInlineObject::QTextInlineObject(int i, QTextEngine *e)
    \internal

    Creates a new inline object for the item at position \a i in the
    text engine \a e.
*/

/*!
    \fn QTextInlineObject::QTextInlineObject()

    \internal
*/

/*!
    \fn bool QTextInlineObject::isValid() const

    Returns \c true if this inline object is valid; otherwise returns
    false.
*/

/*!
    Returns the inline object's rectangle.

    \sa ascent(), descent(), width()
*/
QRectF QTextInlineObject::rect() const
{
    QScriptItem& si = eng->layoutData->items[itm];
    return QRectF(0, -si.ascent.toReal(), si.width.toReal(), si.height().toReal());
}

/*!
    Returns the inline object's width.

    \sa ascent(), descent(), rect()
*/
qreal QTextInlineObject::width() const
{
    return eng->layoutData->items.at(itm).width.toReal();
}

/*!
    Returns the inline object's ascent.

    \sa descent(), width(), rect()
*/
qreal QTextInlineObject::ascent() const
{
    return eng->layoutData->items.at(itm).ascent.toReal();
}

/*!
    Returns the inline object's descent.

    \sa ascent(), width(), rect()
*/
qreal QTextInlineObject::descent() const
{
    return eng->layoutData->items.at(itm).descent.toReal();
}

/*!
    Returns the inline object's total height. This is equal to
    ascent() + descent() + 1.

    \sa ascent(), descent(), width(), rect()
*/
qreal QTextInlineObject::height() const
{
    return eng->layoutData->items.at(itm).height().toReal();
}

/*!
    Sets the inline object's width to \a w.

    \sa width(), ascent(), descent(), rect()
*/
void QTextInlineObject::setWidth(qreal w)
{
    eng->layoutData->items[itm].width = QFixed::fromReal(w);
}

/*!
    Sets the inline object's ascent to \a a.

    \sa ascent(), setDescent(), width(), rect()
*/
void QTextInlineObject::setAscent(qreal a)
{
    eng->layoutData->items[itm].ascent = QFixed::fromReal(a);
}

/*!
    Sets the inline object's descent to \a d.

    \sa descent(), setAscent(), width(), rect()
*/
void QTextInlineObject::setDescent(qreal d)
{
    eng->layoutData->items[itm].descent = QFixed::fromReal(d);
}

/*!
    The position of the inline object within the text layout.
*/
int QTextInlineObject::textPosition() const
{
    return eng->layoutData->items[itm].position;
}

/*!
    Returns an integer describing the format of the inline object
    within the text layout.
*/
int QTextInlineObject::formatIndex() const
{
    return eng->formatIndex(&eng->layoutData->items[itm]);
}

/*!
    Returns format of the inline object within the text layout.
*/
QTextFormat QTextInlineObject::format() const
{
    return eng->format(&eng->layoutData->items[itm]);
}

/*!
    Returns if the object should be laid out right-to-left or left-to-right.
*/
Qt::LayoutDirection QTextInlineObject::textDirection() const
{
    return (eng->layoutData->items[itm].analysis.bidiLevel % 2 ? Qt::RightToLeft : Qt::LeftToRight);
}

/*!
    \class QTextLayout
    \reentrant

    \brief The QTextLayout class is used to lay out and render text.
    \inmodule QtGui

    \ingroup richtext-processing

    It offers many features expected from a modern text layout
    engine, including Unicode compliant rendering, line breaking and
    handling of cursor positioning. It can also produce and render
    device independent layout, something that is important for WYSIWYG
    applications.

    The class has a rather low level API and unless you intend to
    implement your own text rendering for some specialized widget, you
    probably won't need to use it directly.

    QTextLayout can be used with both plain and rich text.

    QTextLayout can be used to create a sequence of QTextLine
    instances with given widths and can position them independently
    on the screen. Once the layout is done, these lines can be drawn
    on a paint device.

    The text to be laid out can be provided in the constructor or set with
    setText().

    The layout can be seen as a sequence of QTextLine objects; use createLine()
    to create a QTextLine instance, and lineAt() or lineForTextPosition() to retrieve
    created lines.

    Here is a code snippet that demonstrates the layout phase:
    \snippet code/src_gui_text_qtextlayout.cpp 0

    The text can then be rendered by calling the layout's draw() function:
    \snippet code/src_gui_text_qtextlayout.cpp 1

    For a given position in the text you can find a valid cursor position with
    isValidCursorPosition(), nextCursorPosition(), and previousCursorPosition().

    The QTextLayout itself can be positioned with setPosition(); it has a
    boundingRect(), and a minimumWidth() and a maximumWidth().

    \sa QStaticText
*/

/*!
    \enum QTextLayout::CursorMode

    \value SkipCharacters
    \value SkipWords
*/

/*!
    \fn QTextEngine *QTextLayout::engine() const
    \internal

    Returns the text engine used to render the text layout.
*/

/*!
    Constructs an empty text layout.

    \sa setText()
*/
QTextLayout::QTextLayout()
{ d = new QTextEngine(); }

/*!
    Constructs a text layout to lay out the given \a text.
*/
QTextLayout::QTextLayout(const QString& text)
{
    d = new QTextEngine();
    d->text = text;
}

/*!
    \since 5.13
    \fn QTextLayout::QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice)
    Constructs a text layout to lay out the given \a text with the specified
    \a font.

    All the metric and layout calculations will be done in terms of
    the paint device, \a paintdevice. If \a paintdevice is 0 the
    calculations will be done in screen metrics.
*/

#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
/*!
    \fn QTextLayout::QTextLayout(const QString &text, const QFont &font, QPaintDevice *paintdevice)
    \obsolete
    Identical to QTextLayout::QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice)
*/

QTextLayout::QTextLayout(const QString &text, const QFont &font, QPaintDevice *paintdevice)
#else
QTextLayout::QTextLayout(const QString &text, const QFont &font, const QPaintDevice *paintdevice)
#endif
{
    const QFont f(paintdevice ? QFont(font, paintdevice) : font);
    d = new QTextEngine((text.isNull() ? (const QString&)QString::fromLatin1("") : text), f);
}

/*!
    \internal
    Constructs a text layout to lay out the given \a block.
*/
QTextLayout::QTextLayout(const QTextBlock &block)
{
    d = new QTextEngine();
    d->block = block;
}

/*!
    Destructs the layout.
*/
QTextLayout::~QTextLayout()
{
    if (!d->stackEngine)
        delete d;
}

#ifndef QT_NO_RAWFONT
/*!
    \internal
    Sets a raw font, to be used with QTextLayout::glyphRuns.
    Note that this only supports the needs of WebKit.
    Use of this function with e.g. QTextLayout::draw will result
    in undefined behaviour.
*/
void QTextLayout::setRawFont(const QRawFont &rawFont)
{
    d->rawFont = rawFont;
    d->useRawFont = true;
    d->resetFontEngineCache();
}
#endif

/*!
    Sets the layout's font to the given \a font. The layout is
    invalidated and must be laid out again.

    \sa font()
*/
void QTextLayout::setFont(const QFont &font)
{
    d->fnt = font;
#ifndef QT_NO_RAWFONT
    d->useRawFont = false;
#endif
    d->resetFontEngineCache();
}

/*!
    Returns the current font that is used for the layout, or a default
    font if none is set.

    \sa setFont()
*/
QFont QTextLayout::font() const
{
    return d->font();
}

/*!
    Sets the layout's text to the given \a string. The layout is
    invalidated and must be laid out again.

    Notice that when using this QTextLayout as part of a QTextDocument this
    method will have no effect.

    \sa text()
*/
void QTextLayout::setText(const QString& string)
{
    d->invalidate();
    d->clearLineData();
    d->text = string;
}

/*!
    Returns the layout's text.

    \sa setText()
*/
QString QTextLayout::text() const
{
    return d->text;
}

/*!
    Sets the text option structure that controls the layout process to the
    given \a option.

    \sa textOption()
*/
void QTextLayout::setTextOption(const QTextOption &option)
{
    d->option = option;
}

/*!
    Returns the current text option used to control the layout process.

    \sa setTextOption()
*/
const QTextOption &QTextLayout::textOption() const
{
    return d->option;
}

/*!
    Sets the \a position and \a text of the area in the layout that is
    processed before editing occurs. The layout is
    invalidated and must be laid out again.

    \sa preeditAreaPosition(), preeditAreaText()
*/
void QTextLayout::setPreeditArea(int position, const QString &text)
{
    if (d->preeditAreaPosition() == position && d->preeditAreaText() == text)
        return;
    d->setPreeditArea(position, text);

    if (d->block.docHandle())
        d->block.docHandle()->documentChange(d->block.position(), d->block.length());
}

/*!
    Returns the position of the area in the text layout that will be
    processed before editing occurs.

    \sa preeditAreaText()
*/
int QTextLayout::preeditAreaPosition() const
{
    return d->preeditAreaPosition();
}

/*!
    Returns the text that is inserted in the layout before editing occurs.

    \sa preeditAreaPosition()
*/
QString QTextLayout::preeditAreaText() const
{
    return d->preeditAreaText();
}

#if QT_DEPRECATED_SINCE(5, 6)
/*!
    \obsolete Use setFormats() instead.
*/
void QTextLayout::setAdditionalFormats(const QList<FormatRange> &formatList)
{
    setFormats(formatList.toVector());
}
#endif // deprecated since 5.6

/*!
    \since 5.6

    Sets the additional formats supported by the text layout to \a formats.
    The formats are applied with preedit area text in place.

    \sa formats(), clearFormats()
*/
void QTextLayout::setFormats(const QVector<FormatRange> &formats)
{
    d->setFormats(formats);

    if (d->block.docHandle())
        d->block.docHandle()->documentChange(d->block.position(), d->block.length());
}

#if QT_DEPRECATED_SINCE(5, 6)
/*!
    \obsolete Use formats() instead.

    \sa setAdditionalFormats(), clearAdditionalFormats()
*/
QList<QTextLayout::FormatRange> QTextLayout::additionalFormats() const
{
    return formats().toList();
}
#endif // deprecated since 5.6

/*!
    \since 5.6

    Returns the list of additional formats supported by the text layout.

    \sa setFormats(), clearFormats()
*/
QVector<QTextLayout::FormatRange> QTextLayout::formats() const
{
    return d->formats();
}

#if QT_DEPRECATED_SINCE(5, 6)
/*!
    \obsolete Use clearFormats() instead.
*/
void QTextLayout::clearAdditionalFormats()
{
    clearFormats();
}
#endif // deprecated since 5.6

/*!
    \since 5.6

    Clears the list of additional formats supported by the text layout.

    \sa formats(), setFormats()
*/
void QTextLayout::clearFormats()
{
    setFormats(QVector<FormatRange>());
}

/*!
    Enables caching of the complete layout information if \a enable is
    true; otherwise disables layout caching. Usually
    QTextLayout throws most of the layouting information away after a
    call to endLayout() to reduce memory consumption. If you however
    want to draw the laid out text directly afterwards enabling caching
    might speed up drawing significantly.

    \sa cacheEnabled()
*/
void QTextLayout::setCacheEnabled(bool enable)
{
    d->cacheGlyphs = enable;
}

/*!
    Returns \c true if the complete layout information is cached; otherwise
    returns \c false.

    \sa setCacheEnabled()
*/
bool QTextLayout::cacheEnabled() const
{
    return d->cacheGlyphs;
}

/*!
    Sets the visual cursor movement style to the given \a style. If the
    QTextLayout is backed by a document, you can ignore this and use the option
    in QTextDocument, this option is for widgets like QLineEdit or custom
    widgets without a QTextDocument. Default value is Qt::LogicalMoveStyle.

    \sa cursorMoveStyle()
*/
void QTextLayout::setCursorMoveStyle(Qt::CursorMoveStyle style)
{
    d->visualMovement = style == Qt::VisualMoveStyle;
}

/*!
    The cursor movement style of this QTextLayout. The default is
    Qt::LogicalMoveStyle.

    \sa setCursorMoveStyle()
*/
Qt::CursorMoveStyle QTextLayout::cursorMoveStyle() const
{
    return d->visualMovement ? Qt::VisualMoveStyle : Qt::LogicalMoveStyle;
}

/*!
    Begins the layout process.

    \warning This will invalidate the layout, so all existing QTextLine objects
    that refer to the previous contents should now be discarded.

    \sa endLayout()
*/
void QTextLayout::beginLayout()
{
#ifndef QT_NO_DEBUG
    if (d->layoutData && d->layoutData->layoutState == QTextEngine::InLayout) {
        qWarning("QTextLayout::beginLayout: Called while already doing layout");
        return;
    }
#endif
    d->invalidate();
    d->clearLineData();
    d->itemize();
    d->layoutData->layoutState = QTextEngine::InLayout;
}

/*!
    Ends the layout process.

    \sa beginLayout()
*/
void QTextLayout::endLayout()
{
#ifndef QT_NO_DEBUG
    if (!d->layoutData || d->layoutData->layoutState == QTextEngine::LayoutEmpty) {
        qWarning("QTextLayout::endLayout: Called without beginLayout()");
        return;
    }
#endif
    int l = d->lines.size();
    if (l && d->lines.at(l-1).length < 0) {
        QTextLine(l-1, d).setNumColumns(INT_MAX);
    }
    d->layoutData->layoutState = QTextEngine::LayoutEmpty;
    if (!d->cacheGlyphs)
        d->freeMemory();
}

/*!
    \since 4.4

    Clears the line information in the layout. After having called
    this function, lineCount() returns 0.

    \warning This will invalidate the layout, so all existing QTextLine objects
    that refer to the previous contents should now be discarded.
*/
void QTextLayout::clearLayout()
{
    d->clearLineData();
}

/*!
    Returns the next valid cursor position after \a oldPos that
    respects the given cursor \a mode.
    Returns value of \a oldPos, if \a oldPos is not a valid cursor position.

    \sa isValidCursorPosition(), previousCursorPosition()
*/
int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
{
    const QCharAttributes *attributes = d->attributes();
    int len = d->block.isValid() ? d->block.length() - 1
                                 : d->layoutData->string.length();
    Q_ASSERT(len <= d->layoutData->string.length());
    if (!attributes || oldPos < 0 || oldPos >= len)
        return oldPos;

    if (mode == SkipCharacters) {
        oldPos++;
        while (oldPos < len && !attributes[oldPos].graphemeBoundary)
            oldPos++;
    } else {
        if (oldPos < len && d->atWordSeparator(oldPos)) {
            oldPos++;
            while (oldPos < len && d->atWordSeparator(oldPos))
                oldPos++;
        } else {
            while (oldPos < len && !attributes[oldPos].whiteSpace && !d->atWordSeparator(oldPos))
                oldPos++;
        }
        while (oldPos < len && attributes[oldPos].whiteSpace)
            oldPos++;
    }

    return oldPos;
}

/*!
    Returns the first valid cursor position before \a oldPos that
    respects the given cursor \a mode.
    Returns value of \a oldPos, if \a oldPos is not a valid cursor position.

    \sa isValidCursorPosition(), nextCursorPosition()
*/
int QTextLayout::previousCursorPosition(int oldPos, CursorMode mode) const
{
    const QCharAttributes *attributes = d->attributes();
    int len = d->block.isValid() ? d->block.length() - 1
                                 : d->layoutData->string.length();
    Q_ASSERT(len <= d->layoutData->string.length());
    if (!attributes || oldPos <= 0 || oldPos > len)
        return oldPos;

    if (mode == SkipCharacters) {
        oldPos--;
        while (oldPos && !attributes[oldPos].graphemeBoundary)
            oldPos--;
    } else {
        while (oldPos > 0 && attributes[oldPos - 1].whiteSpace)
            oldPos--;

        if (oldPos && d->atWordSeparator(oldPos-1)) {
            oldPos--;
            while (oldPos && d->atWordSeparator(oldPos-1))
                oldPos--;
        } else {
            while (oldPos > 0 && !attributes[oldPos - 1].whiteSpace && !d->atWordSeparator(oldPos-1))
                oldPos--;
        }
    }

    return oldPos;
}

/*!
    Returns the cursor position to the right of \a oldPos, next to it.
    It's dependent on the visual position of characters, after bi-directional
    reordering.

    \sa leftCursorPosition(), nextCursorPosition()
*/
int QTextLayout::rightCursorPosition(int oldPos) const
{
    int newPos = d->positionAfterVisualMovement(oldPos, QTextCursor::Right);
//    qDebug("%d -> %d", oldPos, newPos);
    return newPos;
}

/*!
    Returns the cursor position to the left of \a oldPos, next to it.
    It's dependent on the visual position of characters, after bi-directional
    reordering.

    \sa rightCursorPosition(), previousCursorPosition()
*/
int QTextLayout::leftCursorPosition(int oldPos) const
{
    int newPos = d->positionAfterVisualMovement(oldPos, QTextCursor::Left);
//    qDebug("%d -> %d", oldPos, newPos);
    return newPos;
}

/*!/
    Returns \c true if position \a pos is a valid cursor position.

    In a Unicode context some positions in the text are not valid
    cursor positions, because the position is inside a Unicode
    surrogate or a grapheme cluster.

    A grapheme cluster is a sequence of two or more Unicode characters
    that form one indivisible entity on the screen. For example the
    latin character `\unicode{0xC4}' can be represented in Unicode by two
    characters, `A' (0x41), and the combining diaresis (0x308). A text
    cursor can only validly be positioned before or after these two
    characters, never between them since that wouldn't make sense. In
    indic languages every syllable forms a grapheme cluster.
*/
bool QTextLayout::isValidCursorPosition(int pos) const
{
    const QCharAttributes *attributes = d->attributes();
    if (!attributes || pos < 0 || pos > (int)d->layoutData->string.length())
        return false;
    return attributes[pos].graphemeBoundary;
}

/*!
    Returns a new text line to be laid out if there is text to be
    inserted into the layout; otherwise returns an invalid text line.

    The text layout creates a new line object that starts after the
    last line in the layout, or at the beginning if the layout is empty.
    The layout maintains an internal cursor, and each line is filled
    with text from the cursor position onwards when the
    QTextLine::setLineWidth() function is called.

    Once QTextLine::setLineWidth() is called, a new line can be created and
    filled with text. Repeating this process will lay out the whole block
    of text contained in the QTextLayout. If there is no text left to be
    inserted into the layout, the QTextLine returned will not be valid
    (isValid() will return false).
*/
QTextLine QTextLayout::createLine()
{
#ifndef QT_NO_DEBUG
    if (!d->layoutData || d->layoutData->layoutState == QTextEngine::LayoutEmpty) {
        qWarning("QTextLayout::createLine: Called without layouting");
        return QTextLine();
    }
#endif
    if (d->layoutData->layoutState == QTextEngine::LayoutFailed)
        return QTextLine();

    int l = d->lines.size();
    if (l && d->lines.at(l-1).length < 0) {
        QTextLine(l-1, d).setNumColumns(INT_MAX);
    }
    int from = l > 0 ? d->lines.at(l-1).from + d->lines.at(l-1).length + d->lines.at(l-1).trailingSpaces : 0;
    int strlen = d->layoutData->string.length();
    if (l && from >= strlen) {
        if (!d->lines.at(l-1).length || d->layoutData->string.at(strlen - 1) != QChar::LineSeparator)
            return QTextLine();
    }

    QScriptLine line;
    line.from = from;
    line.length = -1;
    line.justified = false;
    line.gridfitted = false;

    d->lines.append(line);
    return QTextLine(l, d);
}

/*!
    Returns the number of lines in this text layout.

    \sa lineAt()
*/
int QTextLayout::lineCount() const
{
    return d->lines.size();
}

/*!
    Returns the \a{i}-th line of text in this text layout.

    \sa lineCount(), lineForTextPosition()
*/
QTextLine QTextLayout::lineAt(int i) const
{
    return i < lineCount() ? QTextLine(i, d) : QTextLine();
}

/*!
    Returns the line that contains the cursor position specified by \a pos.

    \sa isValidCursorPosition(), lineAt()
*/
QTextLine QTextLayout::lineForTextPosition(int pos) const
{
    int lineNum = d->lineNumberForTextPosition(pos);
    return lineNum >= 0 ? lineAt(lineNum) : QTextLine();
}

/*!
    \since 4.2

    The global position of the layout. This is independent of the
    bounding rectangle and of the layout process.

    \sa setPosition()
*/
QPointF QTextLayout::position() const
{
    return d->position;
}

/*!
    Moves the text layout to point \a p.

    \sa position()
*/
void QTextLayout::setPosition(const QPointF &p)
{
    d->position = p;
}

/*!
    The smallest rectangle that contains all the lines in the layout.
*/
QRectF QTextLayout::boundingRect() const
{
    if (d->lines.isEmpty())
        return QRectF();

    QFixed xmax, ymax;
    QFixed xmin = d->lines.at(0).x;
    QFixed ymin = d->lines.at(0).y;

    for (int i = 0; i < d->lines.size(); ++i) {
        const QScriptLine &si = d->lines.at(i);
        xmin = qMin(xmin, si.x);
        ymin = qMin(ymin, si.y);
        QFixed lineWidth = si.width < QFIXED_MAX ? qMax(si.width, si.textWidth) : si.textWidth;
        xmax = qMax(xmax, si.x+lineWidth);
        // ### shouldn't the ascent be used in ymin???
        ymax = qMax(ymax, si.y+si.height().ceil());
    }
    return QRectF(xmin.toReal(), ymin.toReal(), (xmax-xmin).toReal(), (ymax-ymin).toReal());
}

/*!
    The minimum width the layout needs. This is the width of the
    layout's smallest non-breakable substring.

    \warning This function only returns a valid value after the layout
    has been done.

    \sa maximumWidth()
*/
qreal QTextLayout::minimumWidth() const
{
    return d->minWidth.toReal();
}

/*!
    The maximum width the layout could expand to; this is essentially
    the width of the entire text.

    \warning This function only returns a valid value after the layout
    has been done.

    \sa minimumWidth()
*/
qreal QTextLayout::maximumWidth() const
{
    return d->maxWidth.toReal();
}


/*!
    \internal
*/
void QTextLayout::setFlags(int flags)
{
    if (flags & Qt::TextJustificationForced) {
        d->option.setAlignment(Qt::AlignJustify);
        d->forceJustification = true;
    }

    if (flags & (Qt::TextForceLeftToRight|Qt::TextForceRightToLeft)) {
        d->ignoreBidi = true;
        d->option.setTextDirection((flags & Qt::TextForceLeftToRight) ? Qt::LeftToRight : Qt::RightToLeft);
    }
}

static void addSelectedRegionsToPath(QTextEngine *eng, int lineNumber, const QPointF &pos, QTextLayout::FormatRange *selection,
                                     QPainterPath *region, const QRectF &boundingRect)
{
    const QScriptLine &line = eng->lines[lineNumber];

    QTextLineItemIterator iterator(eng, lineNumber, pos, selection);



    const qreal selectionY = pos.y() + line.y.toReal();
    const qreal lineHeight = line.height().toReal();

    QFixed lastSelectionX = iterator.x;
    QFixed lastSelectionWidth;

    while (!iterator.atEnd()) {
        iterator.next();

        QFixed selectionX, selectionWidth;
        if (iterator.getSelectionBounds(&selectionX, &selectionWidth)) {
            if (selectionX == lastSelectionX + lastSelectionWidth) {
                lastSelectionWidth += selectionWidth;
                continue;
            }

            if (lastSelectionWidth > 0) {
                const QRectF rect = boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight);
                region->addRect(rect.toAlignedRect());
            }

            lastSelectionX = selectionX;
            lastSelectionWidth = selectionWidth;
        }
    }
    if (lastSelectionWidth > 0) {
        const QRectF rect = boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight);
        region->addRect(rect.toAlignedRect());
    }
}

static inline QRectF clipIfValid(const QRectF &rect, const QRectF &clip)
{
    return clip.isValid() ? (rect & clip) : rect;
}


/*!
    Returns the glyph indexes and positions for all glyphs corresponding to the \a length characters
    starting at the position \a from in this QTextLayout. This is an expensive function, and should
    not be called in a time sensitive context.

    If \a from is less than zero, then the glyph run will begin at the first character in the
    layout. If \a length is less than zero, it will span the entire string from the start position.

    \since 4.8

    \sa draw(), QPainter::drawGlyphRun()
*/
#if !defined(QT_NO_RAWFONT)
QList<QGlyphRun> QTextLayout::glyphRuns(int from, int length) const
{
    if (from < 0)
        from = 0;
    if (length < 0)
        length = text().length();

    QHash<QPair<QFontEngine *, int>, QGlyphRun> glyphRunHash;
    for (int i=0; i<d->lines.size(); ++i) {
        if (d->lines.at(i).from > from + length)
            break;
        else if (d->lines.at(i).from + d->lines[i].length >= from) {
            QList<QGlyphRun> glyphRuns = QTextLine(i, d).glyphRuns(from, length);

            for (int j = 0; j < glyphRuns.size(); j++) {
                const QGlyphRun &glyphRun = glyphRuns.at(j);
                QRawFont rawFont = glyphRun.rawFont();

                QFontEngine *fontEngine = rawFont.d->fontEngine;
                QGlyphRun::GlyphRunFlags flags = glyphRun.flags();
                QPair<QFontEngine *, int> key(fontEngine, int(flags));
                // merge the glyph runs using the same font
                QGlyphRun &oldGlyphRun = glyphRunHash[key];
                if (oldGlyphRun.isEmpty()) {
                    oldGlyphRun = glyphRun;
                } else {
                    QVector<quint32> indexes = oldGlyphRun.glyphIndexes();
                    QVector<QPointF> positions = oldGlyphRun.positions();
                    QRectF boundingRect = oldGlyphRun.boundingRect();

                    indexes += glyphRun.glyphIndexes();
                    positions += glyphRun.positions();
                    boundingRect = boundingRect.united(glyphRun.boundingRect());

                    oldGlyphRun.setGlyphIndexes(indexes);
                    oldGlyphRun.setPositions(positions);
                    oldGlyphRun.setBoundingRect(boundingRect);
                }
            }
        }
    }

    return glyphRunHash.values();
}
#endif // QT_NO_RAWFONT

/*!
    Draws the whole layout on the painter \a p at the position specified by \a pos.
    The rendered layout includes the given \a selections and is clipped within
    the rectangle specified by \a clip.
*/
void QTextLayout::draw(QPainter *p, const QPointF &pos, const QVector<FormatRange> &selections, const QRectF &clip) const
{
    if (d->lines.isEmpty())
        return;

    if (!d->layoutData)
        d->itemize();

    QPointF position = pos + d->position;

    QFixed clipy = (INT_MIN/256);
    QFixed clipe = (INT_MAX/256);
    if (clip.isValid()) {
        clipy = QFixed::fromReal(clip.y() - position.y());
        clipe = clipy + QFixed::fromReal(clip.height());
    }

    int firstLine = 0;
    int lastLine = d->lines.size();
    for (int i = 0; i < d->lines.size(); ++i) {
        QTextLine l(i, d);
        const QScriptLine &sl = d->lines.at(i);

        if (sl.y > clipe) {
            lastLine = i;
            break;
        }
        if ((sl.y + sl.height()) < clipy) {
            firstLine = i;
            continue;
        }
    }

    QPainterPath excludedRegion;
    QPainterPath textDoneRegion;
    for (int i = 0; i < selections.size(); ++i) {
        FormatRange selection = selections.at(i);
        QPainterPath region;
        region.setFillRule(Qt::WindingFill);

        for (int line = firstLine; line < lastLine; ++line) {
            const QScriptLine &sl = d->lines.at(line);
            QTextLine tl(line, d);

            QRectF lineRect(tl.naturalTextRect());
            lineRect.translate(position);
            lineRect.adjust(0, 0, d->leadingSpaceWidth(sl).toReal(), 0);

            bool isLastLineInBlock = (line == d->lines.size()-1);
            int sl_length = sl.length + (isLastLineInBlock? 1 : 0); // the infamous newline


            if (sl.from > selection.start + selection.length || sl.from + sl_length <= selection.start)
                continue; // no actual intersection

            const bool selectionStartInLine = sl.from <= selection.start;
            const bool selectionEndInLine = selection.start + selection.length < sl.from + sl_length;

            if (sl.length && (selectionStartInLine || selectionEndInLine)) {
                addSelectedRegionsToPath(d, line, position, &selection, &region, clipIfValid(lineRect, clip));
            } else {
                region.addRect(clipIfValid(lineRect, clip));
            }

            if (selection.format.boolProperty(QTextFormat::FullWidthSelection)) {
                QRectF fullLineRect(tl.rect());
                fullLineRect.translate(position);
                fullLineRect.setRight(QFIXED_MAX);
                if (!selectionEndInLine)
                    region.addRect(clipIfValid(QRectF(lineRect.topRight(), fullLineRect.bottomRight()), clip));
                if (!selectionStartInLine)
                    region.addRect(clipIfValid(QRectF(fullLineRect.topLeft(), lineRect.bottomLeft()), clip));
            } else if (!selectionEndInLine
                && isLastLineInBlock
                &&!(d->option.flags() & QTextOption::ShowLineAndParagraphSeparators)) {
                region.addRect(clipIfValid(QRectF(lineRect.right(), lineRect.top(),
                                                  lineRect.height()/4, lineRect.height()), clip));
            }

        }
        {
            const QPen oldPen = p->pen();
            const QBrush oldBrush = p->brush();

            p->setPen(selection.format.penProperty(QTextFormat::OutlinePen));
            p->setBrush(selection.format.brushProperty(QTextFormat::BackgroundBrush));
            p->drawPath(region);

            p->setPen(oldPen);
            p->setBrush(oldBrush);
        }



        bool hasText = (selection.format.foreground().style() != Qt::NoBrush);
        bool hasBackground= (selection.format.background().style() != Qt::NoBrush);

        if (hasBackground) {
            selection.format.setProperty(ObjectSelectionBrush, selection.format.property(QTextFormat::BackgroundBrush));
            // don't just clear the property, set an empty brush that overrides a potential
            // background brush specified in the text
            selection.format.setProperty(QTextFormat::BackgroundBrush, QBrush());
            selection.format.clearProperty(QTextFormat::OutlinePen);
        }

        selection.format.setProperty(SuppressText, !hasText);

        if (hasText && !hasBackground && !(textDoneRegion & region).isEmpty())
            continue;

        p->save();
        p->setClipPath(region, Qt::IntersectClip);

        for (int line = firstLine; line < lastLine; ++line) {
            QTextLine l(line, d);
            l.draw(p, position, &selection);
        }
        p->restore();

        if (hasText) {
            textDoneRegion += region;
        } else {
            if (hasBackground)
                textDoneRegion -= region;
        }

        excludedRegion += region;
    }

    QPainterPath needsTextButNoBackground = excludedRegion - textDoneRegion;
    if (!needsTextButNoBackground.isEmpty()){
        p->save();
        p->setClipPath(needsTextButNoBackground, Qt::IntersectClip);
        FormatRange selection;
        selection.start = 0;
        selection.length = INT_MAX;
        selection.format.setProperty(SuppressBackground, true);
        for (int line = firstLine; line < lastLine; ++line) {
            QTextLine l(line, d);
            l.draw(p, position, &selection);
        }
        p->restore();
    }

    if (!excludedRegion.isEmpty()) {
        p->save();
        QPainterPath path;
        QRectF br = boundingRect().translated(position);
        br.setRight(QFIXED_MAX);
        if (!clip.isNull())
            br = br.intersected(clip);
        path.addRect(br);
        path -= excludedRegion;
        p->setClipPath(path, Qt::IntersectClip);
    }

    for (int i = firstLine; i < lastLine; ++i) {
        QTextLine l(i, d);
        l.draw(p, position);
    }
    if (!excludedRegion.isEmpty())
        p->restore();


    if (!d->cacheGlyphs)
        d->freeMemory();
}

/*!
    \fn void QTextLayout::drawCursor(QPainter *painter, const QPointF &position, int cursorPosition) const
    \overload

    Draws a text cursor with the current pen at the given \a position using the
    \a painter specified.
    The corresponding position within the text is specified by \a cursorPosition.
*/
void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition) const
{
    drawCursor(p, pos, cursorPosition, 1);
}

/*!
    \fn void QTextLayout::drawCursor(QPainter *painter, const QPointF &position, int cursorPosition, int width) const

    Draws a text cursor with the current pen and the specified \a width at the given \a position using the
    \a painter specified.
    The corresponding position within the text is specified by \a cursorPosition.
*/
void QTextLayout::drawCursor(QPainter *p, const QPointF &pos, int cursorPosition, int width) const
{
    if (d->lines.isEmpty())
        return;

    if (!d->layoutData)
        d->itemize();

    QPointF position = pos + d->position;

    cursorPosition = qBound(0, cursorPosition, d->layoutData->string.length());
    int line = d->lineNumberForTextPosition(cursorPosition);
    if (line < 0)
        line = 0;
    if (line >= d->lines.size())
        return;

    QTextLine l(line, d);
    const QScriptLine &sl = d->lines.at(line);

    qreal x = position.x() + l.cursorToX(cursorPosition);

    int itm;

    if (d->visualCursorMovement()) {
        if (cursorPosition == sl.from + sl.length)
            cursorPosition--;
        itm = d->findItem(cursorPosition);
    } else
        itm = d->findItem(cursorPosition - 1);

    QFixed base = sl.base();
    QFixed descent = sl.descent;
    bool rightToLeft = d->isRightToLeft();
    if (itm >= 0) {
        const QScriptItem &si = d->layoutData->items.at(itm);
        if (si.ascent > 0)
            base = si.ascent;
        if (si.descent > 0)
            descent = si.descent;
        rightToLeft = si.analysis.bidiLevel % 2;
    }
    qreal y = position.y() + (sl.y + sl.base() - base).toReal();
    bool toggleAntialiasing = !(p->renderHints() & QPainter::Antialiasing)
                              && (p->transform().type() > QTransform::TxTranslate);
    if (toggleAntialiasing)
        p->setRenderHint(QPainter::Antialiasing);
    QPainter::CompositionMode origCompositionMode = p->compositionMode();
    if (p->paintEngine()->hasFeature(QPaintEngine::RasterOpModes))
        p->setCompositionMode(QPainter::RasterOp_NotDestination);
    p->fillRect(QRectF(x, y, qreal(width), (base + descent).toReal()), p->pen().brush());
    p->setCompositionMode(origCompositionMode);
    if (toggleAntialiasing)
        p->setRenderHint(QPainter::Antialiasing, false);
    if (d->layoutData->hasBidi) {
        const int arrow_extent = 4;
        int sign = rightToLeft ? -1 : 1;
        p->drawLine(QLineF(x, y, x + (sign * arrow_extent/2), y + arrow_extent/2));
        p->drawLine(QLineF(x, y+arrow_extent, x + (sign * arrow_extent/2), y + arrow_extent/2));
    }
    return;
}

/*!
    \class QTextLine
    \reentrant

    \brief The QTextLine class represents a line of text inside a QTextLayout.
    \inmodule QtGui

    \ingroup richtext-processing

    A text line is usually created by QTextLayout::createLine().

    After being created, the line can be filled using the setLineWidth()
    or setNumColumns() functions. A line has a number of attributes including the
    rectangle it occupies, rect(), its coordinates, x() and y(), its
    textLength(), width() and naturalTextWidth(), and its ascent() and descent()
    relative to the text. The position of the cursor in terms of the
    line is available from cursorToX() and its inverse from
    xToCursor(). A line can be moved with setPosition().
*/

/*!
    \enum QTextLine::Edge

    \value Leading
    \value Trailing
*/

/*!
    \enum QTextLine::CursorPosition

    \value CursorBetweenCharacters
    \value CursorOnCharacter
*/

/*!
    \fn QTextLine::QTextLine(int line, QTextEngine *e)
    \internal

    Constructs a new text line using the line at position \a line in
    the text engine \a e.
*/

/*!
    \fn QTextLine::QTextLine()

    Creates an invalid line.
*/

/*!
    \fn bool QTextLine::isValid() const

    Returns \c true if this text line is valid; otherwise returns \c false.
*/

/*!
    \fn int QTextLine::lineNumber() const

    Returns the position of the line in the text engine.
*/


/*!
    Returns the line's bounding rectangle.

    \sa x(), y(), textLength(), width()
*/
QRectF QTextLine::rect() const
{
    const QScriptLine& sl = eng->lines.at(index);
    return QRectF(sl.x.toReal(), sl.y.toReal(), sl.width.toReal(), sl.height().toReal());
}

/*!
    Returns the rectangle covered by the line.
*/
QRectF QTextLine::naturalTextRect() const
{
    const QScriptLine& sl = eng->lines.at(index);
    QFixed x = sl.x + eng->alignLine(sl);

    QFixed width = sl.textWidth;
    if (sl.justified)
        width = sl.width;

    return QRectF(x.toReal(), sl.y.toReal(), width.toReal(), sl.height().toReal());
}

/*!
    Returns the line's x position.

    \sa rect(), y(), textLength(), width()
*/
qreal QTextLine::x() const
{
    return eng->lines.at(index).x.toReal();
}

/*!
    Returns the line's y position.

    \sa x(), rect(), textLength(), width()
*/
qreal QTextLine::y() const
{
    return eng->lines.at(index).y.toReal();
}

/*!
    Returns the line's width as specified by the layout() function.

    \sa naturalTextWidth(), x(), y(), textLength(), rect()
*/
qreal QTextLine::width() const
{
    return eng->lines.at(index).width.toReal();
}


/*!
    Returns the line's ascent.

    \sa descent(), height()
*/
qreal QTextLine::ascent() const
{
    return eng->lines.at(index).ascent.toReal();
}

/*!
    Returns the line's descent.

    \sa ascent(), height()
*/
qreal QTextLine::descent() const
{
    return eng->lines.at(index).descent.toReal();
}

/*!
    Returns the line's height. This is equal to ascent() + descent()
    if leading is not included. If leading is included, this equals to
    ascent() + descent() + leading().

    \sa ascent(), descent(), leading(), setLeadingIncluded()
*/
qreal QTextLine::height() const
{
    return eng->lines.at(index).height().ceil().toReal();
}

/*!
    \since 4.6

    Returns the line's leading.

    \sa ascent(), descent(), height()
*/
qreal QTextLine::leading() const
{
    return eng->lines.at(index).leading.toReal();
}

/*!
    \since 4.6

    Includes positive leading into the line's height if \a included is true;
    otherwise does not include leading.

    By default, leading is not included.

    Note that negative leading is ignored, it must be handled
    in the code using the text lines by letting the lines overlap.

    \sa leadingIncluded()

*/
void QTextLine::setLeadingIncluded(bool included)
{
    eng->lines[index].leadingIncluded= included;

}

/*!
    \since 4.6

    Returns \c true if positive leading is included into the line's height;
    otherwise returns \c false.

    By default, leading is not included.

    \sa setLeadingIncluded()
*/
bool QTextLine::leadingIncluded() const
{
    return eng->lines.at(index).leadingIncluded;
}

/*!
    Returns the width of the line that is occupied by text. This is
    always \<= to width(), and is the minimum width that could be used
    by layout() without changing the line break position.
*/
qreal QTextLine::naturalTextWidth() const
{
    return eng->lines.at(index).textWidth.toReal();
}

/*!
    \since 4.7
    Returns the horizontal advance of the text. The advance of the text
    is the distance from its position to the next position at which
    text would naturally be drawn.

    By adding the advance to the position of the text line and using this
    as the position of a second text line, you will be able to position
    the two lines side-by-side without gaps in-between.
*/
qreal QTextLine::horizontalAdvance() const
{
    return eng->lines.at(index).textAdvance.toReal();
}

/*!
    Lays out the line with the given \a width. The line is filled from
    its starting position with as many characters as will fit into
    the line. In case the text cannot be split at the end of the line,
    it will be filled with additional characters to the next whitespace
    or end of the text.
*/
void QTextLine::setLineWidth(qreal width)
{
    QScriptLine &line = eng->lines[index];
    if (!eng->layoutData) {
        qWarning("QTextLine: Can't set a line width while not layouting.");
        return;
    }

    if (width > QFIXED_MAX)
        width = QFIXED_MAX;

    line.width = QFixed::fromReal(width);
    if (line.length
        && line.textWidth <= line.width
        && line.from + line.length == eng->layoutData->string.length())
        // no need to do anything if the line is already layouted and the last one. This optimization helps
        // when using things in a single line layout.
        return;
    line.length = 0;
    line.textWidth = 0;

    layout_helper(INT_MAX);
}

/*!
    Lays out the line. The line is filled from its starting position
    with as many characters as are specified by \a numColumns. In case
    the text cannot be split until \a numColumns characters, the line
    will be filled with as many characters to the next whitespace or
    end of the text.
*/
void QTextLine::setNumColumns(int numColumns)
{
    QScriptLine &line = eng->lines[index];
    line.width = QFIXED_MAX;
    line.length = 0;
    line.textWidth = 0;
    layout_helper(numColumns);
}

/*!
    Lays out the line. The line is filled from its starting position
    with as many characters as are specified by \a numColumns. In case
    the text cannot be split until \a numColumns characters, the line
    will be filled with as many characters to the next whitespace or
    end of the text. The provided \a alignmentWidth is used as reference
    width for alignment.
*/
void QTextLine::setNumColumns(int numColumns, qreal alignmentWidth)
{
    QScriptLine &line = eng->lines[index];
    line.width = QFixed::fromReal(alignmentWidth);
    line.length = 0;
    line.textWidth = 0;
    layout_helper(numColumns);
}

#if 0
#define LB_DEBUG qDebug
#else
#define LB_DEBUG if (0) qDebug
#endif

namespace {

    struct LineBreakHelper
    {
        LineBreakHelper()
            : glyphCount(0), maxGlyphs(0), currentPosition(0), fontEngine(0), logClusters(0),
              manualWrap(false), whiteSpaceOrObject(true)
        {
        }


        QScriptLine tmpData;
        QScriptLine spaceData;

        QGlyphLayout glyphs;

        int glyphCount;
        int maxGlyphs;
        int currentPosition;
        glyph_t previousGlyph;
        QFontEngine *previousGlyphFontEngine;

        QFixed minw;
        QFixed softHyphenWidth;
        QFixed rightBearing;
        QFixed minimumRightBearing;

        QFontEngine *fontEngine;
        const unsigned short *logClusters;

        bool manualWrap;
        bool whiteSpaceOrObject;

        bool checkFullOtherwiseExtend(QScriptLine &line);

        QFixed calculateNewWidth(const QScriptLine &line) const {
            return line.textWidth + tmpData.textWidth + spaceData.textWidth
                    + softHyphenWidth + negativeRightBearing();
        }

        inline glyph_t currentGlyph() const
        {
            Q_ASSERT(currentPosition > 0);
            Q_ASSERT(logClusters[currentPosition - 1] < glyphs.numGlyphs);

            return glyphs.glyphs[logClusters[currentPosition - 1]];
        }

        inline void saveCurrentGlyph()
        {
            previousGlyph = 0;
            if (currentPosition > 0 &&
                logClusters[currentPosition - 1] < glyphs.numGlyphs) {
                previousGlyph = currentGlyph(); // needed to calculate right bearing later
                previousGlyphFontEngine = fontEngine;
            }
        }

        inline void calculateRightBearing(QFontEngine *engine, glyph_t glyph)
        {
            qreal rb;
            engine->getGlyphBearings(glyph, 0, &rb);

            // We only care about negative right bearings, so we limit the range
            // of the bearing here so that we can assume it's negative in the rest
            // of the code, as well ase use QFixed(1) as a sentinel to represent
            // the state where we have yet to compute the right bearing.
            rightBearing = qMin(QFixed::fromReal(rb), QFixed(0));
        }

        inline void calculateRightBearing()
        {
            if (currentPosition <= 0)
                return;
            calculateRightBearing(fontEngine, currentGlyph());
        }

        inline void calculateRightBearingForPreviousGlyph()
        {
            if (previousGlyph > 0)
                calculateRightBearing(previousGlyphFontEngine, previousGlyph);
        }

        static const QFixed RightBearingNotCalculated;

        inline void resetRightBearing()
        {
            rightBearing = RightBearingNotCalculated;
        }

        // We express the negative right bearing as an absolute number
        // so that it can be applied to the width using addition.
        inline QFixed negativeRightBearing() const
        {
            if (rightBearing == RightBearingNotCalculated)
                return QFixed(0);

            return qAbs(rightBearing);
        }
    };

const QFixed LineBreakHelper::RightBearingNotCalculated = QFixed(1);

inline bool LineBreakHelper::checkFullOtherwiseExtend(QScriptLine &line)
{
    LB_DEBUG("possible break width %f, spacew=%f", tmpData.textWidth.toReal(), spaceData.textWidth.toReal());

    QFixed newWidth = calculateNewWidth(line);
    if (line.length && !manualWrap && (newWidth > line.width || glyphCount > maxGlyphs))
        return true;

    minw = qMax(minw, tmpData.textWidth);
    line += tmpData;
    line.textWidth += spaceData.textWidth;

    line.length += spaceData.length;
    tmpData.textWidth = 0;
    tmpData.length = 0;
    spaceData.textWidth = 0;
    spaceData.length = 0;

    return false;
}

} // anonymous namespace


static inline void addNextCluster(int &pos, int end, QScriptLine &line, int &glyphCount,
                                  const QScriptItem &current, const unsigned short *logClusters,
                                  const QGlyphLayout &glyphs)
{
    int glyphPosition = logClusters[pos];
    do { // got to the first next cluster
        ++pos;
        ++line.length;
    } while (pos < end && logClusters[pos] == glyphPosition);
    do { // calculate the textWidth for the rest of the current cluster.
        if (!glyphs.attributes[glyphPosition].dontPrint)
            line.textWidth += glyphs.advances[glyphPosition];
        ++glyphPosition;
    } while (glyphPosition < current.num_glyphs && !glyphs.attributes[glyphPosition].clusterStart);

    Q_ASSERT((pos == end && glyphPosition == current.num_glyphs) || logClusters[pos] == glyphPosition);

    ++glyphCount;
}


// fill QScriptLine
void QTextLine::layout_helper(int maxGlyphs)
{
    QScriptLine &line = eng->lines[index];
    line.length = 0;
    line.trailingSpaces = 0;
    line.textWidth = 0;
    line.hasTrailingSpaces = false;

    if (!eng->layoutData->items.size() || line.from >= eng->layoutData->string.length()) {
        line.setDefaultHeight(eng);
        return;
    }

    Q_ASSERT(line.from < eng->layoutData->string.length());

    LineBreakHelper lbh;

    lbh.maxGlyphs = maxGlyphs;

    QTextOption::WrapMode wrapMode = eng->option.wrapMode();
    bool breakany = (wrapMode == QTextOption::WrapAnywhere);
    lbh.manualWrap = (wrapMode == QTextOption::ManualWrap || wrapMode == QTextOption::NoWrap);

    int item = -1;
    int newItem = eng->findItem(line.from);
    Q_ASSERT(newItem >= 0);

    LB_DEBUG("from: %d: item=%d, total %d, width available %f", line.from, newItem, eng->layoutData->items.size(), line.width.toReal());

    Qt::Alignment alignment = eng->option.alignment();

    const QCharAttributes *attributes = eng->attributes();
    if (!attributes)
        return;
    lbh.currentPosition = line.from;
    int end = 0;
    lbh.logClusters = eng->layoutData->logClustersPtr;
    lbh.previousGlyph = 0;

    bool hasInlineObject = false;
    QFixed maxInlineObjectHeight = 0;

    while (newItem < eng->layoutData->items.size()) {
        lbh.resetRightBearing();
        lbh.softHyphenWidth = 0;
        if (newItem != item) {
            item = newItem;
            const QScriptItem &current = eng->layoutData->items.at(item);
            if (!current.num_glyphs) {
                eng->shape(item);
                attributes = eng->attributes();
                if (!attributes)
                    return;
                lbh.logClusters = eng->layoutData->logClustersPtr;
            }
            lbh.currentPosition = qMax(line.from, current.position);
            end = current.position + eng->length(item);
            lbh.glyphs = eng->shapedGlyphs(&current);
            QFontEngine *fontEngine = eng->fontEngine(current);
            if (lbh.fontEngine != fontEngine) {
                lbh.fontEngine = fontEngine;
                lbh.minimumRightBearing = qMin(QFixed(),
                                               QFixed::fromReal(fontEngine->minRightBearing()));
            }
        }
        const QScriptItem &current = eng->layoutData->items.at(item);

        lbh.tmpData.leading = qMax(lbh.tmpData.leading + lbh.tmpData.ascent,
                                   current.leading + current.ascent) - qMax(lbh.tmpData.ascent,
                                                                            current.ascent);
        if (current.analysis.flags != QScriptAnalysis::Object) {
            // objects need some special treatment as they can special alignment or be floating
            lbh.tmpData.ascent = qMax(lbh.tmpData.ascent, current.ascent);
            lbh.tmpData.descent = qMax(lbh.tmpData.descent, current.descent);
        }

        if (current.analysis.flags == QScriptAnalysis::Tab && (alignment & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignCenter | Qt::AlignJustify))) {
            lbh.whiteSpaceOrObject = true;
            if (lbh.checkFullOtherwiseExtend(line))
                goto found;

            QFixed x = line.x + line.textWidth + lbh.tmpData.textWidth + lbh.spaceData.textWidth;
            QFixed tabWidth = eng->calculateTabWidth(item, x);
            attributes = eng->attributes();
            if (!attributes)
                return;
            lbh.logClusters = eng->layoutData->logClustersPtr;
            lbh.glyphs = eng->shapedGlyphs(&current);

            lbh.spaceData.textWidth += tabWidth;
            lbh.spaceData.length++;
            newItem = item + 1;

            QFixed averageCharWidth = eng->fontEngine(current)->averageCharWidth();
            lbh.glyphCount += qRound(tabWidth / averageCharWidth);

            if (lbh.checkFullOtherwiseExtend(line))
                goto found;
        } else if (current.analysis.flags == QScriptAnalysis::LineOrParagraphSeparator) {
            lbh.whiteSpaceOrObject = true;
            // if the line consists only of the line separator make sure
            // we have a sane height
            if (!line.length && !lbh.tmpData.length)
                line.setDefaultHeight(eng);
            if (eng->option.flags() & QTextOption::ShowLineAndParagraphSeparators) {
                if (lbh.checkFullOtherwiseExtend(line))
                    goto found;

                addNextCluster(lbh.currentPosition, end, lbh.tmpData, lbh.glyphCount,
                               current, lbh.logClusters, lbh.glyphs);
            } else {
                lbh.tmpData.length++;
                lbh.calculateRightBearingForPreviousGlyph();
            }
            line += lbh.tmpData;
            goto found;
        } else if (current.analysis.flags == QScriptAnalysis::Object) {
            lbh.whiteSpaceOrObject = true;
            lbh.tmpData.length++;

            if (eng->block.docHandle()) {
                QTextInlineObject inlineObject(item, eng);
                QTextFormat f = inlineObject.format();
                eng->docLayout()->positionInlineObject(inlineObject, eng->block.position() + current.position, f);
                QTextCharFormat::VerticalAlignment valign = f.toCharFormat().verticalAlignment();
                if (valign != QTextCharFormat::AlignTop && valign != QTextCharFormat::AlignBottom) {
                    lbh.tmpData.ascent = qMax(lbh.tmpData.ascent, current.ascent);
                    lbh.tmpData.descent = qMax(lbh.tmpData.descent, current.descent);
                }
            }

            hasInlineObject = true;
            maxInlineObjectHeight = qMax(maxInlineObjectHeight, current.ascent + current.descent);

            lbh.tmpData.textWidth += current.width;

            newItem = item + 1;
            ++lbh.glyphCount;
            if (lbh.checkFullOtherwiseExtend(line))
                goto found;
        } else if (attributes[lbh.currentPosition].whiteSpace
                   && eng->layoutData->string.at(lbh.currentPosition).decompositionTag() != QChar::NoBreak) {
            lbh.whiteSpaceOrObject = true;
            while (lbh.currentPosition < end
                   && attributes[lbh.currentPosition].whiteSpace
                   && eng->layoutData->string.at(lbh.currentPosition).decompositionTag() != QChar::NoBreak) {
                addNextCluster(lbh.currentPosition, end, lbh.spaceData, lbh.glyphCount,
                               current, lbh.logClusters, lbh.glyphs);
            }

            if (!lbh.manualWrap && lbh.spaceData.textWidth > line.width) {
                lbh.spaceData.textWidth = line.width; // ignore spaces that fall out of the line.
                goto found;
            }
        } else {
            lbh.whiteSpaceOrObject = false;
            bool sb_or_ws = false;
            lbh.saveCurrentGlyph();
            do {
                addNextCluster(lbh.currentPosition, end, lbh.tmpData, lbh.glyphCount,
                               current, lbh.logClusters, lbh.glyphs);

                // This is a hack to fix a regression caused by the introduction of the
                // whitespace flag to non-breakable spaces and will cause the non-breakable
                // spaces to behave as in previous Qt versions in the line breaking algorithm.
                // The line breaks do not currently follow the Unicode specs, but fixing this would
                // require refactoring the code and would cause behavioral regressions.
                bool isBreakableSpace = lbh.currentPosition < eng->layoutData->string.length()
                                        && attributes[lbh.currentPosition].whiteSpace
                                        && eng->layoutData->string.at(lbh.currentPosition).decompositionTag() != QChar::NoBreak;

                if (lbh.currentPosition >= eng->layoutData->string.length()
                    || isBreakableSpace
                    || attributes[lbh.currentPosition].lineBreak) {
                    sb_or_ws = true;
                    break;
                } else if (breakany && attributes[lbh.currentPosition].graphemeBoundary) {
                    break;
                }
            } while (lbh.currentPosition < end);
            lbh.minw = qMax(lbh.tmpData.textWidth, lbh.minw);

            if (lbh.currentPosition > 0 && lbh.currentPosition < end
                && attributes[lbh.currentPosition].lineBreak
                && eng->layoutData->string.at(lbh.currentPosition - 1).unicode() == QChar::SoftHyphen) {
                // if we are splitting up a word because of
                // a soft hyphen then we ...
                //
                //  a) have to take the width of the soft hyphen into
                //     account to see if the first syllable(s) /and/
                //     the soft hyphen fit into the line
                //
                //  b) if we are so short of available width that the
                //     soft hyphen is the first breakable position, then
                //     we don't want to show it. However we initially
                //     have to take the width for it into account so that
                //     the text document layout sees the overflow and
                //     switch to break-anywhere mode, in which we
                //     want the soft-hyphen to slip into the next line
                //     and thus become invisible again.
                //
                if (line.length)
                    lbh.softHyphenWidth = lbh.glyphs.advances[lbh.logClusters[lbh.currentPosition - 1]];
                else if (breakany)
                    lbh.tmpData.textWidth += lbh.glyphs.advances[lbh.logClusters[lbh.currentPosition - 1]];
            }

            if (sb_or_ws|breakany) {
                // To compute the final width of the text we need to take negative right bearing
                // into account (negative right bearing means the glyph has pixel data past the
                // advance length). Note that the negative right bearing is an absolute number,
                // so that we can apply it to the width using straight forward addition.

                // Store previous right bearing (for the already accepted glyph) in case we
                // end up breaking due to the current glyph being too wide.
                QFixed previousRightBearing = lbh.rightBearing;

                // We skip calculating the right bearing if the minimum negative bearing is too
                // small to possibly expand the text beyond the edge. Note that this optimization
                // will in some cases fail, as the minimum right bearing reported by the font
                // engine may not cover all the glyphs in the font. The result is that we think
                // we don't need to break at the current glyph (because the right bearing is 0),
                // and when we then end up breaking on the next glyph we compute the right bearing
                // and end up with a line width that is slightly larger width than what was requested.
                // Unfortunately we can't remove this optimization as it will slow down text
                // layouting significantly, so we accept the slight correctnes issue.
                if ((lbh.calculateNewWidth(line) + qAbs(lbh.minimumRightBearing)) > line.width)
                    lbh.calculateRightBearing();

                if (lbh.checkFullOtherwiseExtend(line)) {
                    // We are too wide to accept the next glyph with its bearing, so we restore the
                    // right bearing to that of the previous glyph (the one that was already accepted),
                    // so that the bearing can be be applied to the final width of the text below.
                    if (previousRightBearing != LineBreakHelper::RightBearingNotCalculated)
                        lbh.rightBearing = previousRightBearing;
                    else
                        lbh.calculateRightBearingForPreviousGlyph();

                    if (!breakany) {
                        line.textWidth += lbh.softHyphenWidth;
                    }

                    goto found;
                }
            }
            lbh.saveCurrentGlyph();
        }
        if (lbh.currentPosition == end)
            newItem = item + 1;
    }
    LB_DEBUG("reached end of line");
    lbh.checkFullOtherwiseExtend(line);
found:
    line.textAdvance = line.textWidth;

    // If right bearing has not been calculated yet, do that now
    if (lbh.rightBearing == LineBreakHelper::RightBearingNotCalculated && !lbh.whiteSpaceOrObject)
        lbh.calculateRightBearing();

    // Then apply any negative right bearing
    line.textWidth += lbh.negativeRightBearing();

    if (line.length == 0) {
        LB_DEBUG("no break available in line, adding temp: length %d, width %f, space: length %d, width %f",
               lbh.tmpData.length, lbh.tmpData.textWidth.toReal(),
               lbh.spaceData.length, lbh.spaceData.textWidth.toReal());
        line += lbh.tmpData;
    }

    if (hasInlineObject && eng->block.docHandle()) {
        // position top/bottom aligned inline objects
        if (maxInlineObjectHeight > line.ascent + line.descent) {
            // extend line height if required
            QFixed toAdd = (maxInlineObjectHeight - line.ascent - line.descent)/2;
            line.ascent += toAdd;
            line.descent = maxInlineObjectHeight - line.ascent;
        }
        int startItem = eng->findItem(line.from);
        int endItem = eng->findItem(line.from + line.length);
        if (endItem < 0)
            endItem = eng->layoutData->items.size();
        for (int item = startItem; item < endItem; ++item) {
            QScriptItem &current = eng->layoutData->items[item];
            if (current.analysis.flags == QScriptAnalysis::Object) {
                QTextInlineObject inlineObject(item, eng);
                QTextCharFormat::VerticalAlignment align = inlineObject.format().toCharFormat().verticalAlignment();
                QFixed height = current.ascent + current.descent;
                switch (align) {
                case QTextCharFormat::AlignTop:
                    current.ascent = line.ascent;
                    current.descent = height - line.ascent;
                    break;
                case QTextCharFormat::AlignBottom:
                    current.descent = line.descent;
                    current.ascent = height - line.descent;
                    break;
                default:
                    break;
                }
                Q_ASSERT(line.ascent >= current.ascent);
                Q_ASSERT(line.descent >= current.descent);
            }
        }
    }


    LB_DEBUG("line length = %d, ascent=%f, descent=%f, textWidth=%f (spacew=%f)", line.length, line.ascent.toReal(),
           line.descent.toReal(), line.textWidth.toReal(), lbh.spaceData.width.toReal());
    LB_DEBUG("        : '%s'", eng->layoutData->string.mid(line.from, line.length).toUtf8().data());

    if (lbh.manualWrap) {
        eng->minWidth = qMax(eng->minWidth, line.textWidth);
        eng->maxWidth = qMax(eng->maxWidth, line.textWidth);
    } else {
        eng->minWidth = qMax(eng->minWidth, lbh.minw);
        eng->maxWidth += line.textWidth;
    }

    if (line.textWidth > 0 && item < eng->layoutData->items.size())
        eng->maxWidth += lbh.spaceData.textWidth;
    if (eng->option.flags() & QTextOption::IncludeTrailingSpaces)
        line.textWidth += lbh.spaceData.textWidth;
    if (lbh.spaceData.length) {
        line.trailingSpaces = lbh.spaceData.length;
        line.hasTrailingSpaces = true;
    }

    line.justified = false;
    line.gridfitted = false;

    if (eng->option.wrapMode() == QTextOption::WrapAtWordBoundaryOrAnywhere) {
        if ((lbh.maxGlyphs != INT_MAX && lbh.glyphCount > lbh.maxGlyphs)
            || (lbh.maxGlyphs == INT_MAX && line.textWidth > line.width)) {

            eng->option.setWrapMode(QTextOption::WrapAnywhere);
            line.length = 0;
            line.textWidth = 0;
            layout_helper(lbh.maxGlyphs);
            eng->option.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
        }
    }
}

/*!
    Moves the line to position \a pos.
*/
void QTextLine::setPosition(const QPointF &pos)
{
    eng->lines[index].x = QFixed::fromReal(pos.x());
    eng->lines[index].y = QFixed::fromReal(pos.y());
}

/*!
    Returns the line's position relative to the text layout's position.
*/
QPointF QTextLine::position() const
{
    return QPointF(eng->lines.at(index).x.toReal(), eng->lines.at(index).y.toReal());
}

// ### DOC: I have no idea what this means/does.
// You create a text layout with a string of text. Once you laid
// it out, it contains a number of QTextLines. from() returns the position
// inside the text string where this line starts. If you e.g. has a
// text of "This is a string", laid out into two lines (the second
// starting at the word 'a'), layout.lineAt(0).from() == 0 and
// layout.lineAt(1).from() == 8.
/*!
    Returns the start of the line from the beginning of the string
    passed to the QTextLayout.
*/
int QTextLine::textStart() const
{
    return eng->lines.at(index).from;
}

/*!
    Returns the length of the text in the line.

    \sa naturalTextWidth()
*/
int QTextLine::textLength() const
{
    if (eng->option.flags() & QTextOption::ShowLineAndParagraphSeparators
        && eng->block.isValid() && index == eng->lines.count()-1) {
        return eng->lines.at(index).length - 1;
    }
    return eng->lines.at(index).length + eng->lines.at(index).trailingSpaces;
}

static void setPenAndDrawBackground(QPainter *p, const QPen &defaultPen, const QTextCharFormat &chf, const QRectF &r)
{
    QBrush c = chf.foreground();
    if (c.style() == Qt::NoBrush) {
        p->setPen(defaultPen);
    }

    QBrush bg = chf.background();
    if (bg.style() != Qt::NoBrush && !chf.property(SuppressBackground).toBool())
        p->fillRect(r.toAlignedRect(), bg);
    if (c.style() != Qt::NoBrush) {
        p->setPen(QPen(c, 0));
    }

}

#if !defined(QT_NO_RAWFONT)
static QGlyphRun glyphRunWithInfo(QFontEngine *fontEngine,
                                  const QGlyphLayout &glyphLayout,
                                  const QPointF &pos,
                                  const QGlyphRun::GlyphRunFlags &flags,
                                  const QFixed &selectionX,
                                  const QFixed &selectionWidth,
                                  int glyphsStart,
                                  int glyphsEnd,
                                  unsigned short *logClusters,
                                  int textPosition,
                                  int textLength)
{
    Q_ASSERT(logClusters != 0);

    QGlyphRun glyphRun;

    QGlyphRunPrivate *d = QGlyphRunPrivate::get(glyphRun);

    int rangeStart = textPosition;
    while (*logClusters != glyphsStart && rangeStart < textPosition + textLength) {
        ++logClusters;
        ++rangeStart;
    }

    int rangeEnd = rangeStart;
    while (*logClusters != glyphsEnd && rangeEnd < textPosition + textLength) {
        ++logClusters;
        ++rangeEnd;
    }

    d->textRangeStart = rangeStart;
    d->textRangeEnd = rangeEnd;

    // Make a font for this particular engine
    QRawFont font;
    QRawFontPrivate *fontD = QRawFontPrivate::get(font);
    fontD->setFontEngine(fontEngine);

    QVarLengthArray<glyph_t> glyphsArray;
    QVarLengthArray<QFixedPoint> positionsArray;

    QTextItem::RenderFlags renderFlags;
    if (flags.testFlag(QGlyphRun::Overline))
        renderFlags |= QTextItem::Overline;
    if (flags.testFlag(QGlyphRun::Underline))
        renderFlags |= QTextItem::Underline;
    if (flags.testFlag(QGlyphRun::StrikeOut))
        renderFlags |= QTextItem::StrikeOut;
    if (flags.testFlag(QGlyphRun::RightToLeft))
        renderFlags |= QTextItem::RightToLeft;

    fontEngine->getGlyphPositions(glyphLayout, QTransform(), renderFlags, glyphsArray,
                                  positionsArray);
    Q_ASSERT(glyphsArray.size() == positionsArray.size());

    qreal fontHeight = font.ascent() + font.descent();
    qreal minY = 0;
    qreal maxY = 0;
    QVector<quint32> glyphs;
    glyphs.reserve(glyphsArray.size());
    QVector<QPointF> positions;
    positions.reserve(glyphsArray.size());
    for (int i=0; i<glyphsArray.size(); ++i) {
        glyphs.append(glyphsArray.at(i) & 0xffffff);

        QPointF position = positionsArray.at(i).toPointF() + pos;
        positions.append(position);

        if (i == 0) {
            maxY = minY = position.y();
        } else {
            minY = qMin(minY, position.y());
            maxY = qMax(maxY, position.y());
        }
    }

    qreal height = maxY + fontHeight - minY;

    glyphRun.setGlyphIndexes(glyphs);
    glyphRun.setPositions(positions);
    glyphRun.setFlags(flags);
    glyphRun.setRawFont(font);

    glyphRun.setBoundingRect(QRectF(selectionX.toReal(), minY - font.ascent(),
                                    selectionWidth.toReal(), height));

    return glyphRun;
}

/*!
    Returns the glyph indexes and positions for all glyphs in this QTextLine for characters
    in the range defined by \a from and \a length. The \a from index is relative to the beginning
    of the text in the containing QTextLayout, and the range must be within the range of QTextLine
    as given by functions textStart() and textLength().

    If \a from is negative, it will default to textStart(), and if \a length is negative it will
    default to the return value of textLength().

    \since 5.0

    \sa QTextLayout::glyphRuns()
*/
QList<QGlyphRun> QTextLine::glyphRuns(int from, int length) const
{
    const QScriptLine &line = eng->lines.at(index);

    if (line.length == 0)
        return QList<QGlyphRun>();

    if (from < 0)
        from = textStart();

    if (length < 0)
        length = textLength();

    if (length == 0)
        return QList<QGlyphRun>();

    QTextLayout::FormatRange selection;
    selection.start = from;
    selection.length = length;

    QTextLineItemIterator iterator(eng, index, QPointF(), &selection);
    qreal y = line.y.toReal() + line.base().toReal();
    QList<QGlyphRun> glyphRuns;
    while (!iterator.atEnd()) {
        QScriptItem &si = iterator.next();
        if (si.analysis.flags >= QScriptAnalysis::TabOrObject)
            continue;

        if (from >= 0 && length >= 0 && (from >= iterator.itemEnd || from + length <= iterator.itemStart))
            continue;

        QPointF pos(iterator.x.toReal(), y);

        QFont font;
        QGlyphRun::GlyphRunFlags flags;
        if (!eng->useRawFont) {
            font = eng->font(si);
            if (font.overline())
                flags |= QGlyphRun::Overline;
            if (font.underline())
                flags |= QGlyphRun::Underline;
            if (font.strikeOut())
                flags |= QGlyphRun::StrikeOut;
        }

        bool rtl = false;
        if (si.analysis.bidiLevel % 2) {
            flags |= QGlyphRun::RightToLeft;
            rtl = true;
        }

        int relativeFrom = qMax(iterator.itemStart, from) - si.position;
        int relativeTo = qMin(iterator.itemEnd, from + length) - 1 - si.position;

        unsigned short *logClusters = eng->logClusters(&si);
        int glyphsStart = logClusters[relativeFrom];
        int glyphsEnd = (relativeTo == iterator.itemLength) ? si.num_glyphs - 1 : logClusters[relativeTo];
        // the glyph index right next to the requested range
        int nextGlyphIndex = (relativeTo < iterator.itemLength - 1) ? logClusters[relativeTo + 1] : si.num_glyphs;
        if (nextGlyphIndex - 1 > glyphsEnd)
            glyphsEnd = nextGlyphIndex - 1;
        bool startsInsideLigature = relativeFrom > 0 && logClusters[relativeFrom - 1] == glyphsStart;
        bool endsInsideLigature = nextGlyphIndex == glyphsEnd;

        int itemGlyphsStart = logClusters[iterator.itemStart - si.position];
        int itemGlyphsEnd = logClusters[iterator.itemEnd - 1 - si.position];

        QGlyphLayout glyphLayout = eng->shapedGlyphs(&si);

        // Calculate new x position of glyph layout for a subset. This becomes somewhat complex
        // when we're breaking a RTL script item, since the expected position passed into
        // getGlyphPositions() is the left-most edge of the left-most glyph in an RTL run.
        if (relativeFrom != (iterator.itemStart - si.position) && !rtl) {
            for (int i=itemGlyphsStart; i<glyphsStart; ++i) {
                QFixed justification = QFixed::fromFixed(glyphLayout.justifications[i].space_18d6);
                pos.rx() += (glyphLayout.advances[i] + justification).toReal();
            }
        } else if (relativeTo != (iterator.itemEnd - si.position - 1) && rtl) {
            for (int i=itemGlyphsEnd; i>glyphsEnd; --i) {
                QFixed justification = QFixed::fromFixed(glyphLayout.justifications[i].space_18d6);
                pos.rx() += (glyphLayout.advances[i] + justification).toReal();
            }
        }

        glyphLayout = glyphLayout.mid(glyphsStart, glyphsEnd - glyphsStart + 1);

        QFixed x;
        QFixed width;
        iterator.getSelectionBounds(&x, &width);

        if (glyphLayout.numGlyphs > 0) {
            QFontEngine *mainFontEngine;
#ifndef QT_NO_RAWFONT
            if (eng->useRawFont && eng->rawFont.isValid())
                mainFontEngine= eng->fontEngine(si);
            else
#endif
                mainFontEngine = font.d->engineForScript(si.analysis.script);

            if (mainFontEngine->type() == QFontEngine::Multi) {
                QFontEngineMulti *multiFontEngine = static_cast<QFontEngineMulti *>(mainFontEngine);
                int start = rtl ? glyphLayout.numGlyphs : 0;
                int end = start - 1;
                int which = glyphLayout.glyphs[rtl ? start - 1 : end + 1] >> 24;
                for (; (rtl && start > 0) || (!rtl && end < glyphLayout.numGlyphs - 1);
                     rtl ? --start : ++end) {
                    const int e = glyphLayout.glyphs[rtl ? start - 1 : end + 1] >> 24;
                    if (e == which)
                        continue;

                    QGlyphLayout subLayout = glyphLayout.mid(start, end - start + 1);
                    multiFontEngine->ensureEngineAt(which);

                    QGlyphRun::GlyphRunFlags subFlags = flags;
                    if (start == 0 && startsInsideLigature)
                        subFlags |= QGlyphRun::SplitLigature;

                    glyphRuns.append(glyphRunWithInfo(multiFontEngine->engine(which),
                                                      subLayout,
                                                      pos,
                                                      subFlags,
                                                      x,
                                                      width,
                                                      glyphsStart + start,
                                                      glyphsStart + end,
                                                      logClusters + relativeFrom,
                                                      relativeFrom + si.position,
                                                      relativeTo - relativeFrom + 1));
                    for (int i = 0; i < subLayout.numGlyphs; ++i) {
                        QFixed justification = QFixed::fromFixed(subLayout.justifications[i].space_18d6);
                        pos.rx() += (subLayout.advances[i] + justification).toReal();
                    }

                    if (rtl)
                        end = start - 1;
                    else
                        start = end + 1;
                    which = e;
                }

                QGlyphLayout subLayout = glyphLayout.mid(start, end - start + 1);
                multiFontEngine->ensureEngineAt(which);

                QGlyphRun::GlyphRunFlags subFlags = flags;
                if ((start == 0 && startsInsideLigature) || endsInsideLigature)
                    subFlags |= QGlyphRun::SplitLigature;

                QGlyphRun glyphRun = glyphRunWithInfo(multiFontEngine->engine(which),
                                                      subLayout,
                                                      pos,
                                                      subFlags,
                                                      x,
                                                      width,
                                                      glyphsStart + start,
                                                      glyphsStart + end,
                                                      logClusters + relativeFrom,
                                                      relativeFrom + si.position,
                                                      relativeTo - relativeFrom + 1);
                if (!glyphRun.isEmpty())
                    glyphRuns.append(glyphRun);
            } else {
                if (startsInsideLigature || endsInsideLigature)
                    flags |= QGlyphRun::SplitLigature;
                QGlyphRun glyphRun = glyphRunWithInfo(mainFontEngine,
                                                      glyphLayout,
                                                      pos,
                                                      flags,
                                                      x,
                                                      width,
                                                      glyphsStart,
                                                      glyphsEnd,
                                                      logClusters + relativeFrom,
                                                      relativeFrom + si.position,
                                                      relativeTo - relativeFrom + 1);
                if (!glyphRun.isEmpty())
                    glyphRuns.append(glyphRun);
            }
        }
    }

    return glyphRuns;
}
#endif // QT_NO_RAWFONT

/*!
    \fn void QTextLine::draw(QPainter *painter, const QPointF &position, const QTextLayout::FormatRange *selection) const

    Draws a line on the given \a painter at the specified \a position.
    The \a selection is reserved for internal use.
*/
void QTextLine::draw(QPainter *p, const QPointF &pos, const QTextLayout::FormatRange *selection) const
{
#ifndef QT_NO_RAWFONT
    // Not intended to work with rawfont
    Q_ASSERT(!eng->useRawFont);
#endif
    const QScriptLine &line = eng->lines[index];
    QPen pen = p->pen();

    bool noText = (selection && selection->format.property(SuppressText).toBool());

    if (!line.length) {
        if (selection
            && selection->start <= line.from
            && selection->start + selection->length > line.from) {

            const qreal lineHeight = line.height().toReal();
            QRectF r(pos.x() + line.x.toReal(), pos.y() + line.y.toReal(),
                     lineHeight / 2, QFontMetrics(eng->font()).horizontalAdvance(QLatin1Char(' ')));
            setPenAndDrawBackground(p, QPen(), selection->format, r);
            p->setPen(pen);
        }
        return;
    }


    QTextLineItemIterator iterator(eng, index, pos, selection);
    QFixed lineBase = line.base();
    eng->clearDecorations();
    eng->enableDelayDecorations();

    const QFixed y = QFixed::fromReal(pos.y()) + line.y + lineBase;

    bool suppressColors = (eng->option.flags() & QTextOption::SuppressColors);
    while (!iterator.atEnd()) {
        QScriptItem &si = iterator.next();

        if (selection && selection->start >= 0 && iterator.isOutsideSelection())
            continue;

        if (si.analysis.flags == QScriptAnalysis::LineOrParagraphSeparator
            && !(eng->option.flags() & QTextOption::ShowLineAndParagraphSeparators))
            continue;

        QFixed itemBaseLine = y;
        QFont f = eng->font(si);
        QTextCharFormat format;

        if (eng->hasFormats() || selection) {
            format = eng->format(&si);
            if (suppressColors) {
                format.clearForeground();
                format.clearBackground();
                format.clearProperty(QTextFormat::TextUnderlineColor);
            }
            if (selection)
                format.merge(selection->format);

            setPenAndDrawBackground(p, pen, format, QRectF(iterator.x.toReal(), (y - lineBase).toReal(),
                                                           iterator.itemWidth.toReal(), line.height().toReal()));

            QTextCharFormat::VerticalAlignment valign = format.verticalAlignment();
            if (valign == QTextCharFormat::AlignSuperScript || valign == QTextCharFormat::AlignSubScript) {
                QFontEngine *fe = f.d->engineForScript(si.analysis.script);
                QFixed height = fe->ascent() + fe->descent();
                if (valign == QTextCharFormat::AlignSubScript)
                    itemBaseLine += height / 6;
                else if (valign == QTextCharFormat::AlignSuperScript)
                    itemBaseLine -= height / 2;
            }
        }

        if (si.analysis.flags >= QScriptAnalysis::TabOrObject) {

            if (eng->hasFormats()) {
                p->save();
                if (si.analysis.flags == QScriptAnalysis::Object && eng->block.docHandle()) {
                    QFixed itemY = y - si.ascent;
                    if (format.verticalAlignment() == QTextCharFormat::AlignTop) {
                        itemY = y - lineBase;
                    } else if (format.verticalAlignment() == QTextCharFormat::AlignBottom) {
                        itemY = y + line.descent - si.ascent - si.descent;
                    }

                    QRectF itemRect(iterator.x.toReal(), itemY.toReal(), iterator.itemWidth.toReal(), si.height().toReal());

                    eng->docLayout()->drawInlineObject(p, itemRect,
                                                       QTextInlineObject(iterator.item, eng),
                                                       si.position + eng->block.position(),
                                                       format);
                    if (selection) {
                        QBrush bg = format.brushProperty(ObjectSelectionBrush);
                        if (bg.style() != Qt::NoBrush) {
                            QColor c = bg.color();
                            c.setAlpha(128);
                            p->fillRect(itemRect, c);
                        }
                    }
                } else { // si.isTab
                    QFont f = eng->font(si);
                    QTextItemInt gf(si, &f, format);
                    gf.chars = 0;
                    gf.num_chars = 0;
                    gf.width = iterator.itemWidth;
                    QPainterPrivate::get(p)->drawTextItem(QPointF(iterator.x.toReal(), y.toReal()), gf, eng);
                    if (eng->option.flags() & QTextOption::ShowTabsAndSpaces) {
                        QChar visualTab(0x2192);
                        int w = QFontMetrics(f).horizontalAdvance(visualTab);
                        qreal x = iterator.itemWidth.toReal() - w; // Right-aligned
                        if (x < 0)
                             p->setClipRect(QRectF(iterator.x.toReal(), line.y.toReal(),
                                                   iterator.itemWidth.toReal(), line.height().toReal()),
                                            Qt::IntersectClip);
                        else
                             x /= 2; // Centered
                        p->setFont(f);
                        p->drawText(QPointF(iterator.x.toReal() + x,
                                            y.toReal()), visualTab);
                    }

                }
                p->restore();
            }

            continue;
        }

        unsigned short *logClusters = eng->logClusters(&si);
        QGlyphLayout glyphs = eng->shapedGlyphs(&si);

        QTextItemInt gf(glyphs.mid(iterator.glyphsStart, iterator.glyphsEnd - iterator.glyphsStart),
                        &f, eng->layoutData->string.unicode() + iterator.itemStart,
                        iterator.itemEnd - iterator.itemStart, eng->fontEngine(si), format);
        gf.logClusters = logClusters + iterator.itemStart - si.position;
        gf.width = iterator.itemWidth;
        gf.justified = line.justified;
        gf.initWithScriptItem(si);

        Q_ASSERT(gf.fontEngine);

        QPointF pos(iterator.x.toReal(), itemBaseLine.toReal());
        if (format.penProperty(QTextFormat::TextOutline).style() != Qt::NoPen) {
            QPainterPath path;
            path.setFillRule(Qt::WindingFill);

            if (gf.glyphs.numGlyphs)
                gf.fontEngine->addOutlineToPath(pos.x(), pos.y(), gf.glyphs, &path, gf.flags);
            if (gf.flags) {
                const QFontEngine *fe = gf.fontEngine;
                const qreal lw = fe->lineThickness().toReal();
                if (gf.flags & QTextItem::Underline) {
                    qreal offs = fe->underlinePosition().toReal();
                    path.addRect(pos.x(), pos.y() + offs, gf.width.toReal(), lw);
                }
                if (gf.flags & QTextItem::Overline) {
                    qreal offs = fe->ascent().toReal() + 1;
                    path.addRect(pos.x(), pos.y() - offs, gf.width.toReal(), lw);
                }
                if (gf.flags & QTextItem::StrikeOut) {
                    qreal offs = fe->ascent().toReal() / 3;
                    path.addRect(pos.x(), pos.y() - offs, gf.width.toReal(), lw);
                }
            }

            p->save();
            p->setRenderHint(QPainter::Antialiasing);
            //Currently QPen with a Qt::NoPen style still returns a default
            //QBrush which != Qt::NoBrush so we need this specialcase to reset it
            if (p->pen().style() == Qt::NoPen)
                p->setBrush(Qt::NoBrush);
            else
                p->setBrush(p->pen().brush());

            p->setPen(format.textOutline());
            p->drawPath(path);
            p->restore();
        } else {
            if (noText)
                gf.glyphs.numGlyphs = 0; // slightly less elegant than it should be
            QPainterPrivate::get(p)->drawTextItem(pos, gf, eng);
        }

        if ((si.analysis.flags == QScriptAnalysis::Space
             || si.analysis.flags == QScriptAnalysis::Nbsp)
            && (eng->option.flags() & QTextOption::ShowTabsAndSpaces)) {
            QBrush c = format.foreground();
            if (c.style() != Qt::NoBrush)
                p->setPen(c.color());
            QChar visualSpace(si.analysis.flags == QScriptAnalysis::Space ? (ushort)0xb7 : (ushort)0xb0);
            QFont oldFont = p->font();
            p->setFont(eng->font(si));
            p->drawText(QPointF(iterator.x.toReal(), itemBaseLine.toReal()), visualSpace);
            p->setPen(pen);
            p->setFont(oldFont);
        }
    }
    eng->drawDecorations(p);

    if (eng->hasFormats())
        p->setPen(pen);
}

/*!
    \fn int QTextLine::cursorToX(int cursorPos, Edge edge) const

    \overload
*/

/*!
    Converts the cursor position \a cursorPos to the corresponding x position
    inside the line, taking account of the \a edge.

    If \a cursorPos is not a valid cursor position, the nearest valid
    cursor position will be used instead, and \a cursorPos will be modified to
    point to this valid cursor position.

    \sa xToCursor()
*/
qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
{
    const QScriptLine &line = eng->lines[index];
    bool lastLine = index >= eng->lines.size() - 1;

    QFixed x = line.x + eng->alignLine(line) - eng->leadingSpaceWidth(line);

    if (!eng->layoutData)
        eng->itemize();
    if (!eng->layoutData->items.size()) {
        *cursorPos = line.from;
        return x.toReal();
    }

    int lineEnd = line.from + line.length + line.trailingSpaces;
    int pos = qBound(line.from, *cursorPos, lineEnd);
    int itm;
    const QCharAttributes *attributes = eng->attributes();
    if (!attributes) {
        *cursorPos = line.from;
        return x.toReal();
    }
    while (pos < lineEnd && !attributes[pos].graphemeBoundary)
        pos++;
    if (pos == lineEnd) {
        // end of line ensure we have the last item on the line
        itm = eng->findItem(pos-1);
    }
    else
        itm = eng->findItem(pos);
    if (itm < 0) {
        *cursorPos = line.from;
        return x.toReal();
    }
    eng->shapeLine(line);

    const QScriptItem *si = &eng->layoutData->items[itm];
    if (!si->num_glyphs)
        eng->shape(itm);

    const int l = eng->length(itm);
    pos = qBound(0, pos - si->position, l);

    QGlyphLayout glyphs = eng->shapedGlyphs(si);
    unsigned short *logClusters = eng->logClusters(si);
    Q_ASSERT(logClusters);

    int glyph_pos = pos == l ? si->num_glyphs : logClusters[pos];
    if (edge == Trailing && glyph_pos < si->num_glyphs) {
        // trailing edge is leading edge of next cluster
        glyph_pos++;
        while (glyph_pos < si->num_glyphs && !glyphs.attributes[glyph_pos].clusterStart)
            glyph_pos++;
    }

    bool reverse = si->analysis.bidiLevel % 2;


    // add the items left of the cursor

    int firstItem = eng->findItem(line.from);
    int lastItem = eng->findItem(lineEnd - 1, itm);
    int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0;

    QVarLengthArray<int> visualOrder(nItems);
    QVarLengthArray<uchar> levels(nItems);
    for (int i = 0; i < nItems; ++i)
        levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel;
    QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());

    for (int i = 0; i < nItems; ++i) {
        int item = visualOrder[i]+firstItem;
        if (item == itm)
            break;
        QScriptItem &si = eng->layoutData->items[item];
        if (!si.num_glyphs)
            eng->shape(item);

        if (si.analysis.flags >= QScriptAnalysis::TabOrObject) {
            x += si.width;
            continue;
        }

        const int itemLength = eng->length(item);
        int start = qMax(line.from, si.position);
        int end = qMin(lineEnd, si.position + itemLength);

        logClusters = eng->logClusters(&si);

        int gs = logClusters[start-si.position];
        int ge = (end == si.position + itemLength) ? si.num_glyphs-1 : logClusters[end-si.position-1];

        QGlyphLayout glyphs = eng->shapedGlyphs(&si);

        while (gs <= ge) {
            x += glyphs.effectiveAdvance(gs);
            ++gs;
        }
    }

    logClusters = eng->logClusters(si);
    glyphs = eng->shapedGlyphs(si);
    if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
        if (pos == (reverse ? 0 : l))
            x += si->width;
    } else {
        bool rtl = eng->isRightToLeft();
        bool visual = eng->visualCursorMovement();
        int end = qMin(lineEnd, si->position + l) - si->position;
        if (reverse) {
            int glyph_end = end == l ? si->num_glyphs : logClusters[end];
            int glyph_start = glyph_pos;
            if (visual && !rtl && !(lastLine && itm == (visualOrder[nItems - 1] + firstItem)))
                glyph_start++;
            for (int i = glyph_end - 1; i >= glyph_start; i--)
                x += glyphs.effectiveAdvance(i);
            x -= eng->offsetInLigature(si, pos, end, glyph_pos);
        } else {
            int start = qMax(line.from - si->position, 0);
            int glyph_start = logClusters[start];
            int glyph_end = glyph_pos;
            if (!visual || !rtl || (lastLine && itm == visualOrder[0] + firstItem))
                glyph_end--;
            for (int i = glyph_start; i <= glyph_end; i++)
                x += glyphs.effectiveAdvance(i);
            x += eng->offsetInLigature(si, pos, end, glyph_pos);
        }
    }

    if (eng->option.wrapMode() != QTextOption::NoWrap && x > line.x + line.width)
        x = line.x + line.width;
    if (eng->option.wrapMode() != QTextOption::NoWrap && x < 0)
        x = 0;

    *cursorPos = pos + si->position;
    return x.toReal();
}

/*!
    \fn int QTextLine::xToCursor(qreal x, CursorPosition cpos) const

    Converts the x-coordinate \a x, to the nearest matching cursor
    position, depending on the cursor position type, \a cpos.
    Note that result cursor position includes possible preedit area text.

    \sa cursorToX()
*/
int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
{
    QFixed x = QFixed::fromReal(_x);
    const QScriptLine &line = eng->lines[index];
    bool lastLine = index >= eng->lines.size() - 1;
    int lineNum = index;

    if (!eng->layoutData)
        eng->itemize();

    int line_length = textLength();

    if (!line_length)
        return line.from;

    int firstItem = eng->findItem(line.from);
    int lastItem = eng->findItem(line.from + line_length - 1, firstItem);
    int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0;

    if (!nItems)
        return 0;

    x -= line.x;
    x -= eng->alignLine(line);
//     qDebug("xToCursor: x=%f, cpos=%d", x.toReal(), cpos);

    QVarLengthArray<int> visualOrder(nItems);
    QVarLengthArray<unsigned char> levels(nItems);
    for (int i = 0; i < nItems; ++i)
        levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel;
    QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());

    bool visual = eng->visualCursorMovement();
    if (x <= 0) {
        // left of first item
        int item = visualOrder[0]+firstItem;
        QScriptItem &si = eng->layoutData->items[item];
        if (!si.num_glyphs)
            eng->shape(item);
        int pos = si.position;
        if (si.analysis.bidiLevel % 2)
            pos += eng->length(item);
        pos = qMax(line.from, pos);
        pos = qMin(line.from + line_length, pos);
        return pos;
    } else if (x < line.textWidth
               || (line.justified && x < line.width)) {
        // has to be in one of the runs
        QFixed pos;
        bool rtl = eng->isRightToLeft();

        eng->shapeLine(line);
        const auto insertionPoints = (visual && rtl) ? eng->insertionPointsForLine(lineNum) : std::vector<int>();
        int nchars = 0;
        for (int i = 0; i < nItems; ++i) {
            int item = visualOrder[i]+firstItem;
            QScriptItem &si = eng->layoutData->items[item];
            int item_length = eng->length(item);
//             qDebug("    item %d, visual %d x_remain=%f", i, item, x.toReal());

            int start = qMax(line.from - si.position, 0);
            int end = qMin(line.from + line_length - si.position, item_length);

            unsigned short *logClusters = eng->logClusters(&si);

            int gs = logClusters[start];
            int ge = (end == item_length ? si.num_glyphs : logClusters[end]) - 1;
            QGlyphLayout glyphs = eng->shapedGlyphs(&si);

            QFixed item_width = 0;
            if (si.analysis.flags >= QScriptAnalysis::TabOrObject) {
                item_width = si.width;
            } else {
                int g = gs;
                while (g <= ge) {
                    item_width += glyphs.effectiveAdvance(g);
                    ++g;
                }
            }
//             qDebug("      start=%d, end=%d, gs=%d, ge=%d item_width=%f", start, end, gs, ge, item_width.toReal());

            if (pos + item_width < x) {
                pos += item_width;
                nchars += end;
                continue;
            }
//             qDebug("      inside run");
            if (si.analysis.flags >= QScriptAnalysis::TabOrObject) {
                if (cpos == QTextLine::CursorOnCharacter)
                    return si.position;
                bool left_half = (x - pos) < item_width/2;

                if (bool(si.analysis.bidiLevel % 2) != left_half)
                    return si.position;
                return si.position + 1;
            }

            int glyph_pos = -1;
            QFixed edge;
            // has to be inside run
            if (cpos == QTextLine::CursorOnCharacter) {
                if (si.analysis.bidiLevel % 2) {
                    pos += item_width;
                    glyph_pos = gs;
                    while (gs <= ge) {
                        if (glyphs.attributes[gs].clusterStart) {
                            if (pos < x)
                                break;
                            glyph_pos = gs;
                            edge = pos;
                        }
                        pos -= glyphs.effectiveAdvance(gs);
                        ++gs;
                    }
                } else {
                    glyph_pos = gs;
                    while (gs <= ge) {
                        if (glyphs.attributes[gs].clusterStart) {
                            if (pos > x)
                                break;
                            glyph_pos = gs;
                            edge = pos;
                        }
                        pos += glyphs.effectiveAdvance(gs);
                        ++gs;
                    }
                }
            } else {
                QFixed dist = INT_MAX/256;
                if (si.analysis.bidiLevel % 2) {
                    if (!visual || rtl || (lastLine && i == nItems - 1)) {
                        pos += item_width;
                        while (gs <= ge) {
                            if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
                                glyph_pos = gs;
                                edge = pos;
                                dist = qAbs(x-pos);
                            }
                            pos -= glyphs.effectiveAdvance(gs);
                            ++gs;
                        }
                    } else {
                        while (ge >= gs) {
                            if (glyphs.attributes[ge].clusterStart && qAbs(x-pos) < dist) {
                                glyph_pos = ge;
                                edge = pos;
                                dist = qAbs(x-pos);
                            }
                            pos += glyphs.effectiveAdvance(ge);
                            --ge;
                        }
                    }
                } else {
                    if (!visual || !rtl || (lastLine && i == 0)) {
                        while (gs <= ge) {
                            if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
                                glyph_pos = gs;
                                edge = pos;
                                dist = qAbs(x-pos);
                            }
                            pos += glyphs.effectiveAdvance(gs);
                            ++gs;
                        }
                    } else {
                        QFixed oldPos = pos;
                        while (gs <= ge) {
                            pos += glyphs.effectiveAdvance(gs);
                            if (glyphs.attributes[gs].clusterStart && qAbs(x-pos) < dist) {
                                glyph_pos = gs;
                                edge = pos;
                                dist = qAbs(x-pos);
                            }
                            ++gs;
                        }
                        pos = oldPos;
                    }
                }
                if (qAbs(x-pos) < dist) {
                    if (visual) {
                        if (!rtl && i < nItems - 1) {
                            nchars += end;
                            continue;
                        }
                        if (rtl && nchars > 0)
                            return insertionPoints[size_t(lastLine ? nchars : nchars - 1)];
                    }
                    return eng->positionInLigature(&si, end, x, pos, -1,
                                                   cpos == QTextLine::CursorOnCharacter);
                }
            }
            Q_ASSERT(glyph_pos != -1);
            return eng->positionInLigature(&si, end, x, edge, glyph_pos,
                                           cpos == QTextLine::CursorOnCharacter);
        }
    }
    // right of last item
//     qDebug("right of last");
    int item = visualOrder[nItems-1]+firstItem;
    QScriptItem &si = eng->layoutData->items[item];
    if (!si.num_glyphs)
        eng->shape(item);
    int pos = si.position;
    if (!(si.analysis.bidiLevel % 2))
        pos += eng->length(item);
    pos = qMax(line.from, pos);

    int maxPos = line.from + line_length;

    // except for the last line we assume that the
    // character between lines is a space and we want
    // to position the cursor to the left of that
    // character.
    if (this->index < eng->lines.count() - 1)
        maxPos = eng->previousLogicalPosition(maxPos);

    pos = qMin(pos, maxPos);
    return pos;
}

QT_END_NAMESPACE
