/****************************************************************************
**
** 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 "qpathsimplifier_p.h"

#include <QtCore/qvarlengtharray.h>
#include <QtCore/qglobal.h>
#include <QtCore/qpoint.h>
#include <QtCore/qalgorithms.h>

#include <private/qopengl_p.h>
#include <private/qrbtree_p.h>

QT_BEGIN_NAMESPACE

#define Q_FIXED_POINT_SCALE 256
#define Q_TRIANGULATE_END_OF_POLYGON quint32(-1)



//============================================================================//
//                                   QPoint                                   //
//============================================================================//

inline bool operator < (const QPoint &a, const QPoint &b)
{
    return a.y() < b.y() || (a.y() == b.y() && a.x() < b.x());
}

inline bool operator > (const QPoint &a, const QPoint &b)
{
    return b < a;
}

inline bool operator <= (const QPoint &a, const QPoint &b)
{
    return !(a > b);
}

inline bool operator >= (const QPoint &a, const QPoint &b)
{
    return !(a < b);
}

namespace {

inline int cross(const QPoint &u, const QPoint &v)
{
    return u.x() * v.y() - u.y() * v.x();
}

inline int dot(const QPoint &u, const QPoint &v)
{
    return u.x() * v.x() + u.y() * v.y();
}

//============================================================================//
//                                  Fraction                                  //
//============================================================================//

// Fraction must be in the range [0, 1)
struct Fraction
{
    bool isValid() const { return denominator != 0; }

    // numerator and denominator must not have common denominators.
    unsigned int numerator, denominator;
};

inline unsigned int gcd(unsigned int x, unsigned int y)
{
    while (y != 0) {
        unsigned int z = y;
        y = x % y;
        x = z;
    }
    return x;
}

// Fraction must be in the range [0, 1)
// Assume input is valid.
Fraction fraction(unsigned int n, unsigned int d) {
    Fraction result;
    if (n == 0) {
        result.numerator = 0;
        result.denominator = 1;
    } else {
        unsigned int g = gcd(n, d);
        result.numerator = n / g;
        result.denominator = d / g;
    }
    return result;
}

//============================================================================//
//                                  Rational                                  //
//============================================================================//

struct Rational
{
    int integer;
    Fraction fraction;
};

//============================================================================//
//                             IntersectionPoint                              //
//============================================================================//

struct IntersectionPoint
{
    bool isValid() const { return x.fraction.isValid() && y.fraction.isValid(); }
    QPoint round() const;
    bool isAccurate() const { return x.fraction.numerator == 0 && y.fraction.numerator == 0; }

    Rational x; // 8:8 signed, 32/32
    Rational y; // 8:8 signed, 32/32
};

QPoint IntersectionPoint::round() const
{
    QPoint result(x.integer, y.integer);
    if (2 * x.fraction.numerator >= x.fraction.denominator)
        ++result.rx();
    if (2 * y.fraction.numerator >= y.fraction.denominator)
        ++result.ry();
    return result;
}

// Return positive value if 'p' is to the right of the line 'v1'->'v2', negative if left of the
// line and zero if exactly on the line.
// The returned value is the z-component of the qCross product between 'v2-v1' and 'p-v1',
// which is twice the signed area of the triangle 'p'->'v1'->'v2' (positive for CW order).
inline int pointDistanceFromLine(const QPoint &p, const QPoint &v1, const QPoint &v2)
{
    return cross(v2 - v1, p - v1);
}

IntersectionPoint intersectionPoint(const QPoint &u1, const QPoint &u2,
                                    const QPoint &v1, const QPoint &v2)
{
    IntersectionPoint result = {{0, {0, 0}}, {0, {0, 0}}};

    QPoint u = u2 - u1;
    QPoint v = v2 - v1;
    int d1 = cross(u, v1 - u1);
    int d2 = cross(u, v2 - u1);
    int det = d2 - d1;
    int d3 = cross(v, u1 - v1);
    int d4 = d3 - det; //qCross(v, u2 - v1);

    // Check that the math is correct.
    Q_ASSERT(d4 == cross(v, u2 - v1));

    // The intersection point can be expressed as:
    // v1 - v * d1/det
    // v2 - v * d2/det
    // u1 + u * d3/det
    // u2 + u * d4/det

    // I'm only interested in lines that are crossing, so ignore parallel lines even if they overlap.
    if (det == 0)
        return result;

    if (det < 0) {
        det = -det;
        d1 = -d1;
        d2 = -d2;
        d3 = -d3;
        d4 = -d4;
    }

    // I'm only interested in lines intersecting at their interior, not at their end points.
    // The lines intersect at their interior if and only if 'd1 < 0', 'd2 > 0', 'd3 < 0' and 'd4 > 0'.
    if (d1 >= 0 || d2 <= 0 || d3 <= 0 || d4 >= 0)
        return result;

    // Calculate the intersection point as follows:
    // v1 - v * d1/det | v1 <= v2 (component-wise)
    // v2 - v * d2/det | v2 < v1 (component-wise)

    // Assuming 16 bits per vector component.
    if (v.x() >= 0) {
        result.x.integer = v1.x() + int(qint64(-v.x()) * d1 / det);
        result.x.fraction = fraction((unsigned int)(qint64(-v.x()) * d1 % det), (unsigned int)det);
    } else {
        result.x.integer = v2.x() + int(qint64(-v.x()) * d2 / det);
        result.x.fraction = fraction((unsigned int)(qint64(-v.x()) * d2 % det), (unsigned int)det);
    }

    if (v.y() >= 0) {
        result.y.integer = v1.y() + int(qint64(-v.y()) * d1 / det);
        result.y.fraction = fraction((unsigned int)(qint64(-v.y()) * d1 % det), (unsigned int)det);
    } else {
        result.y.integer = v2.y() + int(qint64(-v.y()) * d2 / det);
        result.y.fraction = fraction((unsigned int)(qint64(-v.y()) * d2 % det), (unsigned int)det);
    }

    Q_ASSERT(result.x.fraction.isValid());
    Q_ASSERT(result.y.fraction.isValid());
    return result;
}

//============================================================================//
//                               PathSimplifier                               //
//============================================================================//

class PathSimplifier
{
public:
    PathSimplifier(const QVectorPath &path, QDataBuffer<QPoint> &vertices,
                   QDataBuffer<quint32> &indices, const QTransform &matrix);

private:
    struct Element;

    class BoundingVolumeHierarchy
    {
    public:
        struct Node
        {
            enum Type
            {
                Leaf,
                Split
            };
            Type type;
            QPoint minimum;
            QPoint maximum;
            union {
                Element *element; // type == Leaf
                Node *left; // type == Split
            };
            Node *right;
        };

        BoundingVolumeHierarchy();
        ~BoundingVolumeHierarchy();
        void allocate(int nodeCount);
        void free();
        Node *newNode();

        Node *root;
    private:
        void freeNode(Node *n);

        Node *nodeBlock;
        int blockSize;
        int firstFree;
    };

    struct Element
    {
        enum Degree
        {
            Line = 1,
            Quadratic = 2,
            Cubic = 3
        };

        quint32 &upperIndex() { return indices[pointingUp ? degree : 0]; }
        quint32 &lowerIndex() { return indices[pointingUp ? 0 : degree]; }
        quint32 upperIndex() const { return indices[pointingUp ? degree : 0]; }
        quint32 lowerIndex() const { return indices[pointingUp ? 0 : degree]; }
        void flip();

        QPoint middle;
        quint32 indices[4]; // index to points
        Element *next, *previous; // used in connectElements()
        int winding; // used in connectElements()
        union {
            QRBTree<Element *>::Node *edgeNode; // used in connectElements()
            BoundingVolumeHierarchy::Node *bvhNode;
        };
        Degree degree : 8;
        uint processed : 1; // initially false, true when the element has been checked for intersections.
        uint pointingUp : 1; // used in connectElements()
        uint originallyPointingUp : 1; // used in connectElements()
    };

    class ElementAllocator
    {
    public:
        ElementAllocator();
        ~ElementAllocator();
        void allocate(int count);
        Element *newElement();
    private:
        struct ElementBlock
        {
            ElementBlock *next;
            int blockSize;
            int firstFree;
            Element elements[1];
        } *blocks;
    };

    struct Event
    {
        enum Type { Upper, Lower };
        bool operator < (const Event &other) const;

        QPoint point;
        Type type;
        Element *element;
    };

    typedef QRBTree<Element *>::Node RBNode;
    typedef BoundingVolumeHierarchy::Node BVHNode;

    void initElements(const QVectorPath &path, const QTransform &matrix);
    void removeIntersections();
    void connectElements();
    void fillIndices();
    BVHNode *buildTree(Element **elements, int elementCount);
    bool intersectNodes(QDataBuffer<Element *> &elements, BVHNode *elementNode, BVHNode *treeNode);
    bool equalElements(const Element *e1, const Element *e2);
    bool splitLineAt(QDataBuffer<Element *> &elements, BVHNode *node, quint32 pointIndex, bool processAgain);
    void appendSeparatingAxes(QVarLengthArray<QPoint, 12> &axes, Element *element);
    QPair<int, int> calculateSeparatingAxisRange(const QPoint &axis, Element *element);
    void splitCurve(QDataBuffer<Element *> &elements, BVHNode *node);
    bool setElementToQuadratic(Element *element, quint32 pointIndex1, const QPoint &ctrl, quint32 pointIndex2);
    bool setElementToCubic(Element *element, quint32 pointIndex1, const QPoint &ctrl1, const QPoint &ctrl2, quint32 pointIndex2);
    void setElementToCubicAndSimplify(Element *element, quint32 pointIndex1, const QPoint &ctrl1, const QPoint &ctrl2, quint32 pointIndex2);
    RBNode *findElementLeftOf(const Element *element, const QPair<RBNode *, RBNode *> &bounds);
    bool elementIsLeftOf(const Element *left, const Element *right);
    QPair<RBNode *, RBNode *> outerBounds(const QPoint &point);
    static bool flattenQuadratic(const QPoint &u, const QPoint &v, const QPoint &w);
    static bool flattenCubic(const QPoint &u, const QPoint &v, const QPoint &w, const QPoint &q);
    static bool splitQuadratic(const QPoint &u, const QPoint &v, const QPoint &w, QPoint *result);
    static bool splitCubic(const QPoint &u, const QPoint &v, const QPoint &w, const QPoint &q, QPoint *result);
    void subDivQuadratic(const QPoint &u, const QPoint &v, const QPoint &w);
    void subDivCubic(const QPoint &u, const QPoint &v, const QPoint &w, const QPoint &q);
    static void sortEvents(Event *events, int count);

    ElementAllocator m_elementAllocator;
    QDataBuffer<Element *> m_elements;
    QDataBuffer<QPoint> *m_points;
    BoundingVolumeHierarchy m_bvh;
    QDataBuffer<quint32> *m_indices;
    QRBTree<Element *> m_elementList;
    uint m_hints;
};

inline PathSimplifier::BoundingVolumeHierarchy::BoundingVolumeHierarchy()
    : root(nullptr)
    , nodeBlock(nullptr)
    , blockSize(0)
    , firstFree(0)
{
}

inline PathSimplifier::BoundingVolumeHierarchy::~BoundingVolumeHierarchy()
{
    free();
}

inline void PathSimplifier::BoundingVolumeHierarchy::allocate(int nodeCount)
{
    Q_ASSERT(nodeBlock == nullptr);
    Q_ASSERT(firstFree == 0);
    nodeBlock = new Node[blockSize = nodeCount];
}

inline void PathSimplifier::BoundingVolumeHierarchy::free()
{
    freeNode(root);
    delete[] nodeBlock;
    nodeBlock = nullptr;
    firstFree = blockSize = 0;
    root = nullptr;
}

inline PathSimplifier::BVHNode *PathSimplifier::BoundingVolumeHierarchy::newNode()
{
    if (firstFree < blockSize)
        return &nodeBlock[firstFree++];
    return new Node;
}

inline void PathSimplifier::BoundingVolumeHierarchy::freeNode(Node *n)
{
    if (!n)
        return;
    Q_ASSERT(n->type == Node::Split || n->type == Node::Leaf);
    if (n->type == Node::Split) {
        freeNode(n->left);
        freeNode(n->right);
    }
    if (!(n >= nodeBlock && n < nodeBlock + blockSize))
        delete n;
}

inline PathSimplifier::ElementAllocator::ElementAllocator()
    : blocks(nullptr)
{
}

inline PathSimplifier::ElementAllocator::~ElementAllocator()
{
    while (blocks) {
        ElementBlock *block = blocks;
        blocks = blocks->next;
        free(block);
    }
}

inline void PathSimplifier::ElementAllocator::allocate(int count)
{
    Q_ASSERT(blocks == nullptr);
    Q_ASSERT(count > 0);
    blocks = (ElementBlock *)malloc(sizeof(ElementBlock) + (count - 1) * sizeof(Element));
    blocks->blockSize = count;
    blocks->next = nullptr;
    blocks->firstFree = 0;
}

inline PathSimplifier::Element *PathSimplifier::ElementAllocator::newElement()
{
    Q_ASSERT(blocks);
    if (blocks->firstFree < blocks->blockSize)
        return &blocks->elements[blocks->firstFree++];
    ElementBlock *oldBlock = blocks;
    blocks = (ElementBlock *)malloc(sizeof(ElementBlock) + (oldBlock->blockSize - 1) * sizeof(Element));
    blocks->blockSize = oldBlock->blockSize;
    blocks->next = oldBlock;
    blocks->firstFree = 0;
    return &blocks->elements[blocks->firstFree++];
}


inline bool PathSimplifier::Event::operator < (const Event &other) const
{
    if (point == other.point)
        return type < other.type;
    return other.point < point;
}

inline void PathSimplifier::Element::flip()
{
    for (int i = 0; i < (degree + 1) >> 1; ++i) {
        Q_ASSERT(degree >= Line && degree <= Cubic);
        Q_ASSERT(i >= 0 && i < degree);
        qSwap(indices[i], indices[degree - i]);
    }
    pointingUp = !pointingUp;
    Q_ASSERT(next == nullptr && previous == nullptr);
}

PathSimplifier::PathSimplifier(const QVectorPath &path, QDataBuffer<QPoint> &vertices,
                               QDataBuffer<quint32> &indices, const QTransform &matrix)
    : m_elements(0)
    , m_points(&vertices)
    , m_indices(&indices)
{
    m_points->reset();
    m_indices->reset();
    initElements(path, matrix);
    if (!m_elements.isEmpty()) {
        removeIntersections();
        connectElements();
        fillIndices();
    }
}

void PathSimplifier::initElements(const QVectorPath &path, const QTransform &matrix)
{
    m_hints = path.hints();
    int pathElementCount = path.elementCount();
    if (pathElementCount == 0)
        return;
    m_elements.reserve(2 * pathElementCount);
    m_elementAllocator.allocate(2 * pathElementCount);
    m_points->reserve(2 * pathElementCount);
    const QPainterPath::ElementType *e = path.elements();
    const qreal *p = path.points();
    if (e) {
        qreal x, y;
        quint32 moveToIndex = 0;
        quint32 previousIndex = 0;
        for (int i = 0; i < pathElementCount; ++i, ++e, p += 2) {
            switch (*e) {
            case QPainterPath::MoveToElement:
                {
                    if (!m_points->isEmpty()) {
                        const QPoint &from = m_points->at(previousIndex);
                        const QPoint &to = m_points->at(moveToIndex);
                        if (from != to) {
                            Element *element = m_elementAllocator.newElement();
                            element->degree = Element::Line;
                            element->indices[0] = previousIndex;
                            element->indices[1] = moveToIndex;
                            element->middle.rx() = (from.x() + to.x()) >> 1;
                            element->middle.ry() = (from.y() + to.y()) >> 1;
                            m_elements.add(element);
                        }
                    }
                    previousIndex = moveToIndex = m_points->size();
                    matrix.map(p[0], p[1], &x, &y);
                    QPoint to(qRound(x * Q_FIXED_POINT_SCALE), qRound(y * Q_FIXED_POINT_SCALE));
                    m_points->add(to);
                }
                break;
            case QPainterPath::LineToElement:
                Q_ASSERT(!m_points->isEmpty());
                {
                    matrix.map(p[0], p[1], &x, &y);
                    QPoint to(qRound(x * Q_FIXED_POINT_SCALE), qRound(y * Q_FIXED_POINT_SCALE));
                    const QPoint &from = m_points->last();
                    if (to != from) {
                        Element *element = m_elementAllocator.newElement();
                        element->degree = Element::Line;
                        element->indices[0] = previousIndex;
                        element->indices[1] = quint32(m_points->size());
                        element->middle.rx() = (from.x() + to.x()) >> 1;
                        element->middle.ry() = (from.y() + to.y()) >> 1;
                        m_elements.add(element);
                        previousIndex = m_points->size();
                        m_points->add(to);
                    }
                }
                break;
            case QPainterPath::CurveToElement:
                Q_ASSERT(i + 2 < pathElementCount);
                Q_ASSERT(!m_points->isEmpty());
                Q_ASSERT(e[1] == QPainterPath::CurveToDataElement);
                Q_ASSERT(e[2] == QPainterPath::CurveToDataElement);
                {
                    quint32 startPointIndex = previousIndex;
                    matrix.map(p[4], p[5], &x, &y);
                    QPoint end(qRound(x * Q_FIXED_POINT_SCALE), qRound(y * Q_FIXED_POINT_SCALE));
                    previousIndex = m_points->size();
                    m_points->add(end);

                    // See if this cubic bezier is really quadratic.
                    qreal x1 = p[-2] + qreal(1.5) * (p[0] - p[-2]);
                    qreal y1 = p[-1] + qreal(1.5) * (p[1] - p[-1]);
                    qreal x2 = p[4] + qreal(1.5) * (p[2] - p[4]);
                    qreal y2 = p[5] + qreal(1.5) * (p[3] - p[5]);

                    Element *element = m_elementAllocator.newElement();
                    if (qAbs(x1 - x2) < qreal(1e-3) && qAbs(y1 - y2) < qreal(1e-3)) {
                        // The bezier curve is quadratic.
                        matrix.map(x1, y1, &x, &y);
                        QPoint ctrl(qRound(x * Q_FIXED_POINT_SCALE),
                                    qRound(y * Q_FIXED_POINT_SCALE));
                        setElementToQuadratic(element, startPointIndex, ctrl, previousIndex);
                    } else {
                        // The bezier curve is cubic.
                        matrix.map(p[0], p[1], &x, &y);
                        QPoint ctrl1(qRound(x * Q_FIXED_POINT_SCALE),
                                     qRound(y * Q_FIXED_POINT_SCALE));
                        matrix.map(p[2], p[3], &x, &y);
                        QPoint ctrl2(qRound(x * Q_FIXED_POINT_SCALE),
                                     qRound(y * Q_FIXED_POINT_SCALE));
                        setElementToCubicAndSimplify(element, startPointIndex, ctrl1, ctrl2,
                                                     previousIndex);
                    }
                    m_elements.add(element);
                }
                i += 2;
                e += 2;
                p += 4;

                break;
            default:
                Q_ASSERT_X(0, "QSGPathSimplifier::initialize", "Unexpected element type.");
                break;
            }
        }
        if (!m_points->isEmpty()) {
            const QPoint &from = m_points->at(previousIndex);
            const QPoint &to = m_points->at(moveToIndex);
            if (from != to) {
                Element *element = m_elementAllocator.newElement();
                element->degree = Element::Line;
                element->indices[0] = previousIndex;
                element->indices[1] = moveToIndex;
                element->middle.rx() = (from.x() + to.x()) >> 1;
                element->middle.ry() = (from.y() + to.y()) >> 1;
                m_elements.add(element);
            }
        }
    } else {
        qreal x, y;

        for (int i = 0; i < pathElementCount; ++i, p += 2) {
            matrix.map(p[0], p[1], &x, &y);
            QPoint to(qRound(x * Q_FIXED_POINT_SCALE), qRound(y * Q_FIXED_POINT_SCALE));
            if (to != m_points->last())
                m_points->add(to);
        }

        while (!m_points->isEmpty() && m_points->last() == m_points->first())
            m_points->pop_back();

        if (m_points->isEmpty())
            return;

        quint32 prev = quint32(m_points->size() - 1);
        for (int i = 0; i < m_points->size(); ++i) {
            QPoint &to = m_points->at(i);
            QPoint &from = m_points->at(prev);
            Element *element = m_elementAllocator.newElement();
            element->degree = Element::Line;
            element->indices[0] = prev;
            element->indices[1] = quint32(i);
            element->middle.rx() = (from.x() + to.x()) >> 1;
            element->middle.ry() = (from.y() + to.y()) >> 1;
            m_elements.add(element);
            prev = i;
        }
    }

    for (int i = 0; i < m_elements.size(); ++i)
        m_elements.at(i)->processed = false;
}

void PathSimplifier::removeIntersections()
{
    Q_ASSERT(!m_elements.isEmpty());
    QDataBuffer<Element *> elements(m_elements.size());
    for (int i = 0; i < m_elements.size(); ++i)
        elements.add(m_elements.at(i));
    m_bvh.allocate(2 * m_elements.size());
    m_bvh.root = buildTree(elements.data(), elements.size());

    elements.reset();
    for (int i = 0; i < m_elements.size(); ++i)
        elements.add(m_elements.at(i));

    while (!elements.isEmpty()) {
        Element *element = elements.last();
        elements.pop_back();
        BVHNode *node = element->bvhNode;
        Q_ASSERT(node->type == BVHNode::Leaf);
        Q_ASSERT(node->element == element);
        if (!element->processed) {
            if (!intersectNodes(elements, node, m_bvh.root))
                element->processed = true;
        }
    }

    m_bvh.free(); // The bounding volume hierarchy is not needed anymore.
}

void PathSimplifier::connectElements()
{
    Q_ASSERT(!m_elements.isEmpty());
    QDataBuffer<Event> events(m_elements.size() * 2);
    for (int i = 0; i < m_elements.size(); ++i) {
        Element *element = m_elements.at(i);
        element->next = element->previous = nullptr;
        element->winding = 0;
        element->edgeNode = nullptr;
        const QPoint &u = m_points->at(element->indices[0]);
        const QPoint &v = m_points->at(element->indices[element->degree]);
        if (u != v) {
            element->pointingUp = element->originallyPointingUp = v < u;

            Event event;
            event.element = element;
            event.point = u;
            event.type = element->pointingUp ? Event::Lower : Event::Upper;
            events.add(event);
            event.point = v;
            event.type = element->pointingUp ? Event::Upper : Event::Lower;
            events.add(event);
        }
    }
    QVarLengthArray<Element *, 8> orderedElements;
    if (!events.isEmpty())
        sortEvents(events.data(), events.size());
    while (!events.isEmpty()) {
        const Event *event = &events.last();
        QPoint eventPoint = event->point;

        // Find all elements passing through the event point.
        QPair<RBNode *, RBNode *> bounds = outerBounds(eventPoint);

        // Special case: single element above and single element below event point.
        int eventCount = events.size();
        if (event->type == Event::Lower && eventCount > 2) {
            QPair<RBNode *, RBNode *> range;
            range.first = bounds.first ? m_elementList.next(bounds.first)
                                       : m_elementList.front(m_elementList.root);
            range.second = bounds.second ? m_elementList.previous(bounds.second)
                                         : m_elementList.back(m_elementList.root);

            const Event *event2 = &events.at(eventCount - 2);
            const Event *event3 = &events.at(eventCount - 3);
            Q_ASSERT(event2->point == eventPoint); // There are always at least two events at a point.
            if (range.first == range.second && event2->type == Event::Upper && event3->point != eventPoint) {
                Element *element = event->element;
                Element *element2 = event2->element;
                element->edgeNode->data = event2->element;
                element2->edgeNode = element->edgeNode;
                element->edgeNode = nullptr;

                events.pop_back();
                events.pop_back();

                if (element2->pointingUp != element->pointingUp)
                    element2->flip();
                element2->winding = element->winding;
                int winding = element->winding;
                if (element->originallyPointingUp)
                    ++winding;
                if (winding == 0 || winding == 1) {
                    if (element->pointingUp) {
                        element->previous = event2->element;
                        element2->next = event->element;
                    } else {
                        element->next = event2->element;
                        element2->previous = event->element;
                    }
                }
                continue;
            }
        }
        orderedElements.clear();

        // First, find the ones above the event point.
        if (m_elementList.root) {
            RBNode *current = bounds.first ? m_elementList.next(bounds.first)
                                           : m_elementList.front(m_elementList.root);
            while (current != bounds.second) {
                Element *element = current->data;
                Q_ASSERT(element->edgeNode == current);
                int winding = element->winding;
                if (element->originallyPointingUp)
                    ++winding;
                const QPoint &lower = m_points->at(element->lowerIndex());
                if (lower == eventPoint) {
                    if (winding == 0 || winding == 1)
                        orderedElements.append(current->data);
                } else {
                    // The element is passing through 'event.point'.
                    Q_ASSERT(m_points->at(element->upperIndex()) != eventPoint);
                    Q_ASSERT(element->degree == Element::Line);
                    // Split the line.
                    Element *eventElement = event->element;
                    int indexIndex = (event->type == Event::Upper) == eventElement->pointingUp
                                     ? eventElement->degree : 0;
                    quint32 pointIndex = eventElement->indices[indexIndex];
                    Q_ASSERT(eventPoint == m_points->at(pointIndex));

                    Element *upperElement = m_elementAllocator.newElement();
                    *upperElement = *element;
                    upperElement->lowerIndex() = element->upperIndex() = pointIndex;
                    upperElement->edgeNode = nullptr;
                    element->next = element->previous = nullptr;
                    if (upperElement->next)
                        upperElement->next->previous = upperElement;
                    else if (upperElement->previous)
                        upperElement->previous->next = upperElement;
                    if (element->pointingUp != element->originallyPointingUp)
                        element->flip();
                    if (winding == 0 || winding == 1)
                        orderedElements.append(upperElement);
                    m_elements.add(upperElement);
                }
                current = m_elementList.next(current);
            }
        }
        while (!events.isEmpty() && events.last().point == eventPoint) {
            event = &events.last();
            if (event->type == Event::Upper) {
                Q_ASSERT(event->point == m_points->at(event->element->upperIndex()));
                RBNode *left = findElementLeftOf(event->element, bounds);
                RBNode *node = m_elementList.newNode();
                node->data = event->element;
                Q_ASSERT(event->element->edgeNode == nullptr);
                event->element->edgeNode = node;
                m_elementList.attachAfter(left, node);
            } else {
                Q_ASSERT(event->type == Event::Lower);
                Q_ASSERT(event->point == m_points->at(event->element->lowerIndex()));
                Element *element = event->element;
                Q_ASSERT(element->edgeNode);
                m_elementList.deleteNode(element->edgeNode);
                Q_ASSERT(element->edgeNode == nullptr);
            }
            events.pop_back();
        }

        if (m_elementList.root) {
            RBNode *current = bounds.first ? m_elementList.next(bounds.first)
                                           : m_elementList.front(m_elementList.root);
            int winding = bounds.first ? bounds.first->data->winding : 0;

            // Calculate winding numbers and flip elements if necessary.
            while (current != bounds.second) {
                Element *element = current->data;
                Q_ASSERT(element->edgeNode == current);
                int ccw = winding & 1;
                Q_ASSERT(element->pointingUp == element->originallyPointingUp);
                if (element->originallyPointingUp) {
                    --winding;
                } else {
                    ++winding;
                    ccw ^= 1;
                }
                element->winding = winding;
                if (ccw == 0)
                    element->flip();
                current = m_elementList.next(current);
            }

            // Pick elements with correct winding number.
            current = bounds.second ? m_elementList.previous(bounds.second)
                                    : m_elementList.back(m_elementList.root);
            while (current != bounds.first) {
                Element *element = current->data;
                Q_ASSERT(element->edgeNode == current);
                Q_ASSERT(m_points->at(element->upperIndex()) == eventPoint);
                int winding = element->winding;
                if (element->originallyPointingUp)
                    ++winding;
                if (winding == 0 || winding == 1)
                    orderedElements.append(current->data);
                current = m_elementList.previous(current);
            }
        }

        if (!orderedElements.isEmpty()) {
            Q_ASSERT((orderedElements.size() & 1) == 0);
            int i = 0;
            Element *firstElement = orderedElements.at(0);
            if (m_points->at(firstElement->indices[0]) != eventPoint) {
                orderedElements.append(firstElement);
                i = 1;
            }
            for (; i < orderedElements.size(); i += 2) {
                Q_ASSERT(i + 1 < orderedElements.size());
                Element *next = orderedElements.at(i);
                Element *previous = orderedElements.at(i + 1);
                Q_ASSERT(next->previous == nullptr);
                Q_ASSERT(previous->next == nullptr);
                next->previous = previous;
                previous->next = next;
            }
        }
    }
#ifndef QT_NO_DEBUG
    for (int i = 0; i < m_elements.size(); ++i) {
        const Element *element = m_elements.at(i);
        Q_ASSERT(element->next == 0 || element->next->previous == element);
        Q_ASSERT(element->previous == 0 || element->previous->next == element);
        Q_ASSERT((element->next == 0) == (element->previous == 0));
    }
#endif
}

void PathSimplifier::fillIndices()
{
    for (int i = 0; i < m_elements.size(); ++i)
        m_elements.at(i)->processed = false;
    for (int i = 0; i < m_elements.size(); ++i) {
        Element *element = m_elements.at(i);
        if (element->processed || element->next == nullptr)
            continue;
        do {
            m_indices->add(element->indices[0]);
            switch (element->degree) {
            case Element::Quadratic:
                {
                    QPoint pts[] = {
                        m_points->at(element->indices[0]),
                        m_points->at(element->indices[1]),
                        m_points->at(element->indices[2])
                    };
                    subDivQuadratic(pts[0], pts[1], pts[2]);
                }
                break;
            case Element::Cubic:
                {
                    QPoint pts[] = {
                        m_points->at(element->indices[0]),
                        m_points->at(element->indices[1]),
                        m_points->at(element->indices[2]),
                        m_points->at(element->indices[3])
                    };
                    subDivCubic(pts[0], pts[1], pts[2], pts[3]);
                }
                break;
            default:
                break;
            }
            Q_ASSERT(element->next);
            element->processed = true;
            element = element->next;
        } while (element != m_elements.at(i));
        m_indices->add(Q_TRIANGULATE_END_OF_POLYGON);
    }
}

PathSimplifier::BVHNode *PathSimplifier::buildTree(Element **elements, int elementCount)
{
    Q_ASSERT(elementCount > 0);
    BVHNode *node = m_bvh.newNode();
    if (elementCount == 1) {
        Element *element = *elements;
        element->bvhNode = node;
        node->type = BVHNode::Leaf;
        node->element = element;
        node->minimum = node->maximum = m_points->at(element->indices[0]);
        for (int i = 1; i <= element->degree; ++i) {
            const QPoint &p = m_points->at(element->indices[i]);
            node->minimum.rx() = qMin(node->minimum.x(), p.x());
            node->minimum.ry() = qMin(node->minimum.y(), p.y());
            node->maximum.rx() = qMax(node->maximum.x(), p.x());
            node->maximum.ry() = qMax(node->maximum.y(), p.y());
        }
        return node;
    }

    node->type = BVHNode::Split;

    QPoint minimum, maximum;
    minimum = maximum = elements[0]->middle;

    for (int i = 1; i < elementCount; ++i) {
        const QPoint &p = elements[i]->middle;
        minimum.rx() = qMin(minimum.x(), p.x());
        minimum.ry() = qMin(minimum.y(), p.y());
        maximum.rx() = qMax(maximum.x(), p.x());
        maximum.ry() = qMax(maximum.y(), p.y());
    }

    int comp, pivot;
    if (maximum.x() - minimum.x() > maximum.y() - minimum.y()) {
        comp = 0;
        pivot = (maximum.x() + minimum.x()) >> 1;
    } else {
        comp = 1;
        pivot = (maximum.y() + minimum.y()) >> 1;
    }

    int lo = 0;
    int hi = elementCount - 1;
    while (lo < hi) {
        while (lo < hi && (&elements[lo]->middle.rx())[comp] <= pivot)
            ++lo;
        while (lo < hi && (&elements[hi]->middle.rx())[comp] > pivot)
            --hi;
        if (lo < hi)
            qSwap(elements[lo], elements[hi]);
    }

    if (lo == elementCount) {
        // All points are the same.
        Q_ASSERT(minimum.x() == maximum.x() && minimum.y() == maximum.y());
        lo = elementCount >> 1;
    }

    node->left = buildTree(elements, lo);
    node->right = buildTree(elements + lo, elementCount - lo);

    const BVHNode *left = node->left;
    const BVHNode *right = node->right;
    node->minimum.rx() = qMin(left->minimum.x(), right->minimum.x());
    node->minimum.ry() = qMin(left->minimum.y(), right->minimum.y());
    node->maximum.rx() = qMax(left->maximum.x(), right->maximum.x());
    node->maximum.ry() = qMax(left->maximum.y(), right->maximum.y());

    return node;
}

bool PathSimplifier::intersectNodes(QDataBuffer<Element *> &elements, BVHNode *elementNode,
                                    BVHNode *treeNode)
{
    if (elementNode->minimum.x() >= treeNode->maximum.x()
        || elementNode->minimum.y() >= treeNode->maximum.y()
        || elementNode->maximum.x() <= treeNode->minimum.x()
        || elementNode->maximum.y() <= treeNode->minimum.y())
    {
        return false;
    }

    Q_ASSERT(elementNode->type == BVHNode::Leaf);
    Element *element = elementNode->element;
    Q_ASSERT(!element->processed);

    if (treeNode->type == BVHNode::Leaf) {
        Element *nodeElement = treeNode->element;
        if (!nodeElement->processed)
            return false;

        if (treeNode->element == elementNode->element)
            return false;

        if (equalElements(treeNode->element, elementNode->element))
            return false; // element doesn't split itself.

        if (element->degree == Element::Line && nodeElement->degree == Element::Line) {
            const QPoint &u1 = m_points->at(element->indices[0]);
            const QPoint &u2 = m_points->at(element->indices[1]);
            const QPoint &v1 = m_points->at(nodeElement->indices[0]);
            const QPoint &v2 = m_points->at(nodeElement->indices[1]);
            IntersectionPoint intersection = intersectionPoint(u1, u2, v1, v2);
            if (!intersection.isValid())
                return false;

            Q_ASSERT(intersection.x.integer >= qMin(u1.x(), u2.x()));
            Q_ASSERT(intersection.y.integer >= qMin(u1.y(), u2.y()));
            Q_ASSERT(intersection.x.integer >= qMin(v1.x(), v2.x()));
            Q_ASSERT(intersection.y.integer >= qMin(v1.y(), v2.y()));

            Q_ASSERT(intersection.x.integer <= qMax(u1.x(), u2.x()));
            Q_ASSERT(intersection.y.integer <= qMax(u1.y(), u2.y()));
            Q_ASSERT(intersection.x.integer <= qMax(v1.x(), v2.x()));
            Q_ASSERT(intersection.y.integer <= qMax(v1.y(), v2.y()));

            m_points->add(intersection.round());
            splitLineAt(elements, treeNode, m_points->size() - 1, !intersection.isAccurate());
            return splitLineAt(elements, elementNode, m_points->size() - 1, false);
        } else {
            QVarLengthArray<QPoint, 12> axes;
            appendSeparatingAxes(axes, elementNode->element);
            appendSeparatingAxes(axes, treeNode->element);
            for (int i = 0; i < axes.size(); ++i) {
                QPair<int, int> range1 = calculateSeparatingAxisRange(axes.at(i), elementNode->element);
                QPair<int, int> range2 = calculateSeparatingAxisRange(axes.at(i), treeNode->element);
                if (range1.first >= range2.second || range1.second <= range2.first) {
                    return false; // Separating axis found.
                }
            }
            // Bounding areas overlap.
            if (nodeElement->degree > Element::Line)
                splitCurve(elements, treeNode);
            if (element->degree > Element::Line) {
                splitCurve(elements, elementNode);
            } else {
                // The element was not split, so it can be processed further.
                if (intersectNodes(elements, elementNode, treeNode->left))
                    return true;
                if (intersectNodes(elements, elementNode, treeNode->right))
                    return true;
                return false;
            }
            return true;
        }
    } else {
        if (intersectNodes(elements, elementNode, treeNode->left))
            return true;
        if (intersectNodes(elements, elementNode, treeNode->right))
            return true;
        return false;
    }
}

bool PathSimplifier::equalElements(const Element *e1, const Element *e2)
{
    Q_ASSERT(e1 != e2);
    if (e1->degree != e2->degree)
        return false;

    // Possibly equal and in the same direction.
    bool equalSame = true;
    for (int i = 0; i <= e1->degree; ++i)
        equalSame &= m_points->at(e1->indices[i]) == m_points->at(e2->indices[i]);

    // Possibly equal and in opposite directions.
    bool equalOpposite = true;
    for (int i = 0; i <= e1->degree; ++i)
        equalOpposite &= m_points->at(e1->indices[e1->degree - i]) == m_points->at(e2->indices[i]);

    return equalSame || equalOpposite;
}

bool PathSimplifier::splitLineAt(QDataBuffer<Element *> &elements, BVHNode *node,
                                 quint32 pointIndex, bool processAgain)
{
    Q_ASSERT(node->type == BVHNode::Leaf);
    Element *element = node->element;
    Q_ASSERT(element->degree == Element::Line);
    const QPoint &u = m_points->at(element->indices[0]);
    const QPoint &v = m_points->at(element->indices[1]);
    const QPoint &p = m_points->at(pointIndex);
    if (u == p || v == p)
        return false; // No split needed.

    if (processAgain)
        element->processed = false; // Needs to be processed again.

    Element *first = node->element;
    Element *second = m_elementAllocator.newElement();
    *second = *first;
    first->indices[1] = second->indices[0] = pointIndex;
    first->middle.rx() = (u.x() + p.x()) >> 1;
    first->middle.ry() = (u.y() + p.y()) >> 1;
    second->middle.rx() = (v.x() + p.x()) >> 1;
    second->middle.ry() = (v.y() + p.y()) >> 1;
    m_elements.add(second);

    BVHNode *left = m_bvh.newNode();
    BVHNode *right = m_bvh.newNode();
    left->type = right->type = BVHNode::Leaf;
    left->element = first;
    right->element = second;
    left->minimum = right->minimum = node->minimum;
    left->maximum = right->maximum = node->maximum;
    if (u.x() < v.x())
        left->maximum.rx() = right->minimum.rx() = p.x();
    else
        left->minimum.rx() = right->maximum.rx() = p.x();
    if (u.y() < v.y())
        left->maximum.ry() = right->minimum.ry() = p.y();
    else
        left->minimum.ry() = right->maximum.ry() = p.y();
    left->element->bvhNode = left;
    right->element->bvhNode = right;

    node->type = BVHNode::Split;
    node->left = left;
    node->right = right;

    if (!first->processed) {
        elements.add(left->element);
        elements.add(right->element);
    }
    return true;
}

void PathSimplifier::appendSeparatingAxes(QVarLengthArray<QPoint, 12> &axes, Element *element)
{
    switch (element->degree) {
    case Element::Cubic:
        {
            const QPoint &u = m_points->at(element->indices[0]);
            const QPoint &v = m_points->at(element->indices[1]);
            const QPoint &w = m_points->at(element->indices[2]);
            const QPoint &q = m_points->at(element->indices[3]);
            QPoint ns[] = {
                QPoint(u.y() - v.y(), v.x() - u.x()),
                QPoint(v.y() - w.y(), w.x() - v.x()),
                QPoint(w.y() - q.y(), q.x() - w.x()),
                QPoint(q.y() - u.y(), u.x() - q.x()),
                QPoint(u.y() - w.y(), w.x() - u.x()),
                QPoint(v.y() - q.y(), q.x() - v.x())
            };
            for (int i = 0; i < 6; ++i) {
                if (ns[i].x() || ns[i].y())
                    axes.append(ns[i]);
            }
        }
        break;
    case Element::Quadratic:
        {
            const QPoint &u = m_points->at(element->indices[0]);
            const QPoint &v = m_points->at(element->indices[1]);
            const QPoint &w = m_points->at(element->indices[2]);
            QPoint ns[] = {
                QPoint(u.y() - v.y(), v.x() - u.x()),
                QPoint(v.y() - w.y(), w.x() - v.x()),
                QPoint(w.y() - u.y(), u.x() - w.x())
            };
            for (int i = 0; i < 3; ++i) {
                if (ns[i].x() || ns[i].y())
                    axes.append(ns[i]);
            }
        }
        break;
    case Element::Line:
        {
            const QPoint &u = m_points->at(element->indices[0]);
            const QPoint &v = m_points->at(element->indices[1]);
            QPoint n(u.y() - v.y(), v.x() - u.x());
            if (n.x() || n.y())
                axes.append(n);
        }
        break;
    default:
        Q_ASSERT_X(0, "QSGPathSimplifier::appendSeparatingAxes", "Unexpected element type.");
        break;
    }
}

QPair<int, int> PathSimplifier::calculateSeparatingAxisRange(const QPoint &axis, Element *element)
{
    QPair<int, int> range(0x7fffffff, -0x7fffffff);
    for (int i = 0; i <= element->degree; ++i) {
        const QPoint &p = m_points->at(element->indices[i]);
        int dist = dot(axis, p);
        range.first = qMin(range.first, dist);
        range.second = qMax(range.second, dist);
    }
    return range;
}

void PathSimplifier::splitCurve(QDataBuffer<Element *> &elements, BVHNode *node)
{
    Q_ASSERT(node->type == BVHNode::Leaf);

    Element *first = node->element;
    Element *second = m_elementAllocator.newElement();
    *second = *first;
    m_elements.add(second);
    Q_ASSERT(first->degree > Element::Line);

    bool accurate = true;
    const QPoint &u = m_points->at(first->indices[0]);
    const QPoint &v = m_points->at(first->indices[1]);
    const QPoint &w = m_points->at(first->indices[2]);

    if (first->degree == Element::Quadratic) {
        QPoint pts[3];
        accurate = splitQuadratic(u, v, w, pts);
        int pointIndex = m_points->size();
        m_points->add(pts[1]);
        accurate &= setElementToQuadratic(first, first->indices[0], pts[0], pointIndex);
        accurate &= setElementToQuadratic(second, pointIndex, pts[2], second->indices[2]);
    } else {
        Q_ASSERT(first->degree == Element::Cubic);
        const QPoint &q = m_points->at(first->indices[3]);
        QPoint pts[5];
        accurate = splitCubic(u, v, w, q, pts);
        int pointIndex = m_points->size();
        m_points->add(pts[2]);
        accurate &= setElementToCubic(first, first->indices[0], pts[0], pts[1], pointIndex);
        accurate &= setElementToCubic(second, pointIndex, pts[3], pts[4], second->indices[3]);
    }

    if (!accurate)
        first->processed = second->processed = false; // Needs to be processed again.

    BVHNode *left = m_bvh.newNode();
    BVHNode *right = m_bvh.newNode();
    left->type = right->type = BVHNode::Leaf;
    left->element = first;
    right->element = second;

    left->minimum.rx() = left->minimum.ry() = right->minimum.rx() = right->minimum.ry() = INT_MAX;
    left->maximum.rx() = left->maximum.ry() = right->maximum.rx() = right->maximum.ry() = INT_MIN;

    for (int i = 0; i <= first->degree; ++i) {
        QPoint &p = m_points->at(first->indices[i]);
        left->minimum.rx() = qMin(left->minimum.x(), p.x());
        left->minimum.ry() = qMin(left->minimum.y(), p.y());
        left->maximum.rx() = qMax(left->maximum.x(), p.x());
        left->maximum.ry() = qMax(left->maximum.y(), p.y());
    }
    for (int i = 0; i <= second->degree; ++i) {
        QPoint &p = m_points->at(second->indices[i]);
        right->minimum.rx() = qMin(right->minimum.x(), p.x());
        right->minimum.ry() = qMin(right->minimum.y(), p.y());
        right->maximum.rx() = qMax(right->maximum.x(), p.x());
        right->maximum.ry() = qMax(right->maximum.y(), p.y());
    }
    left->element->bvhNode = left;
    right->element->bvhNode = right;

    node->type = BVHNode::Split;
    node->left = left;
    node->right = right;

    if (!first->processed) {
        elements.add(left->element);
        elements.add(right->element);
    }
}

bool PathSimplifier::setElementToQuadratic(Element *element, quint32 pointIndex1,
                                           const QPoint &ctrl, quint32 pointIndex2)
{
    const QPoint &p1 = m_points->at(pointIndex1);
    const QPoint &p2 = m_points->at(pointIndex2);
    if (flattenQuadratic(p1, ctrl, p2)) {
        // Insert line.
        element->degree = Element::Line;
        element->indices[0] = pointIndex1;
        element->indices[1] = pointIndex2;
        element->middle.rx() = (p1.x() + p2.x()) >> 1;
        element->middle.ry() = (p1.y() + p2.y()) >> 1;
        return false;
    } else {
        // Insert bezier.
        element->degree = Element::Quadratic;
        element->indices[0] = pointIndex1;
        element->indices[1] = m_points->size();
        element->indices[2] = pointIndex2;
        element->middle.rx() = (p1.x() + ctrl.x() + p2.x()) / 3;
        element->middle.ry() = (p1.y() + ctrl.y() + p2.y()) / 3;
        m_points->add(ctrl);
        return true;
    }
}

bool PathSimplifier::setElementToCubic(Element *element, quint32 pointIndex1, const QPoint &v,
                                       const QPoint &w, quint32 pointIndex2)
{
    const QPoint &u = m_points->at(pointIndex1);
    const QPoint &q = m_points->at(pointIndex2);
    if (flattenCubic(u, v, w, q)) {
        // Insert line.
        element->degree = Element::Line;
        element->indices[0] = pointIndex1;
        element->indices[1] = pointIndex2;
        element->middle.rx() = (u.x() + q.x()) >> 1;
        element->middle.ry() = (u.y() + q.y()) >> 1;
        return false;
    } else {
        // Insert bezier.
        element->degree = Element::Cubic;
        element->indices[0] = pointIndex1;
        element->indices[1] = m_points->size();
        element->indices[2] = m_points->size() + 1;
        element->indices[3] = pointIndex2;
        element->middle.rx() = (u.x() + v.x() + w.x() + q.x()) >> 2;
        element->middle.ry() = (u.y() + v.y() + w.y() + q.y()) >> 2;
        m_points->add(v);
        m_points->add(w);
        return true;
    }
}

void PathSimplifier::setElementToCubicAndSimplify(Element *element, quint32 pointIndex1,
                                                  const QPoint &v, const QPoint &w,
                                                  quint32 pointIndex2)
{
    const QPoint &u = m_points->at(pointIndex1);
    const QPoint &q = m_points->at(pointIndex2);
    if (flattenCubic(u, v, w, q)) {
        // Insert line.
        element->degree = Element::Line;
        element->indices[0] = pointIndex1;
        element->indices[1] = pointIndex2;
        element->middle.rx() = (u.x() + q.x()) >> 1;
        element->middle.ry() = (u.y() + q.y()) >> 1;
        return;
    }

    bool intersecting = (u == q) || intersectionPoint(u, v, w, q).isValid();
    if (!intersecting) {
        // Insert bezier.
        element->degree = Element::Cubic;
        element->indices[0] = pointIndex1;
        element->indices[1] = m_points->size();
        element->indices[2] = m_points->size() + 1;
        element->indices[3] = pointIndex2;
        element->middle.rx() = (u.x() + v.x() + w.x() + q.x()) >> 2;
        element->middle.ry() = (u.y() + v.y() + w.y() + q.y()) >> 2;
        m_points->add(v);
        m_points->add(w);
        return;
    }

    QPoint pts[5];
    splitCubic(u, v, w, q, pts);
    int pointIndex = m_points->size();
    m_points->add(pts[2]);
    Element *element2 = m_elementAllocator.newElement();
    m_elements.add(element2);
    setElementToCubicAndSimplify(element, pointIndex1, pts[0], pts[1], pointIndex);
    setElementToCubicAndSimplify(element2, pointIndex, pts[3], pts[4], pointIndex2);
}

PathSimplifier::RBNode *PathSimplifier::findElementLeftOf(const Element *element,
                                                          const QPair<RBNode *, RBNode *> &bounds)
{
    if (!m_elementList.root)
        return nullptr;
    RBNode *current = bounds.first;
    Q_ASSERT(!current || !elementIsLeftOf(element, current->data));
    if (!current)
        current = m_elementList.front(m_elementList.root);
    Q_ASSERT(current);
    RBNode *result = nullptr;
    while (current != bounds.second && !elementIsLeftOf(element, current->data)) {
        result = current;
        current = m_elementList.next(current);
    }
    return result;
}

bool PathSimplifier::elementIsLeftOf(const Element *left, const Element *right)
{
    const QPoint &leftU = m_points->at(left->upperIndex());
    const QPoint &leftL = m_points->at(left->lowerIndex());
    const QPoint &rightU = m_points->at(right->upperIndex());
    const QPoint &rightL = m_points->at(right->lowerIndex());
    Q_ASSERT(leftL >= rightU && rightL >= leftU);
    if (leftU.x() < qMin(rightL.x(), rightU.x()))
        return true;
    if (leftU.x() > qMax(rightL.x(), rightU.x()))
        return false;
    int d = pointDistanceFromLine(leftU, rightL, rightU);
    // d < 0: left, d > 0: right, d == 0: on top
    if (d == 0) {
        d = pointDistanceFromLine(leftL, rightL, rightU);
        if (d == 0) {
            if (right->degree > Element::Line) {
                d = pointDistanceFromLine(leftL, rightL, m_points->at(right->indices[1]));
                if (d == 0)
                    d = pointDistanceFromLine(leftL, rightL, m_points->at(right->indices[2]));
            } else if (left->degree > Element::Line) {
                d = pointDistanceFromLine(m_points->at(left->indices[1]), rightL, rightU);
                if (d == 0)
                    d = pointDistanceFromLine(m_points->at(left->indices[2]), rightL, rightU);
            }
        }
    }
    return d < 0;
}

QPair<PathSimplifier::RBNode *, PathSimplifier::RBNode *> PathSimplifier::outerBounds(const QPoint &point)
{
    RBNode *current = m_elementList.root;
    QPair<RBNode *, RBNode *> result(0, 0);

    while (current) {
        const Element *element = current->data;
        Q_ASSERT(element->edgeNode == current);
        const QPoint &v1 = m_points->at(element->lowerIndex());
        const QPoint &v2 = m_points->at(element->upperIndex());
        Q_ASSERT(point >= v2 && point <= v1);
        if (point == v1 || point == v2)
            break;
        int d = pointDistanceFromLine(point, v1, v2);
        if (d == 0) {
            if (element->degree == Element::Line)
                break;
            d = pointDistanceFromLine(point, v1, m_points->at(element->indices[1]));
            if (d == 0)
                d = pointDistanceFromLine(point, v1, m_points->at(element->indices[2]));
            Q_ASSERT(d != 0);
        }
        if (d < 0) {
            result.second = current;
            current = current->left;
        } else {
            result.first = current;
            current = current->right;
        }
    }

    if (!current)
        return result;

    RBNode *mid = current;

    current = mid->left;
    while (current) {
        const Element *element = current->data;
        Q_ASSERT(element->edgeNode == current);
        const QPoint &v1 = m_points->at(element->lowerIndex());
        const QPoint &v2 = m_points->at(element->upperIndex());
        Q_ASSERT(point >= v2 && point <= v1);
        bool equal = (point == v1 || point == v2);
        if (!equal) {
            int d = pointDistanceFromLine(point, v1, v2);
            Q_ASSERT(d >= 0);
            equal = (d == 0 && element->degree == Element::Line);
        }
        if (equal) {
            current = current->left;
        } else {
            result.first = current;
            current = current->right;
        }
    }

    current = mid->right;
    while (current) {
        const Element *element = current->data;
        Q_ASSERT(element->edgeNode == current);
        const QPoint &v1 = m_points->at(element->lowerIndex());
        const QPoint &v2 = m_points->at(element->upperIndex());
        Q_ASSERT(point >= v2 && point <= v1);
        bool equal = (point == v1 || point == v2);
        if (!equal) {
            int d = pointDistanceFromLine(point, v1, v2);
            Q_ASSERT(d <= 0);
            equal = (d == 0 && element->degree == Element::Line);
        }
        if (equal) {
            current = current->right;
        } else {
            result.second = current;
            current = current->left;
        }
    }

    return result;
}

inline bool PathSimplifier::flattenQuadratic(const QPoint &u, const QPoint &v, const QPoint &w)
{
    QPoint deltas[2] = { v - u, w - v };
    int d = qAbs(cross(deltas[0], deltas[1]));
    int l = qAbs(deltas[0].x()) + qAbs(deltas[0].y()) + qAbs(deltas[1].x()) + qAbs(deltas[1].y());
    return d < (Q_FIXED_POINT_SCALE * Q_FIXED_POINT_SCALE * 3 / 2) || l <= Q_FIXED_POINT_SCALE * 2;
}

inline bool PathSimplifier::flattenCubic(const QPoint &u, const QPoint &v,
                                         const QPoint &w, const QPoint &q)
{
    QPoint deltas[] = { v - u, w - v, q - w, q - u };
    int d = qAbs(cross(deltas[0], deltas[1])) + qAbs(cross(deltas[1], deltas[2]))
            + qAbs(cross(deltas[0], deltas[3])) + qAbs(cross(deltas[3], deltas[2]));
    int l = qAbs(deltas[0].x()) + qAbs(deltas[0].y()) + qAbs(deltas[1].x()) + qAbs(deltas[1].y())
            + qAbs(deltas[2].x()) + qAbs(deltas[2].y());
    return d < (Q_FIXED_POINT_SCALE * Q_FIXED_POINT_SCALE * 3) || l <= Q_FIXED_POINT_SCALE * 2;
}

inline bool PathSimplifier::splitQuadratic(const QPoint &u, const QPoint &v,
                                           const QPoint &w, QPoint *result)
{
    result[0] = u + v;
    result[2] = v + w;
    result[1] = result[0] + result[2];
    bool accurate = ((result[0].x() | result[0].y() | result[2].x() | result[2].y()) & 1) == 0
                    && ((result[1].x() | result[1].y()) & 3) == 0;
    result[0].rx() >>= 1;
    result[0].ry() >>= 1;
    result[1].rx() >>= 2;
    result[1].ry() >>= 2;
    result[2].rx() >>= 1;
    result[2].ry() >>= 1;
    return accurate;
}

inline bool PathSimplifier::splitCubic(const QPoint &u, const QPoint &v,
                                       const QPoint &w, const QPoint &q, QPoint *result)
{
    result[0] = u + v;
    result[2] = v + w;
    result[4] = w + q;
    result[1] = result[0] + result[2];
    result[3] = result[2] + result[4];
    result[2] = result[1] + result[3];
    bool accurate = ((result[0].x() | result[0].y() | result[4].x() | result[4].y()) & 1) == 0
                    && ((result[1].x() | result[1].y() | result[3].x() | result[3].y()) & 3) == 0
                    && ((result[2].x() | result[2].y()) & 7) == 0;
    result[0].rx() >>= 1;
    result[0].ry() >>= 1;
    result[1].rx() >>= 2;
    result[1].ry() >>= 2;
    result[2].rx() >>= 3;
    result[2].ry() >>= 3;
    result[3].rx() >>= 2;
    result[3].ry() >>= 2;
    result[4].rx() >>= 1;
    result[4].ry() >>= 1;
    return accurate;
}

inline void PathSimplifier::subDivQuadratic(const QPoint &u, const QPoint &v, const QPoint &w)
{
    if (flattenQuadratic(u, v, w))
        return;
    QPoint pts[3];
    splitQuadratic(u, v, w, pts);
    subDivQuadratic(u, pts[0], pts[1]);
    m_indices->add(m_points->size());
    m_points->add(pts[1]);
    subDivQuadratic(pts[1], pts[2], w);
}

inline void PathSimplifier::subDivCubic(const QPoint &u, const QPoint &v,
                                        const QPoint &w, const QPoint &q)
{
    if (flattenCubic(u, v, w, q))
        return;
    QPoint pts[5];
    splitCubic(u, v, w, q, pts);
    subDivCubic(u, pts[0], pts[1], pts[2]);
    m_indices->add(m_points->size());
    m_points->add(pts[2]);
    subDivCubic(pts[2], pts[3], pts[4], q);
}

void PathSimplifier::sortEvents(Event *events, int count)
{
    // Bucket sort + insertion sort.
    Q_ASSERT(count > 0);
    QDataBuffer<Event> buffer(count);
    buffer.resize(count);
    QScopedArrayPointer<int> bins(new int[count]);
    int counts[0x101];
    memset(counts, 0, sizeof(counts));

    int minimum, maximum;
    minimum = maximum = events[0].point.y();
    for (int i = 1; i < count; ++i) {
        minimum = qMin(minimum, events[i].point.y());
        maximum = qMax(maximum, events[i].point.y());
    }

    for (int i = 0; i < count; ++i) {
        bins[i] = ((maximum - events[i].point.y()) << 8) / (maximum - minimum + 1);
        Q_ASSERT(bins[i] >= 0 && bins[i] < 0x100);
        ++counts[bins[i]];
    }

    for (int i = 1; i < 0x100; ++i)
        counts[i] += counts[i - 1];
    counts[0x100] = counts[0xff];
    Q_ASSERT(counts[0x100] == count);

    for (int i = 0; i < count; ++i)
        buffer.at(--counts[bins[i]]) = events[i];

    int j = 0;
    for (int i = 0; i < 0x100; ++i) {
        for (; j < counts[i + 1]; ++j) {
            int k = j;
            while (k > 0 && (buffer.at(j) < events[k - 1])) {
                events[k] = events[k - 1];
                --k;
            }
            events[k] = buffer.at(j);
        }
    }
}

} // end anonymous namespace


void qSimplifyPath(const QVectorPath &path, QDataBuffer<QPoint> &vertices,
                   QDataBuffer<quint32> &indices, const QTransform &matrix)
{
    PathSimplifier(path, vertices, indices, matrix);
}

void qSimplifyPath(const QPainterPath &path, QDataBuffer<QPoint> &vertices,
                   QDataBuffer<quint32> &indices, const QTransform &matrix)
{
    qSimplifyPath(qtVectorPathForPath(path), vertices, indices, matrix);
}


QT_END_NAMESPACE
