/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qtextlayout.h"
#include "qtextengine_p.h"

#include <qfont.h>
#include <qapplication.h>
#include <qpainter.h>
#include <qvarlengtharray.h>
#include <qtextformat.h>
#include <qabstracttextdocumentlayout.h>
#include "qtextdocument_p.h"
#include "qtextformat_p.h"
#include "qstyleoption.h"
#include "qpainterpath.h"
#include <limits.h>

#include <qdebug.h>

#include "qfontengine_p.h"

QT_BEGIN_NAMESPACE

#define ObjectSelectionBrush (QTextFormat::ForegroundBrush + 1)
#define SuppressText 0x5012
#define SuppressBackground 0x513

static QFixed alignLine(QTextEngine *eng, const QScriptLine &line)
{
    QFixed x = 0;
    eng->justify(line);
    // if width is QFIXED_MAX that means we used setNumColumns() and that implicitly makes this line left aligned.
    if (!line.justified && line.width != QFIXED_MAX) {
        int align = eng->option.alignment();
        if (align & Qt::AlignJustify && eng->isRightToLeft())
            align = Qt::AlignRight;
        if (align & Qt::AlignRight)
            x = line.width - (line.textAdvance + eng->leadingSpaceWidth(line));
        else if (align & Qt::AlignHCenter)
            x = (line.width - (line.textAdvance))/2 - eng->leadingSpaceWidth(line);
    }
    return x;
}

/*!
    \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.

    \sa QTextLayout::setAdditionalFormats(), 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.
*/

/*!
    \class QTextInlineObject
    \reentrant

    \brief The QTextInlineObject class represents an inline object in
    a QTextLayout.

    \ingroup richtext-processing

    This class is only used if the text layout is used to lay out
    parts of a QTextDocument.

    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
    isRightToLeft(). Its position in the text layout is given by at(),
    and its format is given by format().
*/

/*!
    \fn QTextInlineObject::QTextInlineObject(int i, QTextEngine *e)

    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 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[itm].width.toReal();
}

/*!
    Returns the inline object's ascent.

    \sa descent() width() rect()
*/
qreal QTextInlineObject::ascent() const
{
    return eng->layoutData->items[itm].ascent.toReal();
}

/*!
    Returns the inline object's descent.

    \sa ascent() width() rect()
*/
qreal QTextInlineObject::descent() const
{
    return eng->layoutData->items[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[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 decent 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
{
    if (!eng->block.docHandle())
        return QTextFormat();
    return eng->formats()->format(eng->formatIndex(&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.

    \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 doc/src/snippets/code/src_gui_text_qtextlayout.cpp 0

    The text can then be rendered by calling the layout's draw() function:
    \snippet doc/src/snippets/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;
}

/*!
    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.
*/
QTextLayout::QTextLayout(const QString& text, const QFont &font, QPaintDevice *paintdevice)
{
    QFont f(font);
    if (paintdevice)
        f = QFont(font, paintdevice);
    d = new QTextEngine((text.isNull() ? (const QString&)QString::fromLatin1("") : text), f.d.data());
}

/*!
    \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;
}

/*!
    Sets the layout's font to the given \a font. The layout is
    invalidated and must be laid out again.

    \sa text()
*/
void QTextLayout::setFont(const QFont &font)
{
    d->fnt = font;
    d->feCache.reset();
}

/*!
    Returns the current font that is used for the layout, or a default
    font if none is set.
*/
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() QTextOption
*/
void QTextLayout::setTextOption(const QTextOption &option)
{
    d->option = option;
}

/*!
  Returns the current text option used to control the layout process.

  \sa setTextOption() QTextOption
*/
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.
*/
void QTextLayout::setPreeditArea(int position, const QString &text)
{
    if (text.isEmpty()) {
        if (!d->specialData)
            return;
        if (d->specialData->addFormats.isEmpty()) {
            delete d->specialData;
            d->specialData = 0;
        } else {
            d->specialData->preeditText = QString();
            d->specialData->preeditPosition = -1;
        }
    } else {
        if (!d->specialData)
            d->specialData = new QTextEngine::SpecialData;
        d->specialData->preeditPosition = position;
        d->specialData->preeditText = text;
    }
    d->invalidate();
    d->clearLineData();
    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.
*/
int QTextLayout::preeditAreaPosition() const
{
    return d->specialData ? d->specialData->preeditPosition : -1;
}

/*!
    Returns the text that is inserted in the layout before editing occurs.
*/
QString QTextLayout::preeditAreaText() const
{
    return d->specialData ? d->specialData->preeditText : QString();
}


/*!
    Sets the additional formats supported by the text layout to \a
    formatList.

    \sa additionalFormats(), clearAdditionalFormats()
*/
void QTextLayout::setAdditionalFormats(const QList<FormatRange> &formatList)
{
    if (formatList.isEmpty()) {
        if (!d->specialData)
            return;
        if (d->specialData->preeditText.isEmpty()) {
            delete d->specialData;
            d->specialData = 0;
        } else {
            d->specialData->addFormats = formatList;
            d->specialData->addFormatIndices.clear();
        }
    } else {
        if (!d->specialData) {
            d->specialData = new QTextEngine::SpecialData;
            d->specialData->preeditPosition = -1;
        }
        d->specialData->addFormats = formatList;
        d->indexAdditionalFormats();
    }
    if (d->block.docHandle())
        d->block.docHandle()->documentChange(d->block.position(), d->block.length());
    d->feCache.reset();
}

/*!
    Returns the list of additional formats supported by the text layout.

    \sa setAdditionalFormats(), clearAdditionalFormats()
*/
QList<QTextLayout::FormatRange> QTextLayout::additionalFormats() const
{
    QList<FormatRange> formats;
    if (!d->specialData)
        return formats;

    formats = d->specialData->addFormats;

    if (d->specialData->addFormatIndices.isEmpty())
        return formats;

    const QTextFormatCollection *collection = d->formats();

    for (int i = 0; i < d->specialData->addFormatIndices.count(); ++i)
        formats[i].format = collection->charFormat(d->specialData->addFormatIndices.at(i));

    return formats;
}

/*!
    Clears the list of additional formats supported by the text layout.

    \sa additionalFormats(), setAdditionalFormats()
*/
void QTextLayout::clearAdditionalFormats()
{
    setAdditionalFormats(QList<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 true if the complete layout information is cached; otherwise
    returns false.

    \sa setCacheEnabled()
*/
bool QTextLayout::cacheEnabled() const
{
    return d->cacheGlyphs;
}

/*!
    Begins the layout process.
*/
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.
*/
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.
 */
void QTextLayout::clearLayout()
{
    d->clearLineData();
}


/*!
    Returns the next valid cursor position after \a oldPos that
    respects the given cursor \a mode.

    \sa isValidCursorPosition() previousCursorPosition()
*/
int QTextLayout::nextCursorPosition(int oldPos, CursorMode mode) const
{
//      qDebug("looking for next cursor pos for %d", oldPos);
    const HB_CharAttributes *attributes = d->attributes();
    if (!attributes)
        return 0;
    int len = d->block.isValid() ?
              (d->block.length() - 1)
              : d->layoutData->string.length();

    if (oldPos >= len)
        return oldPos;
    if (mode == SkipCharacters) {
        oldPos++;
        while (oldPos < len && !attributes[oldPos].charStop)
            oldPos++;
    } else {
        if (oldPos < len && d->atWordSeparator(oldPos)) {
            oldPos++;
            while (oldPos < len && d->atWordSeparator(oldPos))
                oldPos++;
        } else {
            while (oldPos < len && !d->atSpace(oldPos) && !d->atWordSeparator(oldPos))
                oldPos++;
        }
        while (oldPos < len && d->atSpace(oldPos))
            oldPos++;
    }
//      qDebug("  -> %d", oldPos);
    return oldPos;
}

/*!
    Returns the first valid cursor position before \a oldPos that
    respects the given cursor \a mode.

    \sa isValidCursorPosition() nextCursorPosition()
*/
int QTextLayout::previousCursorPosition(int oldPos, CursorMode mode) const
{
//     qDebug("looking for previous cursor pos for %d", oldPos);
    const HB_CharAttributes *attributes = d->attributes();
    if (!attributes || oldPos <= 0)
        return 0;
    if (mode == SkipCharacters) {
        oldPos--;
        while (oldPos && !attributes[oldPos].charStop)
            oldPos--;
    } else {
        while (oldPos && d->atSpace(oldPos-1))
            oldPos--;

        if (oldPos && d->atWordSeparator(oldPos-1)) {
            oldPos--;
            while (oldPos && d->atWordSeparator(oldPos-1))
                oldPos--;
        } else {
            while (oldPos && !d->atSpace(oldPos-1) && !d->atWordSeparator(oldPos-1))
                oldPos--;
        }
    }
//     qDebug("  -> %d", oldPos);
    return oldPos;
}

/*!
    Returns 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 `\Auml' 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 HB_CharAttributes *attributes = d->attributes();
    if (!attributes || pos < 0 || pos > (int)d->layoutData->string.length())
        return false;
    return attributes[pos].charStop;
}


/*!
    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 : 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 QTextLine(i, d);
}

/*!
    Returns the line that contains the cursor position specified by \a pos.

    \sa isValidCursorPosition() lineAt()
*/
QTextLine QTextLayout::lineForTextPosition(int pos) const
{
    for (int i = 0; i < d->lines.size(); ++i) {
        const QScriptLine& line = d->lines[i];
        if (line.from + (int)line.length > pos)
            return QTextLine(i, d);
    }
    if (!d->layoutData)
        d->itemize();
    if (pos == d->layoutData->string.length() && d->lines.size())
        return QTextLine(d->lines.size()-1, d);
    return 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[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());
    }
    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);
    }
}

struct QTextLineItemIterator
{
    QTextLineItemIterator(QTextEngine *eng, int lineNum, const QPointF &pos = QPointF(),
                          const QTextLayout::FormatRange *_selection = 0);

    inline bool atEnd() const { return logicalItem >= nItems - 1; }
    QScriptItem &next();

    bool getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const;
    inline bool isOutsideSelection() const {
        QFixed tmp1, tmp2;
        return !getSelectionBounds(&tmp1, &tmp2);
    }

    QTextEngine *eng;

    QFixed x;
    QFixed pos_x;
    const QScriptLine &line;
    QScriptItem *si;

    int lineEnd;
    int firstItem;
    int lastItem;
    int nItems;
    int logicalItem;
    int item;
    int itemLength;

    int glyphsStart;
    int glyphsEnd;
    int itemStart;
    int itemEnd;

    QFixed itemWidth;

    QVarLengthArray<int> visualOrder;
    QVarLengthArray<uchar> levels;

    const QTextLayout::FormatRange *selection;
};

QTextLineItemIterator::QTextLineItemIterator(QTextEngine *_eng, int lineNum, const QPointF &pos,
                                             const QTextLayout::FormatRange *_selection)
    : eng(_eng),
      line(eng->lines[lineNum]),
      si(0),
      lineEnd(line.from + line.length),
      firstItem(eng->findItem(line.from)),
      lastItem(eng->findItem(lineEnd - 1)),
      nItems((firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0),
      logicalItem(-1),
      item(-1),
      visualOrder(nItems),
      levels(nItems),
      selection(_selection)
{
    pos_x = x = QFixed::fromReal(pos.x());

    x += line.x;

    x += alignLine(eng, line);

    for (int i = 0; i < nItems; ++i)
        levels[i] = eng->layoutData->items[i+firstItem].analysis.bidiLevel;
    QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());

    eng->shapeLine(line);
}

QScriptItem &QTextLineItemIterator::next()
{
    x += itemWidth;

    ++logicalItem;
    item = visualOrder[logicalItem] + firstItem;
    itemLength = eng->length(item);
    si = &eng->layoutData->items[item];
    if (!si->num_glyphs)
        eng->shape(item);

    if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
        itemWidth = si->width;
        return *si;
    }

    unsigned short *logClusters = eng->logClusters(si);
    QGlyphLayout glyphs = eng->shapedGlyphs(si);

    itemStart = qMax(line.from, si->position);
    glyphsStart = logClusters[itemStart - si->position];
    if (lineEnd < si->position + itemLength) {
        itemEnd = lineEnd;
        glyphsEnd = logClusters[itemEnd-si->position];
    } else {
        itemEnd = si->position + itemLength;
        glyphsEnd = si->num_glyphs;
    }
    // show soft-hyphen at line-break
    if (si->position + itemLength >= lineEnd
        && eng->layoutData->string.at(lineEnd - 1) == 0x00ad)
        glyphs.attributes[glyphsEnd - 1].dontPrint = false;

    itemWidth = 0;
    for (int g = glyphsStart; g < glyphsEnd; ++g)
        itemWidth += glyphs.effectiveAdvance(g);

    return *si;
}

static QFixed offsetInLigature(const unsigned short *logClusters,
                               const QGlyphLayout &glyphs,
                               int pos, int max, int glyph_pos)
{
    int offsetInCluster = 0;
    for (int i = pos - 1; i >= 0; i--) {
        if (logClusters[i] == glyph_pos)
            offsetInCluster++;
        else
            break;
    }

    // in the case that the offset is inside a (multi-character) glyph,
    // interpolate the position.
    if (offsetInCluster > 0) {
        int clusterLength = 0;
        for (int i = pos - offsetInCluster; i < max; i++) {
            if (logClusters[i] == glyph_pos)
                clusterLength++;
            else
                break;
        }
        if (clusterLength)
            return glyphs.advances_x[glyph_pos] * offsetInCluster / clusterLength;
    }

    return 0;
}

bool QTextLineItemIterator::getSelectionBounds(QFixed *selectionX, QFixed *selectionWidth) const
{
    *selectionX = *selectionWidth = 0;

    if (!selection)
        return false;

    if (si->analysis.flags >= QScriptAnalysis::TabOrObject) {
        if (si->position >= selection->start + selection->length
            || si->position + itemLength <= selection->start)
            return false;

        *selectionX = x;
        *selectionWidth = itemWidth;
    } else {
        unsigned short *logClusters = eng->logClusters(si);
        QGlyphLayout glyphs = eng->shapedGlyphs(si);

        int from = qMax(itemStart, selection->start) - si->position;
        int to = qMin(itemEnd, selection->start + selection->length) - si->position;
        if (from >= to)
            return false;

        int start_glyph = logClusters[from];
        int end_glyph = (to == eng->length(item)) ? si->num_glyphs : logClusters[to];
        QFixed soff;
        QFixed swidth;
        if (si->analysis.bidiLevel %2) {
            for (int g = glyphsEnd - 1; g >= end_glyph; --g)
                soff += glyphs.effectiveAdvance(g);
            for (int g = end_glyph - 1; g >= start_glyph; --g)
                swidth += glyphs.effectiveAdvance(g);
        } else {
            for (int g = glyphsStart; g < start_glyph; ++g)
                soff += glyphs.effectiveAdvance(g);
            for (int g = start_glyph; g < end_glyph; ++g)
                swidth += glyphs.effectiveAdvance(g);
        }

        // If the starting character is in the middle of a ligature,
        // selection should only contain the right part of that ligature
        // glyph, so we need to get the width of the left part here and
        // add it to *selectionX
        QFixed leftOffsetInLigature = offsetInLigature(logClusters, glyphs, from,
                                                       to, start_glyph);
        *selectionX = x + soff + leftOffsetInLigature;
        *selectionWidth = swidth - leftOffsetInLigature;
        // If the ending character is also part of a ligature, swidth does
        // not contain that part yet, we also need to find out the width of
        // that left part
        *selectionWidth += offsetInLigature(logClusters, glyphs, to,
                                            eng->length(item), end_glyph);
    }
    return true;
}

static void addSelectedRegionsToPath(QTextEngine *eng, int lineNumber, const QPointF &pos, QTextLayout::FormatRange *selection,
                                     QPainterPath *region, 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)
                region->addRect(boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight));

            lastSelectionX = selectionX;
            lastSelectionWidth = selectionWidth;
        }
    }
    if (lastSelectionWidth > 0)
        region->addRect(boundingRect & QRectF(lastSelectionX.toReal(), selectionY, lastSelectionWidth.toReal(), lineHeight));
}

static inline QRectF clipIfValid(const QRectF &rect, const QRectF &clip)
{
    return clip.isValid() ? (rect & clip) : rect;
}

/*!
    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[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);
        const QBrush bg = selection.format.background();

        QPainterPath region;
        region.setFillRule(Qt::WindingFill);

        for (int line = firstLine; line < lastLine; ++line) {
            const QScriptLine &sl = d->lines[line];
            QTextLine tl(line, d);

            QRectF lineRect(tl.naturalTextRect());
            lineRect.translate(position);

            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;
    QFixed pos_x = QFixed::fromReal(position.x());
    QFixed pos_y = QFixed::fromReal(position.y());

    cursorPosition = qBound(0, cursorPosition, d->layoutData->string.length());
    int line = 0;
    if (cursorPosition == d->layoutData->string.length()) {
        line = d->lines.size() - 1;
    } else {
        // ### binary search
        for (line = 0; line < d->lines.size(); line++) {
            const QScriptLine &sl = d->lines[line];
            if (sl.from <= cursorPosition && sl.from + (int)sl.length > cursorPosition)
                break;
        }
    }

    if (line >= d->lines.size())
        return;

    QTextLine l(line, d);
    const QScriptLine &sl = d->lines[line];

    qreal x = position.x() + l.cursorToX(cursorPosition);

    int 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);
#if defined(QT_MAC_USE_COCOA)
    // Always draw the cursor aligned to pixel boundary.
    x = qRound(x);
#endif
    p->fillRect(QRectF(x, y, qreal(width), (base + descent + 1).toReal()), p->pen().brush());
    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.

    \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 decent()
    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 true if this text line is valid; otherwise returns 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[i];
    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[i];
    QFixed x = sl.x + alignLine(eng, 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[i].x.toReal();
}

/*!
    Returns the line's y position.

    \sa x() rect() textLength() width()
*/
qreal QTextLine::y() const
{
    return eng->lines[i].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[i].width.toReal();
}


/*!
    Returns the line's ascent.

    \sa descent() height()
*/
qreal QTextLine::ascent() const
{
    return eng->lines[i].ascent.toReal();
}

/*!
    Returns the line's descent.

    \sa ascent() height()
*/
qreal QTextLine::descent() const
{
    return eng->lines[i].descent.toReal();
}

/*!
    Returns the line's height. This is equal to ascent() + descent() + 1
    if leading is not included. If leading is included, this equals to
    ascent() + descent() + leading() + 1.

    \sa ascent() descent() leading() setLeadingIncluded()
*/
qreal QTextLine::height() const
{
    return eng->lines[i].height().toReal();
}

/*!
    \since 4.6

    Returns the line's leading.

    \sa ascent() descent() height()
*/
qreal QTextLine::leading() const
{
    return eng->lines[i].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[i].leadingIncluded= included;

}

/*! \since 4.6

  Returns true if positive leading is included into the line's height; otherwise returns false.

  By default, leading is not included.

  \sa setLeadingIncluded()
*/
bool QTextLine::leadingIncluded() const
{
    return eng->lines[i].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[i].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[i].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[i];
    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[i];
    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[i];
    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;

        QFixed minw;
        QFixed softHyphenWidth;
        QFixed rightBearing;
        QFixed minimumRightBearing;

        QFontEngine *fontEngine;
        QFontEngine *previousFontEngine;
        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
                    - qMin(rightBearing, QFixed());
        }

        inline glyph_t currentGlyph() const
        {            
            Q_ASSERT(currentPosition > 0);
            Q_ASSERT(logClusters[currentPosition - 1] < glyphs.numGlyphs);

            return glyphs.glyphs[logClusters[currentPosition - 1]];
        }

        inline void resetPreviousGlyph()
        {
            previousGlyph = 0;
            previousFontEngine = 0;
        }

        inline void saveCurrentGlyph()
        {
            resetPreviousGlyph();
            if (currentPosition > 0 &&
                logClusters[currentPosition - 1] < glyphs.numGlyphs) {
                previousGlyph = currentGlyph(); // needed to calculate right bearing later
                previousFontEngine = fontEngine;
            }
        }

        inline void adjustRightBearing(glyph_t glyph)
        {
            qreal rb;
            fontEngine->getGlyphBearings(glyph, 0, &rb);
            rightBearing = qMin(QFixed(), QFixed::fromReal(rb));
        }

        inline void adjustRightBearing()
        {
            if (currentPosition <= 0)
                return;
            adjustRightBearing(currentGlyph());
        }

        inline void adjustPreviousRightBearing()
        {
            if (previousGlyph > 0 && previousFontEngine) {
                qreal rb;
                previousFontEngine->getGlyphBearings(previousGlyph, 0, &rb);
                rightBearing = qMin(QFixed(), QFixed::fromReal(rb));
            }
        }

        inline void resetRightBearing()
        {
            rightBearing = QFixed(1); // Any positive number is defined as invalid since only
                                      // negative right bearings are interesting to us.
        }
    };

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.
        line.textWidth += glyphs.advances_x[glyphPosition] * !glyphs.attributes[glyphPosition].dontPrint;
        ++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[i];
    line.length = 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);

    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 HB_CharAttributes *attributes = eng->attributes();
    if (!attributes)
        return;
    lbh.currentPosition = line.from;
    int end = 0;
    lbh.logClusters = eng->layoutData->logClustersPtr;
    lbh.resetPreviousGlyph();

    while (newItem < eng->layoutData->items.size()) {
        lbh.resetRightBearing();
        lbh.softHyphenWidth = 0;
        if (newItem != item) {
            item = newItem;
            const QScriptItem &current = eng->layoutData->items[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[item];

        lbh.tmpData.leading = qMax(lbh.tmpData.leading + lbh.tmpData.ascent,
                                   current.leading + current.ascent) - qMax(lbh.tmpData.ascent,
                                                                            current.ascent);
        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);

            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) {
                addNextCluster(lbh.currentPosition, end, lbh.tmpData, lbh.glyphCount,
                               current, lbh.logClusters, lbh.glyphs);
            } else {
                lbh.tmpData.length++;
                lbh.adjustPreviousRightBearing();
            }
            line += lbh.tmpData;
            goto found;
        } else if (current.analysis.flags == QScriptAnalysis::Object) {
            lbh.whiteSpaceOrObject = true;
            lbh.tmpData.length++;

            QTextFormat format = eng->formats()->format(eng->formatIndex(&eng->layoutData->items[item]));
            if (eng->block.docHandle())
                eng->docLayout()->positionInlineObject(QTextInlineObject(item, eng), eng->block.position() + current.position, format);

            lbh.tmpData.textWidth += current.width;

            newItem = item + 1;
            ++lbh.glyphCount;
            if (lbh.checkFullOtherwiseExtend(line))
                goto found;
        } else if (attributes[lbh.currentPosition].whiteSpace) {
            lbh.whiteSpaceOrObject = true;
            while (lbh.currentPosition < end && attributes[lbh.currentPosition].whiteSpace)
                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);

                if (attributes[lbh.currentPosition].whiteSpace || attributes[lbh.currentPosition-1].lineBreakType != HB_NoBreak) {
                    sb_or_ws = true;
                    break;
                } else if (breakany && attributes[lbh.currentPosition].charStop) {
                    break;
                }
            } while (lbh.currentPosition < end);
            lbh.minw = qMax(lbh.tmpData.textWidth, lbh.minw);

            if (lbh.currentPosition && attributes[lbh.currentPosition - 1].lineBreakType == HB_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_x[lbh.logClusters[lbh.currentPosition - 1]];
                else if (breakany)
                    lbh.tmpData.textWidth += lbh.glyphs.advances_x[lbh.logClusters[lbh.currentPosition - 1]];
            }

            // The actual width of the text needs to take the right bearing into account. The
            // right bearing is left-ward, which means that if the rightmost pixel is to the right
            // of the advance of the glyph, the bearing will be negative. We flip the sign
            // for the code to be more readable. Logic borrowed from qfontmetrics.cpp.
            // We ignore the right bearing if the minimum negative bearing is too little to
            // expand the text beyond the edge.
            if (sb_or_ws|breakany) {
                QFixed rightBearing = lbh.rightBearing; // store previous right bearing
#if !defined(Q_WS_MAC)
                if (lbh.calculateNewWidth(line) - lbh.minimumRightBearing > line.width)
#endif
                    lbh.adjustRightBearing();
                if (lbh.checkFullOtherwiseExtend(line)) {
                    // we are too wide, fix right bearing
                    if (rightBearing <= 0)
                        lbh.rightBearing = rightBearing; // take from cache
                    else
                        lbh.adjustPreviousRightBearing();

                    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:
    if (lbh.rightBearing > 0 && !lbh.whiteSpaceOrObject) // If right bearing has not yet been adjusted
        lbh.adjustRightBearing();
    line.textAdvance = line.textWidth;
    line.textWidth -= qMin(QFixed(), lbh.rightBearing);

    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;
    }

    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;
    line.length += lbh.spaceData.length;
    if (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[i].x = QFixed::fromReal(pos.x());
    eng->lines[i].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[i].x.toReal(), eng->lines[i].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[i].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() && i == eng->lines.count()-1) {
        return eng->lines[i].length - 1;
    }
    return eng->lines[i].length;
}

static void drawMenuText(QPainter *p, QFixed x, QFixed y, const QScriptItem &si, QTextItemInt &gf, QTextEngine *eng,
                         int start, int glyph_start)
{
    int ge = glyph_start + gf.glyphs.numGlyphs;
    int gs = glyph_start;
    int end = start + gf.num_chars;
    unsigned short *logClusters = eng->logClusters(&si);
    QGlyphLayout glyphs = eng->shapedGlyphs(&si);
    QFixed orig_width = gf.width;

    int *ul = eng->underlinePositions;
    if (ul)
        while (*ul != -1 && *ul < start)
            ++ul;
    bool rtl = si.analysis.bidiLevel % 2;
    if (rtl)
        x += si.width;

    do {
        int gtmp = ge;
        int stmp = end;
        if (ul && *ul != -1 && *ul < end) {
            stmp = *ul;
            gtmp = logClusters[*ul-si.position];
        }

        gf.glyphs = glyphs.mid(gs, gtmp - gs);
        gf.num_chars = stmp - start;
        gf.chars = eng->layoutData->string.unicode() + start;
        QFixed w = 0;
        while (gs < gtmp) {
            w += glyphs.effectiveAdvance(gs);
            ++gs;
        }
        start = stmp;
        gf.width = w;
        if (rtl)
            x -= w;
        if (gf.num_chars)
            p->drawTextItem(QPointF(x.toReal(), y.toReal()), gf);
        if (!rtl)
            x += w;
        if (ul && *ul != -1 && *ul < end) {
            // draw underline
            gtmp = (*ul == end-1) ? ge : logClusters[*ul+1-si.position];
            ++stmp;
            gf.glyphs = glyphs.mid(gs, gtmp - gs);
            gf.num_chars = stmp - start;
            gf.chars = eng->layoutData->string.unicode() + start;
            gf.logClusters = logClusters + start - si.position;
            w = 0;
            while (gs < gtmp) {
                w += glyphs.effectiveAdvance(gs);
                ++gs;
            }
            ++start;
            gf.width = w;
            gf.underlineStyle = QTextCharFormat::SingleUnderline;
            if (rtl)
                x -= w;
            p->drawTextItem(QPointF(x.toReal(), y.toReal()), gf);
            if (!rtl)
                x += w;
            gf.underlineStyle = QTextCharFormat::NoUnderline;
            ++gf.chars;
            ++ul;
        }
    } while (gs < ge);

    gf.width = orig_width;
}


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, bg);
    if (c.style() != Qt::NoBrush) {
        p->setPen(QPen(c, 0));
    }

}

/*!
    \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
{
    const QScriptLine &line = eng->lines[i];
    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()).width(QLatin1Char(' ')));
            setPenAndDrawBackground(p, QPen(), selection->format, r);
            p->setPen(pen);
        }
        return;
    }


    QTextLineItemIterator iterator(eng, i, pos, selection);
    QFixed lineBase = line.base();

    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) {
            if (!suppressColors)
                format = eng->format(&si);
            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;
                    }

                    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;
                    p->drawTextItem(QPointF(iterator.x.toReal(), y.toReal()), gf);
                    if (eng->option.flags() & QTextOption::ShowTabsAndSpaces) {
                        QChar visualTab(0x2192);
                        int w = QFontMetrics(f).width(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->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);

        if (eng->underlinePositions) {
            // can't have selections in this case
            drawMenuText(p, iterator.x, itemBaseLine, si, gf, eng, iterator.itemStart, iterator.glyphsStart);
        } else {
            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
                p->drawTextItem(pos, gf);
            }
        }
        if (si.analysis.flags == QScriptAnalysis::Space
            && (eng->option.flags() & QTextOption::ShowTabsAndSpaces)) {
            QBrush c = format.foreground();
            if (c.style() != Qt::NoBrush)
                p->setPen(c.color());
            QChar visualSpace((ushort)0xb7);
            p->drawText(QPointF(iterator.x.toReal(), itemBaseLine.toReal()), visualSpace);
            p->setPen(pen);
        }
    }


    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 cpos will be modified to
  point to this valid cursor position.

  \sa xToCursor()
*/
qreal QTextLine::cursorToX(int *cursorPos, Edge edge) const
{
    if (!eng->layoutData)
        eng->itemize();

    const QScriptLine &line = eng->lines[i];

    QFixed x = line.x;
    x += alignLine(eng, line);

    if (!i && !eng->layoutData->items.size()) {
        *cursorPos = 0;
        return x.toReal();
    }

    int pos = *cursorPos;
    int itm;
    if (pos == line.from + (int)line.length) {
        // end of line ensure we have the last item on the line
        itm = eng->findItem(pos-1);
    }
    else
        itm = eng->findItem(pos);
    eng->shapeLine(line);

    const QScriptItem *si = &eng->layoutData->items[itm];
    if (!si->num_glyphs)
        eng->shape(itm);
    pos -= si->position;

    QGlyphLayout glyphs = eng->shapedGlyphs(si);
    unsigned short *logClusters = eng->logClusters(si);
    Q_ASSERT(logClusters);

    int l = eng->length(itm);
    if (pos > l)
        pos = l;
    if (pos < 0)
        pos = 0;

    int glyph_pos = pos == l ? si->num_glyphs : logClusters[pos];
    if (edge == Trailing) {
        // trailing edge is leading edge of next cluster
        while (glyph_pos < si->num_glyphs && !glyphs.attributes[glyph_pos].clusterStart)
            glyph_pos++;
    }

    bool reverse = eng->layoutData->items[itm].analysis.bidiLevel % 2;

    int lineEnd = line.from + line.length;

    // add the items left of the cursor

    int firstItem = eng->findItem(line.from);
    int lastItem = eng->findItem(lineEnd - 1);
    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;
        }
        int start = qMax(line.from, si.position);
        int end = qMin(lineEnd, si.position + eng->length(item));

        logClusters = eng->logClusters(&si);

        int gs = logClusters[start-si.position];
        int ge = (end == si.position + eng->length(item)) ? 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 == l)
            x += si->width;
    } else {
        int end = qMin(lineEnd, si->position + l) - si->position;
        if (reverse) {
            int glyph_end = end == l ? si->num_glyphs : logClusters[end];
            for (int i = glyph_end - 1; i >= glyph_pos; i--)
                x += glyphs.effectiveAdvance(i);
        } else {
            int start = qMax(line.from - si->position, 0);
            int glyph_start = logClusters[start];
            for (int i = glyph_start; i < glyph_pos; i++)
                x += glyphs.effectiveAdvance(i);
        }
        x += offsetInLigature(logClusters, glyphs, pos, end, glyph_pos);
    }

    *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.

  \sa cursorToX()
*/
int QTextLine::xToCursor(qreal _x, CursorPosition cpos) const
{
    QFixed x = QFixed::fromReal(_x);
    const QScriptLine &line = eng->lines[i];

    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);
    int nItems = (firstItem >= 0 && lastItem >= firstItem)? (lastItem-firstItem+1) : 0;

    if (!nItems)
        return 0;

    x -= line.x;
    x -= alignLine(eng, 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());

    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;

        eng->shapeLine(line);
        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;
                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;
                            break;
                        }
                        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) {
                    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 (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;
                    }
                }
                if (qAbs(x-pos) < dist)
                    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.
    // ###### breaks with japanese for example
    if (this->i < eng->lines.count() - 1)
        --maxPos;

    pos = qMin(pos, maxPos);
    return pos;
}

QT_END_NAMESPACE
