/****************************************************************************
**
** 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 "qpaintengineex_p.h"
#include "qpainter_p.h"
#include "qstroker_p.h"
#include "qbezier_p.h"
#include <private/qpainterpath_p.h>
#include <private/qfontengine_p.h>
#include <private/qstatictext_p.h>

#include <qvarlengtharray.h>
#include <qdebug.h>


QT_BEGIN_NAMESPACE

#if !defined(QT_MAX_CACHED_GLYPH_SIZE)
#  define QT_MAX_CACHED_GLYPH_SIZE 64
#endif

/*******************************************************************************
 *
 * class QVectorPath
 *
 */
QVectorPath::~QVectorPath()
{
    if (m_hints & ShouldUseCacheHint) {
        CacheEntry *e = m_cache;
        while (e) {
            if (e->data)
                e->cleanup(e->engine, e->data);
            CacheEntry *n = e->next;
            delete e;
            e = n;
        }
    }
}


QRectF QVectorPath::controlPointRect() const
{
    if (m_hints & ControlPointRect)
        return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2));

    if (m_count == 0) {
        m_cp_rect.x1 = m_cp_rect.x2 = m_cp_rect.y1 = m_cp_rect.y2 = 0;
        m_hints |= ControlPointRect;
        return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2));
    }
    Q_ASSERT(m_points && m_count > 0);

    const qreal *pts = m_points;
    m_cp_rect.x1 = m_cp_rect.x2 = *pts;
    ++pts;
    m_cp_rect.y1 = m_cp_rect.y2 = *pts;
    ++pts;

    const qreal *epts = m_points + (m_count << 1);
    while (pts < epts) {
        qreal x = *pts;
        if (x < m_cp_rect.x1) m_cp_rect.x1 = x;
        else if (x > m_cp_rect.x2) m_cp_rect.x2 = x;
        ++pts;

        qreal y = *pts;
        if (y < m_cp_rect.y1) m_cp_rect.y1 = y;
        else if (y > m_cp_rect.y2) m_cp_rect.y2 = y;
        ++pts;
    }

    m_hints |= ControlPointRect;
    return QRectF(QPointF(m_cp_rect.x1, m_cp_rect.y1), QPointF(m_cp_rect.x2, m_cp_rect.y2));
}


QVectorPath::CacheEntry *QVectorPath::addCacheData(QPaintEngineEx *engine, void *data,
                                                   qvectorpath_cache_cleanup cleanup) const{
    Q_ASSERT(!lookupCacheData(engine));
    if ((m_hints & IsCachedHint) == 0) {
        m_cache = nullptr;
        m_hints |= IsCachedHint;
    }
    CacheEntry *e = new CacheEntry;
    e->engine = engine;
    e->data = data;
    e->cleanup = cleanup;
    e->next = m_cache;
    m_cache = e;
    return m_cache;
}


const QVectorPath &qtVectorPathForPath(const QPainterPath &path)
{
    Q_ASSERT(path.d_func());
    return path.d_func()->vectorPath();
}

#ifndef QT_NO_DEBUG_STREAM
QDebug Q_GUI_EXPORT &operator<<(QDebug &s, const QVectorPath &path)
{
    QDebugStateSaver saver(s);
    QRectF rf = path.controlPointRect();
    s << "QVectorPath(size:" << path.elementCount()
      << " hints:" << Qt::hex << path.hints()
      << rf << ')';
    return s;
}
#endif

/*******************************************************************************
 *
 * class QPaintEngineExPrivate:
 *
 */


struct StrokeHandler {
    StrokeHandler(int reserve) : pts(reserve), types(reserve) {}
    QDataBuffer<qreal> pts;
    QDataBuffer<QPainterPath::ElementType> types;
};


QPaintEngineExPrivate::QPaintEngineExPrivate()
    : dasher(&stroker),
      strokeHandler(nullptr),
      activeStroker(nullptr),
      strokerPen(Qt::NoPen)
{
}


QPaintEngineExPrivate::~QPaintEngineExPrivate()
{
    delete strokeHandler;
}


void QPaintEngineExPrivate::replayClipOperations()
{
    Q_Q(QPaintEngineEx);

    QPainter *p = q->painter();
    if (!p || !p->d_ptr)
        return;

    const QVector<QPainterClipInfo> &clipInfo = p->d_ptr->state->clipInfo;

    QTransform transform = q->state()->matrix;

    for (const QPainterClipInfo &info : clipInfo) {

        if (info.matrix != q->state()->matrix) {
            q->state()->matrix = info.matrix;
            q->transformChanged();
        }

        switch (info.clipType) {
        case QPainterClipInfo::RegionClip:
            q->clip(info.region, info.operation);
            break;
        case QPainterClipInfo::PathClip:
            q->clip(info.path, info.operation);
            break;
        case QPainterClipInfo::RectClip:
            q->clip(info.rect, info.operation);
            break;
        case QPainterClipInfo::RectFClip: {
            qreal right = info.rectf.x() + info.rectf.width();
            qreal bottom = info.rectf.y() + info.rectf.height();
            qreal pts[] = { info.rectf.x(), info.rectf.y(),
                            right, info.rectf.y(),
                            right, bottom,
                            info.rectf.x(), bottom };
            QVectorPath vp(pts, 4, nullptr, QVectorPath::RectangleHint);
            q->clip(vp, info.operation);
            break;
            }
        }
    }

    if (transform != q->state()->matrix) {
        q->state()->matrix = transform;
        q->transformChanged();
    }
}


bool QPaintEngineExPrivate::hasClipOperations() const
{
    Q_Q(const QPaintEngineEx);

    QPainter *p = q->painter();
    if (!p || !p->d_ptr)
        return false;

    return !p->d_ptr->state->clipInfo.isEmpty();
}

/*******************************************************************************
 *
 * class QPaintEngineEx:
 *
 */

static const QPainterPath::ElementType qpaintengineex_ellipse_types[] = {
    QPainterPath::MoveToElement,
    QPainterPath::CurveToElement,
    QPainterPath::CurveToDataElement,
    QPainterPath::CurveToDataElement,

    QPainterPath::CurveToElement,
    QPainterPath::CurveToDataElement,
    QPainterPath::CurveToDataElement,

    QPainterPath::CurveToElement,
    QPainterPath::CurveToDataElement,
    QPainterPath::CurveToDataElement,

    QPainterPath::CurveToElement,
    QPainterPath::CurveToDataElement,
    QPainterPath::CurveToDataElement
};

static const QPainterPath::ElementType qpaintengineex_line_types_16[] = {
    QPainterPath::MoveToElement, QPainterPath::LineToElement,
    QPainterPath::MoveToElement, QPainterPath::LineToElement,
    QPainterPath::MoveToElement, QPainterPath::LineToElement,
    QPainterPath::MoveToElement, QPainterPath::LineToElement,
    QPainterPath::MoveToElement, QPainterPath::LineToElement,
    QPainterPath::MoveToElement, QPainterPath::LineToElement,
    QPainterPath::MoveToElement, QPainterPath::LineToElement,
    QPainterPath::MoveToElement, QPainterPath::LineToElement,
    QPainterPath::MoveToElement, QPainterPath::LineToElement,
    QPainterPath::MoveToElement, QPainterPath::LineToElement,
    QPainterPath::MoveToElement, QPainterPath::LineToElement,
    QPainterPath::MoveToElement, QPainterPath::LineToElement,
    QPainterPath::MoveToElement, QPainterPath::LineToElement,
    QPainterPath::MoveToElement, QPainterPath::LineToElement,
    QPainterPath::MoveToElement, QPainterPath::LineToElement,
    QPainterPath::MoveToElement, QPainterPath::LineToElement
};

static const QPainterPath::ElementType qpaintengineex_rect4_types_32[] = {
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 1
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 2
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 3
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 4
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 5
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 6
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 7
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 8
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 9
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 10
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 11
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 12
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 13
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 14
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 15
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 16
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 17
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 18
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 19
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 20
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 21
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 22
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 23
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 24
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 25
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 26
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 27
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 28
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 29
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 30
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 31
    QPainterPath::MoveToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, QPainterPath::LineToElement, // 32
};


static const QPainterPath::ElementType qpaintengineex_roundedrect_types[] = {
    QPainterPath::MoveToElement,
    QPainterPath::LineToElement,
    QPainterPath::CurveToElement,
    QPainterPath::CurveToDataElement,
    QPainterPath::CurveToDataElement,
    QPainterPath::LineToElement,
    QPainterPath::CurveToElement,
    QPainterPath::CurveToDataElement,
    QPainterPath::CurveToDataElement,
    QPainterPath::LineToElement,
    QPainterPath::CurveToElement,
    QPainterPath::CurveToDataElement,
    QPainterPath::CurveToDataElement,
    QPainterPath::LineToElement,
    QPainterPath::CurveToElement,
    QPainterPath::CurveToDataElement,
    QPainterPath::CurveToDataElement
};



static void qpaintengineex_moveTo(qreal x, qreal y, void *data) {
    ((StrokeHandler *) data)->pts.add(x);
    ((StrokeHandler *) data)->pts.add(y);
    ((StrokeHandler *) data)->types.add(QPainterPath::MoveToElement);
}

static void qpaintengineex_lineTo(qreal x, qreal y, void *data) {
    ((StrokeHandler *) data)->pts.add(x);
    ((StrokeHandler *) data)->pts.add(y);
    ((StrokeHandler *) data)->types.add(QPainterPath::LineToElement);
}

static void qpaintengineex_cubicTo(qreal c1x, qreal c1y, qreal c2x, qreal c2y, qreal ex, qreal ey, void *data) {
    ((StrokeHandler *) data)->pts.add(c1x);
    ((StrokeHandler *) data)->pts.add(c1y);
    ((StrokeHandler *) data)->types.add(QPainterPath::CurveToElement);

    ((StrokeHandler *) data)->pts.add(c2x);
    ((StrokeHandler *) data)->pts.add(c2y);
    ((StrokeHandler *) data)->types.add(QPainterPath::CurveToDataElement);

    ((StrokeHandler *) data)->pts.add(ex);
    ((StrokeHandler *) data)->pts.add(ey);
    ((StrokeHandler *) data)->types.add(QPainterPath::CurveToDataElement);
}

QPaintEngineEx::QPaintEngineEx()
    : QPaintEngine(*new QPaintEngineExPrivate, AllFeatures)
{
    extended = true;
}

QPaintEngineEx::QPaintEngineEx(QPaintEngineExPrivate &data)
    : QPaintEngine(data, AllFeatures)
{
    extended = true;
}

QPainterState *QPaintEngineEx::createState(QPainterState *orig) const
{
    if (!orig)
        return new QPainterState;
    return new QPainterState(orig);
}

Q_GUI_EXPORT extern bool qt_scaleForTransform(const QTransform &transform, qreal *scale); // qtransform.cpp

void QPaintEngineEx::stroke(const QVectorPath &path, const QPen &pen)
{
#ifdef QT_DEBUG_DRAW
    qDebug() << "QPaintEngineEx::stroke()" << pen;
#endif

    Q_D(QPaintEngineEx);

    if (path.isEmpty())
        return;

    if (!d->strokeHandler) {
        d->strokeHandler = new StrokeHandler(path.elementCount()+4);
        d->stroker.setMoveToHook(qpaintengineex_moveTo);
        d->stroker.setLineToHook(qpaintengineex_lineTo);
        d->stroker.setCubicToHook(qpaintengineex_cubicTo);
    }

    if (!qpen_fast_equals(pen, d->strokerPen)) {
        d->strokerPen = pen;
        d->stroker.setJoinStyle(pen.joinStyle());
        d->stroker.setCapStyle(pen.capStyle());
        d->stroker.setMiterLimit(pen.miterLimit());
        qreal penWidth = pen.widthF();
        if (penWidth == 0)
            d->stroker.setStrokeWidth(1);
        else
            d->stroker.setStrokeWidth(penWidth);

        Qt::PenStyle style = pen.style();
        if (style == Qt::SolidLine) {
            d->activeStroker = &d->stroker;
        } else if (style == Qt::NoPen) {
            d->activeStroker = nullptr;
        } else {
            d->dasher.setDashPattern(pen.dashPattern());
            d->dasher.setDashOffset(pen.dashOffset());
            d->activeStroker = &d->dasher;
        }
    }

    if (!d->activeStroker) {
        return;
    }

    if (pen.style() > Qt::SolidLine) {
        if (qt_pen_is_cosmetic(pen, state()->renderHints)){
            d->activeStroker->setClipRect(d->exDeviceRect);
        } else {
            QRectF clipRect = state()->matrix.inverted().mapRect(QRectF(d->exDeviceRect));
            d->activeStroker->setClipRect(clipRect);
        }
    }

    if (d->activeStroker == &d->stroker)
        d->stroker.setForceOpen(path.hasExplicitOpen());

    const QPainterPath::ElementType *types = path.elements();
    const qreal *points = path.points();
    int pointCount = path.elementCount();

    const qreal *lastPoint = points + (pointCount<<1);

    d->strokeHandler->types.reset();
    d->strokeHandler->pts.reset();

    // Some engines might decide to optimize for the non-shape hint later on...
    uint flags = QVectorPath::WindingFill;

    if (path.elementCount() > 2)
        flags |= QVectorPath::NonConvexShapeMask;

    if (d->stroker.capStyle() == Qt::RoundCap || d->stroker.joinStyle() == Qt::RoundJoin)
        flags |= QVectorPath::CurvedShapeMask;

    // ### Perspective Xforms are currently not supported...
    if (!qt_pen_is_cosmetic(pen, state()->renderHints)) {
        // We include cosmetic pens in this case to avoid having to
        // change the current transform. Normal transformed,
        // non-cosmetic pens will be transformed as part of fill
        // later, so they are also covered here..
        d->activeStroker->setCurveThresholdFromTransform(state()->matrix);
        d->activeStroker->begin(d->strokeHandler);
        if (types) {
            while (points < lastPoint) {
                switch (*types) {
                case QPainterPath::MoveToElement:
                    d->activeStroker->moveTo(points[0], points[1]);
                    points += 2;
                    ++types;
                    break;
                case QPainterPath::LineToElement:
                    d->activeStroker->lineTo(points[0], points[1]);
                    points += 2;
                    ++types;
                    break;
                case QPainterPath::CurveToElement:
                    d->activeStroker->cubicTo(points[0], points[1],
                                              points[2], points[3],
                                              points[4], points[5]);
                    points += 6;
                    types += 3;
                    flags |= QVectorPath::CurvedShapeMask;
                    break;
                default:
                    break;
                }
            }
            if (path.hasImplicitClose())
                d->activeStroker->lineTo(path.points()[0], path.points()[1]);

        } else {
            d->activeStroker->moveTo(points[0], points[1]);
            points += 2;
            while (points < lastPoint) {
                d->activeStroker->lineTo(points[0], points[1]);
                points += 2;
            }
            if (path.hasImplicitClose())
                d->activeStroker->lineTo(path.points()[0], path.points()[1]);
        }
        d->activeStroker->end();

        if (!d->strokeHandler->types.size()) // an empty path...
            return;

        QVectorPath strokePath(d->strokeHandler->pts.data(),
                               d->strokeHandler->types.size(),
                               d->strokeHandler->types.data(),
                               flags);
        fill(strokePath, pen.brush());
    } else {
        // For cosmetic pens we need a bit of trickery... We to process xform the input points
        if (state()->matrix.type() >= QTransform::TxProject) {
            QPainterPath painterPath = state()->matrix.map(path.convertToPainterPath());
            d->activeStroker->strokePath(painterPath, d->strokeHandler, QTransform());
        } else {
            d->activeStroker->setCurveThresholdFromTransform(QTransform());
            d->activeStroker->begin(d->strokeHandler);
            if (types) {
                while (points < lastPoint) {
                    switch (*types) {
                    case QPainterPath::MoveToElement: {
                        QPointF pt = (*(const QPointF *) points) * state()->matrix;
                        d->activeStroker->moveTo(pt.x(), pt.y());
                        points += 2;
                        ++types;
                        break;
                    }
                    case QPainterPath::LineToElement: {
                        QPointF pt = (*(const QPointF *) points) * state()->matrix;
                        d->activeStroker->lineTo(pt.x(), pt.y());
                        points += 2;
                        ++types;
                        break;
                    }
                    case QPainterPath::CurveToElement: {
                        QPointF c1 = ((const QPointF *) points)[0] * state()->matrix;
                        QPointF c2 = ((const QPointF *) points)[1] * state()->matrix;
                        QPointF e =  ((const QPointF *) points)[2] * state()->matrix;
                        d->activeStroker->cubicTo(c1.x(), c1.y(), c2.x(), c2.y(), e.x(), e.y());
                        points += 6;
                        types += 3;
                        flags |= QVectorPath::CurvedShapeMask;
                        break;
                    }
                    default:
                        break;
                    }
                }
                if (path.hasImplicitClose()) {
                    QPointF pt = * ((const QPointF *) path.points()) * state()->matrix;
                    d->activeStroker->lineTo(pt.x(), pt.y());
                }

            } else {
                QPointF p = ((const QPointF *)points)[0] * state()->matrix;
                d->activeStroker->moveTo(p.x(), p.y());
                points += 2;
                while (points < lastPoint) {
                    QPointF p = ((const QPointF *)points)[0] * state()->matrix;
                    d->activeStroker->lineTo(p.x(), p.y());
                    points += 2;
                }
                if (path.hasImplicitClose())
                    d->activeStroker->lineTo(p.x(), p.y());
            }
            d->activeStroker->end();
        }

        QVectorPath strokePath(d->strokeHandler->pts.data(),
                               d->strokeHandler->types.size(),
                               d->strokeHandler->types.data(),
                               flags);

        QTransform xform = state()->matrix;
        state()->matrix = QTransform();
        transformChanged();

        QBrush brush = pen.brush();
        if (qbrush_style(brush) != Qt::SolidPattern)
            brush.setTransform(brush.transform() * xform);

        fill(strokePath, brush);

        state()->matrix = xform;
        transformChanged();
    }
}

void QPaintEngineEx::draw(const QVectorPath &path)
{
    const QBrush &brush = state()->brush;
    if (qbrush_style(brush) != Qt::NoBrush)
        fill(path, brush);

    const QPen &pen = state()->pen;
    if (qpen_style(pen) != Qt::NoPen && qbrush_style(qpen_brush(pen)) != Qt::NoBrush)
        stroke(path, pen);
}


void QPaintEngineEx::clip(const QRect &r, Qt::ClipOperation op)
{
    qreal right = r.x() + r.width();
    qreal bottom = r.y() + r.height();
    qreal pts[] = { qreal(r.x()), qreal(r.y()),
                    right, qreal(r.y()),
                    right, bottom,
                    qreal(r.x()), bottom,
                    qreal(r.x()), qreal(r.y()) };
    QVectorPath vp(pts, 5, nullptr, QVectorPath::RectangleHint);
    clip(vp, op);
}

void QPaintEngineEx::clip(const QRegion &region, Qt::ClipOperation op)
{
    const auto rectsInRegion = region.rectCount();
    if (rectsInRegion == 1) {
        clip(*region.begin(), op);
    } else if (rectsInRegion <= 32) {
        qreal pts[2*32*4];
        int pos = 0;
        for (QRect r : region) {
            qreal x1 = r.x();
            qreal y1 = r.y();
            qreal x2 = r.x() + r.width();
            qreal y2 = r.y() + r.height();

            pts[pos++] = x1;
            pts[pos++] = y1;

            pts[pos++] = x2;
            pts[pos++] = y1;

            pts[pos++] = x2;
            pts[pos++] = y2;

            pts[pos++] = x1;
            pts[pos++] = y2;
        }
        QVectorPath vp(pts, rectsInRegion * 4, qpaintengineex_rect4_types_32);
        clip(vp, op);
    } else {
        QVarLengthArray<qreal> pts(rectsInRegion * 2 * 4);
        QVarLengthArray<QPainterPath::ElementType> types(rectsInRegion * 4);
        int ppos = 0;
        int tpos = 0;

        for (QRect r : region) {
            qreal x1 = r.x();
            qreal y1 = r.y();
            qreal x2 = r.x() + r.width();
            qreal y2 = r.y() + r.height();

            pts[ppos++] = x1;
            pts[ppos++] = y1;

            pts[ppos++] = x2;
            pts[ppos++] = y1;

            pts[ppos++] = x2;
            pts[ppos++] = y2;

            pts[ppos++] = x1;
            pts[ppos++] = y2;

            types[tpos++] = QPainterPath::MoveToElement;
            types[tpos++] = QPainterPath::LineToElement;
            types[tpos++] = QPainterPath::LineToElement;
            types[tpos++] = QPainterPath::LineToElement;
        }

        QVectorPath vp(pts.data(), rectsInRegion * 4, types.data());
        clip(vp, op);
    }

}

void QPaintEngineEx::clip(const QPainterPath &path, Qt::ClipOperation op)
{
    if (path.isEmpty()) {
        QVectorPath vp(nullptr, 0);
        clip(vp, op);
    } else {
        clip(qtVectorPathForPath(path), op);
    }
}

void QPaintEngineEx::fillRect(const QRectF &r, const QBrush &brush)
{
    qreal pts[] = { r.x(), r.y(), r.x() + r.width(), r.y(),
                    r.x() + r.width(), r.y() + r.height(), r.x(), r.y() + r.height() };
    QVectorPath vp(pts, 4, nullptr, QVectorPath::RectangleHint);
    fill(vp, brush);
}

void QPaintEngineEx::fillRect(const QRectF &r, const QColor &color)
{
    fillRect(r, QBrush(color));
}

void QPaintEngineEx::drawRects(const QRect *rects, int rectCount)
{
    for (int i=0; i<rectCount; ++i) {
        const QRect &r = rects[i];
        // ### Is there a one off here?
        qreal right = r.x() + r.width();
        qreal bottom = r.y() + r.height();
        qreal pts[] = { qreal(r.x()), qreal(r.y()),
                        right, qreal(r.y()),
                        right, bottom,
                        qreal(r.x()), bottom,
                        qreal(r.x()), qreal(r.y()) };
        QVectorPath vp(pts, 5, nullptr, QVectorPath::RectangleHint);
        draw(vp);
    }
}

void QPaintEngineEx::drawRects(const QRectF *rects, int rectCount)
{
    for (int i=0; i<rectCount; ++i) {
        const QRectF &r = rects[i];
        qreal right = r.x() + r.width();
        qreal bottom = r.y() + r.height();
        qreal pts[] = { r.x(), r.y(),
                        right, r.y(),
                        right, bottom,
                        r.x(), bottom,
                        r.x(), r.y() };
        QVectorPath vp(pts, 5, nullptr, QVectorPath::RectangleHint);
        draw(vp);
    }
}


void QPaintEngineEx::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius,
                                     Qt::SizeMode mode)
{
    qreal x1 = rect.left();
    qreal x2 = rect.right();
    qreal y1 = rect.top();
    qreal y2 = rect.bottom();

    if (mode == Qt::RelativeSize) {
        xRadius = xRadius * rect.width() / 200.;
        yRadius = yRadius * rect.height() / 200.;
    }

    xRadius = qMin(xRadius, rect.width() / 2);
    yRadius = qMin(yRadius, rect.height() / 2);

    qreal pts[] = {
        x1 + xRadius, y1,                   // MoveTo
        x2 - xRadius, y1,                   // LineTo
        x2 - (1 - KAPPA) * xRadius, y1,     // CurveTo
        x2, y1 + (1 - KAPPA) * yRadius,
        x2, y1 + yRadius,
        x2, y2 - yRadius,                   // LineTo
        x2, y2 - (1 - KAPPA) * yRadius,     // CurveTo
        x2 - (1 - KAPPA) * xRadius, y2,
        x2 - xRadius, y2,
        x1 + xRadius, y2,                   // LineTo
        x1 + (1 - KAPPA) * xRadius, y2,           // CurveTo
        x1, y2 - (1 - KAPPA) * yRadius,
        x1, y2 - yRadius,
        x1, y1 + yRadius,                   // LineTo
        x1, y1 + (1 - KAPPA) * yRadius,           // CurveTo
        x1 + (1 - KAPPA) * xRadius, y1,
        x1 + xRadius, y1
    };

    QVectorPath path(pts, 17, qpaintengineex_roundedrect_types, QVectorPath::RoundedRectHint);
    draw(path);
}



void QPaintEngineEx::drawLines(const QLine *lines, int lineCount)
{
    int elementCount = lineCount << 1;
    while (elementCount > 0) {
        int count = qMin(elementCount, 32);

        qreal pts[64];
        int count2 = count<<1;
        for (int i=0; i<count2; ++i)
            pts[i] = ((const int *) lines)[i];

        QVectorPath path(pts, count, qpaintengineex_line_types_16, QVectorPath::LinesHint);
        stroke(path, state()->pen);

        elementCount -= 32;
        lines += 16;
    }
}

void QPaintEngineEx::drawLines(const QLineF *lines, int lineCount)
{
    int elementCount = lineCount << 1;
    while (elementCount > 0) {
        int count = qMin(elementCount, 32);

        QVectorPath path((const qreal *) lines, count, qpaintengineex_line_types_16,
                         QVectorPath::LinesHint);
        stroke(path, state()->pen);

        elementCount -= 32;
        lines += 16;
    }
}

void QPaintEngineEx::drawEllipse(const QRectF &r)
{
    qreal pts[26]; // QPointF[13] without constructors...
    union {
        qreal *ptr;
        QPointF *points;
    } x;
    x.ptr = pts;

    int point_count = 0;
    x.points[0] = qt_curves_for_arc(r, 0, -360, x.points + 1, &point_count);
    if (point_count == 0)
        return;
    QVectorPath vp((qreal *) pts, point_count + 1, qpaintengineex_ellipse_types, QVectorPath::EllipseHint);
    draw(vp);
}

void QPaintEngineEx::drawEllipse(const QRect &r)
{
    drawEllipse(QRectF(r));
}

void QPaintEngineEx::drawPath(const QPainterPath &path)
{
    if (!path.isEmpty())
        draw(qtVectorPathForPath(path));
}


void QPaintEngineEx::drawPoints(const QPointF *points, int pointCount)
{
    QPen pen = state()->pen;
    if (pen.capStyle() == Qt::FlatCap)
        pen.setCapStyle(Qt::SquareCap);

    if (pen.brush().isOpaque()) {
        while (pointCount > 0) {
            int count = qMin(pointCount, 16);
            qreal pts[64];
            int oset = -1;
            for (int i=0; i<count; ++i) {
                pts[++oset] = points[i].x();
                pts[++oset] = points[i].y();
                pts[++oset] = points[i].x() + 1/63.;
                pts[++oset] = points[i].y();
            }
            QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::LinesHint);
            stroke(path, pen);
            pointCount -= 16;
            points += 16;
        }
    } else {
        for (int i=0; i<pointCount; ++i) {
            qreal pts[] = { points[i].x(), points[i].y(), points[i].x() + qreal(1/63.), points[i].y() };
            QVectorPath path(pts, 2, nullptr);
            stroke(path, pen);
        }
    }
}

void QPaintEngineEx::drawPoints(const QPoint *points, int pointCount)
{
    QPen pen = state()->pen;
    if (pen.capStyle() == Qt::FlatCap)
        pen.setCapStyle(Qt::SquareCap);

    if (pen.brush().isOpaque()) {
        while (pointCount > 0) {
            int count = qMin(pointCount, 16);
            qreal pts[64];
            int oset = -1;
            for (int i=0; i<count; ++i) {
                pts[++oset] = points[i].x();
                pts[++oset] = points[i].y();
                pts[++oset] = points[i].x() + 1/63.;
                pts[++oset] = points[i].y();
            }
            QVectorPath path(pts, count * 2, qpaintengineex_line_types_16, QVectorPath::LinesHint);
            stroke(path, pen);
            pointCount -= 16;
            points += 16;
        }
    } else {
        for (int i=0; i<pointCount; ++i) {
            qreal pts[] = { qreal(points[i].x()), qreal(points[i].y()),
                            qreal(points[i].x() +1/63.), qreal(points[i].y()) };
            QVectorPath path(pts, 2, nullptr);
            stroke(path, pen);
        }
    }
}


void QPaintEngineEx::drawPolygon(const QPointF *points, int pointCount, PolygonDrawMode mode)
{
    QVectorPath path((const qreal *) points, pointCount, nullptr, QVectorPath::polygonFlags(mode));

    if (mode == PolylineMode)
        stroke(path, state()->pen);
    else
        draw(path);
}

void QPaintEngineEx::drawPolygon(const QPoint *points, int pointCount, PolygonDrawMode mode)
{
    int count = pointCount<<1;
    QVarLengthArray<qreal> pts(count);

    for (int i=0; i<count; ++i)
        pts[i] = ((const int *) points)[i];

    QVectorPath path(pts.data(), pointCount, nullptr, QVectorPath::polygonFlags(mode));

    if (mode == PolylineMode)
        stroke(path, state()->pen);
    else
        draw(path);

}

void QPaintEngineEx::drawPixmap(const QPointF &pos, const QPixmap &pm)
{
    drawPixmap(QRectF(pos, pm.size() / pm.devicePixelRatio()), pm, pm.rect());
}

void QPaintEngineEx::drawImage(const QPointF &pos, const QImage &image)
{
    drawImage(QRectF(pos, image.size() / image.devicePixelRatio()), image, image.rect());
}

void QPaintEngineEx::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &s)
{
    QBrush brush(state()->pen.color(), pixmap);
    QTransform xform = QTransform::fromTranslate(r.x() - s.x(), r.y() - s.y());
    if (!qFuzzyCompare(pixmap.devicePixelRatioF(), 1.0))
        xform.scale(1.0/pixmap.devicePixelRatioF(), 1.0/pixmap.devicePixelRatioF());
    brush.setTransform(xform);

    qreal pts[] = { r.x(), r.y(),
                    r.x() + r.width(), r.y(),
                    r.x() + r.width(), r.y() + r.height(),
                    r.x(), r.y() + r.height() };

    QVectorPath path(pts, 4, nullptr, QVectorPath::RectangleHint);
    fill(path, brush);
}

void QPaintEngineEx::drawPixmapFragments(const QPainter::PixmapFragment *fragments, int fragmentCount,
                                         const QPixmap &pixmap, QPainter::PixmapFragmentHints /*hints*/)
{
    if (pixmap.isNull())
        return;

    qreal oldOpacity = state()->opacity;
    QTransform oldTransform = state()->matrix;

    for (int i = 0; i < fragmentCount; ++i) {
        QTransform transform = oldTransform;
        transform.translate(fragments[i].x, fragments[i].y);
        transform.rotate(fragments[i].rotation);
        state()->opacity = oldOpacity * fragments[i].opacity;
        state()->matrix = transform;
        opacityChanged();
        transformChanged();

        qreal w = fragments[i].scaleX * fragments[i].width;
        qreal h = fragments[i].scaleY * fragments[i].height;
        QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop,
                          fragments[i].width, fragments[i].height);
        drawPixmap(QRectF(-0.5 * w, -0.5 * h, w, h), pixmap, sourceRect);
    }

    state()->opacity = oldOpacity;
    state()->matrix = oldTransform;
    opacityChanged();
    transformChanged();
}

void QPaintEngineEx::setState(QPainterState *s)
{
    QPaintEngine::state = s;
}


void QPaintEngineEx::updateState(const QPaintEngineState &)
{
    // do nothing...
}

Q_GUI_EXPORT QPainterPath qt_painterPathFromVectorPath(const QVectorPath &path)
{
    const qreal *points = path.points();
    const QPainterPath::ElementType *types = path.elements();

    QPainterPath p;
    if (types) {
        int id = 0;
        for (int i=0; i<path.elementCount(); ++i) {
            switch(types[i]) {
            case QPainterPath::MoveToElement:
                p.moveTo(QPointF(points[id], points[id+1]));
                id+=2;
                break;
            case QPainterPath::LineToElement:
                p.lineTo(QPointF(points[id], points[id+1]));
                id+=2;
                break;
            case QPainterPath::CurveToElement: {
                QPointF p1(points[id], points[id+1]);
                QPointF p2(points[id+2], points[id+3]);
                QPointF p3(points[id+4], points[id+5]);
                p.cubicTo(p1, p2, p3);
                id+=6;
                break;
            }
            case QPainterPath::CurveToDataElement:
                ;
                break;
            }
        }
    } else {
        p.moveTo(QPointF(points[0], points[1]));
        int id = 2;
        for (int i=1; i<path.elementCount(); ++i) {
            p.lineTo(QPointF(points[id], points[id+1]));
            id+=2;
        }
    }
    if (path.hints() & QVectorPath::WindingFill)
        p.setFillRule(Qt::WindingFill);

    return p;
}

void QPaintEngineEx::drawStaticTextItem(QStaticTextItem *staticTextItem)
{
    QPainterPath path;
    path.setFillRule(Qt::WindingFill);

    if (staticTextItem->numGlyphs == 0)
        return;

    QFontEngine *fontEngine = staticTextItem->fontEngine();
    fontEngine->addGlyphsToPath(staticTextItem->glyphs, staticTextItem->glyphPositions,
                                staticTextItem->numGlyphs, &path, { });
    if (!path.isEmpty()) {
        QPainterState *s = state();
        QPainter::RenderHints oldHints = s->renderHints;
        bool changedHints = false;
        if (bool(oldHints & QPainter::TextAntialiasing)
            && !bool(fontEngine->fontDef.styleStrategy & QFont::NoAntialias)
            && !bool(oldHints & QPainter::Antialiasing)) {
            s->renderHints |= QPainter::Antialiasing;
            renderHintsChanged();
            changedHints = true;
        }

        fill(qtVectorPathForPath(path), s->pen.brush());

        if (changedHints) {
            s->renderHints = oldHints;
            renderHintsChanged();
        }
    }
}

bool QPaintEngineEx::requiresPretransformedGlyphPositions(QFontEngine *, const QTransform &) const
{
    return false;
}

bool QPaintEngineEx::shouldDrawCachedGlyphs(QFontEngine *fontEngine, const QTransform &m) const
{
    if (fontEngine->glyphFormat == QFontEngine::Format_ARGB)
        return true;

    static const int maxCachedGlyphSizeSquared = std::pow([]{
        if (int env = qEnvironmentVariableIntValue("QT_MAX_CACHED_GLYPH_SIZE"))
            return env;
        return QT_MAX_CACHED_GLYPH_SIZE;
    }(), 2);

    qreal pixelSize = fontEngine->fontDef.pixelSize;
    return (pixelSize * pixelSize * qAbs(m.determinant())) <= maxCachedGlyphSizeSquared;
}

QT_END_NAMESPACE
