/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtGui module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

// QtCore
#include <qdebug.h>
#include <qmath.h>
#include <qmutex.h>

// QtGui
#include "qbitmap.h"
#include "qimage.h"
#include "qpaintdevice.h"
#include "qpaintengine.h"
#include "qpainter.h"
#include "qpainter_p.h"
#include "qpainterpath.h"
#include "qpicture.h"
#include "qpixmapcache.h"
#include "qpolygon.h"
#include "qtextlayout.h"
#include "qwidget.h"
#include "qapplication.h"
#include "qstyle.h"
#include "qthread.h"
#include "qvarlengtharray.h"

#include <private/qfontengine_p.h>
#include <private/qpaintengine_p.h>
#include <private/qemulationpaintengine_p.h>
#include <private/qpainterpath_p.h>
#include <private/qtextengine_p.h>
#include <private/qwidget_p.h>
#include <private/qpaintengine_raster_p.h>
#include <private/qmath_p.h>
#include <qstatictext.h>
#include <private/qstatictext_p.h>
#include <private/qstylehelper_p.h>

QT_BEGIN_NAMESPACE

#define QGradient_StretchToDevice 0x10000000
#define QPaintEngine_OpaqueBackground 0x40000000

// #define QT_DEBUG_DRAW
#ifdef QT_DEBUG_DRAW
bool qt_show_painter_debug_output = true;
#endif

extern QPixmap qt_pixmapForBrush(int style, bool invert);

void qt_format_text(const QFont &font,
                    const QRectF &_r, int tf, const QTextOption *option, const QString& str, QRectF *brect,
                    int tabstops, int* tabarray, int tabarraylen,
                    QPainter *painter);
static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe,
                                   QTextCharFormat::UnderlineStyle underlineStyle,
                                   const QTextItem::RenderFlags flags, qreal width,
                                   const QTextCharFormat &charFormat);
// Helper function to calculate left most position, width and flags for decoration drawing
Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray,
                                                const QFixedPoint *positions, int glyphCount,
                                                QFontEngine *fontEngine, const QFont &font,
                                                const QTextCharFormat &charFormat);

static inline QGradient::CoordinateMode coordinateMode(const QBrush &brush)
{
    switch (brush.style()) {
    case Qt::LinearGradientPattern:
    case Qt::RadialGradientPattern:
    case Qt::ConicalGradientPattern:
        return brush.gradient()->coordinateMode();
    default:
        ;
    }
    return QGradient::LogicalMode;
}

/* Returns true if the gradient requires stretch to device...*/
static inline bool check_gradient(const QBrush &brush)
{
    return coordinateMode(brush) == QGradient::StretchToDeviceMode;
}

extern bool qHasPixmapTexture(const QBrush &);

static inline bool is_brush_transparent(const QBrush &brush) {
    Qt::BrushStyle s = brush.style();
    bool brushBitmap = qHasPixmapTexture(brush)
                       ? brush.texture().isQBitmap()
                       : (brush.textureImage().depth() == 1);
    return ((s >= Qt::Dense1Pattern && s <= Qt::DiagCrossPattern)
            || (s == Qt::TexturePattern && brushBitmap));
}

static inline bool is_pen_transparent(const QPen &pen) {
    return pen.style() > Qt::SolidLine || is_brush_transparent(pen.brush());
}

/* Discards the emulation flags that are not relevant for line drawing
   and returns the result
*/
static inline uint line_emulation(uint emulation)
{
    return emulation & (QPaintEngine::PrimitiveTransform
                        | QPaintEngine::AlphaBlend
                        | QPaintEngine::Antialiasing
                        | QPaintEngine::BrushStroke
                        | QPaintEngine::ConstantOpacity
                        | QGradient_StretchToDevice
                        | QPaintEngine::ObjectBoundingModeGradients
                        | QPaintEngine_OpaqueBackground);
}

#ifndef QT_NO_DEBUG
static bool qt_painter_thread_test(int devType, const char *what, bool extraCondition = false)
{
    switch (devType) {
    case QInternal::Image:
    case QInternal::Printer:
    case QInternal::Picture:
        // can be drawn onto these devices safely from any thread
#ifndef Q_WS_WIN
        if (extraCondition)
#endif
            break;
    default:
        if (!extraCondition && QThread::currentThread() != qApp->thread()) {
            qWarning("QPainter: It is not safe to use %s outside the GUI thread", what);
            return false;
        }
        break;
    }
    return true;
}
#endif

void QPainterPrivate::checkEmulation()
{
    Q_ASSERT(extended);
    if (extended->flags() & QPaintEngineEx::DoNotEmulate)
        return;

    bool doEmulation = false;
    if (state->bgMode == Qt::OpaqueMode)
        doEmulation = true;

    const QGradient *bg = state->brush.gradient();
    if (bg && bg->coordinateMode() > QGradient::LogicalMode)
        doEmulation = true;

    const QGradient *pg = qpen_brush(state->pen).gradient();
    if (pg && pg->coordinateMode() > QGradient::LogicalMode)
        doEmulation = true;

    if (doEmulation) {
        if (extended != emulationEngine) {
            if (!emulationEngine)
                emulationEngine = new QEmulationPaintEngine(extended);
            extended = emulationEngine;
            extended->setState(state);
        }
    } else if (emulationEngine == extended) {
        extended = emulationEngine->real_engine;
    }
}


QPainterPrivate::~QPainterPrivate()
{
    delete emulationEngine;
    for (int i=0; i<states.size(); ++i)
        delete states.at(i);

    if (dummyState)
        delete dummyState;
}


QTransform QPainterPrivate::viewTransform() const
{
    if (state->VxF) {
        qreal scaleW = qreal(state->vw)/qreal(state->ww);
        qreal scaleH = qreal(state->vh)/qreal(state->wh);
        return QTransform(scaleW, 0, 0, scaleH,
                          state->vx - state->wx*scaleW, state->vy - state->wy*scaleH);
    }
    return QTransform();
}


/*
   \internal
   Returns true if using a shared painter; otherwise false.
*/
bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev)
{
    Q_ASSERT(q);
    Q_ASSERT(pdev);

    if (pdev->devType() != QInternal::Widget)
        return false;

    QWidget *widget = static_cast<QWidget *>(pdev);
    Q_ASSERT(widget);

    // Someone either called QPainter::setRedirected in the widget's paint event
    // right before this painter was created (or begin was called) or
    // sent a paint event directly to the widget.
    if (!widget->d_func()->redirectDev)
        return false;

    QPainter *sp = widget->d_func()->sharedPainter();
    if (!sp || !sp->isActive())
        return false;

    if (sp->paintEngine()->paintDevice() != widget->d_func()->redirectDev)
        return false;

    // Check if we're attempting to paint outside a paint event.
    if (!sp->d_ptr->engine->hasFeature(QPaintEngine::PaintOutsidePaintEvent)
        && !widget->testAttribute(Qt::WA_PaintOutsidePaintEvent)
        && !widget->testAttribute(Qt::WA_WState_InPaintEvent)) {

        qWarning("QPainter::begin: Widget painting can only begin as a result of a paintEvent");
        return false;
    }

    // Save the current state of the shared painter and assign
    // the current d_ptr to the shared painter's d_ptr.
    sp->save();
    if (!sp->d_ptr->d_ptrs) {
        // Allocate space for 4 d-pointers (enough for up to 4 sub-sequent
        // redirections within the same paintEvent(), which should be enough
        // in 99% of all cases). E.g: A renders B which renders C which renders D.
        sp->d_ptr->d_ptrs_size = 4;
        sp->d_ptr->d_ptrs = (QPainterPrivate **)malloc(4 * sizeof(QPainterPrivate *));
        Q_CHECK_PTR(sp->d_ptr->d_ptrs);
    } else if (sp->d_ptr->refcount - 1 == sp->d_ptr->d_ptrs_size) {
        // However, to support corner cases we grow the array dynamically if needed.
        sp->d_ptr->d_ptrs_size <<= 1;
        const int newSize = sp->d_ptr->d_ptrs_size * sizeof(QPainterPrivate *);
        sp->d_ptr->d_ptrs = q_check_ptr((QPainterPrivate **)realloc(sp->d_ptr->d_ptrs, newSize));
    }
    sp->d_ptr->d_ptrs[++sp->d_ptr->refcount - 2] = q->d_ptr.data();
    q->d_ptr.take();
    q->d_ptr.reset(sp->d_ptr.data());

    Q_ASSERT(q->d_ptr->state);

    // Now initialize the painter with correct widget properties.
    q->initFrom(widget);
    QPoint offset;
    widget->d_func()->redirected(&offset);
    offset += q->d_ptr->engine->coordinateOffset();

    // Update system rect.
    q->d_ptr->state->ww = q->d_ptr->state->vw = widget->width();
    q->d_ptr->state->wh = q->d_ptr->state->vh = widget->height();

    // Update matrix.
    if (q->d_ptr->state->WxF) {
        q->d_ptr->state->redirectionMatrix = q->d_ptr->state->matrix;
        q->d_ptr->state->redirectionMatrix.translate(-offset.x(), -offset.y());
        q->d_ptr->state->worldMatrix = QTransform();
        q->d_ptr->state->WxF = false;
    } else {
        q->d_ptr->state->redirectionMatrix = QTransform::fromTranslate(-offset.x(), -offset.y());
    }
    q->d_ptr->updateMatrix();

    QPaintEnginePrivate *enginePrivate = q->d_ptr->engine->d_func();
    if (enginePrivate->currentClipWidget == widget) {
        enginePrivate->systemStateChanged();
        return true;
    }

    // Update system transform and clip.
    enginePrivate->currentClipWidget = widget;
    enginePrivate->setSystemTransform(q->d_ptr->state->matrix);
    return true;
}

void QPainterPrivate::detachPainterPrivate(QPainter *q)
{
    Q_ASSERT(refcount > 1);
    Q_ASSERT(q);

    QPainterPrivate *original = d_ptrs[--refcount - 1];
    if (inDestructor) {
        inDestructor = false;
        if (original)
            original->inDestructor = true;
    } else if (!original) {
        original = new QPainterPrivate(q);
    }

    d_ptrs[refcount - 1] = 0;
    q->restore();
    q->d_ptr.take();
    q->d_ptr.reset(original);

    if (emulationEngine) {
        extended = emulationEngine->real_engine;
        delete emulationEngine;
        emulationEngine = 0;
    }
}


void QPainterPrivate::draw_helper(const QPainterPath &originalPath, DrawOperation op)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output) {
        printf("QPainter::drawHelper\n");
    }
#endif

    if (originalPath.isEmpty())
        return;

    QPaintEngine::PaintEngineFeatures gradientStretch =
        QPaintEngine::PaintEngineFeatures(QGradient_StretchToDevice
                                          | QPaintEngine::ObjectBoundingModeGradients);

    const bool mustEmulateObjectBoundingModeGradients = extended
                                                        || ((state->emulationSpecifier & QPaintEngine::ObjectBoundingModeGradients)
                                                            && !engine->hasFeature(QPaintEngine::PatternTransform));

    if (!(state->emulationSpecifier & ~gradientStretch)
        && !mustEmulateObjectBoundingModeGradients) {
        drawStretchedGradient(originalPath, op);
        return;
    } else if (state->emulationSpecifier & QPaintEngine_OpaqueBackground) {
        drawOpaqueBackground(originalPath, op);
        return;
    }

    Q_Q(QPainter);

    qreal strokeOffsetX = 0, strokeOffsetY = 0;

    QPainterPath path = originalPath * state->matrix;
    QRectF pathBounds = path.boundingRect();
    QRectF strokeBounds;
    bool doStroke = (op & StrokeDraw) && (state->pen.style() != Qt::NoPen);
    if (doStroke) {
        qreal penWidth = state->pen.widthF();
        if (penWidth == 0) {
            strokeOffsetX = 1;
            strokeOffsetY = 1;
        } else {
            // In case of complex xform
            if (state->matrix.type() > QTransform::TxScale) {
                QPainterPathStroker stroker;
                stroker.setWidth(penWidth);
                stroker.setJoinStyle(state->pen.joinStyle());
                stroker.setCapStyle(state->pen.capStyle());
                QPainterPath stroke = stroker.createStroke(originalPath);
                strokeBounds = (stroke * state->matrix).boundingRect();
            } else {
                strokeOffsetX = qAbs(penWidth * state->matrix.m11() / 2.0);
                strokeOffsetY = qAbs(penWidth * state->matrix.m22() / 2.0);
            }
        }
    }

    QRect absPathRect;
    if (!strokeBounds.isEmpty()) {
        absPathRect = strokeBounds.intersected(QRectF(0, 0, device->width(), device->height())).toAlignedRect();
    } else {
        absPathRect = pathBounds.adjusted(-strokeOffsetX, -strokeOffsetY, strokeOffsetX, strokeOffsetY)
            .intersected(QRectF(0, 0, device->width(), device->height())).toAlignedRect();
    }

    if (q->hasClipping()) {
        bool hasPerspectiveTransform = false;
        for (int i = 0; i < state->clipInfo.size(); ++i) {
            const QPainterClipInfo &info = state->clipInfo.at(i);
            if (info.matrix.type() == QTransform::TxProject) {
                hasPerspectiveTransform = true;
                break;
            }
        }
        // avoid mapping QRegions with perspective transforms
        if (!hasPerspectiveTransform) {
            // The trick with txinv and invMatrix is done in order to
            // avoid transforming the clip to logical coordinates, and
            // then back to device coordinates. This is a problem with
            // QRegion/QRect based clips, since they use integer
            // coordinates and converting to/from logical coordinates will
            // lose precision.
            bool old_txinv = txinv;
            QTransform old_invMatrix = invMatrix;
            txinv = true;
            invMatrix = QTransform();
            QPainterPath clipPath = q->clipPath();
            QRectF r = clipPath.boundingRect().intersected(absPathRect);
            absPathRect = r.toAlignedRect();
            txinv = old_txinv;
            invMatrix = old_invMatrix;
        }
    }

//     qDebug("\nQPainterPrivate::draw_helper(), x=%d, y=%d, w=%d, h=%d",
//            devMinX, devMinY, device->width(), device->height());
//     qDebug() << " - matrix" << state->matrix;
//     qDebug() << " - originalPath.bounds" << originalPath.boundingRect();
//     qDebug() << " - path.bounds" << path.boundingRect();

    if (absPathRect.width() <= 0 || absPathRect.height() <= 0)
        return;

    QImage image(absPathRect.width(), absPathRect.height(), QImage::Format_ARGB32_Premultiplied);
    image.fill(0);

    QPainter p(&image);

    p.d_ptr->helper_device = helper_device;

    p.setOpacity(state->opacity);
    p.translate(-absPathRect.x(), -absPathRect.y());
    p.setTransform(state->matrix, true);
    p.setPen(doStroke ? state->pen : QPen(Qt::NoPen));
    p.setBrush((op & FillDraw) ? state->brush : QBrush(Qt::NoBrush));
    p.setBackground(state->bgBrush);
    p.setBackgroundMode(state->bgMode);
    p.setBrushOrigin(state->brushOrigin);

    p.setRenderHint(QPainter::Antialiasing, state->renderHints & QPainter::Antialiasing);
    p.setRenderHint(QPainter::SmoothPixmapTransform,
                    state->renderHints & QPainter::SmoothPixmapTransform);

    p.drawPath(originalPath);

#ifndef QT_NO_DEBUG
    static bool do_fallback_overlay = qgetenv("QT_PAINT_FALLBACK_OVERLAY").size() > 0;
    if (do_fallback_overlay) {
        QImage block(8, 8, QImage::Format_ARGB32_Premultiplied);
        QPainter pt(&block);
        pt.fillRect(0, 0, 8, 8, QColor(196, 0, 196));
        pt.drawLine(0, 0, 8, 8);
        pt.end();
        p.resetTransform();
        p.setCompositionMode(QPainter::CompositionMode_SourceAtop);
        p.setOpacity(0.5);
        p.fillRect(0, 0, image.width(), image.height(), QBrush(block));
    }
#endif

    p.end();

    q->save();
    state->matrix = QTransform();
    state->dirtyFlags |= QPaintEngine::DirtyTransform;
    updateState(state);
    engine->drawImage(absPathRect,
                 image,
                 QRectF(0, 0, absPathRect.width(), absPathRect.height()),
                 Qt::OrderedDither | Qt::OrderedAlphaDither);
    q->restore();
}

void QPainterPrivate::drawOpaqueBackground(const QPainterPath &path, DrawOperation op)
{
    Q_Q(QPainter);

    q->setBackgroundMode(Qt::TransparentMode);

    if (op & FillDraw && state->brush.style() != Qt::NoBrush) {
        q->fillPath(path, state->bgBrush.color());
        q->fillPath(path, state->brush);
    }

    if (op & StrokeDraw && state->pen.style() != Qt::NoPen) {
        q->strokePath(path, QPen(state->bgBrush.color(), state->pen.width()));
        q->strokePath(path, state->pen);
    }

    q->setBackgroundMode(Qt::OpaqueMode);
}

static inline QBrush stretchGradientToUserSpace(const QBrush &brush, const QRectF &boundingRect)
{
    Q_ASSERT(brush.style() >= Qt::LinearGradientPattern
             && brush.style() <= Qt::ConicalGradientPattern);

    QTransform gradientToUser(boundingRect.width(), 0, 0, boundingRect.height(),
                              boundingRect.x(), boundingRect.y());

    QGradient g = *brush.gradient();
    g.setCoordinateMode(QGradient::LogicalMode);

    QBrush b(g);
    b.setTransform(gradientToUser * b.transform());
    return b;
}

void QPainterPrivate::drawStretchedGradient(const QPainterPath &path, DrawOperation op)
{
    Q_Q(QPainter);

    const qreal sw = helper_device->width();
    const qreal sh = helper_device->height();

    bool changedPen = false;
    bool changedBrush = false;
    bool needsFill = false;

    const QPen pen = state->pen;
    const QBrush brush = state->brush;

    const QGradient::CoordinateMode penMode = coordinateMode(pen.brush());
    const QGradient::CoordinateMode brushMode = coordinateMode(brush);

    QRectF boundingRect;

    // Draw the xformed fill if the brush is a stretch gradient.
    if ((op & FillDraw) && brush.style() != Qt::NoBrush) {
        if (brushMode == QGradient::StretchToDeviceMode) {
            q->setPen(Qt::NoPen);
            changedPen = pen.style() != Qt::NoPen;
            q->scale(sw, sh);
            updateState(state);

            const qreal isw = 1.0 / sw;
            const qreal ish = 1.0 / sh;
            QTransform inv(isw, 0, 0, ish, 0, 0);
            engine->drawPath(path * inv);
            q->scale(isw, ish);
        } else {
            needsFill = true;

            if (brushMode == QGradient::ObjectBoundingMode) {
                Q_ASSERT(engine->hasFeature(QPaintEngine::PatternTransform));
                boundingRect = path.boundingRect();
                q->setBrush(stretchGradientToUserSpace(brush, boundingRect));
                changedBrush = true;
            }
        }
    }

    if ((op & StrokeDraw) && pen.style() != Qt::NoPen) {
        // Draw the xformed outline if the pen is a stretch gradient.
        if (penMode == QGradient::StretchToDeviceMode) {
            q->setPen(Qt::NoPen);
            changedPen = true;

            if (needsFill) {
                updateState(state);
                engine->drawPath(path);
            }

            q->scale(sw, sh);
            q->setBrush(pen.brush());
            changedBrush = true;
            updateState(state);

            QPainterPathStroker stroker;
            stroker.setDashPattern(pen.style());
            stroker.setWidth(pen.widthF());
            stroker.setJoinStyle(pen.joinStyle());
            stroker.setCapStyle(pen.capStyle());
            stroker.setMiterLimit(pen.miterLimit());
            QPainterPath stroke = stroker.createStroke(path);

            const qreal isw = 1.0 / sw;
            const qreal ish = 1.0 / sh;
            QTransform inv(isw, 0, 0, ish, 0, 0);
            engine->drawPath(stroke * inv);
            q->scale(isw, ish);
        } else {
            if (!needsFill && brush.style() != Qt::NoBrush) {
                q->setBrush(Qt::NoBrush);
                changedBrush = true;
            }

            if (penMode == QGradient::ObjectBoundingMode) {
                Q_ASSERT(engine->hasFeature(QPaintEngine::PatternTransform));

                // avoid computing the bounding rect twice
                if (!needsFill || brushMode != QGradient::ObjectBoundingMode)
                    boundingRect = path.boundingRect();

                QPen p = pen;
                p.setBrush(stretchGradientToUserSpace(pen.brush(), boundingRect));
                q->setPen(p);
                changedPen = true;
            } else if (changedPen) {
                q->setPen(pen);
                changedPen = false;
            }

            updateState(state);
            engine->drawPath(path);
        }
    } else if (needsFill) {
        if (pen.style() != Qt::NoPen) {
            q->setPen(Qt::NoPen);
            changedPen = true;
        }

        updateState(state);
        engine->drawPath(path);
    }

    if (changedPen)
        q->setPen(pen);
    if (changedBrush)
        q->setBrush(brush);
}


void QPainterPrivate::updateMatrix()
{
    state->matrix = state->WxF ? state->worldMatrix : QTransform();
    if (state->VxF)
        state->matrix *= viewTransform();

    txinv = false;                                // no inverted matrix
    state->matrix *= state->redirectionMatrix;
    if (extended)
        extended->transformChanged();
    else
        state->dirtyFlags |= QPaintEngine::DirtyTransform;

//     printf("VxF=%d, WxF=%d\n", state->VxF, state->WxF);
//     qDebug() << " --- using matrix" << state->matrix << redirection_offset;
}

/*! \internal */
void QPainterPrivate::updateInvMatrix()
{
    Q_ASSERT(txinv == false);
    txinv = true;                                // creating inverted matrix
    invMatrix = state->matrix.inverted();
}

void QPainterPrivate::updateEmulationSpecifier(QPainterState *s)
{
    bool alpha = false;
    bool linearGradient = false;
    bool radialGradient = false;
    bool conicalGradient = false;
    bool patternBrush = false;
    bool xform = false;
    bool complexXform = false;

    bool skip = true;

    // Pen and brush properties (we have to check both if one changes because the
    // one that's unchanged can still be in a state which requires emulation)
    if (s->state() & (QPaintEngine::DirtyPen | QPaintEngine::DirtyBrush | QPaintEngine::DirtyHints)) {
        // Check Brush stroke emulation
        if (!s->pen.isSolid() && !engine->hasFeature(QPaintEngine::BrushStroke))
            s->emulationSpecifier |= QPaintEngine::BrushStroke;
        else
            s->emulationSpecifier &= ~QPaintEngine::BrushStroke;

        skip = false;

        QBrush penBrush = (qpen_style(s->pen) == Qt::NoPen) ? QBrush(Qt::NoBrush) : qpen_brush(s->pen);
        Qt::BrushStyle brushStyle = qbrush_style(s->brush);
        Qt::BrushStyle penBrushStyle = qbrush_style(penBrush);
        alpha = (penBrushStyle != Qt::NoBrush
                 && (penBrushStyle < Qt::LinearGradientPattern && penBrush.color().alpha() != 255)
                 && !penBrush.isOpaque())
                || (brushStyle != Qt::NoBrush
                    && (brushStyle < Qt::LinearGradientPattern && s->brush.color().alpha() != 255)
                    && !s->brush.isOpaque());
        linearGradient = ((penBrushStyle == Qt::LinearGradientPattern) ||
                           (brushStyle == Qt::LinearGradientPattern));
        radialGradient = ((penBrushStyle == Qt::RadialGradientPattern) ||
                           (brushStyle == Qt::RadialGradientPattern));
        conicalGradient = ((penBrushStyle == Qt::ConicalGradientPattern) ||
                            (brushStyle == Qt::ConicalGradientPattern));
        patternBrush = (((penBrushStyle > Qt::SolidPattern
                           && penBrushStyle < Qt::LinearGradientPattern)
                          || penBrushStyle == Qt::TexturePattern) ||
                         ((brushStyle > Qt::SolidPattern
                           && brushStyle < Qt::LinearGradientPattern)
                          || brushStyle == Qt::TexturePattern));

        bool penTextureAlpha = false;
        if (penBrush.style() == Qt::TexturePattern)
            penTextureAlpha = qHasPixmapTexture(penBrush)
                              ? (penBrush.texture().depth() > 1) && penBrush.texture().hasAlpha()
                              : penBrush.textureImage().hasAlphaChannel();
        bool brushTextureAlpha = false;
        if (s->brush.style() == Qt::TexturePattern) {
            brushTextureAlpha = qHasPixmapTexture(s->brush)
                                ? (s->brush.texture().depth() > 1) && s->brush.texture().hasAlpha()
                                : s->brush.textureImage().hasAlphaChannel();
        }
        if (((penBrush.style() == Qt::TexturePattern && penTextureAlpha)
             || (s->brush.style() == Qt::TexturePattern && brushTextureAlpha))
            && !engine->hasFeature(QPaintEngine::MaskedBrush))
            s->emulationSpecifier |= QPaintEngine::MaskedBrush;
        else
            s->emulationSpecifier &= ~QPaintEngine::MaskedBrush;
    }

    if (s->state() & (QPaintEngine::DirtyHints
                      | QPaintEngine::DirtyOpacity
                      | QPaintEngine::DirtyBackgroundMode)) {
        skip = false;
    }

    if (skip)
        return;

#if 0
    qDebug("QPainterPrivate::updateEmulationSpecifier, state=%p\n"
           " - alpha: %d\n"
           " - linearGradient: %d\n"
           " - radialGradient: %d\n"
           " - conicalGradient: %d\n"
           " - patternBrush: %d\n"
           " - hints: %x\n"
           " - xform: %d\n",
           s,
           alpha,
           linearGradient,
           radialGradient,
           conicalGradient,
           patternBrush,
           uint(s->renderHints),
           xform);
#endif

    // XForm properties
    if (s->state() & QPaintEngine::DirtyTransform) {
        xform = !s->matrix.isIdentity();
        complexXform = !s->matrix.isAffine();
    } else if (s->matrix.type() >= QTransform::TxTranslate) {
        xform = true;
        complexXform = !s->matrix.isAffine();
    }

    const bool brushXform = (!s->brush.transform().type() == QTransform::TxNone);
    const bool penXform = (!s->pen.brush().transform().type() == QTransform::TxNone);

    const bool patternXform = patternBrush && (xform || brushXform || penXform);

    // Check alphablending
    if (alpha && !engine->hasFeature(QPaintEngine::AlphaBlend))
        s->emulationSpecifier |= QPaintEngine::AlphaBlend;
    else
        s->emulationSpecifier &= ~QPaintEngine::AlphaBlend;

    // Linear gradient emulation
    if (linearGradient && !engine->hasFeature(QPaintEngine::LinearGradientFill))
        s->emulationSpecifier |= QPaintEngine::LinearGradientFill;
    else
        s->emulationSpecifier &= ~QPaintEngine::LinearGradientFill;

    // Radial gradient emulation
    if (radialGradient && !engine->hasFeature(QPaintEngine::RadialGradientFill))
        s->emulationSpecifier |= QPaintEngine::RadialGradientFill;
    else
        s->emulationSpecifier &= ~QPaintEngine::RadialGradientFill;

    // Conical gradient emulation
    if (conicalGradient && !engine->hasFeature(QPaintEngine::ConicalGradientFill))
        s->emulationSpecifier |= QPaintEngine::ConicalGradientFill;
    else
        s->emulationSpecifier &= ~QPaintEngine::ConicalGradientFill;

    // Pattern brushes
    if (patternBrush && !engine->hasFeature(QPaintEngine::PatternBrush))
        s->emulationSpecifier |= QPaintEngine::PatternBrush;
    else
        s->emulationSpecifier &= ~QPaintEngine::PatternBrush;

    // Pattern XForms
    if (patternXform && !engine->hasFeature(QPaintEngine::PatternTransform))
        s->emulationSpecifier |= QPaintEngine::PatternTransform;
    else
        s->emulationSpecifier &= ~QPaintEngine::PatternTransform;

    // Primitive XForms
    if (xform && !engine->hasFeature(QPaintEngine::PrimitiveTransform))
        s->emulationSpecifier |= QPaintEngine::PrimitiveTransform;
    else
        s->emulationSpecifier &= ~QPaintEngine::PrimitiveTransform;

    // Perspective XForms
    if (complexXform && !engine->hasFeature(QPaintEngine::PerspectiveTransform))
        s->emulationSpecifier |= QPaintEngine::PerspectiveTransform;
    else
        s->emulationSpecifier &= ~QPaintEngine::PerspectiveTransform;

    // Constant opacity
    if (state->opacity != 1 && !engine->hasFeature(QPaintEngine::ConstantOpacity))
        s->emulationSpecifier |= QPaintEngine::ConstantOpacity;
    else
        s->emulationSpecifier &= ~QPaintEngine::ConstantOpacity;

    bool gradientStretch = false;
    bool objectBoundingMode = false;
    if (linearGradient || conicalGradient || radialGradient) {
        QGradient::CoordinateMode brushMode = coordinateMode(s->brush);
        QGradient::CoordinateMode penMode = coordinateMode(s->pen.brush());

        gradientStretch |= (brushMode == QGradient::StretchToDeviceMode);
        gradientStretch |= (penMode == QGradient::StretchToDeviceMode);

        objectBoundingMode |= (brushMode == QGradient::ObjectBoundingMode);
        objectBoundingMode |= (penMode == QGradient::ObjectBoundingMode);
    }
    if (gradientStretch)
        s->emulationSpecifier |= QGradient_StretchToDevice;
    else
        s->emulationSpecifier &= ~QGradient_StretchToDevice;

    if (objectBoundingMode && !engine->hasFeature(QPaintEngine::ObjectBoundingModeGradients))
        s->emulationSpecifier |= QPaintEngine::ObjectBoundingModeGradients;
    else
        s->emulationSpecifier &= ~QPaintEngine::ObjectBoundingModeGradients;

    // Opaque backgrounds...
    if (s->bgMode == Qt::OpaqueMode &&
        (is_pen_transparent(s->pen) || is_brush_transparent(s->brush)))
        s->emulationSpecifier |= QPaintEngine_OpaqueBackground;
    else
        s->emulationSpecifier &= ~QPaintEngine_OpaqueBackground;

#if 0
    //won't be correct either way because the device can already have
    // something rendered to it in which case subsequent emulation
    // on a fully transparent qimage and then blitting the results
    // won't produce correct results
    // Blend modes
    if (state->composition_mode > QPainter::CompositionMode_Xor &&
        !engine->hasFeature(QPaintEngine::BlendModes))
        s->emulationSpecifier |= QPaintEngine::BlendModes;
    else
        s->emulationSpecifier &= ~QPaintEngine::BlendModes;
#endif
}

void QPainterPrivate::updateStateImpl(QPainterState *newState)
{
    // ### we might have to call QPainter::begin() here...
    if (!engine->state) {
        engine->state = newState;
        engine->setDirty(QPaintEngine::AllDirty);
    }

    if (engine->state->painter() != newState->painter)
        // ### this could break with clip regions vs paths.
        engine->setDirty(QPaintEngine::AllDirty);

    // Upon restore, revert all changes since last save
    else if (engine->state != newState)
        newState->dirtyFlags |= QPaintEngine::DirtyFlags(static_cast<QPainterState *>(engine->state)->changeFlags);

    // We need to store all changes made so that restore can deal with them
    else
        newState->changeFlags |= newState->dirtyFlags;

    updateEmulationSpecifier(newState);

    // Unset potential dirty background mode
    newState->dirtyFlags &= ~(QPaintEngine::DirtyBackgroundMode
            | QPaintEngine::DirtyBackground);

    engine->state = newState;
    engine->updateState(*newState);
    engine->clearDirty(QPaintEngine::AllDirty);

}

void QPainterPrivate::updateState(QPainterState *newState)
{

    if (!newState) {
        engine->state = newState;

    } else if (newState->state() || engine->state!=newState) {
        bool setNonCosmeticPen = (newState->renderHints & QPainter::NonCosmeticDefaultPen)
                                 && newState->pen.widthF() == 0;
        if (setNonCosmeticPen) {
            // Override the default pen's cosmetic state if the
            // NonCosmeticDefaultPen render hint is used.
            QPen oldPen = newState->pen;
            newState->pen.setWidth(1);
            newState->pen.setCosmetic(false);
            newState->dirtyFlags |= QPaintEngine::DirtyPen;

            updateStateImpl(newState);

            // Restore the state pen back to its default to preserve visible
            // state.
            newState->pen = oldPen;
        } else {
            updateStateImpl(newState);
        }
    }
}


/*!
    \class QPainter
    \brief The QPainter class performs low-level painting on widgets and
    other paint devices.

    \ingroup painting

    \reentrant

    QPainter provides highly optimized functions to do most of the
    drawing GUI programs require. It can draw everything from simple
    lines to complex shapes like pies and chords. It can also draw
    aligned text and pixmaps. Normally, it draws in a "natural"
    coordinate system, but it can also do view and world
    transformation. QPainter can operate on any object that inherits
    the QPaintDevice class.

    The common use of QPainter is inside a widget's paint event:
    Construct and customize (e.g. set the pen or the brush) the
    painter. Then draw. Remember to destroy the QPainter object after
    drawing. For example:

    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 0

    The core functionality of QPainter is drawing, but the class also
    provide several functions that allows you to customize QPainter's
    settings and its rendering quality, and others that enable
    clipping. In addition you can control how different shapes are
    merged together by specifying the painter's composition mode.

    The isActive() function indicates whether the painter is active. A
    painter is activated by the begin() function and the constructor
    that takes a QPaintDevice argument. The end() function, and the
    destructor, deactivates it.

    Together with the QPaintDevice and QPaintEngine classes, QPainter
    form the basis for Qt's paint system. QPainter is the class used
    to perform drawing operations. QPaintDevice represents a device
    that can be painted on using a QPainter. QPaintEngine provides the
    interface that the painter uses to draw onto different types of
    devices. If the painter is active, device() returns the paint
    device on which the painter paints, and paintEngine() returns the
    paint engine that the painter is currently operating on. For more
    information, see the \l {Paint System}.

    Sometimes it is desirable to make someone else paint on an unusual
    QPaintDevice. QPainter supports a static function to do this,
    setRedirected().

    \warning When the paintdevice is a widget, QPainter can only be
    used inside a paintEvent() function or in a function called by
    paintEvent(); that is unless the Qt::WA_PaintOutsidePaintEvent
    widget attribute is set. On Mac OS X and Windows, you can only
    paint in a paintEvent() function regardless of this attribute's
    setting.

    \tableofcontents

    \section1 Settings

    There are several settings that you can customize to make QPainter
    draw according to your preferences:

    \list

    \o font() is the font used for drawing text. If the painter
        isActive(), you can retrieve information about the currently set
        font, and its metrics, using the fontInfo() and fontMetrics()
        functions respectively.

    \o brush() defines the color or pattern that is used for filling
       shapes.

    \o pen() defines the color or stipple that is used for drawing
       lines or boundaries.

    \o backgroundMode() defines whether there is a background() or
       not, i.e it is either Qt::OpaqueMode or Qt::TransparentMode.

    \o background() only applies when backgroundMode() is \l
       Qt::OpaqueMode and pen() is a stipple. In that case, it
       describes the color of the background pixels in the stipple.

    \o brushOrigin() defines the origin of the tiled brushes, normally
       the origin of widget's background.

    \o viewport(), window(), worldTransform() make up the painter's coordinate
        transformation system. For more information, see the \l
        {Coordinate Transformations} section and the \l {Coordinate
        System} documentation.

    \o hasClipping() tells whether the painter clips at all. (The paint
       device clips, too.) If the painter clips, it clips to clipRegion().

    \o layoutDirection() defines the layout direction used by the
       painter when drawing text.

    \o worldMatrixEnabled() tells whether world transformation is enabled.

    \o viewTransformEnabled() tells whether view transformation is
        enabled.

    \endlist

    Note that some of these settings mirror settings in some paint
    devices, e.g.  QWidget::font(). The QPainter::begin() function (or
    equivalently the QPainter constructor) copies these attributes
    from the paint device.

    You can at any time save the QPainter's state by calling the
    save() function which saves all the available settings on an
    internal stack. The restore() function pops them back.

    \section1 Drawing

    QPainter provides functions to draw most primitives: drawPoint(),
    drawPoints(), drawLine(), drawRect(), drawRoundedRect(),
    drawEllipse(), drawArc(), drawPie(), drawChord(), drawPolyline(),
    drawPolygon(), drawConvexPolygon() and drawCubicBezier().  The two
    convenience functions, drawRects() and drawLines(), draw the given
    number of rectangles or lines in the given array of \l
    {QRect}{QRects} or \l {QLine}{QLines} using the current pen and
    brush.

    The QPainter class also provides the fillRect() function which
    fills the given QRect, with the given QBrush, and the eraseRect()
    function that erases the area inside the given rectangle.

    All of these functions have both integer and floating point
    versions.

    \table 100%
    \row
    \o \inlineimage qpainter-basicdrawing.png
    \o
    \bold {Basic Drawing Example}

    The \l {painting/basicdrawing}{Basic Drawing} example shows how to
    display basic graphics primitives in a variety of styles using the
    QPainter class.

    \endtable

    If you need to draw a complex shape, especially if you need to do
    so repeatedly, consider creating a QPainterPath and drawing it
    using drawPath().

    \table 100%
    \row
    \o
    \bold {Painter Paths example}

    The QPainterPath class provides a container for painting
    operations, enabling graphical shapes to be constructed and
    reused.

    The \l {painting/painterpaths}{Painter Paths} example shows how
    painter paths can be used to build complex shapes for rendering.

    \o \inlineimage qpainter-painterpaths.png
    \endtable

    QPainter also provides the fillPath() function which fills the
    given QPainterPath with the given QBrush, and the strokePath()
    function that draws the outline of the given path (i.e. strokes
    the path).

    See also the \l {demos/deform}{Vector Deformation} demo which
    shows how to use advanced vector techniques to draw text using a
    QPainterPath, the \l {demos/gradients}{Gradients} demo which shows
    the different types of gradients that are available in Qt, and the \l
    {demos/pathstroke}{Path Stroking} demo which shows Qt's built-in
    dash patterns and shows how custom patterns can be used to extend
    the range of available patterns.

    \table
    \header
    \o \l {demos/deform}{Vector Deformation}
    \o \l {demos/gradients}{Gradients}
    \o \l {demos/pathstroke}{Path Stroking}
    \row
    \o \inlineimage qpainter-vectordeformation.png
    \o \inlineimage qpainter-gradients.png
    \o \inlineimage qpainter-pathstroking.png
    \endtable


    There are functions to draw pixmaps/images, namely drawPixmap(),
    drawImage() and drawTiledPixmap(). Both drawPixmap() and drawImage()
    produce the same result, except that drawPixmap() is faster
    on-screen while drawImage() may be faster on a QPrinter or other
    devices.

    Text drawing is done using drawText(). When you need
    fine-grained positioning, boundingRect() tells you where a given
    drawText() command will draw.

    There is a drawPicture() function that draws the contents of an
    entire QPicture. The drawPicture() function is the only function
    that disregards all the painter's settings as QPicture has its own
    settings.

    \section1 Rendering Quality

    To get the optimal rendering result using QPainter, you should use
    the platform independent QImage as paint device; i.e. using QImage
    will ensure that the result has an identical pixel representation
    on any platform.

    The QPainter class also provides a means of controlling the
    rendering quality through its RenderHint enum and the support for
    floating point precision: All the functions for drawing primitives
    has a floating point version. These are often used in combination
    with the \l {RenderHint}{QPainter::Antialiasing} render hint.

    \table 100%
    \row
    \o \inlineimage qpainter-concentriccircles.png
    \o
    \bold {Concentric Circles Example}

    The \l {painting/concentriccircles}{Concentric Circles} example
    shows the improved rendering quality that can be obtained using
    floating point precision and anti-aliasing when drawing custom
    widgets.

    The application's main window displays several widgets which are
    drawn using the various combinations of precision and
    anti-aliasing.

    \endtable

    The RenderHint enum specifies flags to QPainter that may or may
    not be respected by any given engine.  \l
    {RenderHint}{QPainter::Antialiasing} indicates that the engine
    should antialias edges of primitives if possible, \l
    {RenderHint}{QPainter::TextAntialiasing} indicates that the engine
    should antialias text if possible, and the \l
    {RenderHint}{QPainter::SmoothPixmapTransform} indicates that the
    engine should use a smooth pixmap transformation algorithm.
    \l {RenderHint}{HighQualityAntialiasing} is an OpenGL-specific rendering hint
    indicating that the engine should use fragment programs and offscreen
    rendering for antialiasing.

    The renderHints() function returns a flag that specifies the
    rendering hints that are set for this painter.  Use the
    setRenderHint() function to set or clear the currently set
    RenderHints.

    \section1 Coordinate Transformations

    Normally, the QPainter operates on the device's own coordinate
    system (usually pixels), but QPainter has good support for
    coordinate transformations.

    \table
    \header
    \o  nop \o rotate() \o scale() \o translate()
    \row
    \o \inlineimage qpainter-clock.png
    \o \inlineimage qpainter-rotation.png
    \o \inlineimage qpainter-scale.png
    \o \inlineimage qpainter-translation.png
    \endtable

    The most commonly used transformations are scaling, rotation,
    translation and shearing. Use the scale() function to scale the
    coordinate system by a given offset, the rotate() function to
    rotate it clockwise and translate() to translate it (i.e. adding a
    given offset to the points). You can also twist the coordinate
    system around the origin using the shear() function. See the \l
    {demos/affine}{Affine Transformations} demo for a visualization of
    a sheared coordinate system.

    See also the \l {painting/transformations}{Transformations}
    example which shows how transformations influence the way that
    QPainter renders graphics primitives. In particular it shows how
    the order of transformations affects the result.

    \table 100%
    \row
    \o
    \bold {Affine Transformations Demo}

    The \l {demos/affine}{Affine Transformations} demo show Qt's
    ability to perform affine transformations on painting
    operations. The demo also allows the user to experiment with the
    transformation operations and see the results immediately.

    \o \inlineimage qpainter-affinetransformations.png
    \endtable

    All the tranformation operations operate on the transformation
    worldTransform(). A matrix transforms a point in the plane to another
    point. For more information about the transformation matrix, see
    the \l {Coordinate System} and QTransform documentation.

    The setWorldTransform() function can replace or add to the currently
    set worldTransform(). The resetTransform() function resets any
    transformations that were made using translate(), scale(),
    shear(), rotate(), setWorldTransform(), setViewport() and setWindow()
    functions. The deviceTransform() returns the matrix that transforms
    from logical coordinates to device coordinates of the platform
    dependent paint device. The latter function is only needed when
    using platform painting commands on the platform dependent handle,
    and the platform does not do transformations nativly.

    When drawing with QPainter, we specify points using logical
    coordinates which then are converted into the physical coordinates
    of the paint device. The mapping of the logical coordinates to the
    physical coordinates are handled by QPainter's combinedTransform(), a
    combination of viewport() and window() and worldTransform(). The
    viewport() represents the physical coordinates specifying an
    arbitrary rectangle, the window() describes the same rectangle in
    logical coordinates, and the worldTransform() is identical with the
    transformation matrix.

    See also \l {Coordinate System}

    \section1 Clipping

    QPainter can clip any drawing operation to a rectangle, a region,
    or a vector path. The current clip is available using the
    functions clipRegion() and clipPath(). Whether paths or regions are
    preferred (faster) depends on the underlying paintEngine(). For
    example, the QImage paint engine prefers paths while the X11 paint
    engine prefers regions. Setting a clip is done in the painters
    logical coordinates.

    After QPainter's clipping, the paint device may also clip. For
    example, most widgets clip away the pixels used by child widgets,
    and most printers clip away an area near the edges of the paper.
    This additional clipping is not reflected by the return value of
    clipRegion() or hasClipping().

    \section1 Composition Modes
    \target Composition Modes

    QPainter provides the CompositionMode enum which defines the
    Porter-Duff rules for digital image compositing; it describes a
    model for combining the pixels in one image, the source, with the
    pixels in another image, the destination.

    The two most common forms of composition are \l
    {QPainter::CompositionMode}{Source} and \l
    {QPainter::CompositionMode}{SourceOver}.  \l
    {QPainter::CompositionMode}{Source} is used to draw opaque objects
    onto a paint device. In this mode, each pixel in the source
    replaces the corresponding pixel in the destination. In \l
    {QPainter::CompositionMode}{SourceOver} composition mode, the
    source object is transparent and is drawn on top of the
    destination.

    Note that composition transformation operates pixelwise. For that
    reason, there is a difference between using the graphic primitive
    itself and its bounding rectangle: The bounding rect contains
    pixels with alpha == 0 (i.e the pixels surrounding the
    primitive). These pixels will overwrite the other image's pixels,
    affectively clearing those, while the primitive only overwrites
    its own area.

    \table 100%
    \row
    \o \inlineimage qpainter-compositiondemo.png

    \o
    \bold {Composition Modes Demo}

    The \l {demos/composition}{Composition Modes} demo, available in
    Qt's demo directory, allows you to experiment with the various
    composition modes and see the results immediately.

    \endtable

    \section1 Limitations
    \target Limitations

    If you are using coordinates with Qt's raster-based paint engine, it is
    important to note that, while coordinates greater than +/- 2\sup 15 can
    be used, any painting performed with coordinates outside this range is not
    guaranteed to be shown; the drawing may be clipped. This is due to the
    use of \c{short int} in the implementation.

    The outlines generated by Qt's stroker are only an approximation when dealing
    with curved shapes. It is in most cases impossible to represent the outline of
    a bezier curve segment using another bezier curve segment, and so Qt approximates
    the curve outlines by using several smaller curves. For performance reasons there
    is a limit to how many curves Qt uses for these outlines, and thus when using
    large pen widths or scales the outline error increases. To generate outlines with
    smaller errors it is possible to use the QPainterPathStroker class, which has the
    setCurveThreshold member function which let's the user specify the error tolerance.
    Another workaround is to convert the paths to polygons first and then draw the
    polygons instead.

    \section1 Performance

    QPainter is a rich framework that allows developers to do a great
    variety of graphical operations, such as gradients, composition
    modes and vector graphics. And QPainter can do this across a
    variety of different hardware and software stacks. Naturally the
    underlying combination of hardware and software has some
    implications for performance, and ensuring that every single
    operation is fast in combination with all the various combinations
    of composition modes, brushes, clipping, transformation, etc, is
    close to an impossible task because of the number of
    permutations. As a compromise we have selected a subset of the
    QPainter API and backends, where performance is guaranteed to be as
    good as we can sensibly get it for the given combination of
    hardware and software.

    The backends we focus on as high-performance engines are:

    \list

    \o Raster - This backend implements all rendering in pure software
    and is always used to render into QImages. For optimal performance
    only use the format types QImage::Format_ARGB32_Premultiplied,
    QImage::Format_RGB32 or QImage::Format_RGB16. Any other format,
    including QImage::Format_ARGB32, has significantly worse
    performance. This engine is also used by default on Windows and on
    QWS. It can be used as default graphics system on any
    OS/hardware/software combination by passing \c {-graphicssystem
    raster} on the command line

    \o OpenGL 2.0 (ES) - This backend is the primary backend for
    hardware accelerated graphics. It can be run on desktop machines
    and embedded devices supporting the OpenGL 2.0 or OpenGL/ES 2.0
    specification. This includes most graphics chips produced in the
    last couple of years. The engine can be enabled by using QPainter
    onto a QGLWidget or by passing \c {-graphicssystem opengl} on the
    command line when the underlying system supports it.

    \o OpenVG - This backend implements the Khronos standard for 2D
    and Vector Graphics. It is primarily for embedded devices with
    hardware support for OpenVG.  The engine can be enabled by
    passing \c {-graphicssystem openvg} on the command line when
    the underlying system supports it.

    \endlist

    These operations are:

    \list

    \o Simple transformations, meaning translation and scaling, pluss
    0, 90, 180, 270 degree rotations.

    \o \c drawPixmap() in combination with simple transformations and
    opacity with non-smooth transformation mode
    (\c QPainter::SmoothPixmapTransform not enabled as a render hint).

    \o Rectangle fills with solid color, two-color linear gradients
    and simple transforms.

    \o Rectangular clipping with simple transformations and intersect
    clip.

    \o Composition Modes \c QPainter::CompositionMode_Source and
    QPainter::CompositionMode_SourceOver

    \o Rounded rectangle filling using solid color and two-color
    linear gradients fills.

    \o 3x3 patched pixmaps, via qDrawBorderPixmap.

    \endlist

    This list gives an indication of which features to safely use in
    an application where performance is critical. For certain setups,
    other operations may be fast too, but before making extensive use
    of them, it is recommended to benchmark and verify them on the
    system where the software will run in the end. There are also
    cases where expensive operations are ok to use, for instance when
    the result is cached in a QPixmap.

    \sa QPaintDevice, QPaintEngine, {QtSvg Module}, {Basic Drawing Example},
        {Drawing Utility Functions}
*/

/*!
    \enum QPainter::RenderHint

    Renderhints are used to specify flags to QPainter that may or
    may not be respected by any given engine.

    \value Antialiasing Indicates that the engine should antialias
    edges of primitives if possible.

    \value TextAntialiasing Indicates that the engine should antialias
    text if possible. To forcibly disable antialiasing for text, do not
    use this hint. Instead, set QFont::NoAntialias on your font's style
    strategy.

    \value SmoothPixmapTransform Indicates that the engine should use
    a smooth pixmap transformation algorithm (such as bilinear) rather
    than nearest neighbor.

    \value HighQualityAntialiasing An OpenGL-specific rendering hint
    indicating that the engine should use fragment programs and offscreen
    rendering for antialiasing.

    \value NonCosmeticDefaultPen The engine should interpret pens with a width
    of 0 (which otherwise enables QPen::isCosmetic()) as being a non-cosmetic
    pen with a width of 1.

    \sa renderHints(), setRenderHint(), {QPainter#Rendering
    Quality}{Rendering Quality}, {Concentric Circles Example}

*/

/*!
    Constructs a painter.

    \sa begin(), end()
*/

QPainter::QPainter()
    : d_ptr(new QPainterPrivate(this))
{
}

/*!
    \fn QPainter::QPainter(QPaintDevice *device)

    Constructs a painter that begins painting the paint \a device
    immediately.

    This constructor is convenient for short-lived painters, e.g. in a
    QWidget::paintEvent() and should be used only once. The
    constructor calls begin() for you and the QPainter destructor
    automatically calls end().

    Here's an example using begin() and end():
    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 1

    The same example using this constructor:
    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 2

    Since the constructor cannot provide feedback when the initialization
    of the painter failed you should rather use begin() and end() to paint
    on external devices, e.g. printers.

    \sa begin(), end()
*/

QPainter::QPainter(QPaintDevice *pd)
    : d_ptr(0)
{
    Q_ASSERT(pd != 0);
    if (!QPainterPrivate::attachPainterPrivate(this, pd)) {
        d_ptr.reset(new QPainterPrivate(this));
        begin(pd);
    }
    Q_ASSERT(d_ptr);
}

/*!
    Destroys the painter.
*/
QPainter::~QPainter()
{
    d_ptr->inDestructor = true;
    QT_TRY {
        if (isActive())
            end();
        else if (d_ptr->refcount > 1)
            d_ptr->detachPainterPrivate(this);
    } QT_CATCH(...) {
        // don't throw anything in the destructor.
    }
    if (d_ptr) {
        // Make sure we haven't messed things up.
        Q_ASSERT(d_ptr->inDestructor);
        d_ptr->inDestructor = false;
        Q_ASSERT(d_ptr->refcount == 1);
        if (d_ptr->d_ptrs)
            free(d_ptr->d_ptrs);
    }
}

/*!
    Returns the paint device on which this painter is currently
    painting, or 0 if the painter is not active.

    \sa isActive()
*/

QPaintDevice *QPainter::device() const
{
    Q_D(const QPainter);
    if (isActive() && d->engine->d_func()->currentClipWidget)
        return d->engine->d_func()->currentClipWidget;
    return d->original_device;
}

/*!
    Returns true if begin() has been called and end() has not yet been
    called; otherwise returns false.

    \sa begin(), QPaintDevice::paintingActive()
*/

bool QPainter::isActive() const
{
    Q_D(const QPainter);
    return d->engine;
}

/*!
    Initializes the painters pen, background and font to the same as
    the given \a widget. This function is called automatically when the
    painter is opened on a QWidget.

    \sa begin(), {QPainter#Settings}{Settings}
*/
void QPainter::initFrom(const QWidget *widget)
{
    Q_ASSERT_X(widget, "QPainter::initFrom(const QWidget *widget)", "Widget cannot be 0");
    Q_D(QPainter);
    if (!d->engine) {
        qWarning("QPainter::initFrom: Painter not active, aborted");
        return;
    }

    const QPalette &pal = widget->palette();
    d->state->pen = QPen(pal.brush(widget->foregroundRole()), 0);
    d->state->bgBrush = pal.brush(widget->backgroundRole());
    d->state->deviceFont = QFont(widget->font(), const_cast<QWidget*> (widget));
    d->state->font = d->state->deviceFont;
    if (d->extended) {
        d->extended->penChanged();
    } else if (d->engine) {
        d->engine->setDirty(QPaintEngine::DirtyPen);
        d->engine->setDirty(QPaintEngine::DirtyBrush);
        d->engine->setDirty(QPaintEngine::DirtyFont);
    }
}


/*!
    Saves the current painter state (pushes the state onto a stack). A
    save() must be followed by a corresponding restore(); the end()
    function unwinds the stack.

    \sa restore()
*/

void QPainter::save()
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::save()\n");
#endif
    Q_D(QPainter);
    if (!d->engine) {
        qWarning("QPainter::save: Painter not active");
        return;
    }

    if (d->extended) {
        d->state = d->extended->createState(d->states.back());
        d->extended->setState(d->state);
    } else {
        d->updateState(d->state);
        d->state = new QPainterState(d->states.back());
        d->engine->state = d->state;
    }
    d->states.push_back(d->state);
}

/*!
    Restores the current painter state (pops a saved state off the
    stack).

    \sa save()
*/

void QPainter::restore()
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::restore()\n");
#endif
    Q_D(QPainter);
    if (d->states.size()<=1) {
        qWarning("QPainter::restore: Unbalanced save/restore");
        return;
    } else if (!d->engine) {
        qWarning("QPainter::restore: Painter not active");
        return;
    }

    QPainterState *tmp = d->state;
    d->states.pop_back();
    d->state = d->states.back();
    d->txinv = false;

    if (d->extended) {
        d->checkEmulation();
        d->extended->setState(d->state);
        delete tmp;
        return;
    }

    // trigger clip update if the clip path/region has changed since
    // last save
    if (!d->state->clipInfo.isEmpty()
        && (tmp->changeFlags & (QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyClipPath))) {
        // reuse the tmp state to avoid any extra allocs...
        tmp->dirtyFlags = QPaintEngine::DirtyClipPath;
        tmp->clipOperation = Qt::NoClip;
        tmp->clipPath = QPainterPath();
        d->engine->updateState(*tmp);
        // replay the list of clip states,
        for (int i=0; i<d->state->clipInfo.size(); ++i) {
            const QPainterClipInfo &info = d->state->clipInfo.at(i);
            tmp->matrix = info.matrix;
            tmp->matrix *= d->state->redirectionMatrix;
            tmp->clipOperation = info.operation;
            if (info.clipType == QPainterClipInfo::RectClip) {
                tmp->dirtyFlags = QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyTransform;
                tmp->clipRegion = info.rect;
            } else if (info.clipType == QPainterClipInfo::RegionClip) {
                tmp->dirtyFlags = QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyTransform;
                tmp->clipRegion = info.region;
            } else { // clipType == QPainterClipInfo::PathClip
                tmp->dirtyFlags = QPaintEngine::DirtyClipPath | QPaintEngine::DirtyTransform;
                tmp->clipPath = info.path;
            }
            d->engine->updateState(*tmp);
        }


        //Since we've updated the clip region anyway, pretend that the clip path hasn't changed:
        d->state->dirtyFlags &= ~(QPaintEngine::DirtyClipPath | QPaintEngine::DirtyClipRegion);
        tmp->changeFlags &= ~(QPaintEngine::DirtyClipPath | QPaintEngine::DirtyClipRegion);
        tmp->changeFlags |= QPaintEngine::DirtyTransform;
    }

    d->updateState(d->state);
    delete tmp;
}


/*!

    \fn bool QPainter::begin(QPaintDevice *device)

    Begins painting the paint \a device and returns true if
    successful; otherwise returns false.

    Notice that all painter settings (setPen(), setBrush() etc.) are reset
    to default values when begin() is called.

    The errors that can occur are serious problems, such as these:

    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 3

    Note that most of the time, you can use one of the constructors
    instead of begin(), and that end() is automatically done at
    destruction.

    \warning A paint device can only be painted by one painter at a
    time.

    \warning Painting on a QImage with the format
    QImage::Format_Indexed8 is not supported.

    \sa end(), QPainter()
*/

static inline void qt_cleanup_painter_state(QPainterPrivate *d)
{
    d->states.clear();
    delete d->state;
    d->state = 0;
    d->engine = 0;
    d->device = 0;
}

bool QPainter::begin(QPaintDevice *pd)
{
    Q_ASSERT(pd);

    if (pd->painters > 0) {
        qWarning("QPainter::begin: A paint device can only be painted by one painter at a time.");
        return false;
    }

    if (d_ptr->engine) {
        qWarning("QPainter::begin: Painter already active");
        return false;
    }

    if (QPainterPrivate::attachPainterPrivate(this, pd))
        return true;

    Q_D(QPainter);

    d->helper_device = pd;
    d->original_device = pd;
    QPaintDevice *rpd = 0;

    QPoint redirectionOffset;
    // We know for sure that redirection is broken when the widget is inside
    // its paint event, so it's safe to use our hard-coded redirection. However,
    // there IS one particular case we still need to support, and that's
    // when people call QPainter::setRedirected in the widget's paint event right
    // before any painter is created (or QPainter::begin is called). In that
    // particular case our hard-coded redirection is restored and the redirection
    // is retrieved from QPainter::redirected (as before).
    if (pd->devType() == QInternal::Widget)
        rpd = static_cast<QWidget *>(pd)->d_func()->redirected(&redirectionOffset);

    if (!rpd)
        rpd = redirected(pd, &redirectionOffset);

    if (rpd)
        pd = rpd;

#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::begin(), device=%p, type=%d\n", pd, pd->devType());
#endif

    if (pd->devType() == QInternal::Pixmap)
        static_cast<QPixmap *>(pd)->detach();
    else if (pd->devType() == QInternal::Image)
        static_cast<QImage *>(pd)->detach();

    d->engine = pd->paintEngine();

    if (!d->engine) {
        qWarning("QPainter::begin: Paint device returned engine == 0, type: %d", pd->devType());
        return false;
    }

    d->device = pd;

    d->extended = d->engine->isExtended() ? static_cast<QPaintEngineEx *>(d->engine) : 0;
    if (d->emulationEngine)
        d->emulationEngine->real_engine = d->extended;

    // Setup new state...
    Q_ASSERT(!d->state);
    d->state = d->extended ? d->extended->createState(0) : new QPainterState;
    d->state->painter = this;
    d->states.push_back(d->state);

    d->state->redirectionMatrix.translate(-redirectionOffset.x(), -redirectionOffset.y());
    d->state->brushOrigin = QPointF();

    // Slip a painter state into the engine before we do any other operations
    if (d->extended)
        d->extended->setState(d->state);
    else
        d->engine->state = d->state;

    switch (pd->devType()) {
        case QInternal::Widget:
        {
            const QWidget *widget = static_cast<const QWidget *>(pd);
            Q_ASSERT(widget);

            const bool paintOutsidePaintEvent = widget->testAttribute(Qt::WA_PaintOutsidePaintEvent);
            const bool inPaintEvent = widget->testAttribute(Qt::WA_WState_InPaintEvent);
            if(!d->engine->hasFeature(QPaintEngine::PaintOutsidePaintEvent)
                && !paintOutsidePaintEvent && !inPaintEvent) {
                qWarning("QPainter::begin: Widget painting can only begin as a "
                         "result of a paintEvent");
                qt_cleanup_painter_state(d);
                return false;
            }

            // Adjust offset for alien widgets painting outside the paint event.
            if (!inPaintEvent && paintOutsidePaintEvent && !widget->internalWinId()
                && widget->testAttribute(Qt::WA_WState_Created)) {
                const QPoint offset = widget->mapTo(widget->nativeParentWidget(), QPoint());
                d->state->redirectionMatrix.translate(offset.x(), offset.y());
            }
            break;
        }
        case QInternal::Pixmap:
        {
            QPixmap *pm = static_cast<QPixmap *>(pd);
            Q_ASSERT(pm);
            if (pm->isNull()) {
                qWarning("QPainter::begin: Cannot paint on a null pixmap");
                qt_cleanup_painter_state(d);
                return false;
            }

            if (pm->depth() == 1) {
                d->state->pen = QPen(Qt::color1);
                d->state->brush = QBrush(Qt::color0);
            }
            break;
        }
        case QInternal::Image:
        {
            QImage *img = static_cast<QImage *>(pd);
            Q_ASSERT(img);
            if (img->isNull()) {
                qWarning("QPainter::begin: Cannot paint on a null image");
                qt_cleanup_painter_state(d);
                return false;
            } else if (img->format() == QImage::Format_Indexed8) {
                // Painting on indexed8 images is not supported.
                qWarning("QPainter::begin: Cannot paint on an image with the QImage::Format_Indexed8 format");
                qt_cleanup_painter_state(d);
                return false;
            }
            if (img->depth() == 1) {
                d->state->pen = QPen(Qt::color1);
                d->state->brush = QBrush(Qt::color0);
            }
            break;
        }
        default:
            break;
    }
    if (d->state->ww == 0) // For compat with 3.x painter defaults
        d->state->ww = d->state->wh = d->state->vw = d->state->vh = 1024;

    d->engine->setPaintDevice(pd);

    bool begun = d->engine->begin(pd);
    if (!begun) {
        qWarning("QPainter::begin(): Returned false");
        if (d->engine->isActive()) {
            end();
        } else {
            qt_cleanup_painter_state(d);
        }
        return false;
    } else {
        d->engine->setActive(begun);
    }

    // Copy painter properties from original paint device,
    // required for QPixmap::grabWidget()
    if (d->original_device->devType() == QInternal::Widget) {
        QWidget *widget = static_cast<QWidget *>(d->original_device);
        initFrom(widget);
    } else {
        d->state->layoutDirection = Qt::LayoutDirectionAuto;
        // make sure we have a font compatible with the paintdevice
        d->state->deviceFont = d->state->font = QFont(d->state->deviceFont, device());
    }

    QRect systemRect = d->engine->systemRect();
    if (!systemRect.isEmpty()) {
        d->state->ww = d->state->vw = systemRect.width();
        d->state->wh = d->state->vh = systemRect.height();
    } else {
        d->state->ww = d->state->vw = pd->metric(QPaintDevice::PdmWidth);
        d->state->wh = d->state->vh = pd->metric(QPaintDevice::PdmHeight);
    }

    const QPoint coordinateOffset = d->engine->coordinateOffset();
    d->state->redirectionMatrix.translate(-coordinateOffset.x(), -coordinateOffset.y());

    Q_ASSERT(d->engine->isActive());

    if (!d->state->redirectionMatrix.isIdentity())
        d->updateMatrix();

    Q_ASSERT(d->engine->isActive());
    d->state->renderHints = QPainter::TextAntialiasing;
    ++d->device->painters;

    d->state->emulationSpecifier = 0;

    return true;
}

/*!
    Ends painting. Any resources used while painting are released. You
    don't normally need to call this since it is called by the
    destructor.

    Returns true if the painter is no longer active; otherwise returns false.

    \sa begin(), isActive()
*/

bool QPainter::end()
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::end()\n");
#endif
    Q_D(QPainter);

    if (!d->engine) {
        qWarning("QPainter::end: Painter not active, aborted");
        qt_cleanup_painter_state(d);
        return false;
    }

    if (d->refcount > 1) {
        d->detachPainterPrivate(this);
        return true;
    }

    bool ended = true;

    if (d->engine->isActive()) {
        ended = d->engine->end();
        d->updateState(0);

        --d->device->painters;
        if (d->device->painters == 0) {
            d->engine->setPaintDevice(0);
            d->engine->setActive(false);
        }
    }

    if (d->states.size() > 1) {
        qWarning("QPainter::end: Painter ended with %d saved states",
                 d->states.size());
    }

    if (d->engine->autoDestruct()) {
        delete d->engine;
    }

    if (d->emulationEngine) {
        delete d->emulationEngine;
        d->emulationEngine = 0;
    }

    if (d->extended) {
        d->extended = 0;
    }

    qt_cleanup_painter_state(d);

    return ended;
}


/*!
    Returns the paint engine that the painter is currently operating
    on if the painter is active; otherwise 0.

    \sa isActive()
*/
QPaintEngine *QPainter::paintEngine() const
{
    Q_D(const QPainter);
    return d->engine;
}

/*!
    \since 4.6

    Flushes the painting pipeline and prepares for the user issuing commands
    directly to the underlying graphics context. Must be followed by a call to
    endNativePainting().

    Note that only the states the underlying paint engine changes will be reset
    to their respective default states. The states we reset may change from
    release to release. The following states are currently reset in the OpenGL
    2 engine:

    \list
    \i blending is disabled
    \i the depth, stencil and scissor tests are disabled
    \i the active texture unit is reset to 0
    \i the depth mask, depth function and the clear depth are reset to their
    default values
    \i the stencil mask, stencil operation and stencil function are reset to
    their default values
     \i the current color is reset to solid white
    \endlist

    If, for example, the OpenGL polygon mode is changed by the user inside a
    beginNativePaint()/endNativePainting() block, it will not be reset to the
    default state by endNativePainting(). Here is an example that shows
    intermixing of painter commands and raw OpenGL commands:

    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 21

    \sa endNativePainting()
*/
void QPainter::beginNativePainting()
{
    Q_D(QPainter);
    if (!d->engine) {
        qWarning("QPainter::beginNativePainting: Painter not active");
        return;
    }

    if (d->extended)
        d->extended->beginNativePainting();
}

/*!
    \since 4.6

    Restores the painter after manually issuing native painting commands. Lets
    the painter restore any native state that it relies on before calling any
    other painter commands.

    \sa beginNativePainting()
*/
void QPainter::endNativePainting()
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::beginNativePainting: Painter not active");
        return;
    }

    if (d->extended)
        d->extended->endNativePainting();
    else
        d->engine->syncState();
}

/*!
    Returns the font metrics for the painter if the painter is
    active. Otherwise, the return value is undefined.

    \sa font(), isActive(), {QPainter#Settings}{Settings}
*/

QFontMetrics QPainter::fontMetrics() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::fontMetrics: Painter not active");
        return QFontMetrics(QFont());
    }
    return QFontMetrics(d->state->font);
}


/*!
    Returns the font info for the painter if the painter is
    active. Otherwise, the return value is undefined.

    \sa font(), isActive(), {QPainter#Settings}{Settings}
*/

QFontInfo QPainter::fontInfo() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::fontInfo: Painter not active");
        return QFontInfo(QFont());
    }
    return QFontInfo(d->state->font);
}

/*!
    \since 4.2

    Returns the opacity of the painter. The default value is
    1.
*/

qreal QPainter::opacity() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::opacity: Painter not active");
        return 1.0;
    }
    return d->state->opacity;
}

/*!
    \since 4.2

    Sets the opacity of the painter to \a opacity. The value should
    be in the range 0.0 to 1.0, where 0.0 is fully transparent and
    1.0 is fully opaque.

    Opacity set on the painter will apply to all drawing operations
    individually.
*/

void QPainter::setOpacity(qreal opacity)
{
    Q_D(QPainter);

    if (!d->engine) {
        qWarning("QPainter::setOpacity: Painter not active");
        return;
    }

    opacity = qMin(qreal(1), qMax(qreal(0), opacity));

    if (opacity == d->state->opacity)
        return;

    d->state->opacity = opacity;

    if (d->extended)
        d->extended->opacityChanged();
    else
        d->state->dirtyFlags |= QPaintEngine::DirtyOpacity;
}


/*!
    Returns the currently set brush origin.

    \sa setBrushOrigin(), {QPainter#Settings}{Settings}
*/

QPoint QPainter::brushOrigin() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::brushOrigin: Painter not active");
        return QPoint();
    }
    return QPointF(d->state->brushOrigin).toPoint();
}

/*!
    \fn void QPainter::setBrushOrigin(const QPointF &position)

    Sets the brush origin to \a position.

    The brush origin specifies the (0, 0) coordinate of the painter's
    brush.

    Note that while the brushOrigin() was necessary to adopt the
    parent's background for a widget in Qt 3, this is no longer the
    case since the Qt 4 painter doesn't paint the background unless
    you explicitly tell it to do so by setting the widget's \l
    {QWidget::autoFillBackground}{autoFillBackground} property to
    true.

    \sa brushOrigin(), {QPainter#Settings}{Settings}
*/

void QPainter::setBrushOrigin(const QPointF &p)
{
    Q_D(QPainter);
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::setBrushOrigin(), (%.2f,%.2f)\n", p.x(), p.y());
#endif

    if (!d->engine) {
        qWarning("QPainter::setBrushOrigin: Painter not active");
        return;
    }

    d->state->brushOrigin = p;

    if (d->extended) {
        d->extended->brushOriginChanged();
        return;
    }

    d->state->dirtyFlags |= QPaintEngine::DirtyBrushOrigin;
}

/*!
    \fn void QPainter::setBrushOrigin(const QPoint &position)
    \overload

    Sets the brush's origin to the given \a position.
*/

/*!
    \fn void QPainter::setBrushOrigin(int x, int y)

    \overload

    Sets the brush's origin to point (\a x, \a y).
*/

/*!
    \enum QPainter::CompositionMode

    Defines the modes supported for digital image compositing.
    Composition modes are used to specify how the pixels in one image,
    the source, are merged with the pixel in another image, the
    destination.

    Please note that the bitwise raster operation modes, denoted with
    a RasterOp prefix, are only natively supported in the X11 and
    raster paint engines. This means that the only way to utilize
    these modes on the Mac is via a QImage. The RasterOp denoted blend
    modes are \e not supported for pens and brushes with alpha
    components. Also, turning on the QPainter::Antialiasing render
    hint will effectively disable the RasterOp modes.


     \image qpainter-compositionmode1.png
     \image qpainter-compositionmode2.png

    The most common type is SourceOver (often referred to as just
    alpha blending) where the source pixel is blended on top of the
    destination pixel in such a way that the alpha component of the
    source defines the translucency of the pixel.

    When the paint device is a QImage, the image format must be set to
    \l {QImage::Format}{Format_ARGB32Premultiplied} or
    \l {QImage::Format}{Format_ARGB32} for the composition modes to have
    any effect. For performance the premultiplied version is the preferred
    format.

    When a composition mode is set it applies to all painting
    operator, pens, brushes, gradients and pixmap/image drawing.

    \value CompositionMode_SourceOver This is the default mode. The
    alpha of the source is used to blend the pixel on top of the
    destination.

    \value CompositionMode_DestinationOver The alpha of the
    destination is used to blend it on top of the source pixels. This
    mode is the inverse of CompositionMode_SourceOver.

    \value CompositionMode_Clear The pixels in the destination are
    cleared (set to fully transparent) independent of the source.

    \value CompositionMode_Source The output is the source
    pixel. (This means a basic copy operation and is identical to
    SourceOver when the source pixel is opaque).

    \value CompositionMode_Destination The output is the destination
    pixel. This means that the blending has no effect. This mode is
    the inverse of CompositionMode_Source.

    \value CompositionMode_SourceIn The output is the source, where
    the alpha is reduced by that of the destination.

    \value CompositionMode_DestinationIn The output is the
    destination, where the alpha is reduced by that of the
    source. This mode is the inverse of CompositionMode_SourceIn.

    \value CompositionMode_SourceOut The output is the source, where
    the alpha is reduced by the inverse of destination.

    \value CompositionMode_DestinationOut The output is the
    destination, where the alpha is reduced by the inverse of the
    source. This mode is the inverse of CompositionMode_SourceOut.

    \value CompositionMode_SourceAtop The source pixel is blended on
    top of the destination, with the alpha of the source pixel reduced
    by the alpha of the destination pixel.

    \value CompositionMode_DestinationAtop The destination pixel is
    blended on top of the source, with the alpha of the destination
    pixel is reduced by the alpha of the destination pixel. This mode
    is the inverse of CompositionMode_SourceAtop.

    \value CompositionMode_Xor The source, whose alpha is reduced with
    the inverse of the destination alpha, is merged with the
    destination, whose alpha is reduced by the inverse of the source
    alpha. CompositionMode_Xor is not the same as the bitwise Xor.

    \value CompositionMode_Plus Both the alpha and color of the source
    and destination pixels are added together.

    \value CompositionMode_Multiply The output is the source color
    multiplied by the destination. Multiplying a color with white
    leaves the color unchanged, while multiplying a color
    with black produces black.

    \value CompositionMode_Screen The source and destination colors
    are inverted and then multiplied. Screening a color with white
    produces white, whereas screening a color with black leaves the
    color unchanged.

    \value CompositionMode_Overlay Multiplies or screens the colors
    depending on the destination color. The destination color is mixed
    with the source color to reflect the lightness or darkness of the
    destination.

    \value CompositionMode_Darken The darker of the source and
    destination colors is selected.

    \value CompositionMode_Lighten The lighter of the source and
    destination colors is selected.

    \value CompositionMode_ColorDodge The destination color is
    brightened to reflect the source color. A black source color
    leaves the destination color unchanged.

    \value CompositionMode_ColorBurn The destination color is darkened
    to reflect the source color. A white source color leaves the
    destination color unchanged.

    \value CompositionMode_HardLight Multiplies or screens the colors
    depending on the source color. A light source color will lighten
    the destination color, whereas a dark source color will darken the
    destination color.

    \value CompositionMode_SoftLight Darkens or lightens the colors
    depending on the source color. Similar to
    CompositionMode_HardLight.

    \value CompositionMode_Difference Subtracts the darker of the
    colors from the lighter.  Painting with white inverts the
    destination color, whereas painting with black leaves the
    destination color unchanged.

    \value CompositionMode_Exclusion Similar to
    CompositionMode_Difference, but with a lower contrast. Painting
    with white inverts the destination color, whereas painting with
    black leaves the destination color unchanged.

    \value RasterOp_SourceOrDestination Does a bitwise OR operation on
    the source and destination pixels (src OR dst).

    \value RasterOp_SourceAndDestination Does a bitwise AND operation
    on the source and destination pixels (src AND dst).

    \value RasterOp_SourceXorDestination Does a bitwise XOR operation
    on the source and destination pixels (src XOR dst).

    \value RasterOp_NotSourceAndNotDestination Does a bitwise NOR
    operation on the source and destination pixels ((NOT src) AND (NOT
    dst)).

    \value RasterOp_NotSourceOrNotDestination Does a bitwise NAND
    operation on the source and destination pixels ((NOT src) OR (NOT
    dst)).

    \value RasterOp_NotSourceXorDestination Does a bitwise operation
    where the source pixels are inverted and then XOR'ed with the
    destination ((NOT src) XOR dst).

    \value RasterOp_NotSource Does a bitwise operation where the
    source pixels are inverted (NOT src).

    \value RasterOp_NotSourceAndDestination Does a bitwise operation
    where the source is inverted and then AND'ed with the destination
    ((NOT src) AND dst).

    \value RasterOp_SourceAndNotDestination Does a bitwise operation
    where the source is AND'ed with the inverted destination pixels
    (src AND (NOT dst)).

    \sa compositionMode(), setCompositionMode(), {QPainter#Composition
    Modes}{Composition Modes}, {Image Composition Example}
*/

/*!
    Sets the composition mode to the given \a mode.

    \warning Only a QPainter operating on a QImage fully supports all
    composition modes. The RasterOp modes are supported for X11 as
    described in compositionMode().

    \sa compositionMode()
*/
void QPainter::setCompositionMode(CompositionMode mode)
{
    Q_D(QPainter);
    if (!d->engine) {
        qWarning("QPainter::setCompositionMode: Painter not active");
        return;
    }
    if (d->state->composition_mode == mode)
        return;
    if (d->extended) {
        d->state->composition_mode = mode;
        d->extended->compositionModeChanged();
        return;
    }

    if (mode >= QPainter::RasterOp_SourceOrDestination) {
        if (!d->engine->hasFeature(QPaintEngine::RasterOpModes)) {
            qWarning("QPainter::setCompositionMode: "
                     "Raster operation modes not supported on device");
            return;
        }
    } else if (mode >= QPainter::CompositionMode_Plus) {
        if (!d->engine->hasFeature(QPaintEngine::BlendModes)) {
            qWarning("QPainter::setCompositionMode: "
                     "Blend modes not supported on device");
            return;
        }
    } else if (!d->engine->hasFeature(QPaintEngine::PorterDuff)) {
        if (mode != CompositionMode_Source && mode != CompositionMode_SourceOver) {
            qWarning("QPainter::setCompositionMode: "
                     "PorterDuff modes not supported on device");
            return;
        }
    }

    d->state->composition_mode = mode;
    d->state->dirtyFlags |= QPaintEngine::DirtyCompositionMode;
}

/*!
  Returns the current composition mode.

  \sa CompositionMode, setCompositionMode()
*/
QPainter::CompositionMode QPainter::compositionMode() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::compositionMode: Painter not active");
        return QPainter::CompositionMode_SourceOver;
    }
    return d->state->composition_mode;
}

/*!
    Returns the current background brush.

    \sa setBackground(), {QPainter#Settings}{Settings}
*/

const QBrush &QPainter::background() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::background: Painter not active");
        return d->fakeState()->brush;
    }
    return d->state->bgBrush;
}


/*!
    Returns true if clipping has been set; otherwise returns false.

    \sa setClipping(), {QPainter#Clipping}{Clipping}
*/

bool QPainter::hasClipping() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::hasClipping: Painter not active");
        return false;
    }
    return d->state->clipEnabled && d->state->clipOperation != Qt::NoClip;
}


/*!
    Enables clipping if  \a enable is true, or disables clipping if  \a
    enable is false.

    \sa hasClipping(), {QPainter#Clipping}{Clipping}
*/

void QPainter::setClipping(bool enable)
{
    Q_D(QPainter);
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::setClipping(), enable=%s, was=%s\n",
               enable ? "on" : "off",
               hasClipping() ? "on" : "off");
#endif
    if (!d->engine) {
        qWarning("QPainter::setClipping: Painter not active, state will be reset by begin");
        return;
    }

    if (hasClipping() == enable)
        return;

    // we can't enable clipping if we don't have a clip
    if (enable
        && (d->state->clipInfo.isEmpty() || d->state->clipInfo.last().operation == Qt::NoClip))
        return;
    d->state->clipEnabled = enable;

    if (d->extended) {
        d->extended->clipEnabledChanged();
        return;
    }

    d->state->dirtyFlags |= QPaintEngine::DirtyClipEnabled;
    d->updateState(d->state);
}


/*!
    Returns the currently set clip region. Note that the clip region
    is given in logical coordinates.

    \warning QPainter does not store the combined clip explicitly as
    this is handled by the underlying QPaintEngine, so the path is
    recreated on demand and transformed to the current logical
    coordinate system. This is potentially an expensive operation.

    \sa setClipRegion(), clipPath(), setClipping()
*/

QRegion QPainter::clipRegion() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::clipRegion: Painter not active");
        return QRegion();
    }

    QRegion region;
    bool lastWasNothing = true;

    if (!d->txinv)
        const_cast<QPainter *>(this)->d_ptr->updateInvMatrix();

    // ### Falcon: Use QPainterPath
    for (int i=0; i<d->state->clipInfo.size(); ++i) {
        const QPainterClipInfo &info = d->state->clipInfo.at(i);
        switch (info.clipType) {

        case QPainterClipInfo::RegionClip: {
            QTransform matrix = (info.matrix * d->invMatrix);
            if (lastWasNothing) {
                region = info.region * matrix;
                lastWasNothing = false;
                continue;
            }
            if (info.operation == Qt::IntersectClip)
                region &= info.region * matrix;
            else if (info.operation == Qt::UniteClip)
                region |= info.region * matrix;
            else if (info.operation == Qt::NoClip) {
                lastWasNothing = true;
                region = QRegion();
            } else
                region = info.region * matrix;
            break;
        }

        case QPainterClipInfo::PathClip: {
            QTransform matrix = (info.matrix * d->invMatrix);
            if (lastWasNothing) {
                region = QRegion((info.path * matrix).toFillPolygon().toPolygon(),
                                 info.path.fillRule());
                lastWasNothing = false;
                continue;
            }
            if (info.operation == Qt::IntersectClip) {
                region &= QRegion((info.path * matrix).toFillPolygon().toPolygon(),
                                  info.path.fillRule());
            } else if (info.operation == Qt::UniteClip) {
                region |= QRegion((info.path * matrix).toFillPolygon().toPolygon(),
                                  info.path.fillRule());
            } else if (info.operation == Qt::NoClip) {
                lastWasNothing = true;
                region = QRegion();
            } else {
                region = QRegion((info.path * matrix).toFillPolygon().toPolygon(),
                                 info.path.fillRule());
            }
            break;
        }

        case QPainterClipInfo::RectClip: {
            QTransform matrix = (info.matrix * d->invMatrix);
            if (lastWasNothing) {
                region = QRegion(info.rect) * matrix;
                lastWasNothing = false;
                continue;
            }
            if (info.operation == Qt::IntersectClip) {
                // Use rect intersection if possible.
                if (matrix.type() <= QTransform::TxScale)
                    region &= matrix.mapRect(info.rect);
                else
                    region &= matrix.map(QRegion(info.rect));
            } else if (info.operation == Qt::UniteClip) {
                region |= QRegion(info.rect) * matrix;
            } else if (info.operation == Qt::NoClip) {
                lastWasNothing = true;
                region = QRegion();
            } else {
                region = QRegion(info.rect) * matrix;
            }
            break;
        }

        case QPainterClipInfo::RectFClip: {
            QTransform matrix = (info.matrix * d->invMatrix);
            if (lastWasNothing) {
                region = QRegion(info.rectf.toRect()) * matrix;
                lastWasNothing = false;
                continue;
            }
            if (info.operation == Qt::IntersectClip) {
                // Use rect intersection if possible.
                if (matrix.type() <= QTransform::TxScale)
                    region &= matrix.mapRect(info.rectf.toRect());
                else
                    region &= matrix.map(QRegion(info.rectf.toRect()));
            } else if (info.operation == Qt::UniteClip) {
                region |= QRegion(info.rectf.toRect()) * matrix;
            } else if (info.operation == Qt::NoClip) {
                lastWasNothing = true;
                region = QRegion();
            } else {
                region = QRegion(info.rectf.toRect()) * matrix;
            }
            break;
        }
        }
    }

    return region;
}

extern QPainterPath qt_regionToPath(const QRegion &region);

/*!
    Returns the currently clip as a path. Note that the clip path is
    given in logical coordinates.

    \warning QPainter does not store the combined clip explicitly as
    this is handled by the underlying QPaintEngine, so the path is
    recreated on demand and transformed to the current logical
    coordinate system. This is potentially an expensive operation.

    \sa setClipPath(), clipRegion(), setClipping()
*/
QPainterPath QPainter::clipPath() const
{
    Q_D(const QPainter);

    // ### Since we do not support path intersections and path unions yet,
    // we just use clipRegion() here...
    if (!d->engine) {
        qWarning("QPainter::clipPath: Painter not active");
        return QPainterPath();
    }

    // No clip, return empty
    if (d->state->clipInfo.size() == 0) {
        return QPainterPath();
    } else {

        // Update inverse matrix, used below.
        if (!d->txinv)
            const_cast<QPainter *>(this)->d_ptr->updateInvMatrix();

        // For the simple case avoid conversion.
        if (d->state->clipInfo.size() == 1
            && d->state->clipInfo.at(0).clipType == QPainterClipInfo::PathClip) {
            QTransform matrix = (d->state->clipInfo.at(0).matrix * d->invMatrix);
            return d->state->clipInfo.at(0).path * matrix;

        } else if (d->state->clipInfo.size() == 1
                   && d->state->clipInfo.at(0).clipType == QPainterClipInfo::RectClip) {
            QTransform matrix = (d->state->clipInfo.at(0).matrix * d->invMatrix);
            QPainterPath path;
            path.addRect(d->state->clipInfo.at(0).rect);
            return path * matrix;
        } else {
            // Fallback to clipRegion() for now, since we don't have isect/unite for paths
            return qt_regionToPath(clipRegion());
        }
    }
}

/*!
    \fn void QPainter::setClipRect(const QRectF &rectangle, Qt::ClipOperation operation)

    Enables clipping, and sets the clip region to the given \a
    rectangle using the given clip \a operation. The default operation
    is to replace the current clip rectangle.

    Note that the clip rectangle is specified in logical (painter)
    coordinates.

    \sa clipRegion(), setClipping(), {QPainter#Clipping}{Clipping}
*/
void QPainter::setClipRect(const QRectF &rect, Qt::ClipOperation op)
{
    Q_D(QPainter);

    if (d->extended) {
        if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip))
            op = Qt::ReplaceClip;

        if (!d->engine) {
            qWarning("QPainter::setClipRect: Painter not active");
            return;
        }
        qreal right = rect.x() + rect.width();
        qreal bottom = rect.y() + rect.height();
        qreal pts[] = { rect.x(), rect.y(),
                        right, rect.y(),
                        right, bottom,
                        rect.x(), bottom };
        QVectorPath vp(pts, 4, 0, QVectorPath::RectangleHint);
        d->state->clipEnabled = true;
        d->extended->clip(vp, op);
        if (op == Qt::ReplaceClip || op == Qt::NoClip)
            d->state->clipInfo.clear();
        d->state->clipInfo << QPainterClipInfo(rect, op, d->state->matrix);
        d->state->clipOperation = op;
        return;
    }

    if (qreal(int(rect.top())) == rect.top()
        && qreal(int(rect.bottom())) == rect.bottom()
        && qreal(int(rect.left())) == rect.left()
        && qreal(int(rect.right())) == rect.right())
    {
        setClipRect(rect.toRect(), op);
        return;
    }

    if (rect.isEmpty()) {
        setClipRegion(QRegion(), op);
        return;
    }

    QPainterPath path;
    path.addRect(rect);
    setClipPath(path, op);
}

/*!
    \fn void QPainter::setClipRect(const QRect &rectangle, Qt::ClipOperation operation)
    \overload

    Enables clipping, and sets the clip region to the given \a rectangle using the given
    clip \a operation.
*/
void QPainter::setClipRect(const QRect &rect, Qt::ClipOperation op)
{
    Q_D(QPainter);

    if (!d->engine) {
        qWarning("QPainter::setClipRect: Painter not active");
        return;
    }

    if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip))
        op = Qt::ReplaceClip;

    if (d->extended) {
        d->state->clipEnabled = true;
        d->extended->clip(rect, op);
        if (op == Qt::ReplaceClip || op == Qt::NoClip)
            d->state->clipInfo.clear();
        d->state->clipInfo << QPainterClipInfo(rect, op, d->state->matrix);
        d->state->clipOperation = op;
        return;
    }

    if (d->state->clipOperation == Qt::NoClip && op == Qt::IntersectClip)
        op = Qt::ReplaceClip;

    d->state->clipRegion = rect;
    d->state->clipOperation = op;
    if (op == Qt::NoClip || op == Qt::ReplaceClip)
        d->state->clipInfo.clear();
    d->state->clipInfo << QPainterClipInfo(rect, op, d->state->matrix);
    d->state->clipEnabled = true;
    d->state->dirtyFlags |= QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyClipEnabled;
    d->updateState(d->state);
}

/*!
    \fn void QPainter::setClipRect(int x, int y, int width, int height, Qt::ClipOperation operation)

    Enables clipping, and sets the clip region to the rectangle beginning at (\a x, \a y)
    with the given \a width and \a height.
*/

/*!
    \fn void QPainter::setClipRegion(const QRegion &region, Qt::ClipOperation operation)

    Sets the clip region to the given \a region using the specified clip
    \a operation. The default clip operation is to replace the current
    clip region.

    Note that the clip region is given in logical coordinates.

    \sa clipRegion(), setClipRect(), {QPainter#Clipping}{Clipping}
*/
void QPainter::setClipRegion(const QRegion &r, Qt::ClipOperation op)
{
    Q_D(QPainter);
#ifdef QT_DEBUG_DRAW
    QRect rect = r.boundingRect();
    if (qt_show_painter_debug_output)
        printf("QPainter::setClipRegion(), size=%d, [%d,%d,%d,%d]\n",
           r.rects().size(), rect.x(), rect.y(), rect.width(), rect.height());
#endif
    if (!d->engine) {
        qWarning("QPainter::setClipRegion: Painter not active");
        return;
    }

    if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip))
        op = Qt::ReplaceClip;

    if (d->extended) {
        d->state->clipEnabled = true;
        d->extended->clip(r, op);
        if (op == Qt::NoClip || op == Qt::ReplaceClip)
            d->state->clipInfo.clear();
        d->state->clipInfo << QPainterClipInfo(r, op, d->state->matrix);
        d->state->clipOperation = op;
        return;
    }

    if (d->state->clipOperation == Qt::NoClip && op == Qt::IntersectClip)
        op = Qt::ReplaceClip;

    d->state->clipRegion = r;
    d->state->clipOperation = op;
    if (op == Qt::NoClip || op == Qt::ReplaceClip)
        d->state->clipInfo.clear();
    d->state->clipInfo << QPainterClipInfo(r, op, d->state->matrix);
    d->state->clipEnabled = true;
    d->state->dirtyFlags |= QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyClipEnabled;
    d->updateState(d->state);
}

/*!
    \since 4.2
    \obsolete

    Sets the transformation matrix to \a matrix and enables transformations.

    \note It is advisable to use setWorldTransform() instead of this function to
    preserve the properties of perspective transformations.

    If \a combine is true, then \a matrix is combined with the current
    transformation matrix; otherwise \a matrix replaces the current
    transformation matrix.

    If \a matrix is the identity matrix and \a combine is false, this
    function calls setWorldMatrixEnabled(false). (The identity matrix is the
    matrix where QMatrix::m11() and QMatrix::m22() are 1.0 and the
    rest are 0.0.)

    The following functions can transform the coordinate system without using
    a QMatrix:
    \list
    \i translate()
    \i scale()
    \i shear()
    \i rotate()
    \endlist

    They operate on the painter's worldMatrix() and are implemented like this:

    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 4

    Note that when using setWorldMatrix() function you should always have
    \a combine be true when you are drawing into a QPicture. Otherwise
    it may not be possible to replay the picture with additional
    transformations; using the translate(), scale(), etc. convenience
    functions is safe.

    For more information about the coordinate system, transformations
    and window-viewport conversion, see \l {Coordinate System}.

    \sa setWorldTransform(), QTransform
*/

void QPainter::setWorldMatrix(const QMatrix &matrix, bool combine)
{
    setWorldTransform(QTransform(matrix), combine);
}

/*!
    \since 4.2
    \obsolete

    Returns the world transformation matrix.

    It is advisable to use worldTransform() because worldMatrix() does not
    preserve the properties of perspective transformations.

    \sa {QPainter#Coordinate Transformations}{Coordinate Transformations},
    {Coordinate System}
*/

const QMatrix &QPainter::worldMatrix() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::worldMatrix: Painter not active");
        return d->fakeState()->transform.toAffine();
    }
    return d->state->worldMatrix.toAffine();
}

/*!
    \obsolete

    Use setWorldTransform() instead.

    \sa setWorldTransform()
*/

void QPainter::setMatrix(const QMatrix &matrix, bool combine)
{
    setWorldTransform(QTransform(matrix), combine);
}

/*!
    \obsolete

    Use worldTransform() instead.

    \sa worldTransform()
*/

const QMatrix &QPainter::matrix() const
{
    return worldMatrix();
}


/*!
    \since 4.2
    \obsolete

    Returns the transformation matrix combining the current
    window/viewport and world transformation.

    It is advisable to use combinedTransform() instead of this
    function to preserve the properties of perspective transformations.

    \sa setWorldTransform(), setWindow(), setViewport()
*/
QMatrix QPainter::combinedMatrix() const
{
    return combinedTransform().toAffine();
}


/*!
    \obsolete

    Returns the matrix that transforms from logical coordinates to
    device coordinates of the platform dependent paint device.

    \note It is advisable to use deviceTransform() instead of this
    function to preserve the properties of perspective transformations.

    This function is \e only needed when using platform painting
    commands on the platform dependent handle (Qt::HANDLE), and the
    platform does not do transformations nativly.

    The QPaintEngine::PaintEngineFeature enum can be queried to
    determine whether the platform performs the transformations or
    not.

    \sa worldMatrix(), QPaintEngine::hasFeature(),
*/
const QMatrix &QPainter::deviceMatrix() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::deviceMatrix: Painter not active");
        return d->fakeState()->transform.toAffine();
    }
    return d->state->matrix.toAffine();
}

/*!
    \obsolete

    Resets any transformations that were made using translate(), scale(),
    shear(), rotate(), setWorldMatrix(), setViewport() and
    setWindow().

    It is advisable to use resetTransform() instead of this function
    to preserve the properties of perspective transformations.

    \sa {QPainter#Coordinate Transformations}{Coordinate
    Transformations}
*/

void QPainter::resetMatrix()
{
    resetTransform();
}


/*!
    \since 4.2

    Enables transformations if \a enable is true, or disables
    transformations if \a enable is false. The world transformation
    matrix is not changed.

    \sa worldMatrixEnabled(), worldTransform(), {QPainter#Coordinate
    Transformations}{Coordinate Transformations}
*/

void QPainter::setWorldMatrixEnabled(bool enable)
{
    Q_D(QPainter);
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::setMatrixEnabled(), enable=%d\n", enable);
#endif

    if (!d->engine) {
        qWarning("QPainter::setMatrixEnabled: Painter not active");
        return;
    }
    if (enable == d->state->WxF)
        return;

    d->state->WxF = enable;
    d->updateMatrix();
}

/*!
    \since 4.2

    Returns true if world transformation is enabled; otherwise returns
    false.

    \sa setWorldMatrixEnabled(), worldTransform(), {Coordinate System}
*/

bool QPainter::worldMatrixEnabled() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::worldMatrixEnabled: Painter not active");
        return false;
    }
    return d->state->WxF;
}

/*!
    \obsolete

    Use setWorldMatrixEnabled() instead.

    \sa setWorldMatrixEnabled()
*/

void QPainter::setMatrixEnabled(bool enable)
{
    setWorldMatrixEnabled(enable);
}

/*!
    \obsolete

    Use worldMatrixEnabled() instead

    \sa worldMatrixEnabled()
*/

bool QPainter::matrixEnabled() const
{
    return worldMatrixEnabled();
}

/*!
    Scales the coordinate system by (\a{sx}, \a{sy}).

    \sa setWorldTransform() {QPainter#Coordinate Transformations}{Coordinate
    Transformations}
*/

void QPainter::scale(qreal sx, qreal sy)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::scale(), sx=%f, sy=%f\n", sx, sy);
#endif
    Q_D(QPainter);
    if (!d->engine) {
        qWarning("QPainter::scale: Painter not active");
        return;
    }

    d->state->worldMatrix.scale(sx,sy);
    d->state->WxF = true;
    d->updateMatrix();
}

/*!
    Shears the coordinate system by (\a{sh}, \a{sv}).

    \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate
    Transformations}
*/

void QPainter::shear(qreal sh, qreal sv)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::shear(), sh=%f, sv=%f\n", sh, sv);
#endif
    Q_D(QPainter);
    if (!d->engine) {
        qWarning("QPainter::shear: Painter not active");
        return;
    }

    d->state->worldMatrix.shear(sh, sv);
    d->state->WxF = true;
    d->updateMatrix();
}

/*!
    \fn void QPainter::rotate(qreal angle)

    Rotates the coordinate system the given \a angle clockwise.

    \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate
    Transformations}
*/

void QPainter::rotate(qreal a)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::rotate(), angle=%f\n", a);
#endif
    Q_D(QPainter);
    if (!d->engine) {
        qWarning("QPainter::rotate: Painter not active");
        return;
    }

    d->state->worldMatrix.rotate(a);
    d->state->WxF = true;
    d->updateMatrix();
}

/*!
    Translates the coordinate system by the given \a offset; i.e. the
    given \a offset is added to points.

    \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate
    Transformations}
*/
void QPainter::translate(const QPointF &offset)
{
    qreal dx = offset.x();
    qreal dy = offset.y();
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::translate(), dx=%f, dy=%f\n", dx, dy);
#endif
    Q_D(QPainter);
    if (!d->engine) {
        qWarning("QPainter::translate: Painter not active");
        return;
    }

    d->state->worldMatrix.translate(dx, dy);
    d->state->WxF = true;
    d->updateMatrix();
}

/*!
    \fn void QPainter::translate(const QPoint &offset)
    \overload

    Translates the coordinate system by the given \a offset.
*/

/*!
    \fn void QPainter::translate(qreal dx, qreal dy)
    \overload

    Translates the coordinate system by the vector (\a dx, \a dy).
*/

/*!
    \fn void QPainter::setClipPath(const QPainterPath &path, Qt::ClipOperation operation)

    Enables clipping, and sets the clip path for the painter to the
    given \a path, with the clip \a operation.

    Note that the clip path is specified in logical (painter)
    coordinates.

    \sa clipPath(), clipRegion(), {QPainter#Clipping}{Clipping}

*/
void QPainter::setClipPath(const QPainterPath &path, Qt::ClipOperation op)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output) {
        QRectF b = path.boundingRect();
        printf("QPainter::setClipPath(), size=%d, op=%d, bounds=[%.2f,%.2f,%.2f,%.2f]\n",
               path.elementCount(), op, b.x(), b.y(), b.width(), b.height());
    }
#endif
    Q_D(QPainter);

    if (!d->engine) {
        qWarning("QPainter::setClipPath: Painter not active");
        return;
    }

    if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip))
        op = Qt::ReplaceClip;

    if (d->extended) {
        d->state->clipEnabled = true;
        d->extended->clip(path, op);
        if (op == Qt::NoClip || op == Qt::ReplaceClip)
            d->state->clipInfo.clear();
        d->state->clipInfo << QPainterClipInfo(path, op, d->state->matrix);
        d->state->clipOperation = op;
        return;
    }

    if (d->state->clipOperation == Qt::NoClip && op == Qt::IntersectClip)
        op = Qt::ReplaceClip;

    d->state->clipPath = path;
    d->state->clipOperation = op;
    if (op == Qt::NoClip || op == Qt::ReplaceClip)
        d->state->clipInfo.clear();
    d->state->clipInfo << QPainterClipInfo(path, op, d->state->matrix);
    d->state->clipEnabled = true;
    d->state->dirtyFlags |= QPaintEngine::DirtyClipPath | QPaintEngine::DirtyClipEnabled;
    d->updateState(d->state);
}

/*!
    Draws the outline (strokes) the path \a path with the pen specified
    by \a pen

    \sa fillPath(), {QPainter#Drawing}{Drawing}
*/
void QPainter::strokePath(const QPainterPath &path, const QPen &pen)
{
    Q_D(QPainter);

    if (!d->engine) {
        qWarning("QPainter::strokePath: Painter not active");
        return;
    }

    if (path.isEmpty())
        return;

    if (d->extended) {
        const QGradient *g = qpen_brush(pen).gradient();
        if (!g || g->coordinateMode() == QGradient::LogicalMode) {
            d->extended->stroke(qtVectorPathForPath(path), pen);
            return;
        }
    }

    QBrush oldBrush = d->state->brush;
    QPen oldPen = d->state->pen;

    setPen(pen);
    setBrush(Qt::NoBrush);

    drawPath(path);

    // Reset old state
    setPen(oldPen);
    setBrush(oldBrush);
}

/*!
    Fills the given \a path using the given \a brush. The outline is
    not drawn.

    Alternatively, you can specify a QColor instead of a QBrush; the
    QBrush constructor (taking a QColor argument) will automatically
    create a solid pattern brush.

    \sa drawPath()
*/
void QPainter::fillPath(const QPainterPath &path, const QBrush &brush)
{
    Q_D(QPainter);

    if (!d->engine) {
        qWarning("QPainter::fillPath: Painter not active");
        return;
    }

    if (path.isEmpty())
        return;

    if (d->extended) {
        const QGradient *g = brush.gradient();
        if (!g || g->coordinateMode() == QGradient::LogicalMode) {
            d->extended->fill(qtVectorPathForPath(path), brush);
            return;
        }
    }

    QBrush oldBrush = d->state->brush;
    QPen oldPen = d->state->pen;

    setPen(Qt::NoPen);
    setBrush(brush);

    drawPath(path);

    // Reset old state
    setPen(oldPen);
    setBrush(oldBrush);
}

/*!
    Draws the given painter \a path using the current pen for outline
    and the current brush for filling.

    \table 100%
    \row
    \o \inlineimage qpainter-path.png
    \o
    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 5
    \endtable

    \sa {painting/painterpaths}{the Painter Paths
    example},{demos/deform}{the Vector Deformation demo}
*/
void QPainter::drawPath(const QPainterPath &path)
{
#ifdef QT_DEBUG_DRAW
    QRectF pathBounds = path.boundingRect();
    if (qt_show_painter_debug_output)
        printf("QPainter::drawPath(), size=%d, [%.2f,%.2f,%.2f,%.2f]\n",
               path.elementCount(),
               pathBounds.x(), pathBounds.y(), pathBounds.width(), pathBounds.height());
#endif

    Q_D(QPainter);

    if (!d->engine) {
        qWarning("QPainter::drawPath: Painter not active");
        return;
    }

    if (d->extended) {
        d->extended->drawPath(path);
        return;
    }
    d->updateState(d->state);

    if (d->engine->hasFeature(QPaintEngine::PainterPaths) && d->state->emulationSpecifier == 0) {
        d->engine->drawPath(path);
    } else {
        d->draw_helper(path);
    }
}

/*!
    \fn void QPainter::drawLine(const QLineF &line)

    Draws a line defined by \a line.

    \table 100%
    \row
    \o \inlineimage qpainter-line.png
    \o
    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 6
    \endtable

    \sa drawLines(), drawPolyline(), {Coordinate System}
*/

/*!
    \fn void QPainter::drawLine(const QLine &line)
    \overload

    Draws a line defined by \a line.
*/

/*!
    \fn void QPainter::drawLine(const QPoint &p1, const QPoint &p2)
    \overload

    Draws a line from \a p1 to \a p2.
*/

/*!
    \fn void QPainter::drawLine(const QPointF &p1, const QPointF &p2)
    \overload

    Draws a line from \a p1 to \a p2.
*/

/*!
    \fn void QPainter::drawLine(int x1, int y1, int x2, int y2)
    \overload

    Draws a line from (\a x1, \a y1) to (\a x2, \a y2) and sets the
    current pen position to (\a x2, \a y2).
*/

/*!
    \fn void QPainter::drawRect(const QRectF &rectangle)

    Draws the current \a rectangle with the current pen and brush.

    A filled rectangle has a size of \a{rectangle}.size(). A stroked
    rectangle has a size of \a{rectangle}.size() plus the pen width.

    \table 100%
    \row
    \o \inlineimage qpainter-rectangle.png
    \o
    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 7
    \endtable

    \sa drawRects(), drawPolygon(), {Coordinate System}
*/

/*!
    \fn void QPainter::drawRect(const QRect &rectangle)

    \overload

    Draws the current \a rectangle with the current pen and brush.
*/

/*!
    \fn void QPainter::drawRect(int x, int y, int width, int height)

    \overload

    Draws a rectangle with upper left corner at (\a{x}, \a{y}) and
    with the given \a width and \a height.
*/

/*!
    \fn void QPainter::drawRects(const QRectF *rectangles, int rectCount)

    Draws the first \a rectCount of the given \a rectangles using the
    current pen and brush.

    \sa drawRect()
*/
void QPainter::drawRects(const QRectF *rects, int rectCount)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawRects(), count=%d\n", rectCount);
#endif
    Q_D(QPainter);

    if (!d->engine) {
        qWarning("QPainter::drawRects: Painter not active");
        return;
    }

    if (rectCount <= 0)
        return;

    if (d->extended) {
        d->extended->drawRects(rects, rectCount);
        return;
    }

    d->updateState(d->state);

    if (!d->state->emulationSpecifier) {
        d->engine->drawRects(rects, rectCount);
        return;
    }

    if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
        && d->state->matrix.type() == QTransform::TxTranslate) {
        for (int i=0; i<rectCount; ++i) {
            QRectF r(rects[i].x() + d->state->matrix.dx(),
                     rects[i].y() + d->state->matrix.dy(),
                     rects[i].width(),
                     rects[i].height());
            d->engine->drawRects(&r, 1);
        }
    } else {
        if (d->state->brushNeedsResolving() || d->state->penNeedsResolving()) {
            for (int i=0; i<rectCount; ++i) {
                QPainterPath rectPath;
                rectPath.addRect(rects[i]);
                d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
            }
        } else {
            QPainterPath rectPath;
            for (int i=0; i<rectCount; ++i)
                rectPath.addRect(rects[i]);
            d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
        }
    }
}

/*!
    \fn void QPainter::drawRects(const QRect *rectangles, int rectCount)
    \overload

    Draws the first \a rectCount of the given \a rectangles using the
    current pen and brush.
*/
void QPainter::drawRects(const QRect *rects, int rectCount)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawRects(), count=%d\n", rectCount);
#endif
    Q_D(QPainter);

    if (!d->engine) {
        qWarning("QPainter::drawRects: Painter not active");
        return;
    }

    if (rectCount <= 0)
        return;

    if (d->extended) {
        d->extended->drawRects(rects, rectCount);
        return;
    }

    d->updateState(d->state);

    if (!d->state->emulationSpecifier) {
        d->engine->drawRects(rects, rectCount);
        return;
    }

    if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
        && d->state->matrix.type() == QTransform::TxTranslate) {
        for (int i=0; i<rectCount; ++i) {
            QRectF r(rects[i].x() + d->state->matrix.dx(),
                     rects[i].y() + d->state->matrix.dy(),
                     rects[i].width(),
                     rects[i].height());

            d->engine->drawRects(&r, 1);
        }
    } else {
        if (d->state->brushNeedsResolving() || d->state->penNeedsResolving()) {
            for (int i=0; i<rectCount; ++i) {
                QPainterPath rectPath;
                rectPath.addRect(rects[i]);
                d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
            }
        } else {
            QPainterPath rectPath;
            for (int i=0; i<rectCount; ++i)
                rectPath.addRect(rects[i]);

            d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
        }
    }
}

/*!
    \fn void QPainter::drawRects(const QVector<QRectF> &rectangles)
    \overload

    Draws the given \a rectangles using the current pen and brush.
*/

/*!
    \fn void QPainter::drawRects(const QVector<QRect> &rectangles)

    \overload

    Draws the given \a rectangles using the current pen and brush.
*/

/*!
  \fn void QPainter::drawPoint(const QPointF &position)

    Draws a single point at the given \a position using the current
    pen's color.

    \sa {Coordinate System}
*/

/*!
    \fn void QPainter::drawPoint(const QPoint &position)
    \overload

    Draws a single point at the given \a position using the current
    pen's color.
*/

/*! \fn void QPainter::drawPoint(int x, int y)

    \overload

    Draws a single point at position (\a x, \a y).
*/

/*!
    Draws the first \a pointCount points in the array \a points using
    the current pen's color.

    \sa {Coordinate System}
*/
void QPainter::drawPoints(const QPointF *points, int pointCount)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawPoints(), count=%d\n", pointCount);
#endif
    Q_D(QPainter);

    if (!d->engine) {
        qWarning("QPainter::drawPoints: Painter not active");
        return;
    }

    if (pointCount <= 0)
        return;

    if (d->extended) {
        d->extended->drawPoints(points, pointCount);
        return;
    }

    d->updateState(d->state);

    if (!d->state->emulationSpecifier) {
        d->engine->drawPoints(points, pointCount);
        return;
    }

    if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
        && d->state->matrix.type() == QTransform::TxTranslate) {
        // ### use drawPoints function
        for (int i=0; i<pointCount; ++i) {
            QPointF pt(points[i].x() + d->state->matrix.dx(),
                       points[i].y() + d->state->matrix.dy());
            d->engine->drawPoints(&pt, 1);
        }
    } else {
        QPen pen = d->state->pen;
        bool flat_pen = pen.capStyle() == Qt::FlatCap;
        if (flat_pen) {
            save();
            pen.setCapStyle(Qt::SquareCap);
            setPen(pen);
        }
        QPainterPath path;
        for (int i=0; i<pointCount; ++i) {
            path.moveTo(points[i].x(), points[i].y());
            path.lineTo(points[i].x() + 0.0001, points[i].y());
        }
        d->draw_helper(path, QPainterPrivate::StrokeDraw);
        if (flat_pen)
            restore();
    }
}

/*!
    \overload

    Draws the first \a pointCount points in the array \a points using
    the current pen's color.
*/

void QPainter::drawPoints(const QPoint *points, int pointCount)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawPoints(), count=%d\n", pointCount);
#endif
    Q_D(QPainter);

    if (!d->engine) {
        qWarning("QPainter::drawPoints: Painter not active");
        return;
    }

    if (pointCount <= 0)
        return;

    if (d->extended) {
        d->extended->drawPoints(points, pointCount);
        return;
    }

    d->updateState(d->state);

    if (!d->state->emulationSpecifier) {
        d->engine->drawPoints(points, pointCount);
        return;
    }

    if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
        && d->state->matrix.type() == QTransform::TxTranslate) {
        // ### use drawPoints function
        for (int i=0; i<pointCount; ++i) {
            QPointF pt(points[i].x() + d->state->matrix.dx(),
                       points[i].y() + d->state->matrix.dy());
            d->engine->drawPoints(&pt, 1);
        }
    } else {
        QPen pen = d->state->pen;
        bool flat_pen = (pen.capStyle() == Qt::FlatCap);
        if (flat_pen) {
            save();
            pen.setCapStyle(Qt::SquareCap);
            setPen(pen);
        }
        QPainterPath path;
        for (int i=0; i<pointCount; ++i) {
            path.moveTo(points[i].x(), points[i].y());
            path.lineTo(points[i].x() + 0.0001, points[i].y());
        }
        d->draw_helper(path, QPainterPrivate::StrokeDraw);
        if (flat_pen)
            restore();
    }
}

/*!
    \fn void QPainter::drawPoints(const QPolygonF &points)

    \overload

    Draws the points in the vector  \a points.
*/

/*!
    \fn void QPainter::drawPoints(const QPolygon &points)

    \overload

    Draws the points in the vector  \a points.
*/

/*!
    \fn void QPainter::drawPoints(const QPolygon &polygon, int index,
    int count)

    \overload
    \compat

    Draws \a count points in the vector \a polygon starting on \a index
    using the current pen.

    Use drawPoints() combined with QPolygon::constData() instead.

    \oldcode
        QPainter painter(this);
        painter.drawPoints(polygon, index, count);
    \newcode
        int pointCount = (count == -1) ?  polygon.size() - index : count;

        QPainter painter(this);
        painter.drawPoints(polygon.constData() + index, pointCount);
    \endcode
*/

/*!
    Sets the background mode of the painter to the given \a mode

    Qt::TransparentMode (the default) draws stippled lines and text
    without setting the background pixels.  Qt::OpaqueMode fills these
    space with the current background color.

    Note that in order to draw a bitmap or pixmap transparently, you
    must use QPixmap::setMask().

    \sa backgroundMode(), setBackground(),
    {QPainter#Settings}{Settings}
*/

void QPainter::setBackgroundMode(Qt::BGMode mode)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::setBackgroundMode(), mode=%d\n", mode);
#endif

    Q_D(QPainter);
    if (!d->engine) {
        qWarning("QPainter::setBackgroundMode: Painter not active");
        return;
    }
    if (d->state->bgMode == mode)
        return;

    d->state->bgMode = mode;
    if (d->extended) {
        d->checkEmulation();
    } else {
        d->state->dirtyFlags |= QPaintEngine::DirtyBackgroundMode;
    }
}

/*!
    Returns the current background mode.

    \sa setBackgroundMode(), {QPainter#Settings}{Settings}
*/
Qt::BGMode QPainter::backgroundMode() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::backgroundMode: Painter not active");
        return Qt::TransparentMode;
    }
    return d->state->bgMode;
}


/*!
    \overload

    Sets the painter's pen to have style Qt::SolidLine, width 0 and the
    specified \a color.
*/

void QPainter::setPen(const QColor &color)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::setPen(), color=%04x\n", color.rgb());
#endif
    Q_D(QPainter);
    if (!d->engine) {
        qWarning("QPainter::setPen: Painter not active");
        return;
    }

    if (d->state->pen.style() == Qt::SolidLine
        && d->state->pen.widthF() == 0
        && d->state->pen.isSolid()
        && d->state->pen.color() == color)
        return;

    QPen pen(color.isValid() ? color : QColor(Qt::black), 0, Qt::SolidLine);

    d->state->pen = pen;
    if (d->extended)
        d->extended->penChanged();
    else
        d->state->dirtyFlags |= QPaintEngine::DirtyPen;
}

/*!
    Sets the painter's pen to be the given \a pen.

    The \a pen defines how to draw lines and outlines, and it also
    defines the text color.

    \sa pen(), {QPainter#Settings}{Settings}
*/

void QPainter::setPen(const QPen &pen)
{

#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::setPen(), color=%04x, (brushStyle=%d) style=%d, cap=%d, join=%d\n",
           pen.color().rgb(), pen.brush().style(), pen.style(), pen.capStyle(), pen.joinStyle());
#endif
    Q_D(QPainter);
    if (!d->engine) {
        qWarning("QPainter::setPen: Painter not active");
        return;
    }

    if (d->state->pen == pen)
        return;

    d->state->pen = pen;

    if (d->extended) {
        d->checkEmulation();
        d->extended->penChanged();
        return;
    }

    d->state->dirtyFlags |= QPaintEngine::DirtyPen;
}

/*!
    \overload

    Sets the painter's pen to have the given \a style, width 0 and
    black color.
*/

void QPainter::setPen(Qt::PenStyle style)
{
    Q_D(QPainter);
    if (!d->engine) {
        qWarning("QPainter::setPen: Painter not active");
        return;
    }

    if (d->state->pen.style() == style
        && (style == Qt::NoPen || (d->state->pen.widthF() == 0
                                   && d->state->pen.isSolid()
                                   && d->state->pen.color() == QColor(Qt::black))))
        return;

    // QPen(Qt::NoPen) is to avoid creating QPenData, including its brush (from the color)
    // Note that this works well as long as QPen(Qt::NoPen) returns a black, zero-width pen
    d->state->pen = (style == Qt::NoPen) ? QPen(Qt::NoPen) : QPen(Qt::black, 0, style);

    if (d->extended)
        d->extended->penChanged();
    else
        d->state->dirtyFlags |= QPaintEngine::DirtyPen;

}

/*!
    Returns the painter's current pen.

    \sa setPen(), {QPainter#Settings}{Settings}
*/

const QPen &QPainter::pen() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::pen: Painter not active");
        return d->fakeState()->pen;
    }
    return d->state->pen;
}


/*!
    Sets the painter's brush to the given \a brush.

    The painter's brush defines how shapes are filled.

    \sa brush(), {QPainter#Settings}{Settings}
*/

void QPainter::setBrush(const QBrush &brush)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::setBrush(), color=%04x, style=%d\n", brush.color().rgb(), brush.style());
#endif
    Q_D(QPainter);
    if (!d->engine) {
        qWarning("QPainter::setBrush: Painter not active");
        return;
    }

    if (d->state->brush.d == brush.d)
        return;

    if (d->extended) {
        d->state->brush = brush;
        d->checkEmulation();
        d->extended->brushChanged();
        return;
    }

    d->state->brush = brush;
    d->state->dirtyFlags |= QPaintEngine::DirtyBrush;
}


/*!
    \overload

    Sets the painter's brush to black color and the specified \a
    style.
*/

void QPainter::setBrush(Qt::BrushStyle style)
{
    Q_D(QPainter);
    if (!d->engine) {
        qWarning("QPainter::setBrush: Painter not active");
        return;
    }
    if (d->state->brush.style() == style &&
        (style == Qt::NoBrush
         || (style == Qt::SolidPattern && d->state->brush.color() == QColor(0, 0, 0))))
        return;
    d->state->brush = QBrush(Qt::black, style);
    if (d->extended)
        d->extended->brushChanged();
    else
        d->state->dirtyFlags |= QPaintEngine::DirtyBrush;
}

/*!
    Returns the painter's current brush.

    \sa QPainter::setBrush(), {QPainter#Settings}{Settings}
*/

const QBrush &QPainter::brush() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::brush: Painter not active");
        return d->fakeState()->brush;
    }
    return d->state->brush;
}

/*!
    \fn void QPainter::setBackground(const QBrush &brush)

    Sets the background brush of the painter to the given \a brush.

    The background brush is the brush that is filled in when drawing
    opaque text, stippled lines and bitmaps. The background brush has
    no effect in transparent background mode (which is the default).

    \sa background(), setBackgroundMode(),
    {QPainter#Settings}{Settings}
*/

void QPainter::setBackground(const QBrush &bg)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::setBackground(), color=%04x, style=%d\n", bg.color().rgb(), bg.style());
#endif

    Q_D(QPainter);
    if (!d->engine) {
        qWarning("QPainter::setBackground: Painter not active");
        return;
    }
    d->state->bgBrush = bg;
    if (!d->extended)
        d->state->dirtyFlags |= QPaintEngine::DirtyBackground;
}

/*!
    Sets the painter's font to the given \a font.

    This font is used by subsequent drawText() functions. The text
    color is the same as the pen color.

    If you set a font that isn't available, Qt finds a close match.
    font() will return what you set using setFont() and fontInfo() returns the
    font actually being used (which may be the same).

    \sa font(), drawText(), {QPainter#Settings}{Settings}
*/

void QPainter::setFont(const QFont &font)
{
    Q_D(QPainter);

#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::setFont(), family=%s, pointSize=%d\n", font.family().toLatin1().constData(), font.pointSize());
#endif

    if (!d->engine) {
        qWarning("QPainter::setFont: Painter not active");
        return;
    }

    d->state->font = QFont(font.resolve(d->state->deviceFont), device());
    if (!d->extended)
        d->state->dirtyFlags |= QPaintEngine::DirtyFont;
}

/*!
    Returns the currently set font used for drawing text.

    \sa setFont(), drawText(), {QPainter#Settings}{Settings}
*/
const QFont &QPainter::font() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::font: Painter not active");
        return d->fakeState()->font;
    }
    return d->state->font;
}

/*!
    \since 4.4

    Draws the given rectangle \a rect with rounded corners.

    The \a xRadius and \a yRadius arguments specify the radii
    of the ellipses defining the corners of the rounded rectangle.
    When \a mode is Qt::RelativeSize, \a xRadius and
    \a yRadius are specified in percentage of half the rectangle's
    width and height respectively, and should be in the range
    0.0 to 100.0.

    A filled rectangle has a size of rect.size(). A stroked rectangle
    has a size of rect.size() plus the pen width.

    \table 100%
    \row
    \o \inlineimage qpainter-roundrect.png
    \o
    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 8
    \endtable

    \sa drawRect(), QPen
*/
void QPainter::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawRoundedRect(), [%.2f,%.2f,%.2f,%.2f]\n", rect.x(), rect.y(), rect.width(), rect.height());
#endif
    Q_D(QPainter);

    if (!d->engine)
        return;

    if (xRadius <= 0 || yRadius <= 0) {             // draw normal rectangle
        drawRect(rect);
        return;
    }

    if (d->extended) {
        d->extended->drawRoundedRect(rect, xRadius, yRadius, mode);
        return;
    }

    QPainterPath path;
    path.addRoundedRect(rect, xRadius, yRadius, mode);
    drawPath(path);
}

/*!
    \fn void QPainter::drawRoundedRect(const QRect &rect, qreal xRadius, qreal yRadius,
                                       Qt::SizeMode mode = Qt::AbsoluteSize);
    \since 4.4
    \overload

    Draws the given rectangle \a rect with rounded corners.
*/

/*!
    \fn void QPainter::drawRoundedRect(int x, int y, int w, int h, qreal xRadius, qreal yRadius,
                                       Qt::SizeMode mode = Qt::AbsoluteSize);
    \since 4.4
    \overload

    Draws the given rectangle \a x, \a y, \a w, \a h with rounded corners.
*/

/*!
    \obsolete

    Draws a rectangle \a r with rounded corners.

    The \a xRnd and \a yRnd arguments specify how rounded the corners
    should be. 0 is angled corners, 99 is maximum roundedness.

    A filled rectangle has a size of r.size(). A stroked rectangle
    has a size of r.size() plus the pen width.

    \sa drawRoundedRect()
*/
void QPainter::drawRoundRect(const QRectF &r, int xRnd, int yRnd)
{
    drawRoundedRect(r, xRnd, yRnd, Qt::RelativeSize);
}


/*!
    \fn void QPainter::drawRoundRect(const QRect &r, int xRnd = 25, int yRnd = 25)

    \overload
    \obsolete

    Draws the rectangle \a r with rounded corners.
*/

/*!
    \obsolete

    \fn QPainter::drawRoundRect(int x, int y, int w, int h, int xRnd, int yRnd)

    \overload

    Draws the rectangle \a x, \a y, \a w, \a h with rounded corners.
*/

/*!
    \fn void QPainter::drawEllipse(const QRectF &rectangle)

    Draws the ellipse defined by the given \a rectangle.

    A filled ellipse has a size of \a{rectangle}.\l
    {QRect::size()}{size()}. A stroked ellipse has a size of
    \a{rectangle}.\l {QRect::size()}{size()} plus the pen width.

    \table 100%
    \row
    \o \inlineimage qpainter-ellipse.png
    \o
    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 9
    \endtable

    \sa drawPie(), {Coordinate System}
*/
void QPainter::drawEllipse(const QRectF &r)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawEllipse(), [%.2f,%.2f,%.2f,%.2f]\n", r.x(), r.y(), r.width(), r.height());
#endif
    Q_D(QPainter);

    if (!d->engine)
        return;

    QRectF rect(r.normalized());

    if (d->extended) {
        d->extended->drawEllipse(rect);
        return;
    }

    d->updateState(d->state);
    if (d->state->emulationSpecifier) {
        if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
            && d->state->matrix.type() == QTransform::TxTranslate) {
            rect.translate(QPointF(d->state->matrix.dx(), d->state->matrix.dy()));
        } else {
            QPainterPath path;
            path.addEllipse(rect);
            d->draw_helper(path, QPainterPrivate::StrokeAndFillDraw);
            return;
        }
    }

    d->engine->drawEllipse(rect);
}

/*!
    \fn QPainter::drawEllipse(const QRect &rectangle)

    \overload

    Draws the ellipse defined by the given \a rectangle.
*/
void QPainter::drawEllipse(const QRect &r)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawEllipse(), [%d,%d,%d,%d]\n", r.x(), r.y(), r.width(), r.height());
#endif
    Q_D(QPainter);

    if (!d->engine)
        return;

    QRect rect(r.normalized());

    if (d->extended) {
        d->extended->drawEllipse(rect);
        return;
    }

    d->updateState(d->state);

    if (d->state->emulationSpecifier) {
        if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
            && d->state->matrix.type() == QTransform::TxTranslate) {
            rect.translate(QPoint(qRound(d->state->matrix.dx()), qRound(d->state->matrix.dy())));
        } else {
            QPainterPath path;
            path.addEllipse(rect);
            d->draw_helper(path, QPainterPrivate::StrokeAndFillDraw);
            return;
        }
    }

    d->engine->drawEllipse(rect);
}

/*!
    \fn QPainter::drawEllipse(int x, int y, int width, int height)

    \overload

    Draws the ellipse defined by the rectangle beginning at (\a{x},
    \a{y}) with the given \a width and \a height.
*/

/*!
    \since 4.4

    \fn QPainter::drawEllipse(const QPointF &center, qreal rx, qreal ry)

    \overload

    Draws the ellipse positioned at \a{center} with radii \a{rx} and \a{ry}.
*/

/*!
    \since 4.4

    \fn QPainter::drawEllipse(const QPoint &center, int rx, int ry)

    \overload

    Draws the ellipse positioned at \a{center} with radii \a{rx} and \a{ry}.
*/

/*!
    \fn void QPainter::drawArc(const QRectF &rectangle, int startAngle, int spanAngle)

    Draws the arc defined by the given \a rectangle, \a startAngle and
    \a spanAngle.

    The \a startAngle and \a spanAngle must be specified in 1/16th of
    a degree, i.e. a full circle equals 5760 (16 * 360). Positive
    values for the angles mean counter-clockwise while negative values
    mean the clockwise direction. Zero degrees is at the 3 o'clock
    position.

    \table 100%
    \row
    \o \inlineimage qpainter-arc.png
    \o
    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 10
    \endtable

    \sa drawPie(), drawChord(), {Coordinate System}
*/

void QPainter::drawArc(const QRectF &r, int a, int alen)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawArc(), [%.2f,%.2f,%.2f,%.2f], angle=%d, sweep=%d\n",
           r.x(), r.y(), r.width(), r.height(), a/16, alen/16);
#endif
    Q_D(QPainter);

    if (!d->engine)
        return;

    QRectF rect = r.normalized();

    QPainterPath path;
    path.arcMoveTo(rect, a/16.0);
    path.arcTo(rect, a/16.0, alen/16.0);
    strokePath(path, d->state->pen);
}

/*! \fn void QPainter::drawArc(const QRect &rectangle, int startAngle,
                               int spanAngle)

    \overload

    Draws the arc defined by the given \a rectangle, \a startAngle and
    \a spanAngle.
*/

/*!
    \fn void QPainter::drawArc(int x, int y, int width, int height,
                               int startAngle, int spanAngle)

    \overload

    Draws the arc defined by the rectangle beginning at (\a x, \a y)
    with the specified \a width and \a height, and the given \a
    startAngle and \a spanAngle.
*/

/*!
    \fn void QPainter::drawPie(const QRectF &rectangle, int startAngle, int spanAngle)

    Draws a pie defined by the given \a rectangle, \a startAngle and
    and \a spanAngle.

    The pie is filled with the current brush().

    The startAngle and spanAngle must be specified in 1/16th of a
    degree, i.e. a full circle equals 5760 (16 * 360). Positive values
    for the angles mean counter-clockwise while negative values mean
    the clockwise direction. Zero degrees is at the 3 o'clock
    position.

    \table 100%
    \row
    \o \inlineimage qpainter-pie.png
    \o
    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 11
    \endtable

    \sa drawEllipse(), drawChord(), {Coordinate System}
*/
void QPainter::drawPie(const QRectF &r, int a, int alen)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawPie(), [%.2f,%.2f,%.2f,%.2f], angle=%d, sweep=%d\n",
           r.x(), r.y(), r.width(), r.height(), a/16, alen/16);
#endif
    Q_D(QPainter);

    if (!d->engine)
        return;

    if (a > (360*16)) {
        a = a % (360*16);
    } else if (a < 0) {
        a = a % (360*16);
        if (a < 0) a += (360*16);
    }

    QRectF rect = r.normalized();

    QPainterPath path;
    path.moveTo(rect.center());
    path.arcTo(rect.x(), rect.y(), rect.width(), rect.height(), a/16.0, alen/16.0);
    path.closeSubpath();
    drawPath(path);

}

/*!
    \fn void QPainter::drawPie(const QRect &rectangle, int startAngle, int spanAngle)
    \overload

    Draws a pie defined by the given \a rectangle, \a startAngle and
    and \a spanAngle.
*/

/*!
    \fn void QPainter::drawPie(int x, int y, int width, int height, int
    startAngle, int spanAngle)

    \overload

    Draws the pie defined by the rectangle beginning at (\a x, \a y) with
    the specified \a width and \a height, and the given \a startAngle and
    \a spanAngle.
*/

/*!
    \fn void QPainter::drawChord(const QRectF &rectangle, int startAngle, int spanAngle)

    Draws the chord defined by the given \a rectangle, \a startAngle and
    \a spanAngle.  The chord is filled with the current brush().

    The startAngle and spanAngle must be specified in 1/16th of a
    degree, i.e. a full circle equals 5760 (16 * 360). Positive values
    for the angles mean counter-clockwise while negative values mean
    the clockwise direction. Zero degrees is at the 3 o'clock
    position.

    \table 100%
    \row
    \o \inlineimage qpainter-chord.png
    \o
    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 12
    \endtable

    \sa drawArc(), drawPie(), {Coordinate System}
*/
void QPainter::drawChord(const QRectF &r, int a, int alen)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawChord(), [%.2f,%.2f,%.2f,%.2f], angle=%d, sweep=%d\n",
           r.x(), r.y(), r.width(), r.height(), a/16, alen/16);
#endif
    Q_D(QPainter);

    if (!d->engine)
        return;

    QRectF rect = r.normalized();

    QPainterPath path;
    path.arcMoveTo(rect, a/16.0);
    path.arcTo(rect, a/16.0, alen/16.0);
    path.closeSubpath();
    drawPath(path);
}
/*!
    \fn void QPainter::drawChord(const QRect &rectangle, int startAngle, int spanAngle)

    \overload

    Draws the chord defined by the given \a rectangle, \a startAngle and
    \a spanAngle.
*/

/*!
    \fn void QPainter::drawChord(int x, int y, int width, int height, int
    startAngle, int spanAngle)

    \overload

   Draws the chord defined by the rectangle beginning at (\a x, \a y)
   with the specified \a width and \a height, and the given \a
   startAngle and \a spanAngle.
*/

#ifdef QT3_SUPPORT
/*!
    \fn void QPainter::drawLineSegments(const QPolygon &polygon, int
    index, int count)

    Draws \a count separate lines from points defined by the \a
    polygon, starting at \a{polygon}\e{[index]} (\a index defaults to
    0). If \a count is -1 (the default) all points until the end of
    the array are used.

    Use drawLines() combined with QPolygon::constData() instead.

    \oldcode
        QPainter painter(this);
        painter.drawLineSegments(polygon, index, count);
    \newcode
        int lineCount = (count == -1) ?  (polygon.size() - index) / 2  : count;

        QPainter painter(this);
        painter.drawLines(polygon.constData() + index * 2, lineCount);
    \endcode
*/

void QPainter::drawLineSegments(const QPolygon &a, int index, int nlines)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawLineSegments(), count=%d\n", a.size()/2);
#endif
    Q_D(QPainter);

    if (!d->engine)
        return;

    if (nlines < 0)
        nlines = a.size()/2 - index/2;
    if (index + nlines*2 > (int)a.size())
        nlines = (a.size() - index)/2;
    if (nlines < 1 || index < 0)
        return;

    if (d->extended) {
        // FALCON: Use QVectorPath
        QVector<QLineF> lines;
        for (int i=index; i<index + nlines*2; i+=2)
            lines << QLineF(a.at(i), a.at(i+1));
        d->extended->drawLines(lines.data(), lines.size());
        return;
    }

    d->updateState(d->state);

    QVector<QLineF> lines;
    if (d->state->emulationSpecifier) {
        if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
            && d->state->matrix.type() == QTransform::TxTranslate) {
            QPointF offset(d->state->matrix.dx(), d->state->matrix.dy());
            for (int i=index; i<index + nlines*2; i+=2)
                lines << QLineF(a.at(i) + offset, a.at(i+1) + offset);
        } else {
            QPainterPath linesPath;
            for (int i=index; i<index + nlines*2; i+=2) {
                linesPath.moveTo(a.at(i));
                linesPath.lineTo(a.at(i+1));
            }
            d->draw_helper(linesPath, QPainterPrivate::StrokeDraw);
            return;
        }
    } else {
        for (int i=index; i<index + nlines*2; i+=2)
            lines << QLineF(a.at(i), a.at(i+1));
    }

    d->engine->drawLines(lines.data(), lines.size());
}
#endif // QT3_SUPPORT

/*!
    Draws the first \a lineCount lines in the array \a lines
    using the current pen.

    \sa drawLine(), drawPolyline()
*/
void QPainter::drawLines(const QLineF *lines, int lineCount)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawLines(), line count=%d\n", lineCount);
#endif

    Q_D(QPainter);

    if (!d->engine || lineCount < 1)
        return;

    if (d->extended) {
        d->extended->drawLines(lines, lineCount);
        return;
    }

    d->updateState(d->state);

    uint lineEmulation = line_emulation(d->state->emulationSpecifier);

    if (lineEmulation) {
        if (lineEmulation == QPaintEngine::PrimitiveTransform
            && d->state->matrix.type() == QTransform::TxTranslate) {
            for (int i = 0; i < lineCount; ++i) {
                QLineF line = lines[i];
                line.translate(d->state->matrix.dx(), d->state->matrix.dy());
                d->engine->drawLines(&line, 1);
            }
        } else {
            QPainterPath linePath;
            for (int i = 0; i < lineCount; ++i) {
                linePath.moveTo(lines[i].p1());
                linePath.lineTo(lines[i].p2());
            }
            d->draw_helper(linePath, QPainterPrivate::StrokeDraw);
        }
        return;
    }
    d->engine->drawLines(lines, lineCount);
}

/*!
    \fn void QPainter::drawLines(const QLine *lines, int lineCount)
    \overload

    Draws the first \a lineCount lines in the array \a lines
    using the current pen.
*/
void QPainter::drawLines(const QLine *lines, int lineCount)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawLine(), line count=%d\n", lineCount);
#endif

    Q_D(QPainter);

    if (!d->engine || lineCount < 1)
        return;

    if (d->extended) {
        d->extended->drawLines(lines, lineCount);
        return;
    }

    d->updateState(d->state);

    uint lineEmulation = line_emulation(d->state->emulationSpecifier);

    if (lineEmulation) {
        if (lineEmulation == QPaintEngine::PrimitiveTransform
            && d->state->matrix.type() == QTransform::TxTranslate) {
            for (int i = 0; i < lineCount; ++i) {
                QLineF line = lines[i];
                line.translate(d->state->matrix.dx(), d->state->matrix.dy());
                d->engine->drawLines(&line, 1);
            }
        } else {
            QPainterPath linePath;
            for (int i = 0; i < lineCount; ++i) {
                linePath.moveTo(lines[i].p1());
                linePath.lineTo(lines[i].p2());
            }
            d->draw_helper(linePath, QPainterPrivate::StrokeDraw);
        }
        return;
    }
    d->engine->drawLines(lines, lineCount);
}

/*!
    \overload

    Draws the first \a lineCount lines in the array \a pointPairs
    using the current pen.  The lines are specified as pairs of points
    so the number of entries in \a pointPairs must be at least \a
    lineCount * 2.
*/
void QPainter::drawLines(const QPointF *pointPairs, int lineCount)
{
    Q_ASSERT(sizeof(QLineF) == 2*sizeof(QPointF));

    drawLines((QLineF*)pointPairs, lineCount);
}

/*!
    \overload

    Draws the first \a lineCount lines in the array \a pointPairs
    using the current pen.
*/
void QPainter::drawLines(const QPoint *pointPairs, int lineCount)
{
    Q_ASSERT(sizeof(QLine) == 2*sizeof(QPoint));

    drawLines((QLine*)pointPairs, lineCount);
}


/*!
    \fn void QPainter::drawLines(const QVector<QPointF> &pointPairs)
    \overload

    Draws a line for each pair of points in the vector \a pointPairs
    using the current pen. If there is an odd number of points in the
    array, the last point will be ignored.
*/

/*!
    \fn void QPainter::drawLines(const QVector<QPoint> &pointPairs)
    \overload

    Draws a line for each pair of points in the vector \a pointPairs
    using the current pen.
*/

/*!
    \fn void QPainter::drawLines(const QVector<QLineF> &lines)
    \overload

    Draws the set of lines defined by the list \a lines using the
    current pen and brush.
*/

/*!
    \fn void QPainter::drawLines(const QVector<QLine> &lines)
    \overload

    Draws the set of lines defined by the list \a lines using the
    current pen and brush.
*/

/*!
    Draws the polyline defined by the first \a pointCount points in \a
    points using the current pen.

    Note that unlike the drawPolygon() function the last point is \e
    not connected to the first, neither is the polyline filled.

    \table 100%
    \row
    \o
    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 13
    \endtable

    \sa drawLines(), drawPolygon(), {Coordinate System}
*/
void QPainter::drawPolyline(const QPointF *points, int pointCount)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawPolyline(), count=%d\n", pointCount);
#endif
    Q_D(QPainter);

    if (!d->engine || pointCount < 2)
        return;

    if (d->extended) {
        d->extended->drawPolygon(points, pointCount, QPaintEngine::PolylineMode);
        return;
    }

    d->updateState(d->state);

    uint lineEmulation = line_emulation(d->state->emulationSpecifier);

    if (lineEmulation) {
        // ###
//         if (lineEmulation == QPaintEngine::PrimitiveTransform
//             && d->state->matrix.type() == QTransform::TxTranslate) {
//         } else {
        QPainterPath polylinePath(points[0]);
        for (int i=1; i<pointCount; ++i)
            polylinePath.lineTo(points[i]);
        d->draw_helper(polylinePath, QPainterPrivate::StrokeDraw);
//         }
    } else {
        d->engine->drawPolygon(points, pointCount, QPaintEngine::PolylineMode);
    }
}

/*!
    \overload

    Draws the polyline defined by the first \a pointCount points in \a
    points using the current pen.
 */
void QPainter::drawPolyline(const QPoint *points, int pointCount)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawPolyline(), count=%d\n", pointCount);
#endif
    Q_D(QPainter);

    if (!d->engine || pointCount < 2)
        return;

    if (d->extended) {
        d->extended->drawPolygon(points, pointCount, QPaintEngine::PolylineMode);
        return;
    }

    d->updateState(d->state);

    uint lineEmulation = line_emulation(d->state->emulationSpecifier);

    if (lineEmulation) {
        // ###
//         if (lineEmulation == QPaintEngine::PrimitiveTransform
//             && d->state->matrix.type() == QTransform::TxTranslate) {
//         } else {
        QPainterPath polylinePath(points[0]);
        for (int i=1; i<pointCount; ++i)
            polylinePath.lineTo(points[i]);
        d->draw_helper(polylinePath, QPainterPrivate::StrokeDraw);
//         }
    } else {
        d->engine->drawPolygon(points, pointCount, QPaintEngine::PolylineMode);
    }
}

/*!
    \fn void QPainter::drawPolyline(const QPolygon &polygon, int index, int
    count)

    \overload
    \compat

    Draws the polyline defined by the \a count lines of the given \a
    polygon starting at \a index (\a index defaults to 0).

    Use drawPolyline() combined with QPolygon::constData() instead.

    \oldcode
        QPainter painter(this);
        painter.drawPolyline(polygon, index, count);
    \newcode
        int pointCount = (count == -1) ?  polygon.size() - index : count;

        QPainter painter(this);
        painter.drawPolyline(polygon.constData() + index, pointCount);
    \endcode
*/

/*!
    \fn void QPainter::drawPolyline(const QPolygonF &points)

    \overload

    Draws the polyline defined by the given \a points using the
    current pen.
*/

/*!
    \fn void QPainter::drawPolyline(const QPolygon &points)

    \overload

    Draws the polyline defined by the given \a points using the
    current pen.
*/

/*!
    Draws the polygon defined by the first \a pointCount points in the
    array \a points using the current pen and brush.

    \table 100%
    \row
    \o \inlineimage qpainter-polygon.png
    \o
    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 14
    \endtable

    The first point is implicitly connected to the last point, and the
    polygon is filled with the current brush().

    If \a fillRule is Qt::WindingFill, the polygon is filled using the
    winding fill algorithm.  If \a fillRule is Qt::OddEvenFill, the
    polygon is filled using the odd-even fill algorithm. See
    \l{Qt::FillRule} for a more detailed description of these fill
    rules.

    \sa  drawConvexPolygon(), drawPolyline(), {Coordinate System}
*/
void QPainter::drawPolygon(const QPointF *points, int pointCount, Qt::FillRule fillRule)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawPolygon(), count=%d\n", pointCount);
#endif

    Q_D(QPainter);

    if (!d->engine || pointCount < 2)
        return;

    if (d->extended) {
        d->extended->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
        return;
    }

    d->updateState(d->state);

    uint emulationSpecifier = d->state->emulationSpecifier;

    if (emulationSpecifier) {
        QPainterPath polygonPath(points[0]);
        for (int i=1; i<pointCount; ++i)
            polygonPath.lineTo(points[i]);
        polygonPath.closeSubpath();
        polygonPath.setFillRule(fillRule);
        d->draw_helper(polygonPath);
        return;
    }

    d->engine->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
}

/*! \overload

    Draws the polygon defined by the first \a pointCount points in the
    array \a points.
*/
void QPainter::drawPolygon(const QPoint *points, int pointCount, Qt::FillRule fillRule)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawPolygon(), count=%d\n", pointCount);
#endif

    Q_D(QPainter);

    if (!d->engine || pointCount < 2)
        return;

    if (d->extended) {
        d->extended->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
        return;
    }

    d->updateState(d->state);

    uint emulationSpecifier = d->state->emulationSpecifier;

    if (emulationSpecifier) {
        QPainterPath polygonPath(points[0]);
        for (int i=1; i<pointCount; ++i)
            polygonPath.lineTo(points[i]);
        polygonPath.closeSubpath();
        polygonPath.setFillRule(fillRule);
        d->draw_helper(polygonPath);
        return;
    }

    d->engine->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
}

/*! \fn void QPainter::drawPolygon(const QPolygonF &polygon, bool winding, int index = 0,
                                   int count = -1)
    \compat
    \overload

    Use drawPolygon() combined with QPolygonF::constData() instead.

    \oldcode
        QPainter painter(this);
        painter.drawPolygon(polygon, winding, index, count);
    \newcode
        int pointCount = (count == -1) ?  polygon.size() - index : count;
        int fillRule = winding ? Qt::WindingFill : Qt::OddEvenFill;

        QPainter painter(this);
        painter.drawPolygon( polygon.constData() + index, pointCount, fillRule);
    \endcode
*/

/*! \fn void QPainter::drawPolygon(const QPolygon &polygon, bool winding,
                                   int index = 0, int count = -1)

    \compat
    \overload

    Use drawPolygon() combined with QPolygon::constData() instead.

    \oldcode
        QPainter painter(this);
        painter.drawPolygon(polygon, winding, index, count);
    \newcode
        int pointCount = (count == -1) ?  polygon.size() - index : count;
        int fillRule = winding ? Qt::WindingFill : Qt::OddEvenFill;

        QPainter painter(this);
        painter.drawPolygon( polygon.constData() + index, pointCount, fillRule);
    \endcode
*/

/*! \fn void QPainter::drawPolygon(const QPolygonF &points, Qt::FillRule fillRule)

    \overload

    Draws the polygon defined by the given \a points using the fill
    rule \a fillRule.
*/

/*! \fn void QPainter::drawPolygon(const QPolygon &points, Qt::FillRule fillRule)

    \overload

    Draws the polygon defined by the given \a points using the fill
    rule \a fillRule.
*/

/*!
    \fn void QPainter::drawConvexPolygon(const QPointF *points, int pointCount)

    Draws the convex polygon defined by the first \a pointCount points
    in the array \a points using the current pen.

    \table 100%
    \row
    \o \inlineimage qpainter-polygon.png
    \o
    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 15
    \endtable

    The first point is implicitly connected to the last point, and the
    polygon is filled with the current brush().  If the supplied
    polygon is not convex, i.e. it contains at least one angle larger
    than 180 degrees, the results are undefined.

    On some platforms (e.g. X11), the drawConvexPolygon() function can
    be faster than the drawPolygon() function.

    \sa drawPolygon(), drawPolyline(), {Coordinate System}
*/

/*!
    \fn void QPainter::drawConvexPolygon(const QPoint *points, int pointCount)
    \overload

    Draws the convex polygon defined by the first \a pointCount points
    in the array \a points using the current pen.
*/

/*!
    \fn void QPainter::drawConvexPolygon(const QPolygonF &polygon)

    \overload

    Draws the convex polygon defined by \a polygon using the current
    pen and brush.
*/

/*!
    \fn void QPainter::drawConvexPolygon(const QPolygon &polygon)
    \overload

    Draws the convex polygon defined by \a polygon using the current
    pen and brush.
*/

/*!
    \fn void QPainter::drawConvexPolygon(const QPolygonF &polygon, int
    index, int count)

    \compat
    \overload

    Use drawConvexPolygon() combined with QPolygonF::constData()
    instead.

    \oldcode
        QPainter painter(this);
        painter.drawConvexPolygon(polygon, index, count);
    \newcode
        int pointCount = (count == -1) ?  polygon.size() - index : count;

        QPainter painter(this);
        painter.drawConvexPolygon(polygon.constData() + index, pointCount);
    \endcode
*/

/*!
    \fn void QPainter::drawConvexPolygon(const QPolygon &polygon, int
    index, int count)

    \compat
    \overload

    Use drawConvexPolygon() combined with QPolygon::constData()
    instead.

    \oldcode
        QPainter painter(this);
        painter.drawConvexPolygon(polygon, index, count);
    \newcode
        int pointCount = (count == -1) ?  polygon.size() - index : count;

        QPainter painter(this);
        painter.drawConvexPolygon(polygon.constData() + index, pointCount);
    \endcode
*/

void QPainter::drawConvexPolygon(const QPoint *points, int pointCount)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawConvexPolygon(), count=%d\n", pointCount);
#endif

    Q_D(QPainter);

    if (!d->engine || pointCount < 2)
        return;

    if (d->extended) {
        d->extended->drawPolygon(points, pointCount, QPaintEngine::ConvexMode);
        return;
    }

    d->updateState(d->state);

    uint emulationSpecifier = d->state->emulationSpecifier;

    if (emulationSpecifier) {
        QPainterPath polygonPath(points[0]);
        for (int i=1; i<pointCount; ++i)
            polygonPath.lineTo(points[i]);
        polygonPath.closeSubpath();
        polygonPath.setFillRule(Qt::WindingFill);
        d->draw_helper(polygonPath);
        return;
    }

    d->engine->drawPolygon(points, pointCount, QPaintEngine::ConvexMode);
}

void QPainter::drawConvexPolygon(const QPointF *points, int pointCount)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawConvexPolygon(), count=%d\n", pointCount);
#endif

    Q_D(QPainter);

    if (!d->engine || pointCount < 2)
        return;

    if (d->extended) {
        d->extended->drawPolygon(points, pointCount, QPaintEngine::ConvexMode);
        return;
    }

    d->updateState(d->state);

    uint emulationSpecifier = d->state->emulationSpecifier;

    if (emulationSpecifier) {
        QPainterPath polygonPath(points[0]);
        for (int i=1; i<pointCount; ++i)
            polygonPath.lineTo(points[i]);
        polygonPath.closeSubpath();
        polygonPath.setFillRule(Qt::WindingFill);
        d->draw_helper(polygonPath);
        return;
    }

    d->engine->drawPolygon(points, pointCount, QPaintEngine::ConvexMode);
}

static inline QPointF roundInDeviceCoordinates(const QPointF &p, const QTransform &m)
{
    return m.inverted().map(QPointF(m.map(p).toPoint()));
}

/*!
    \fn void QPainter::drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)

    Draws the rectangular portion \a source of the given \a pixmap
    into the given \a target in the paint device.

    \note The pixmap is scaled to fit the rectangle, if both the pixmap and rectangle size disagree.

    \table 100%
    \row
    \o
    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 16
    \endtable

    If \a pixmap is a QBitmap it is drawn with the bits that are "set"
    using the pens color. If backgroundMode is Qt::OpaqueMode, the
    "unset" bits are drawn using the color of the background brush; if
    backgroundMode is Qt::TransparentMode, the "unset" bits are
    transparent. Drawing bitmaps with gradient or texture colors is
    not supported.

    \sa drawImage()
*/
void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
{
#if defined QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawPixmap(), p=[%.2f,%.2f], pix=[%d,%d]\n",
               p.x(), p.y(),
               pm.width(), pm.height());
#endif

    Q_D(QPainter);

    if (!d->engine || pm.isNull())
        return;

#ifndef QT_NO_DEBUG
    qt_painter_thread_test(d->device->devType(), "drawPixmap()");
#endif

    if (d->extended) {
        d->extended->drawPixmap(p, pm);
        return;
    }

    qreal x = p.x();
    qreal y = p.y();

    int w = pm.width();
    int h = pm.height();

    if (w <= 0)
        return;

    // Emulate opaque background for bitmaps
    if (d->state->bgMode == Qt::OpaqueMode && pm.isQBitmap()) {
        fillRect(QRectF(x, y, w, h), d->state->bgBrush.color());
    }

    d->updateState(d->state);

    if ((d->state->matrix.type() > QTransform::TxTranslate
         && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
        || (!d->state->matrix.isAffine() && !d->engine->hasFeature(QPaintEngine::PerspectiveTransform))
        || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity)))
    {
        save();
        // If there is no rotation involved we have to make sure we use the
        // antialiased and not the aliased coordinate system by rounding the coordinates.
        if (d->state->matrix.type() <= QTransform::TxScale) {
            const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
            x = p.x();
            y = p.y();
        }
        translate(x, y);
        setBackgroundMode(Qt::TransparentMode);
        setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
        QBrush brush(d->state->pen.color(), pm);
        setBrush(brush);
        setPen(Qt::NoPen);
        setBrushOrigin(QPointF(0, 0));

        drawRect(pm.rect());
        restore();
    } else {
        if (!d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
            x += d->state->matrix.dx();
            y += d->state->matrix.dy();
        }
        d->engine->drawPixmap(QRectF(x, y, w, h), pm, QRectF(0, 0, w, h));
    }
}

void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
{
#if defined QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawPixmap(), target=[%.2f,%.2f,%.2f,%.2f], pix=[%d,%d], source=[%.2f,%.2f,%.2f,%.2f]\n",
               r.x(), r.y(), r.width(), r.height(),
               pm.width(), pm.height(),
               sr.x(), sr.y(), sr.width(), sr.height());
#endif

    Q_D(QPainter);
    if (!d->engine || pm.isNull())
        return;
#ifndef QT_NO_DEBUG
    qt_painter_thread_test(d->device->devType(), "drawPixmap()");
#endif

    qreal x = r.x();
    qreal y = r.y();
    qreal w = r.width();
    qreal h = r.height();
    qreal sx = sr.x();
    qreal sy = sr.y();
    qreal sw = sr.width();
    qreal sh = sr.height();

    // Sanity-check clipping
    if (sw <= 0)
        sw = pm.width() - sx;

    if (sh <= 0)
        sh = pm.height() - sy;

    if (w < 0)
        w = sw;
    if (h < 0)
        h = sh;

    if (sx < 0) {
        qreal w_ratio = sx * w/sw;
        x -= w_ratio;
        w += w_ratio;
        sw += sx;
        sx = 0;
    }

    if (sy < 0) {
        qreal h_ratio = sy * h/sh;
        y -= h_ratio;
        h += h_ratio;
        sh += sy;
        sy = 0;
    }

    if (sw + sx > pm.width()) {
        qreal delta = sw - (pm.width() - sx);
        qreal w_ratio = delta * w/sw;
        sw -= delta;
        w -= w_ratio;
    }

    if (sh + sy > pm.height()) {
        qreal delta = sh - (pm.height() - sy);
        qreal h_ratio = delta * h/sh;
        sh -= delta;
        h -= h_ratio;
    }

    if (w == 0 || h == 0 || sw <= 0 || sh <= 0)
        return;

    if (d->extended) {
        d->extended->drawPixmap(QRectF(x, y, w, h), pm, QRectF(sx, sy, sw, sh));
        return;
    }

    // Emulate opaque background for bitmaps
    if (d->state->bgMode == Qt::OpaqueMode && pm.isQBitmap())
        fillRect(QRectF(x, y, w, h), d->state->bgBrush.color());

    d->updateState(d->state);

    if ((d->state->matrix.type() > QTransform::TxTranslate
         && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
        || (!d->state->matrix.isAffine() && !d->engine->hasFeature(QPaintEngine::PerspectiveTransform))
        || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity))
        || ((sw != w || sh != h) && !d->engine->hasFeature(QPaintEngine::PixmapTransform)))
    {
        save();
        // If there is no rotation involved we have to make sure we use the
        // antialiased and not the aliased coordinate system by rounding the coordinates.
        if (d->state->matrix.type() <= QTransform::TxScale) {
            const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
            x = p.x();
            y = p.y();
        }

        if (d->state->matrix.type() <= QTransform::TxTranslate && sw == w && sh == h) {
            sx = qRound(sx);
            sy = qRound(sy);
            sw = qRound(sw);
            sh = qRound(sh);
        }

        translate(x, y);
        scale(w / sw, h / sh);
        setBackgroundMode(Qt::TransparentMode);
        setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
        QBrush brush;

        if (sw == pm.width() && sh == pm.height())
            brush = QBrush(d->state->pen.color(), pm);
        else
            brush = QBrush(d->state->pen.color(), pm.copy(sx, sy, sw, sh));

        setBrush(brush);
        setPen(Qt::NoPen);

        drawRect(QRectF(0, 0, sw, sh));
        restore();
    } else {
        if (!d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
            x += d->state->matrix.dx();
            y += d->state->matrix.dy();
        }
        d->engine->drawPixmap(QRectF(x, y, w, h), pm, QRectF(sx, sy, sw, sh));
    }
}


/*!
    \fn void QPainter::drawPixmap(const QRect &target, const QPixmap &pixmap,
                                  const QRect &source)
    \overload

    Draws the rectangular portion \a source of the given \a pixmap
    into the given \a target in the paint device.

    \note The pixmap is scaled to fit the rectangle, if both the pixmap and rectangle size disagree.
*/

/*!
    \fn void QPainter::drawPixmap(const QPointF &point, const QPixmap &pixmap,
                                  const QRectF &source)
    \overload

    Draws the rectangular portion \a source of the given \a pixmap
    with its origin at the given \a point.
*/

/*!
    \fn void QPainter::drawPixmap(const QPoint &point, const QPixmap &pixmap,
                                  const QRect &source)

    \overload

    Draws the rectangular portion \a source of the given \a pixmap
    with its origin at the given \a point.
*/

/*!
    \fn void QPainter::drawPixmap(const QPointF &point, const QPixmap &pixmap)
    \overload

    Draws the given \a pixmap with its origin at the given \a point.
*/

/*!
    \fn void QPainter::drawPixmap(const QPoint &point, const QPixmap &pixmap)
    \overload

    Draws the given \a pixmap with its origin at the given \a point.
*/

/*!
    \fn void QPainter::drawPixmap(int x, int y, const QPixmap &pixmap)

    \overload

    Draws the given \a pixmap at position (\a{x}, \a{y}).
*/

/*!
    \fn void QPainter::drawPixmap(const QRect &rectangle, const QPixmap &pixmap)
    \overload

    Draws the given \a  pixmap into the given \a rectangle.

    \note The pixmap is scaled to fit the rectangle, if both the pixmap and rectangle size disagree.
*/

/*!
    \fn void QPainter::drawPixmap(int x, int y, int width, int height,
    const QPixmap &pixmap)

    \overload

    Draws the \a pixmap into the rectangle at position (\a{x}, \a{y})
    with  the given \a width and \a height.
*/

/*!
    \fn void QPainter::drawPixmap(int x, int y, int w, int h, const QPixmap &pixmap,
                                  int sx, int sy, int sw, int sh)

    \overload

    Draws the rectangular portion with the origin (\a{sx}, \a{sy}),
    width \a sw and height \a sh, of the given \a pixmap , at the
    point (\a{x}, \a{y}), with a width of \a w and a height of \a h.
    If sw or sh are equal to zero the width/height of the pixmap
    is used and adjusted by the offset sx/sy;
*/

/*!
    \fn void QPainter::drawPixmap(int x, int y, const QPixmap &pixmap,
                                  int sx, int sy, int sw, int sh)

    \overload

    Draws a pixmap at (\a{x}, \a{y}) by copying a part of the given \a
    pixmap into the paint device.

    (\a{x}, \a{y}) specifies the top-left point in the paint device that is
    to be drawn onto. (\a{sx}, \a{sy}) specifies the top-left point in \a
    pixmap that is to be drawn. The default is (0, 0).

    (\a{sw}, \a{sh}) specifies the size of the pixmap that is to be drawn.
    The default, (0, 0) (and negative) means all the way to the
    bottom-right of the pixmap.
*/

void QPainter::drawImage(const QPointF &p, const QImage &image)
{
    Q_D(QPainter);

    if (!d->engine || image.isNull())
        return;

    if (d->extended) {
        d->extended->drawImage(p, image);
        return;
    }

    qreal x = p.x();
    qreal y = p.y();

    int w = image.width();
    int h = image.height();

    d->updateState(d->state);

    if (((d->state->matrix.type() > QTransform::TxTranslate)
         && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
        || (!d->state->matrix.isAffine() && !d->engine->hasFeature(QPaintEngine::PerspectiveTransform))
        || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity)))
    {
        save();
        // If there is no rotation involved we have to make sure we use the
        // antialiased and not the aliased coordinate system by rounding the coordinates.
        if (d->state->matrix.type() <= QTransform::TxScale) {
            const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
            x = p.x();
            y = p.y();
        }
        translate(x, y);
        setBackgroundMode(Qt::TransparentMode);
        setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
        QBrush brush(image);
        setBrush(brush);
        setPen(Qt::NoPen);
        setBrushOrigin(QPointF(0, 0));

        drawRect(image.rect());
        restore();
        return;
    }

    if (d->state->matrix.type() == QTransform::TxTranslate
        && !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
        x += d->state->matrix.dx();
        y += d->state->matrix.dy();
    }

    d->engine->drawImage(QRectF(x, y, w, h), image, QRectF(0, 0, w, h), Qt::AutoColor);
}

void QPainter::drawImage(const QRectF &targetRect, const QImage &image, const QRectF &sourceRect,
                         Qt::ImageConversionFlags flags)
{
    Q_D(QPainter);

    if (!d->engine || image.isNull())
        return;

    qreal x = targetRect.x();
    qreal y = targetRect.y();
    qreal w = targetRect.width();
    qreal h = targetRect.height();
    qreal sx = sourceRect.x();
    qreal sy = sourceRect.y();
    qreal sw = sourceRect.width();
    qreal sh = sourceRect.height();

    // Sanity-check clipping
    if (sw <= 0)
        sw = image.width() - sx;

    if (sh <= 0)
        sh = image.height() - sy;

    if (w < 0)
        w = sw;
    if (h < 0)
        h = sh;

    if (sx < 0) {
        qreal w_ratio = sx * w/sw;
        x -= w_ratio;
        w += w_ratio;
        sw += sx;
        sx = 0;
    }

    if (sy < 0) {
        qreal h_ratio = sy * h/sh;
        y -= h_ratio;
        h += h_ratio;
        sh += sy;
        sy = 0;
    }

    if (sw + sx > image.width()) {
        qreal delta = sw - (image.width() - sx);
        qreal w_ratio = delta * w/sw;
        sw -= delta;
        w -= w_ratio;
    }

    if (sh + sy > image.height()) {
        qreal delta = sh - (image.height() - sy);
        qreal h_ratio = delta * h/sh;
        sh -= delta;
        h -= h_ratio;
    }

    if (w == 0 || h == 0 || sw <= 0 || sh <= 0)
        return;

    if (d->extended) {
        d->extended->drawImage(QRectF(x, y, w, h), image, QRectF(sx, sy, sw, sh), flags);
        return;
    }

    d->updateState(d->state);

    if (((d->state->matrix.type() > QTransform::TxTranslate || (sw != w || sh != h))
         && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
        || (!d->state->matrix.isAffine() && !d->engine->hasFeature(QPaintEngine::PerspectiveTransform))
        || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity)))
    {
        save();
        // If there is no rotation involved we have to make sure we use the
        // antialiased and not the aliased coordinate system by rounding the coordinates.
        if (d->state->matrix.type() <= QTransform::TxScale) {
            const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
            x = p.x();
            y = p.y();
        }

        if (d->state->matrix.type() <= QTransform::TxTranslate && sw == w && sh == h) {
            sx = qRound(sx);
            sy = qRound(sy);
            sw = qRound(sw);
            sh = qRound(sh);
        }
        translate(x, y);
        scale(w / sw, h / sh);
        setBackgroundMode(Qt::TransparentMode);
        setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
        QBrush brush(image);
        setBrush(brush);
        setPen(Qt::NoPen);
        setBrushOrigin(QPointF(-sx, -sy));

        drawRect(QRectF(0, 0, sw, sh));
        restore();
        return;
    }

    if (d->state->matrix.type() == QTransform::TxTranslate
        && !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
        x += d->state->matrix.dx();
        y += d->state->matrix.dy();
    }

    d->engine->drawImage(QRectF(x, y, w, h), image, QRectF(sx, sy, sw, sh), flags);
}


void qt_draw_glyphs(QPainter *painter, const quint32 *glyphArray, const QPointF *positionArray,
                    int glyphCount)
{
    QPainterPrivate *painter_d = QPainterPrivate::get(painter);
    painter_d->drawGlyphs(glyphArray, positionArray, glyphCount);
}

void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, const QPointF *positionArray,
                                 int glyphCount)
{
    updateState(state);

    QFontEngine *fontEngine = state->font.d->engineForScript(QUnicodeTables::Common);

    while (fontEngine->type() == QFontEngine::Multi) {
        // Pick engine based on first glyph in array if we are using a multi engine.
        // (all glyphs must be for same font)
        int engineIdx = 0;
        if (glyphCount > 0)
            engineIdx = glyphArray[0] >> 24;

        fontEngine = static_cast<QFontEngineMulti *>(fontEngine)->engine(engineIdx);
    }

    QVarLengthArray<QFixedPoint, 128> positions;
    for (int i=0; i<glyphCount; ++i) {
        QFixedPoint fp = QFixedPoint::fromPointF(positionArray[i]);
        positions.append(fp);
    }

    if (extended != 0) {
        QStaticTextItem staticTextItem;
        staticTextItem.color = state->pen.color();
        staticTextItem.font = state->font;
        staticTextItem.setFontEngine(fontEngine);
        staticTextItem.numGlyphs = glyphCount;
        staticTextItem.glyphs = reinterpret_cast<glyph_t *>(const_cast<glyph_t *>(glyphArray));
        staticTextItem.glyphPositions = positions.data();

        extended->drawStaticTextItem(&staticTextItem);
    } else {
        QTextItemInt textItem;
        textItem.f = &state->font;
        textItem.fontEngine = fontEngine;

        QVarLengthArray<QFixed, 128> advances(glyphCount);
        QVarLengthArray<QGlyphJustification, 128> glyphJustifications(glyphCount);
        QVarLengthArray<HB_GlyphAttributes, 128> glyphAttributes(glyphCount);
        qMemSet(glyphAttributes.data(), 0, glyphAttributes.size() * sizeof(HB_GlyphAttributes));
        qMemSet(advances.data(), 0, advances.size() * sizeof(QFixed));
        qMemSet(glyphJustifications.data(), 0, glyphJustifications.size() * sizeof(QGlyphJustification));

        textItem.glyphs.numGlyphs = glyphCount;
        textItem.glyphs.glyphs = reinterpret_cast<HB_Glyph *>(const_cast<quint32 *>(glyphArray));
        textItem.glyphs.offsets = positions.data();
        textItem.glyphs.advances_x = advances.data();
        textItem.glyphs.advances_y = advances.data();
        textItem.glyphs.justifications = glyphJustifications.data();
        textItem.glyphs.attributes = glyphAttributes.data();

        engine->drawTextItem(QPointF(0, 0), textItem);
    }
}

/*!

    \fn void QPainter::drawStaticText(const QPoint &topLeftPosition, const QStaticText &staticText)
    \since 4.7
    \overload

    Draws the \a staticText at the \a topLeftPosition.

    \note The y-position is used as the top of the font.

*/

/*!
    \fn void QPainter::drawStaticText(int left, int top, const QStaticText &staticText)
    \since 4.7
    \overload

    Draws the \a staticText at coordinates \a left and \a top.

    \note The y-position is used as the top of the font.
*/

/*!
    \fn void QPainter::drawText(const QPointF &position, const QString &text)

    Draws the given \a text with the currently defined text direction,
    beginning at the given \a position.

    This function does not handle the newline character (\n), as it cannot
    break text into multiple lines, and it cannot display the newline character.
    Use the QPainter::drawText() overload that takes a rectangle instead
    if you want to draw multiple lines of text with the newline character, or
    if you want the text to be wrapped.

    By default, QPainter draws text anti-aliased.

    \note The y-position is used as the baseline of the font.
*/

void QPainter::drawText(const QPointF &p, const QString &str)
{
    drawText(p, str, 0, 0);
}

/*!
    \since 4.7

    Draws the given \a staticText at the given \a topLeftPosition.

    The text will be drawn using the font and the transformation set on the painter. If the
    font and/or transformation set on the painter are different from the ones used to initialize
    the layout of the QStaticText, then the layout will have to be recalculated. Use
    QStaticText::prepare() to initialize \a staticText with the font and transformation with which
    it will later be drawn.

    If \a topLeftPosition is not the same as when \a staticText was initialized, or when it was
    last drawn, then there will be a slight overhead when translating the text to its new position.

    \note If the painter's transformation is not affine, then \a staticText will be drawn using
    regular calls to drawText(), losing any potential for performance improvement.

    \note The y-position is used as the top of the font.

    \sa QStaticText
*/
void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText &staticText)
{
    Q_D(QPainter);
    if (!d->engine || staticText.text().isEmpty() || pen().style() == Qt::NoPen)
        return;

    QStaticTextPrivate *staticText_d =
            const_cast<QStaticTextPrivate *>(QStaticTextPrivate::get(&staticText));

    if (font() != staticText_d->font) {
        staticText_d->font = font();
        staticText_d->needsRelayout = true;
    }

    // If we don't have an extended paint engine, or if the painter is projected,
    // we go through standard code path
    if (d->extended == 0 || !d->state->matrix.isAffine()) {
        staticText_d->paintText(topLeftPosition, this);
        return;
    }

    bool paintEngineSupportsTransformations = d->extended->type() == QPaintEngine::OpenGL2
                                           || d->extended->type() == QPaintEngine::OpenVG
                                           || d->extended->type() == QPaintEngine::OpenGL;

    if (paintEngineSupportsTransformations && !staticText_d->untransformedCoordinates) {
        staticText_d->untransformedCoordinates = true;
        staticText_d->needsRelayout = true;
    } else if (!paintEngineSupportsTransformations && staticText_d->untransformedCoordinates) {
        staticText_d->untransformedCoordinates = false;
        staticText_d->needsRelayout = true;
    }

    // Don't recalculate entire layout because of translation, rather add the dx and dy
    // into the position to move each text item the correct distance.
    QPointF transformedPosition = topLeftPosition;
    if (!staticText_d->untransformedCoordinates)
        transformedPosition = transformedPosition * d->state->matrix;
    QTransform oldMatrix;

    // The translation has been applied to transformedPosition. Remove translation
    // component from matrix.
    if (d->state->matrix.isTranslating() && !staticText_d->untransformedCoordinates) {
        qreal m11 = d->state->matrix.m11();
        qreal m12 = d->state->matrix.m12();
        qreal m13 = d->state->matrix.m13();
        qreal m21 = d->state->matrix.m21();
        qreal m22 = d->state->matrix.m22();
        qreal m23 = d->state->matrix.m23();
        qreal m33 = d->state->matrix.m33();

        oldMatrix = d->state->matrix;
        d->state->matrix.setMatrix(m11, m12, m13,
                                   m21, m22, m23,
                                   0.0, 0.0, m33);
    }

    // If the transform is not identical to the text transform,
    // we have to relayout the text (for other transformations than plain translation)
    bool staticTextNeedsReinit = staticText_d->needsRelayout;
    if (!staticText_d->untransformedCoordinates && staticText_d->matrix != d->state->matrix) {
        staticText_d->matrix = d->state->matrix;
        staticTextNeedsReinit = true;
    }

    // Recreate the layout of the static text because the matrix or font has changed
    if (staticTextNeedsReinit)
        staticText_d->init();

    if (transformedPosition != staticText_d->position) { // Translate to actual position
        QFixed fx = QFixed::fromReal(transformedPosition.x());
        QFixed fy = QFixed::fromReal(transformedPosition.y());
        QFixed oldX = QFixed::fromReal(staticText_d->position.x());
        QFixed oldY = QFixed::fromReal(staticText_d->position.y());
        for (int item=0; item<staticText_d->itemCount;++item) {
            QStaticTextItem *textItem = staticText_d->items + item;
            for (int i=0; i<textItem->numGlyphs; ++i) {
                textItem->glyphPositions[i].x += fx - oldX;
                textItem->glyphPositions[i].y += fy - oldY;
            }
            textItem->userDataNeedsUpdate = true;
        }

        staticText_d->position = transformedPosition;
    }

    QPen oldPen = d->state->pen;
    QColor currentColor = oldPen.color();
    for (int i=0; i<staticText_d->itemCount; ++i) {
        QStaticTextItem *item = staticText_d->items + i;
        if (item->color.isValid() && currentColor != item->color) {
            setPen(item->color);
            currentColor = item->color;
        }
        d->extended->drawStaticTextItem(item);

        qt_draw_decoration_for_glyphs(this, item->glyphs, item->glyphPositions,
                                      item->numGlyphs, item->fontEngine(), staticText_d->font,
                                      QTextCharFormat());
    }
    if (currentColor != oldPen.color())
        setPen(oldPen);

    if (!staticText_d->untransformedCoordinates && oldMatrix.isTranslating())
        d->state->matrix = oldMatrix;
}

/*!
   \internal
*/
void QPainter::drawText(const QPointF &p, const QString &str, int tf, int justificationPadding)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawText(), pos=[%.2f,%.2f], str='%s'\n", p.x(), p.y(), str.toLatin1().constData());
#endif

    Q_D(QPainter);

    if (!d->engine || str.isEmpty() || pen().style() == Qt::NoPen)
        return;

    if (tf & Qt::TextBypassShaping) {
        // Skip harfbuzz complex shaping, shape using glyph advances only
        int len = str.length();
        int numGlyphs = len;
        QVarLengthGlyphLayoutArray glyphs(len);
        QFontEngine *fontEngine = d->state->font.d->engineForScript(QUnicodeTables::Common);
        if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0)) {
            glyphs.resize(numGlyphs);
            if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0))
                Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice");
        }

        QTextItemInt gf(glyphs, &d->state->font, str.data(), len, fontEngine);
        drawTextItem(p, gf);
        return;
    }

    QStackTextEngine engine(str, d->state->font);
    engine.option.setTextDirection(d->state->layoutDirection);
    if (tf & (Qt::TextForceLeftToRight|Qt::TextForceRightToLeft)) {
        engine.ignoreBidi = true;
        engine.option.setTextDirection((tf & Qt::TextForceLeftToRight) ? Qt::LeftToRight : Qt::RightToLeft);
    }
    engine.itemize();
    QScriptLine line;
    line.length = str.length();
    engine.shapeLine(line);

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

    if (justificationPadding > 0) {
        engine.option.setAlignment(Qt::AlignJustify);
        engine.forceJustification = true;
        // this works because justify() is only interested in the difference between width and textWidth
        line.width = justificationPadding;
        engine.justify(line);
    }
    QFixed x = QFixed::fromReal(p.x());

    for (int i = 0; i < nItems; ++i) {
        int item = visualOrder[i];
        const QScriptItem &si = engine.layoutData->items.at(item);
        if (si.analysis.flags >= QScriptAnalysis::TabOrObject) {
            x += si.width;
            continue;
        }
        QFont f = engine.font(si);
        QTextItemInt gf(si, &f);
        gf.glyphs = engine.shapedGlyphs(&si);
        gf.chars = engine.layoutData->string.unicode() + si.position;
        gf.num_chars = engine.length(item);
        if (engine.forceJustification) {
            for (int j=0; j<gf.glyphs.numGlyphs; ++j)
                gf.width += gf.glyphs.effectiveAdvance(j);
        } else {
            gf.width = si.width;
        }
        gf.logClusters = engine.logClusters(&si);

        drawTextItem(QPointF(x.toReal(), p.y()), gf);

        x += gf.width;
    }
}

void QPainter::drawText(const QRect &r, int flags, const QString &str, QRect *br)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawText(), r=[%d,%d,%d,%d], flags=%d, str='%s'\n",
           r.x(), r.y(), r.width(), r.height(), flags, str.toLatin1().constData());
#endif

    Q_D(QPainter);

    if (!d->engine || str.length() == 0 || pen().style() == Qt::NoPen)
        return;

    if (!d->extended)
        d->updateState(d->state);

    QRectF bounds;
    qt_format_text(d->state->font, r, flags, 0, str, br ? &bounds : 0, 0, 0, 0, this);
    if (br)
        *br = bounds.toAlignedRect();
}

/*!
    \fn void QPainter::drawText(const QPoint &position, const QString &text)

    \overload

    Draws the given \a text with the currently defined text direction,
    beginning at the given \a position.

    By default, QPainter draws text anti-aliased.

    \note The y-position is used as the baseline of the font.

*/

/*!
    \fn void QPainter::drawText(const QRectF &rectangle, int flags, const QString &text, QRectF *boundingRect)
    \overload

    Draws the given \a text within the provided \a rectangle.

    \table 100%
    \row
    \o \inlineimage qpainter-text.png
    \o
    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 17
    \endtable

    The \a boundingRect (if not null) is set to the what the bounding rectangle
    should be in order to enclose the whole text. The \a flags argument is a bitwise
    OR of the following flags:

    \list
    \o Qt::AlignLeft
    \o Qt::AlignRight
    \o Qt::AlignHCenter
    \o Qt::AlignJustify
    \o Qt::AlignTop
    \o Qt::AlignBottom
    \o Qt::AlignVCenter
    \o Qt::AlignCenter
    \o Qt::TextDontClip
    \o Qt::TextSingleLine
    \o Qt::TextExpandTabs
    \o Qt::TextShowMnemonic
    \o Qt::TextWordWrap
    \o Qt::TextIncludeTrailingSpaces
    \endlist

    \sa Qt::AlignmentFlag, Qt::TextFlag, boundingRect(), layoutDirection()

    By default, QPainter draws text anti-aliased.

    \note The y-coordinate of \a rectangle is used as the top of the font.
*/
void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF *br)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawText(), r=[%.2f,%.2f,%.2f,%.2f], flags=%d, str='%s'\n",
           r.x(), r.y(), r.width(), r.height(), flags, str.toLatin1().constData());
#endif

    Q_D(QPainter);

    if (!d->engine || str.length() == 0 || pen().style() == Qt::NoPen)
        return;

    if (!d->extended)
        d->updateState(d->state);

    qt_format_text(d->state->font, r, flags, 0, str, br, 0, 0, 0, this);
}

/*!
    \fn void QPainter::drawText(const QRect &rectangle, int flags, const QString &text, QRect *boundingRect)
    \overload

    Draws the given \a text within the provided \a rectangle according
    to the specified \a flags. The \a boundingRect (if not null) is set to
    the what the bounding rectangle should be in order to enclose the whole text.

    By default, QPainter draws text anti-aliased.

    \note The y-coordinate of \a rectangle is used as the top of the font.
*/

/*!
    \fn void QPainter::drawText(int x, int y, const QString &text)

    \overload

    Draws the given \a text at position (\a{x}, \a{y}), using the painter's
    currently defined text direction.

    By default, QPainter draws text anti-aliased.

    \note The y-position is used as the baseline of the font.

*/

/*!
    \fn void QPainter::drawText(int x, int y, int width, int height, int flags,
                                const QString &text, QRect *boundingRect)

    \overload

    Draws the given \a text within the rectangle with origin (\a{x},
    \a{y}), \a width and \a height.

    The \a boundingRect (if not null) is set to the actual bounding
    rectangle of the output.  The \a flags argument is a bitwise OR of
    the following flags:

    \list
    \o Qt::AlignLeft
    \o Qt::AlignRight
    \o Qt::AlignHCenter
    \o Qt::AlignJustify
    \o Qt::AlignTop
    \o Qt::AlignBottom
    \o Qt::AlignVCenter
    \o Qt::AlignCenter
    \o Qt::TextSingleLine
    \o Qt::TextExpandTabs
    \o Qt::TextShowMnemonic
    \o Qt::TextWordWrap
    \endlist

    By default, QPainter draws text anti-aliased.

    \note The y-position is used as the top of the font.

    \sa Qt::AlignmentFlag, Qt::TextFlag
*/

/*!
    \fn void QPainter::drawText(const QRectF &rectangle, const QString &text,
        const QTextOption &option)
    \overload

    Draws the given \a text in the \a rectangle specified using the \a option
    to control its positioning and orientation.

    By default, QPainter draws text anti-aliased.

    \note The y-coordinate of \a rectangle is used as the top of the font.
*/
void QPainter::drawText(const QRectF &r, const QString &text, const QTextOption &o)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawText(), r=[%.2f,%.2f,%.2f,%.2f], str='%s'\n",
           r.x(), r.y(), r.width(), r.height(), text.toLatin1().constData());
#endif

    Q_D(QPainter);

    if (!d->engine || text.length() == 0 || pen().style() == Qt::NoPen)
        return;

    if (!d->extended)
        d->updateState(d->state);

    qt_format_text(d->state->font, r, 0, &o, text, 0, 0, 0, 0, this);
}

/*!
    \fn void QPainter::drawTextItem(int x, int y, const QTextItem &ti)

    \internal
    \overload
*/

/*!
    \fn void QPainter::drawTextItem(const QPoint &p, const QTextItem &ti)

    \internal
    \overload

    Draws the text item \a ti at position \a p.
*/

/*!
    \fn void QPainter::drawTextItem(const QPointF &p, const QTextItem &ti)

    \internal
    \since 4.1

    Draws the text item \a ti at position \a p.

    This method ignores the painters background mode and
    color. drawText and qt_format_text have to do it themselves, as
    only they know the extents of the complete string.

    It ignores the font set on the painter as the text item has one of its own.

    The underline and strikeout parameters of the text items font are
    ignored aswell. You'll need to pass in the correct flags to get
    underlining and strikeout.
*/

static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
{
    const qreal radiusBase = qMax(qreal(1), maxRadius);

    QString key = QLatin1Literal("WaveUnderline-")
                  % pen.color().name()
                  % HexString<qreal>(radiusBase);

    QPixmap pixmap;
    if (QPixmapCache::find(key, pixmap))
        return pixmap;

    const qreal halfPeriod = qMax(qreal(2), qreal(radiusBase * 1.61803399)); // the golden ratio
    const int width = qCeil(100 / (2 * halfPeriod)) * (2 * halfPeriod);
    const int radius = qFloor(radiusBase);

    QPainterPath path;

    qreal xs = 0;
    qreal ys = radius;

    while (xs < width) {
        xs += halfPeriod;
        ys = -ys;
        path.quadTo(xs - halfPeriod / 2, ys, xs, 0);
    }

    pixmap = QPixmap(width, radius * 2);
    pixmap.fill(Qt::transparent);
    {
        QPen wavePen = pen;
        wavePen.setCapStyle(Qt::SquareCap);

        // This is to protect against making the line too fat, as happens on Mac OS X
        // due to it having a rather thick width for the regular underline.
        const qreal maxPenWidth = .8 * radius;
        if (wavePen.widthF() > maxPenWidth)
            wavePen.setWidth(maxPenWidth);

        QPainter imgPainter(&pixmap);
        imgPainter.setPen(wavePen);
        imgPainter.setRenderHint(QPainter::Antialiasing);
        imgPainter.translate(0, radius);
        imgPainter.drawPath(path);
    }

    QPixmapCache::insert(key, pixmap);

    return pixmap;
}

static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe,
                                   QTextCharFormat::UnderlineStyle underlineStyle,
                                   const QTextItem::RenderFlags flags, qreal width,
                                   const QTextCharFormat &charFormat)
{
    if (underlineStyle == QTextCharFormat::NoUnderline
        && !(flags & (QTextItem::StrikeOut | QTextItem::Overline)))
        return;

    const QPen oldPen = painter->pen();
    const QBrush oldBrush = painter->brush();
    painter->setBrush(Qt::NoBrush);
    QPen pen = oldPen;
    pen.setStyle(Qt::SolidLine);
    pen.setWidthF(fe->lineThickness().toReal());
    pen.setCapStyle(Qt::FlatCap);

    QLineF line(pos.x(), pos.y(), pos.x() + width, pos.y());

    qreal underlineOffset = fe->underlinePosition().toReal();
    qreal y = pos.y();
    // compensate for different rounding rule in Core Graphics paint engine,
    // ideally code like this should be moved to respective engines.
    if (painter->paintEngine()->type() == QPaintEngine::CoreGraphics) {
        y = qCeil(y);
    }
    // deliberately ceil the offset to avoid the underline coming too close to
    // the text above it.
    const qreal underlinePos = y + qCeil(underlineOffset);

    if (underlineStyle == QTextCharFormat::SpellCheckUnderline) {
        underlineStyle = QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle));
    }

    if (underlineStyle == QTextCharFormat::WaveUnderline) {
        painter->save();
        painter->translate(0, pos.y() + 1);

        QColor uc = charFormat.underlineColor();
        if (uc.isValid())
            pen.setColor(uc);

        // Adapt wave to underlineOffset or pen width, whatever is larger, to make it work on all platforms
        const QPixmap wave = generateWavyPixmap(qMax(underlineOffset, pen.widthF()), pen);
        const int descent = (int) fe->descent().toReal();

        painter->setBrushOrigin(painter->brushOrigin().x(), 0);
        painter->fillRect(pos.x(), 0, qCeil(width), qMin(wave.height(), descent), wave);
        painter->restore();
    } else if (underlineStyle != QTextCharFormat::NoUnderline) {
        QLineF underLine(line.x1(), underlinePos, line.x2(), underlinePos);

        QColor uc = charFormat.underlineColor();
        if (uc.isValid())
            pen.setColor(uc);

        pen.setStyle((Qt::PenStyle)(underlineStyle));
        painter->setPen(pen);
        painter->drawLine(underLine);
    }

    pen.setStyle(Qt::SolidLine);
    pen.setColor(oldPen.color());

    if (flags & QTextItem::StrikeOut) {
        QLineF strikeOutLine = line;
        strikeOutLine.translate(0., - fe->ascent().toReal() / 3.);
        painter->setPen(pen);
        painter->drawLine(strikeOutLine);
    }

    if (flags & QTextItem::Overline) {
        QLineF overLine = line;
        overLine.translate(0., - fe->ascent().toReal());
        painter->setPen(pen);
        painter->drawLine(overLine);
    }

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

Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray,
                                                const QFixedPoint *positions, int glyphCount,
                                                QFontEngine *fontEngine, const QFont &font,
                                                const QTextCharFormat &charFormat)
{
    if (!(font.underline() || font.strikeOut() || font.overline()))
        return;

    QFixed leftMost;
    QFixed rightMost;
    QFixed baseLine;
    for (int i=0; i<glyphCount; ++i) {
        glyph_metrics_t gm = fontEngine->boundingBox(glyphArray[i]);
        if (i == 0 || leftMost > positions[i].x)
            leftMost = positions[i].x;

        // We don't support glyphs that do not share a common baseline. If this turns out to
        // be a relevant use case, then we need to find clusters of glyphs that share a baseline
        // and do a drawTextItemDecorations call per cluster.
        if (i == 0 || baseLine < positions[i].y)
            baseLine = positions[i].y;

        // We use the advance rather than the actual bounds to match the algorithm in drawText()
        if (i == 0 || rightMost < positions[i].x + gm.xoff)
            rightMost = positions[i].x + gm.xoff;
    }

    QFixed width = rightMost - leftMost;
    QTextItem::RenderFlags flags = 0;

    if (font.underline())
        flags |= QTextItem::Underline;
    if (font.overline())
        flags |= QTextItem::Overline;
    if (font.strikeOut())
        flags |= QTextItem::StrikeOut;

    drawTextItemDecoration(painter, QPointF(leftMost.toReal(), baseLine.toReal()),
                           fontEngine,
                           font.underline() ? QTextCharFormat::SingleUnderline
                                            : QTextCharFormat::NoUnderline, flags,
                           width.toReal(), charFormat);
}

void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawTextItem(), pos=[%.f,%.f], str='%s'\n",
               p.x(), p.y(), qPrintable(_ti.text()));
#endif

    Q_D(QPainter);

    if (!d->engine)
        return;

#ifndef QT_NO_DEBUG
    qt_painter_thread_test(d->device->devType(),
                           "text and fonts",
                           QFontDatabase::supportsThreadedFontRendering());
#endif

    QTextItemInt &ti = const_cast<QTextItemInt &>(static_cast<const QTextItemInt &>(_ti));

    if (!d->extended && d->state->bgMode == Qt::OpaqueMode) {
        QRectF rect(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent + 1).toReal());
        fillRect(rect, d->state->bgBrush);
    }

    if (pen().style() == Qt::NoPen)
        return;

    const RenderHints oldRenderHints = d->state->renderHints;
    if (!d->state->renderHints & QPainter::Antialiasing && d->state->matrix.type() >= QTransform::TxScale) {
        // draw antialias decoration (underline/overline/strikeout) with
        // transformed text

        bool aa = true;
        const QTransform &m = d->state->matrix;
        if (d->state->matrix.type() < QTransform::TxShear) {
            bool isPlain90DegreeRotation =
                (qFuzzyIsNull(m.m11())
                 && qFuzzyIsNull(m.m12() - qreal(1))
                 && qFuzzyIsNull(m.m21() + qreal(1))
                 && qFuzzyIsNull(m.m22())
                    )
                ||
                (qFuzzyIsNull(m.m11() + qreal(1))
                 && qFuzzyIsNull(m.m12())
                 && qFuzzyIsNull(m.m21())
                 && qFuzzyIsNull(m.m22() + qreal(1))
                    )
                ||
                (qFuzzyIsNull(m.m11())
                 && qFuzzyIsNull(m.m12() + qreal(1))
                 && qFuzzyIsNull(m.m21() - qreal(1))
                 && qFuzzyIsNull(m.m22())
                    )
                ;
            aa = !isPlain90DegreeRotation;
        }
        if (aa)
            setRenderHint(QPainter::Antialiasing, true);
    }

    if (!d->extended)
        d->updateState(d->state);

    if (!ti.glyphs.numGlyphs) {
        // nothing to do
    } else if (ti.fontEngine->type() == QFontEngine::Multi) {
        QFontEngineMulti *multi = static_cast<QFontEngineMulti *>(ti.fontEngine);

        const QGlyphLayout &glyphs = ti.glyphs;
        int which = glyphs.glyphs[0] >> 24;

        qreal x = p.x();
        qreal y = p.y();

        bool rtl = ti.flags & QTextItem::RightToLeft;
        if (rtl)
            x += ti.width.toReal();

        int start = 0;
        int end, i;
        for (end = 0; end < ti.glyphs.numGlyphs; ++end) {
            const int e = glyphs.glyphs[end] >> 24;
            if (e == which)
                continue;


            QTextItemInt ti2 = ti.midItem(multi->engine(which), start, end - start);
            ti2.width = 0;
            // set the high byte to zero and calc the width
            for (i = start; i < end; ++i) {
                glyphs.glyphs[i] = glyphs.glyphs[i] & 0xffffff;
                ti2.width += ti.glyphs.effectiveAdvance(i);
            }

            if (rtl)
                x -= ti2.width.toReal();

            d->engine->drawTextItem(QPointF(x, y), ti2);

            if (!rtl)
                x += ti2.width.toReal();

            // reset the high byte for all glyphs and advance to the next sub-string
            const int hi = which << 24;
            for (i = start; i < end; ++i) {
                glyphs.glyphs[i] = hi | glyphs.glyphs[i];
            }

            // change engine
            start = end;
            which = e;
        }

        QTextItemInt ti2 = ti.midItem(multi->engine(which), start, end - start);
        ti2.width = 0;
        // set the high byte to zero and calc the width
        for (i = start; i < end; ++i) {
            glyphs.glyphs[i] = glyphs.glyphs[i] & 0xffffff;
            ti2.width += ti.glyphs.effectiveAdvance(i);
        }

        if (rtl)
            x -= ti2.width.toReal();

        if (d->extended)
            d->extended->drawTextItem(QPointF(x, y), ti2);
        else
            d->engine->drawTextItem(QPointF(x,y), ti2);

        // reset the high byte for all glyphs
        const int hi = which << 24;
        for (i = start; i < end; ++i)
            glyphs.glyphs[i] = hi | glyphs.glyphs[i];

    } else {
        if (d->extended)
            d->extended->drawTextItem(p, ti);
        else
            d->engine->drawTextItem(p, ti);
    }
    drawTextItemDecoration(this, p, ti.fontEngine, ti.underlineStyle, ti.flags, ti.width.toReal(),
                           ti.charFormat);

    if (d->state->renderHints != oldRenderHints) {
        d->state->renderHints = oldRenderHints;
        if (d->extended)
            d->extended->renderHintsChanged();
        else
            d->state->dirtyFlags |= QPaintEngine::DirtyHints;
    }
}

/*!
    \fn QRectF QPainter::boundingRect(const QRectF &rectangle, int flags, const QString &text)

    Returns the bounding rectangle of the \a text as it will appear
    when drawn inside the given \a rectangle with the specified \a
    flags using the currently set font(); i.e the function tells you
    where the drawText() function will draw when given the same
    arguments.

    If the \a text does not fit within the given \a rectangle using
    the specified \a flags, the function returns the required
    rectangle.

    The \a flags argument is a bitwise OR of the following flags:
    \list
         \o Qt::AlignLeft
         \o Qt::AlignRight
         \o Qt::AlignHCenter
         \o Qt::AlignTop
         \o Qt::AlignBottom
         \o Qt::AlignVCenter
         \o Qt::AlignCenter
         \o Qt::TextSingleLine
         \o Qt::TextExpandTabs
         \o Qt::TextShowMnemonic
         \o Qt::TextWordWrap
         \o Qt::TextIncludeTrailingSpaces
    \endlist
    If several of the horizontal or several of the vertical alignment
    flags are set, the resulting alignment is undefined.

    \sa drawText(), Qt::Alignment, Qt::TextFlag
*/

/*!
    \fn QRect QPainter::boundingRect(const QRect &rectangle, int flags,
                                     const QString &text)

    \overload

    Returns the bounding rectangle of the \a text as it will appear
    when drawn inside the given \a rectangle with the specified \a
    flags using the currently set font().
*/

/*!
    \fn QRect QPainter::boundingRect(int x, int y, int w, int h, int flags,
                                     const QString &text);

    \overload

    Returns the bounding rectangle of the given \a text as it will
    appear when drawn inside the rectangle beginning at the point
    (\a{x}, \a{y}) with width \a w and height \a h.
*/
QRect QPainter::boundingRect(const QRect &rect, int flags, const QString &str)
{
    if (str.isEmpty())
        return QRect(rect.x(),rect.y(), 0,0);
    QRect brect;
    drawText(rect, flags | Qt::TextDontPrint, str, &brect);
    return brect;
}



QRectF QPainter::boundingRect(const QRectF &rect, int flags, const QString &str)
{
    if (str.isEmpty())
        return QRectF(rect.x(),rect.y(), 0,0);
    QRectF brect;
    drawText(rect, flags | Qt::TextDontPrint, str, &brect);
    return brect;
}

/*!
    \fn QRectF QPainter::boundingRect(const QRectF &rectangle,
        const QString &text, const QTextOption &option)

    \overload

    Instead of specifying flags as a bitwise OR of the
    Qt::AlignmentFlag and Qt::TextFlag, this overloaded function takes
    an \a option argument. The QTextOption class provides a
    description of general rich text properties.

    \sa QTextOption
*/
QRectF QPainter::boundingRect(const QRectF &r, const QString &text, const QTextOption &o)
{
    Q_D(QPainter);

    if (!d->engine || text.length() == 0)
        return QRectF(r.x(),r.y(), 0,0);

    QRectF br;
    qt_format_text(d->state->font, r, Qt::TextDontPrint, &o, text, &br, 0, 0, 0, this);
    return br;
}

/*!
    \fn void QPainter::drawTiledPixmap(const QRectF &rectangle, const QPixmap &pixmap, const QPointF &position)

    Draws a tiled \a pixmap, inside the given \a rectangle with its
    origin at the given \a position.

    Calling drawTiledPixmap() is similar to calling drawPixmap()
    several times to fill (tile) an area with a pixmap, but is
    potentially much more efficient depending on the underlying window
    system.

    \sa drawPixmap()
*/
void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &sp)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::drawTiledPixmap(), target=[%.2f,%.2f,%.2f,%.2f], pix=[%d,%d], offset=[%.2f,%.2f]\n",
               r.x(), r.y(), r.width(), r.height(),
               pixmap.width(), pixmap.height(),
               sp.x(), sp.y());
#endif

    Q_D(QPainter);
    if (!d->engine || pixmap.isNull() || r.isEmpty())
        return;

#ifndef QT_NO_DEBUG
    qt_painter_thread_test(d->device->devType(), "drawTiledPixmap()");
#endif

    qreal sw = pixmap.width();
    qreal sh = pixmap.height();
    qreal sx = sp.x();
    qreal sy = sp.y();
    if (sx < 0)
        sx = qRound(sw) - qRound(-sx) % qRound(sw);
    else
        sx = qRound(sx) % qRound(sw);
    if (sy < 0)
        sy = qRound(sh) - -qRound(sy) % qRound(sh);
    else
        sy = qRound(sy) % qRound(sh);


    if (d->extended) {
        d->extended->drawTiledPixmap(r, pixmap, QPointF(sx, sy));
        return;
    }

    if (d->state->bgMode == Qt::OpaqueMode && pixmap.isQBitmap())
        fillRect(r, d->state->bgBrush);

    d->updateState(d->state);
    if ((d->state->matrix.type() > QTransform::TxTranslate
        && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
        || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity)))
    {
        save();
        setBackgroundMode(Qt::TransparentMode);
        setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
        setBrush(QBrush(d->state->pen.color(), pixmap));
        setPen(Qt::NoPen);

        // If there is no rotation involved we have to make sure we use the
        // antialiased and not the aliased coordinate system by rounding the coordinates.
        if (d->state->matrix.type() <= QTransform::TxScale) {
            const QPointF p = roundInDeviceCoordinates(r.topLeft(), d->state->matrix);

            if (d->state->matrix.type() <= QTransform::TxTranslate) {
                sx = qRound(sx);
                sy = qRound(sy);
            }

            setBrushOrigin(QPointF(r.x()-sx, r.y()-sy));
            drawRect(QRectF(p, r.size()));
        } else {
            setBrushOrigin(QPointF(r.x()-sx, r.y()-sy));
            drawRect(r);
        }
        restore();
        return;
    }

    qreal x = r.x();
    qreal y = r.y();
    if (d->state->matrix.type() == QTransform::TxTranslate
        && !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
        x += d->state->matrix.dx();
        y += d->state->matrix.dy();
    }

    d->engine->drawTiledPixmap(QRectF(x, y, r.width(), r.height()), pixmap, QPointF(sx, sy));
}

/*!
    \fn QPainter::drawTiledPixmap(const QRect &rectangle, const QPixmap &pixmap,
                                  const QPoint &position = QPoint())
    \overload

    Draws a tiled \a pixmap, inside the given \a rectangle with its
    origin at the given \a position.
*/

/*!
    \fn void QPainter::drawTiledPixmap(int x, int y, int width, int height, const
         QPixmap &pixmap, int sx, int sy);
    \overload

    Draws a tiled \a pixmap in the specified rectangle.

    (\a{x}, \a{y}) specifies the top-left point in the paint device
    that is to be drawn onto; with the given \a width and \a
    height. (\a{sx}, \a{sy}) specifies the top-left point in the \a
    pixmap that is to be drawn; this defaults to (0, 0).
*/

#ifndef QT_NO_PICTURE

/*!
    \fn void QPainter::drawPicture(const QPointF &point, const QPicture &picture)

    Replays the given \a picture at the given \a point.

    The QPicture class is a paint device that records and replays
    QPainter commands. A picture serializes the painter commands to an
    IO device in a platform-independent format. Everything that can be
    painted on a widget or pixmap can also be stored in a picture.

    This function does exactly the same as QPicture::play() when
    called with \a point = QPoint(0, 0).

    \table 100%
    \row
    \o
    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 18
    \endtable

    \sa QPicture::play()
*/

void QPainter::drawPicture(const QPointF &p, const QPicture &picture)
{
    Q_D(QPainter);

    if (!d->engine)
        return;

    if (!d->extended)
        d->updateState(d->state);

    save();
    translate(p);
    const_cast<QPicture *>(&picture)->play(this);
    restore();
}

/*!
    \fn void QPainter::drawPicture(const QPoint &point, const QPicture &picture)
    \overload

    Replays the given \a picture at the given \a point.
*/

/*!
    \fn void QPainter::drawPicture(int x, int y, const QPicture &picture)
    \overload

    Draws the given \a picture at point (\a x, \a y).
*/

#endif // QT_NO_PICTURE

/*!
    \fn void QPainter::eraseRect(const QRectF &rectangle)

    Erases the area inside the given \a rectangle. Equivalent to
    calling
    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 19

    \sa fillRect()
*/
void QPainter::eraseRect(const QRectF &r)
{
    Q_D(QPainter);

    fillRect(r, d->state->bgBrush);
}

static inline bool needsResolving(const QBrush &brush)
{
    Qt::BrushStyle s = brush.style();
    return ((s == Qt::LinearGradientPattern || s == Qt::RadialGradientPattern ||
             s == Qt::ConicalGradientPattern) &&
            brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode);
}

/*!
    \fn void QPainter::eraseRect(const QRect &rectangle)
    \overload

    Erases the area inside the given  \a rectangle.
*/

/*!
    \fn void QPainter::eraseRect(int x, int y, int width, int height)
    \overload

    Erases the area inside the rectangle beginning at (\a x, \a y)
    with the given \a width and \a height.
*/


/*!
    \fn void QPainter::fillRect(int x, int y, int width, int height, Qt::BrushStyle style)
    \overload

    Fills the rectangle beginning at (\a{x}, \a{y}) with the given \a
    width and \a height, using the brush \a style specified.

    \since 4.5
*/

/*!
    \fn void QPainter::fillRect(const QRect &rectangle, Qt::BrushStyle style)
    \overload

    Fills the given \a rectangle  with the brush \a style specified.

    \since 4.5
*/

/*!
    \fn void QPainter::fillRect(const QRectF &rectangle, Qt::BrushStyle style)
    \overload

    Fills the given \a rectangle  with the brush \a style specified.

    \since 4.5
*/

/*!
    \fn void QPainter::fillRect(const QRectF &rectangle, const QBrush &brush)

    Fills the given \a rectangle  with the \a brush specified.

    Alternatively, you can specify a QColor instead of a QBrush; the
    QBrush constructor (taking a QColor argument) will automatically
    create a solid pattern brush.

    \sa drawRect()
*/
void QPainter::fillRect(const QRectF &r, const QBrush &brush)
{
    Q_D(QPainter);

    if (!d->engine)
        return;

    if (d->extended) {
        const QGradient *g = brush.gradient();
        if (!g || g->coordinateMode() == QGradient::LogicalMode) {
            d->extended->fillRect(r, brush);
            return;
        }
    }

    QPen oldPen = pen();
    QBrush oldBrush = this->brush();
    setPen(Qt::NoPen);
    if (brush.style() == Qt::SolidPattern) {
        d->colorBrush.setStyle(Qt::SolidPattern);
        d->colorBrush.setColor(brush.color());
        setBrush(d->colorBrush);
    } else {
        setBrush(brush);
    }

    drawRect(r);
    setBrush(oldBrush);
    setPen(oldPen);
}

/*!
    \fn void QPainter::fillRect(const QRect &rectangle, const QBrush &brush)
    \overload

    Fills the given \a rectangle with the specified \a brush.
*/

void QPainter::fillRect(const QRect &r, const QBrush &brush)
{
    Q_D(QPainter);

    if (!d->engine)
        return;

    if (d->extended) {
        const QGradient *g = brush.gradient();
        if (!g || g->coordinateMode() == QGradient::LogicalMode) {
            d->extended->fillRect(r, brush);
            return;
        }
    }

    QPen oldPen = pen();
    QBrush oldBrush = this->brush();
    setPen(Qt::NoPen);
    if (brush.style() == Qt::SolidPattern) {
        d->colorBrush.setStyle(Qt::SolidPattern);
        d->colorBrush.setColor(brush.color());
        setBrush(d->colorBrush);
    } else {
        setBrush(brush);
    }

    drawRect(r);
    setBrush(oldBrush);
    setPen(oldPen);
}



/*!
    \fn void QPainter::fillRect(const QRect &rectangle, const QColor &color)
    \overload

    Fills the given \a rectangle with the \a color specified.

    \since 4.5
*/
void QPainter::fillRect(const QRect &r, const QColor &color)
{
    Q_D(QPainter);

    if (!d->engine)
        return;

    if (d->extended) {
        d->extended->fillRect(r, color);
        return;
    }

    fillRect(r, QBrush(color));
}


/*!
    \fn void QPainter::fillRect(const QRectF &rectangle, const QColor &color)
    \overload

    Fills the given \a rectangle with the \a color specified.

    \since 4.5
*/
void QPainter::fillRect(const QRectF &r, const QColor &color)
{
    Q_D(QPainter);

    if (!d->engine)
        return;

    if (d->extended) {
        d->extended->fillRect(r, color);
        return;
    }

    fillRect(r, QBrush(color));
}

/*!
    \fn void QPainter::fillRect(int x, int y, int width, int height, const QBrush &brush)

    \overload

    Fills the rectangle beginning at (\a{x}, \a{y}) with the given \a
    width and \a height, using the given \a brush.
*/

/*!
    \fn void QPainter::fillRect(int x, int y, int width, int height, const QColor &color)

    \overload

    Fills the rectangle beginning at (\a{x}, \a{y}) with the given \a
    width and \a height, using the given \a color.

    \since 4.5
*/

/*!
    \fn void QPainter::fillRect(int x, int y, int width, int height, Qt::GlobalColor color)

    \overload

    Fills the rectangle beginning at (\a{x}, \a{y}) with the given \a
    width and \a height, using the given \a color.

    \since 4.5
*/

/*!
    \fn void QPainter::fillRect(const QRect &rectangle, Qt::GlobalColor color);

    \overload

    Fills the given \a rectangle with the specified \a color.

    \since 4.5
*/

/*!
    \fn void QPainter::fillRect(const QRectF &rectangle, Qt::GlobalColor color);

    \overload

    Fills the given \a rectangle with the specified \a color.

    \since 4.5
*/

/*!
    Sets the given render \a hint on the painter if \a on is true;
    otherwise clears the render hint.

    \sa setRenderHints(), renderHints(), {QPainter#Rendering
    Quality}{Rendering Quality}
*/
void QPainter::setRenderHint(RenderHint hint, bool on)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::setRenderHint: hint=%x, %s\n", hint, on ? "on" : "off");
#endif

#ifndef QT_NO_DEBUG
    static const bool antialiasingDisabled = qgetenv("QT_NO_ANTIALIASING").toInt();
    if (hint == QPainter::Antialiasing && antialiasingDisabled)
        return;
#endif

    setRenderHints(hint, on);
}

/*!
    \since 4.2

    Sets the given render \a hints on the painter if \a on is true;
    otherwise clears the render hints.

    \sa setRenderHint(), renderHints(), {QPainter#Rendering
    Quality}{Rendering Quality}
*/

void QPainter::setRenderHints(RenderHints hints, bool on)
{
    Q_D(QPainter);

    if (!d->engine) {
        qWarning("QPainter::setRenderHint: Painter must be active to set rendering hints");
        return;
    }

    if (on)
        d->state->renderHints |= hints;
    else
        d->state->renderHints &= ~hints;

    if (d->extended)
        d->extended->renderHintsChanged();
    else
        d->state->dirtyFlags |= QPaintEngine::DirtyHints;
}

/*!
    Returns a flag that specifies the rendering hints that are set for
    this painter.

    \sa testRenderHint(), {QPainter#Rendering Quality}{Rendering Quality}
*/
QPainter::RenderHints QPainter::renderHints() const
{
    Q_D(const QPainter);

    if (!d->engine)
        return 0;

    return d->state->renderHints;
}

/*!
    \fn bool QPainter::testRenderHint(RenderHint hint) const
    \since 4.3

    Returns true if \a hint is set; otherwise returns false.

    \sa renderHints(), setRenderHint()
*/

/*!
    Returns true if view transformation is enabled; otherwise returns
    false.

    \sa setViewTransformEnabled(), worldTransform()
*/

bool QPainter::viewTransformEnabled() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::viewTransformEnabled: Painter not active");
        return false;
    }
    return d->state->VxF;
}

/*!
    \fn void QPainter::setWindow(const QRect &rectangle)

    Sets the painter's window to the given \a rectangle, and enables
    view transformations.

    The window rectangle is part of the view transformation. The
    window specifies the logical coordinate system. Its sister, the
    viewport(), specifies the device coordinate system.

    The default window rectangle is the same as the device's
    rectangle.

    \sa window(), viewTransformEnabled(), {Coordinate
    System#Window-Viewport Conversion}{Window-Viewport Conversion}
*/

/*!
    \fn void QPainter::setWindow(int x, int y, int width, int height)
    \overload

    Sets the painter's window to the rectangle beginning at (\a x, \a
    y) and the given \a width and \a height.
*/

void QPainter::setWindow(const QRect &r)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::setWindow(), [%d,%d,%d,%d]\n", r.x(), r.y(), r.width(), r.height());
#endif

    Q_D(QPainter);

    if (!d->engine) {
        qWarning("QPainter::setWindow: Painter not active");
        return;
    }

    d->state->wx = r.x();
    d->state->wy = r.y();
    d->state->ww = r.width();
    d->state->wh = r.height();

    d->state->VxF = true;
    d->updateMatrix();
}

/*!
    Returns the window rectangle.

    \sa setWindow(), setViewTransformEnabled()
*/

QRect QPainter::window() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::window: Painter not active");
        return QRect();
    }
    return QRect(d->state->wx, d->state->wy, d->state->ww, d->state->wh);
}

/*!
    \fn void QPainter::setViewport(const QRect &rectangle)

    Sets the painter's viewport rectangle to the given \a rectangle,
    and enables view transformations.

    The viewport rectangle is part of the view transformation. The
    viewport specifies the device coordinate system. Its sister, the
    window(), specifies the logical coordinate system.

    The default viewport rectangle is the same as the device's
    rectangle.

    \sa viewport(), viewTransformEnabled() {Coordinate
    System#Window-Viewport Conversion}{Window-Viewport Conversion}
*/

/*!
    \fn void QPainter::setViewport(int x, int y, int width, int height)
    \overload

    Sets the painter's viewport rectangle to be the rectangle
    beginning at (\a x, \a y) with the given \a width and \a height.
*/

void QPainter::setViewport(const QRect &r)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::setViewport(), [%d,%d,%d,%d]\n", r.x(), r.y(), r.width(), r.height());
#endif

    Q_D(QPainter);

    if (!d->engine) {
        qWarning("QPainter::setViewport: Painter not active");
        return;
    }

    d->state->vx = r.x();
    d->state->vy = r.y();
    d->state->vw = r.width();
    d->state->vh = r.height();

    d->state->VxF = true;
    d->updateMatrix();
}

/*!
    Returns the viewport rectangle.

    \sa setViewport(), setViewTransformEnabled()
*/

QRect QPainter::viewport() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::viewport: Painter not active");
        return QRect();
    }
    return QRect(d->state->vx, d->state->vy, d->state->vw, d->state->vh);
}

/*! \fn bool QPainter::hasViewXForm() const
    \compat

    Use viewTransformEnabled() instead.
*/

/*! \fn bool QPainter::hasWorldXForm() const
    \compat

    Use worldMatrixEnabled() instead.
*/

/*! \fn void QPainter::resetXForm()
    \compat

    Use resetTransform() instead.
*/

/*! \fn void QPainter::setViewXForm(bool enabled)
    \compat

    Use setViewTransformEnabled() instead.
*/

/*! \fn void QPainter::setWorldXForm(bool enabled)
    \compat

    Use setWorldMatrixEnabled() instead.
*/
/*!
    Enables view transformations if \a enable is true, or disables
    view transformations if \a enable is false.

    \sa viewTransformEnabled(), {Coordinate System#Window-Viewport
    Conversion}{Window-Viewport Conversion}
*/

void QPainter::setViewTransformEnabled(bool enable)
{
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::setViewTransformEnabled(), enable=%d\n", enable);
#endif

    Q_D(QPainter);

    if (!d->engine) {
        qWarning("QPainter::setViewTransformEnabled: Painter not active");
        return;
    }

    if (enable == d->state->VxF)
        return;

    d->state->VxF = enable;
    d->updateMatrix();
}

#ifdef QT3_SUPPORT

/*!
    \obsolete

    Use the worldTransform() combined with QTransform::dx() instead.

    \oldcode
        QPainter painter(this);
        qreal x = painter.translationX();
    \newcode
        QPainter painter(this);
        qreal x = painter.worldTransform().dx();
    \endcode
*/
qreal QPainter::translationX() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::translationX: Painter not active");
        return 0.0;
    }
    return d->state->worldMatrix.dx();
}

/*!
    \obsolete

    Use the worldTransform() combined with QTransform::dy() instead.

    \oldcode
        QPainter painter(this);
        qreal y = painter.translationY();
    \newcode
        QPainter painter(this);
        qreal y = painter.worldTransform().dy();
    \endcode
*/
qreal QPainter::translationY() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::translationY: Painter not active");
        return 0.0;
    }
    return d->state->worldMatrix.dy();
}

/*!
    \fn void QPainter::map(int x, int y, int *rx, int *ry) const

    \internal

    Sets (\a{rx}, \a{ry}) to the point that results from applying the
    painter's current transformation on the point (\a{x}, \a{y}).
*/
void QPainter::map(int x, int y, int *rx, int *ry) const
{
    QPoint p(x, y);
    p = p * combinedMatrix();
    *rx = p.x();
    *ry = p.y();
}

/*!
    \fn QPoint QPainter::xForm(const QPoint &point) const

    Use combinedTransform() instead.
*/

QPoint QPainter::xForm(const QPoint &p) const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::xForm: Painter not active");
        return QPoint();
    }
    if (d->state->matrix.type() == QTransform::TxNone)
        return p;
    return p * combinedMatrix();
}


/*!
    \fn QRect QPainter::xForm(const QRect &rectangle) const
    \overload

    Use combinedTransform() instead of this function and call
    mapRect() on the result to obtain a QRect.
*/

QRect QPainter::xForm(const QRect &r) const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::xForm: Painter not active");
        return QRect();
    }
    if (d->state->matrix.type() == QTransform::TxNone)
        return r;
    return combinedMatrix().mapRect(r);
}

/*!
    \fn QPolygon QPainter::xForm(const QPolygon &polygon) const
    \overload

    Use combinedTransform() instead.
*/

QPolygon QPainter::xForm(const QPolygon &a) const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::xForm: Painter not active");
        return QPolygon();
    }
    if (d->state->matrix.type() == QTransform::TxNone)
        return a;
    return a * combinedMatrix();
}

/*!
    \fn QPolygon QPainter::xForm(const QPolygon &polygon, int index, int count) const
    \overload

    Use combinedTransform() combined with QPolygon::mid() instead.

    \oldcode
        QPainter painter(this);
        QPolygon transformed = painter.xForm(polygon, index, count)
    \newcode
        QPainter painter(this);
        QPolygon transformed = polygon.mid(index, count) * painter.combinedTransform();
    \endcode
*/

QPolygon QPainter::xForm(const QPolygon &av, int index, int npoints) const
{
    int lastPoint = npoints < 0 ? av.size() : index+npoints;
    QPolygon a(lastPoint-index);
    memcpy(a.data(), av.data()+index, (lastPoint-index)*sizeof(QPoint));
    return a * combinedMatrix();
}

/*!
    \fn QPoint QPainter::xFormDev(const QPoint &point) const
    \overload
    \obsolete

    Use combinedTransform() combined with QTransform::inverted() instead.

    \oldcode
        QPainter painter(this);
        QPoint transformed = painter.xFormDev(point);
    \newcode
        QPainter painter(this);
        QPoint transformed = point * painter.combinedTransform().inverted();
    \endcode
*/

QPoint QPainter::xFormDev(const QPoint &p) const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::xFormDev: Painter not active");
        return QPoint();
    }
    if(d->state->matrix.type() == QTransform::TxNone)
        return p;
    return p * combinedMatrix().inverted();
}

/*!
    \fn QRect QPainter::xFormDev(const QRect &rectangle) const
    \overload
    \obsolete

    Use combinedTransform() combined with QTransform::inverted() instead.

    \oldcode
        QPainter painter(this);
        QRect transformed = painter.xFormDev(rectangle);
    \newcode
        QPainter painter(this);
        QRegion region = QRegion(rectangle) * painter.combinedTransform().inverted();
        QRect transformed = region.boundingRect();
    \endcode
*/

QRect QPainter::xFormDev(const QRect &r)  const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::xFormDev: Painter not active");
        return QRect();
    }
    if (d->state->matrix.type() == QTransform::TxNone)
        return r;
    return combinedMatrix().inverted().mapRect(r);
}

/*!
    \overload

    \fn QPoint QPainter::xFormDev(const QPolygon &polygon) const
    \obsolete

    Use  combinedTransform() combined with QTransform::inverted() instead.

    \oldcode
        QPainter painter(this);
        QPolygon transformed = painter.xFormDev(rectangle);
    \newcode
        QPainter painter(this);
        QPolygon transformed = polygon * painter.combinedTransform().inverted();
    \endcode
*/

QPolygon QPainter::xFormDev(const QPolygon &a) const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::xFormDev: Painter not active");
        return QPolygon();
    }
    if (d->state->matrix.type() == QTransform::TxNone)
        return a;
    return a * combinedMatrix().inverted();
}

/*!
    \fn QPolygon QPainter::xFormDev(const QPolygon &polygon, int index, int count) const
    \overload
    \obsolete

    Use combinedTransform() combined with QPolygon::mid() and QTransform::inverted() instead.

    \oldcode
        QPainter painter(this);
        QPolygon transformed = painter.xFormDev(polygon, index, count);
    \newcode
        QPainter painter(this);
        QPolygon transformed = polygon.mid(index, count) * painter.combinedTransform().inverted();
    \endcode
*/

QPolygon QPainter::xFormDev(const QPolygon &ad, int index, int npoints) const
{
    Q_D(const QPainter);
    int lastPoint = npoints < 0 ? ad.size() : index+npoints;
    QPolygon a(lastPoint-index);
    memcpy(a.data(), ad.data()+index, (lastPoint-index)*sizeof(QPoint));
    if (d->state->matrix.type() == QTransform::TxNone)
        return a;
    return a * combinedMatrix().inverted();
}

/*!
    \fn void QPainter::drawCubicBezier(const QPolygon &controlPoints, int index)

    Draws a cubic Bezier curve defined by the \a controlPoints,
    starting at \a{controlPoints}\e{[index]} (\a index defaults to 0).
    Points after \a{controlPoints}\e{[index + 3]} are ignored. Nothing
    happens if there aren't enough control points.

    Use strokePath() instead.

    \oldcode
             QPainter painter(this);
             painter.drawCubicBezier(controlPoints, index)
    \newcode
             QPainterPath path;
             path.moveTo(controlPoints.at(index));
             path.cubicTo(controlPoints.at(index+1),
                                 controlPoints.at(index+2),
                                 controlPoints.at(index+3));

             QPainter painter(this);
             painter.strokePath(path, painter.pen());
    \endcode
*/
void QPainter::drawCubicBezier(const QPolygon &a, int index)
{
    Q_D(QPainter);

    if (!d->engine)
        return;

    if ((int)a.size() - index < 4) {
        qWarning("QPainter::drawCubicBezier: Cubic Bezier needs 4 control "
                  "points");
        return;
    }

    QPainterPath path;
    path.moveTo(a.at(index));
    path.cubicTo(a.at(index+1), a.at(index+2), a.at(index+3));
    strokePath(path, d->state->pen);
}
#endif

struct QPaintDeviceRedirection
{
    QPaintDeviceRedirection() : device(0), replacement(0), internalWidgetRedirectionIndex(-1) {}
    QPaintDeviceRedirection(const QPaintDevice *device, QPaintDevice *replacement,
                            const QPoint& offset, int internalWidgetRedirectionIndex)
        : device(device), replacement(replacement), offset(offset),
          internalWidgetRedirectionIndex(internalWidgetRedirectionIndex) { }
    const QPaintDevice *device;
    QPaintDevice *replacement;
    QPoint offset;
    int internalWidgetRedirectionIndex;
    bool operator==(const QPaintDevice *pdev) const { return device == pdev; }
    Q_DUMMY_COMPARISON_OPERATOR(QPaintDeviceRedirection)
};

typedef QList<QPaintDeviceRedirection> QPaintDeviceRedirectionList;
Q_GLOBAL_STATIC(QPaintDeviceRedirectionList, globalRedirections)
Q_GLOBAL_STATIC(QMutex, globalRedirectionsMutex)
Q_GLOBAL_STATIC(QAtomicInt, globalRedirectionAtomic)

/*!
    \threadsafe

    \obsolete

    Please use QWidget::render() instead.

    Redirects all paint commands for the given paint \a device, to the
    \a replacement device. The optional point \a offset defines an
    offset within the source device.

    The redirection will not be effective until the begin() function
    has been called; make sure to call end() for the given \a
    device's painter (if any) before redirecting. Call
    restoreRedirected() to restore the previous redirection.

    \warning Making use of redirections in the QPainter API implies
    that QPainter::begin() and QPaintDevice destructors need to hold
    a mutex for a short period. This can impact performance. Use of
    QWidget::render is strongly encouraged.

    \sa redirected(), restoreRedirected()
*/
void QPainter::setRedirected(const QPaintDevice *device,
                             QPaintDevice *replacement,
                             const QPoint &offset)
{
    Q_ASSERT(device != 0);

    bool hadInternalWidgetRedirection = false;
    if (device->devType() == QInternal::Widget) {
        const QWidgetPrivate *widgetPrivate = static_cast<const QWidget *>(device)->d_func();
        // This is the case when the widget is in a paint event.
        if (widgetPrivate->redirectDev) {
            // Remove internal redirection and put it back into the global redirection list.
            QPoint oldOffset;
            QPaintDevice *oldReplacement = widgetPrivate->redirected(&oldOffset);
            const_cast<QWidgetPrivate *>(widgetPrivate)->restoreRedirected();
            setRedirected(device, oldReplacement, oldOffset);
            hadInternalWidgetRedirection = true;
        }
    }

    QPoint roffset;
    QPaintDevice *rdev = redirected(replacement, &roffset);

    QMutexLocker locker(globalRedirectionsMutex());
    QPaintDeviceRedirectionList *redirections = globalRedirections();
    Q_ASSERT(redirections != 0);
    *redirections += QPaintDeviceRedirection(device, rdev ? rdev : replacement, offset + roffset,
                                             hadInternalWidgetRedirection ? redirections->size() - 1 : -1);
    globalRedirectionAtomic()->ref();
}

/*!
    \threadsafe

    \obsolete

    Using QWidget::render() obsoletes the use of this function.

    Restores the previous redirection for the given \a device after a
    call to setRedirected().

    \warning Making use of redirections in the QPainter API implies
    that QPainter::begin() and QPaintDevice destructors need to hold
    a mutex for a short period. This can impact performance. Use of
    QWidget::render is strongly encouraged.

    \sa redirected()
 */
void QPainter::restoreRedirected(const QPaintDevice *device)
{
    Q_ASSERT(device != 0);
    QMutexLocker locker(globalRedirectionsMutex());
    QPaintDeviceRedirectionList *redirections = globalRedirections();
    Q_ASSERT(redirections != 0);
    for (int i = redirections->size()-1; i >= 0; --i) {
        if (redirections->at(i) == device) {
            globalRedirectionAtomic()->deref();
            const int internalWidgetRedirectionIndex = redirections->at(i).internalWidgetRedirectionIndex;
            redirections->removeAt(i);
            // Restore the internal widget redirection, i.e. remove it from the global
            // redirection list and put it back into QWidgetPrivate. The index is only set when
            // someone call QPainter::setRedirected in a widget's paint event and we internally
            // have a redirection set (typically set in QWidgetPrivate::drawWidget).
            if (internalWidgetRedirectionIndex >= 0) {
                Q_ASSERT(internalWidgetRedirectionIndex < redirections->size());
                const QPaintDeviceRedirection &redirectionDevice = redirections->at(internalWidgetRedirectionIndex);
                QWidget *widget = static_cast<QWidget *>(const_cast<QPaintDevice *>(device));
                widget->d_func()->setRedirected(redirectionDevice.replacement, redirectionDevice.offset);
                redirections->removeAt(internalWidgetRedirectionIndex);
            }
            return;
        }
    }
}

/*!
    \threadsafe

    \obsolete

    Using QWidget::render() obsoletes the use of this function.

    Returns the replacement for given \a device. The optional out
    parameter \a offset returns the offset within the replaced device.

    \warning Making use of redirections in the QPainter API implies
    that QPainter::begin() and QPaintDevice destructors need to hold
    a mutex for a short period. This can impact performance. Use of
    QWidget::render is strongly encouraged.

    \sa setRedirected(), restoreRedirected()
*/
QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
{
    Q_ASSERT(device != 0);

    if (device->devType() == QInternal::Widget) {
        const QWidgetPrivate *widgetPrivate = static_cast<const QWidget *>(device)->d_func();
        if (widgetPrivate->redirectDev)
            return widgetPrivate->redirected(offset);
    }

    if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0)
        return 0;

    QMutexLocker locker(globalRedirectionsMutex());
    QPaintDeviceRedirectionList *redirections = globalRedirections();
    Q_ASSERT(redirections != 0);
    for (int i = redirections->size()-1; i >= 0; --i)
        if (redirections->at(i) == device) {
            if (offset)
                *offset = redirections->at(i).offset;
            return redirections->at(i).replacement;
        }
    if (offset)
        *offset = QPoint(0, 0);
    return 0;
}


void qt_painter_removePaintDevice(QPaintDevice *dev)
{
    if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0)
        return;

    QMutex *mutex = 0;
    QT_TRY {
        mutex = globalRedirectionsMutex();
    } QT_CATCH(...) {
        // ignore the missing mutex, since we could be called from
        // a destructor, and destructors shall not throw
    }
    QMutexLocker locker(mutex);
    QPaintDeviceRedirectionList *redirections = 0;
    QT_TRY {
        redirections = globalRedirections();
    } QT_CATCH(...) {
        // do nothing - code below is safe with redirections being 0.
    }
    if (redirections) {
        for (int i = 0; i < redirections->size(); ) {
            if(redirections->at(i) == dev || redirections->at(i).replacement == dev)
                redirections->removeAt(i);
            else
                ++i;
        }
    }
}

void qt_format_text(const QFont &fnt, const QRectF &_r,
                    int tf, const QString& str, QRectF *brect,
                    int tabstops, int *ta, int tabarraylen,
                    QPainter *painter)
{
    qt_format_text(fnt, _r,
                    tf, 0, str, brect,
                    tabstops, ta, tabarraylen,
                    painter);
}
void qt_format_text(const QFont &fnt, const QRectF &_r,
                    int tf, const QTextOption *option, const QString& str, QRectF *brect,
                    int tabstops, int *, int tabarraylen,
                    QPainter *painter)
{

    Q_ASSERT( !((tf & ~Qt::TextDontPrint)!=0 && option!=0) ); // we either have an option or flags

    if (option) {
        tf |= option->alignment();
        if (option->wrapMode() != QTextOption::NoWrap)
            tf |= Qt::TextWordWrap;

        if (option->flags() & QTextOption::IncludeTrailingSpaces)
            tf |= Qt::TextIncludeTrailingSpaces;

        if (option->tabStop() >= 0 || !option->tabArray().isEmpty())
            tf |= Qt::TextExpandTabs;
    }

    // we need to copy r here to protect against the case (&r == brect).
    QRectF r(_r);

    bool dontclip  = (tf & Qt::TextDontClip);
    bool wordwrap  = (tf & Qt::TextWordWrap) || (tf & Qt::TextWrapAnywhere);
    bool singleline = (tf & Qt::TextSingleLine);
    bool showmnemonic = (tf & Qt::TextShowMnemonic);
    bool hidemnmemonic = (tf & Qt::TextHideMnemonic);

    Qt::LayoutDirection layout_direction;
    if (tf & Qt::TextForceLeftToRight)
        layout_direction = Qt::LeftToRight;
    else if (tf & Qt::TextForceRightToLeft)
        layout_direction = Qt::RightToLeft;
    else if (option)
        layout_direction = option->textDirection();
    else if (painter)
        layout_direction = painter->layoutDirection();
    else
        layout_direction = Qt::LeftToRight;

    tf = QStyle::visualAlignment(layout_direction, QFlag(tf));

    bool isRightToLeft = layout_direction == Qt::RightToLeft;
    bool expandtabs = ((tf & Qt::TextExpandTabs) &&
                        (((tf & Qt::AlignLeft) && !isRightToLeft) ||
                          ((tf & Qt::AlignRight) && isRightToLeft)));

    if (!painter)
        tf |= Qt::TextDontPrint;

    uint maxUnderlines = 0;
    int numUnderlines = 0;
    QVarLengthArray<int, 32> underlinePositions(1);

    QFontMetricsF fm(fnt);
    QString text = str;
    int offset = 0;
start_lengthVariant:
    bool hasMoreLengthVariants = false;
    // compatible behaviour to the old implementation. Replace
    // tabs by spaces
    int old_offset = offset;
    for (; offset < text.length(); offset++) {
        QChar chr = text.at(offset);
        if (chr == QLatin1Char('\r') || (singleline && chr == QLatin1Char('\n'))) {
            text[offset] = QLatin1Char(' ');
        } else if (chr == QLatin1Char('\n')) {
            text[offset] = QChar::LineSeparator;
        } else if (chr == QLatin1Char('&')) {
            ++maxUnderlines;
        } else if (chr == QLatin1Char('\t')) {
            if (!expandtabs) {
                text[offset] = QLatin1Char(' ');
            } else if (!tabarraylen && !tabstops) {
                tabstops = qRound(fm.width(QLatin1Char('x'))*8);
            }
        } else if (chr == QChar(ushort(0x9c))) {
            // string with multiple length variants
            hasMoreLengthVariants = true;
            break;
        }
    }

    int length = offset - old_offset;
    if ((hidemnmemonic || showmnemonic) && maxUnderlines > 0) {
        underlinePositions.resize(maxUnderlines + 1);

        QChar *cout = text.data() + old_offset;
        QChar *cin = cout;
        int l = length;
        while (l) {
            if (*cin == QLatin1Char('&')) {
                ++cin;
                --length;
                --l;
                if (!l)
                    break;
                if (*cin != QLatin1Char('&') && !hidemnmemonic)
                    underlinePositions[numUnderlines++] = cout - text.data() - old_offset;
            }
            *cout = *cin;
            ++cout;
            ++cin;
            --l;
        }
    }

    // no need to do extra work for underlines if we don't paint
    if (tf & Qt::TextDontPrint)
        numUnderlines = 0;

    underlinePositions[numUnderlines] = -1;
    qreal height = 0;
    qreal width = 0;

    QString finalText = text.mid(old_offset, length);
    QStackTextEngine engine(finalText, fnt);
    if (option) {
        engine.option = *option;
    }

    engine.option.setTextDirection(layout_direction);
    if (tf & Qt::AlignJustify)
        engine.option.setAlignment(Qt::AlignJustify);
    else
        engine.option.setAlignment(Qt::AlignLeft); // do not do alignment twice

    if (!option && (tf & Qt::TextWrapAnywhere))
        engine.option.setWrapMode(QTextOption::WrapAnywhere);

    if (tf & Qt::TextJustificationForced)
        engine.forceJustification = true;
    QTextLayout textLayout(&engine);
    textLayout.setCacheEnabled(true);
    textLayout.engine()->underlinePositions = underlinePositions.data();

    if (finalText.isEmpty()) {
        height = fm.height();
        width = 0;
        tf |= Qt::TextDontPrint;
    } else {
        qreal lineWidth = 0x01000000;
        if (wordwrap || (tf & Qt::TextJustificationForced))
            lineWidth = qMax<qreal>(0, r.width());
        if(!wordwrap)
            tf |= Qt::TextIncludeTrailingSpaces;
        textLayout.engine()->ignoreBidi = bool(tf & Qt::TextDontPrint);
        textLayout.beginLayout();

        qreal leading = fm.leading();
        height = -leading;

        while (1) {
            QTextLine l = textLayout.createLine();
            if (!l.isValid())
                break;

            l.setLineWidth(lineWidth);
            height += leading;
            l.setPosition(QPointF(0., height));
            height += l.height();
            width = qMax(width, l.naturalTextWidth());
            if (!dontclip && !brect && height >= r.height())
                break;
        }
        textLayout.endLayout();
    }

    qreal yoff = 0;
    qreal xoff = 0;
    if (tf & Qt::AlignBottom) {
        yoff = r.height() - height;
    } else if (tf & Qt::AlignVCenter) {
        yoff = (r.height() - height)/2;
        if (painter) {
            QTransform::TransformationType type = painter->transform().type();
            if (type <= QTransform::TxScale) {
                // do the rounding manually to work around inconsistencies
                // in the paint engines when drawing on floating point offsets
                const qreal scale = painter->transform().m22();
                if (scale != 0)
                    yoff = -qRound(-yoff * scale) / scale;
            }
        }
    }
    if (tf & Qt::AlignRight) {
        xoff = r.width() - width;
    } else if (tf & Qt::AlignHCenter) {
        xoff = (r.width() - width)/2;
        if (painter) {
            QTransform::TransformationType type = painter->transform().type();
            if (type <= QTransform::TxScale) {
                // do the rounding manually to work around inconsistencies
                // in the paint engines when drawing on floating point offsets
                const qreal scale = painter->transform().m11();
                if (scale != 0)
                    xoff = qRound(xoff * scale) / scale;
            }
        }
    }
    QRectF bounds = QRectF(r.x() + xoff, r.y() + yoff, width, height);

    if (hasMoreLengthVariants && !(tf & Qt::TextLongestVariant) && !r.contains(bounds)) {
        offset++;
        goto start_lengthVariant;
    }
    if (brect)
        *brect = bounds;

    if (!(tf & Qt::TextDontPrint)) {
        bool restore = false;
        if (!dontclip && !r.contains(bounds)) {
            restore = true;
            painter->save();
            painter->setClipRect(r, Qt::IntersectClip);
        }

        for (int i = 0; i < textLayout.lineCount(); i++) {
            QTextLine line = textLayout.lineAt(i);

            qreal advance = line.horizontalAdvance();
            xoff = 0;
            if (tf & Qt::AlignRight) {
                QTextEngine *eng = textLayout.engine();
                xoff = r.width() - advance -
                    eng->leadingSpaceWidth(eng->lines[line.lineNumber()]).toReal();
            }
            else if (tf & Qt::AlignHCenter)
                xoff = (r.width() - advance) / 2;

            line.draw(painter, QPointF(r.x() + xoff, r.y() + yoff));
        }

        if (restore) {
            painter->restore();
        }
    }
}

/*!
    Sets the layout direction used by the painter when drawing text,
    to the specified \a direction.

    The default is Qt::LayoutDirectionAuto, which will implicitly determine the
    direction from the text drawn.

    \sa QTextOption::setTextDirection(), layoutDirection(), drawText(), {QPainter#Settings}{Settings}
*/
void QPainter::setLayoutDirection(Qt::LayoutDirection direction)
{
    Q_D(QPainter);
    if (d->state)
        d->state->layoutDirection = direction;
}

/*!
    Returns the layout direction used by the painter when drawing text.

    \sa QTextOption::textDirection(), setLayoutDirection(), drawText(), {QPainter#Settings}{Settings}
*/
Qt::LayoutDirection QPainter::layoutDirection() const
{
    Q_D(const QPainter);
    return d->state ? d->state->layoutDirection : Qt::LayoutDirectionAuto;
}

QPainterState::QPainterState(const QPainterState *s)
    : brushOrigin(s->brushOrigin), font(s->font), deviceFont(s->deviceFont),
      pen(s->pen), brush(s->brush), bgBrush(s->bgBrush),
      clipRegion(s->clipRegion), clipPath(s->clipPath),
      clipOperation(s->clipOperation),
      renderHints(s->renderHints), clipInfo(s->clipInfo),
      worldMatrix(s->worldMatrix), matrix(s->matrix), redirectionMatrix(s->redirectionMatrix),
      wx(s->wx), wy(s->wy), ww(s->ww), wh(s->wh),
      vx(s->vx), vy(s->vy), vw(s->vw), vh(s->vh),
      opacity(s->opacity), WxF(s->WxF), VxF(s->VxF),
      clipEnabled(s->clipEnabled), bgMode(s->bgMode), painter(s->painter),
      layoutDirection(s->layoutDirection),
      composition_mode(s->composition_mode),
      emulationSpecifier(s->emulationSpecifier), changeFlags(0)
{
    dirtyFlags = s->dirtyFlags;
}

QPainterState::QPainterState()
    : brushOrigin(0, 0), bgBrush(Qt::white), clipOperation(Qt::NoClip),
      renderHints(0),
      wx(0), wy(0), ww(0), wh(0), vx(0), vy(0), vw(0), vh(0),
      opacity(1), WxF(false), VxF(false), clipEnabled(true),
      bgMode(Qt::TransparentMode), painter(0),
      layoutDirection(QApplication::layoutDirection()),
      composition_mode(QPainter::CompositionMode_SourceOver),
      emulationSpecifier(0), changeFlags(0)
{
    dirtyFlags = 0;
}

QPainterState::~QPainterState()
{
}

void QPainterState::init(QPainter *p) {
    bgBrush = Qt::white;
    bgMode = Qt::TransparentMode;
    WxF = false;
    VxF = false;
    clipEnabled = true;
    wx = wy = ww = wh = 0;
    vx = vy = vw = vh = 0;
    painter = p;
    pen = QPen();
    brushOrigin = QPointF(0, 0);
    brush = QBrush();
    font = deviceFont = QFont();
    clipRegion = QRegion();
    clipPath = QPainterPath();
    clipOperation = Qt::NoClip;
    clipInfo.clear();
    worldMatrix.reset();
    matrix.reset();
    layoutDirection = QApplication::layoutDirection();
    composition_mode = QPainter::CompositionMode_SourceOver;
    emulationSpecifier = 0;
    dirtyFlags = 0;
    changeFlags = 0;
    renderHints = 0;
    opacity = 1;
}

#ifdef QT3_SUPPORT
static void bitBlt_helper(QPaintDevice *dst, const QPoint &dp,
                          const QPaintDevice *src, const QRect &sr, bool)
{
    Q_ASSERT(dst);
    Q_ASSERT(src);

    if (src->devType() == QInternal::Pixmap) {
        const QPixmap *pixmap = static_cast<const QPixmap *>(src);
        QPainter pt(dst);
        pt.drawPixmap(dp, *pixmap, sr);

    } else {
        qWarning("QPainter: bitBlt only works when source is of type pixmap");
    }
}

void bitBlt(QPaintDevice *dst, int dx, int dy,
             const QPaintDevice *src, int sx, int sy, int sw, int sh,
             bool ignoreMask )
{
    bitBlt_helper(dst, QPoint(dx, dy), src, QRect(sx, sy, sw, sh), ignoreMask);
}

void bitBlt(QPaintDevice *dst, const QPoint &dp, const QPaintDevice *src, const QRect &sr, bool ignoreMask)
{
    bitBlt_helper(dst, dp, src, sr, ignoreMask);
}

void bitBlt(QPaintDevice *dst, int dx, int dy,
            const QImage *src, int sx, int sy, int sw, int sh, int fl)
{
    Qt::ImageConversionFlags flags(fl);
    QPixmap srcPixmap = QPixmap::fromImage(*src, flags);
    bitBlt_helper(dst, QPoint(dx, dy), &srcPixmap, QRect(sx, sy, sw, sh), false);
}

#endif // QT3_SUPPORT

/*!
    \fn void QPainter::setBackgroundColor(const QColor &color)

    Use setBackground() instead.
*/

/*!
    \fn const QColor &QPainter::backgroundColor() const

    Use background() and QBrush::color() instead.

    \oldcode
        QColor myColor = backgroundColor();
    \newcode
        QColor myColor = background().color();
    \endcode

    Note that the background can be a complex brush such as a texture
    or a gradient.
*/

/*!
    \fn void QPainter::drawText(int x, int y, const QString &text, int pos, int length)
    \compat

    Use drawText() combined with QString::mid() instead.

    \oldcode
        QPainter painter(this);
        painter.drawText(x, y, text, pos, length);
    \newcode
        QPainter painter(this);
        painter.drawText(x, y, text.mid(pos, length));
    \endcode
*/

/*!
    \fn void QPainter::drawText(const QPoint &point, const QString &text, int pos, int length)
    \compat

    Use drawText() combined with QString::mid() instead.

    \oldcode
        QPainter painter(this);
        painter.drawText(point, text, pos, length);
    \newcode
        QPainter painter(this);
        painter.drawText(point, text.mid(pos, length));
    \endcode
*/

/*!
    \fn void QPainter::drawText(int x, int y, const QString &text, int length)
    \compat

    Use drawText() combined with QString::left() instead.

    \oldcode
        QPainter painter(this);
        painter.drawText(x, y, text, length);
    \newcode
        QPainter painter(this);
        painter.drawText(x, y, text.left(length));
    \endcode
*/

/*!
    \fn void QPainter::drawText(const QPoint &point, const QString &text, int length)
    \compat

    Use drawText() combined with QString::left() instead.

    \oldcode
        QPainter painter(this);
        painter.drawText(point, text, length);
    \newcode
        QPainter painter(this);
        painter.drawText(point, text.left(length));
    \endcode
*/

/*!
    \fn bool QPainter::begin(QPaintDevice *device, const QWidget *init)
    \compat

    Use begin() instead.

    If the paint \a device is a QWidget, QPainter is initialized after
    the widget's settings automatically. Otherwise, you must call the
    initFrom() function to initialize the painters pen, background and
    font to the same as any given widget.

    \oldcode
        QPainter painter(this);
        painter.begin(device, init);
    \newcode
        QPainter painter(this);
        painter.begin(device);
        painter.initFrom(init);
    \endcode
*/

/*!
    \fn void QPainter::drawImage(const QRectF &target, const QImage &image, const QRectF &source,
                         Qt::ImageConversionFlags flags)

    Draws the rectangular portion \a source of the given \a image
    into the \a target rectangle in the paint device.

    \note The image is scaled to fit the rectangle, if both the image and rectangle size disagree.

    If the image needs to be modified to fit in a lower-resolution
    result (e.g. converting from 32-bit to 8-bit), use the \a flags to
    specify how you would prefer this to happen.

    \table 100%
    \row
    \o
    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 20
    \endtable

    \sa drawPixmap()
*/

/*!
    \fn void QPainter::drawImage(const QRect &target, const QImage &image, const QRect &source,
                                 Qt::ImageConversionFlags flags)
    \overload

    Draws the rectangular portion \a source of the given \a image
    into the \a target rectangle in the paint device.

    \note The image is scaled to fit the rectangle, if both the image and rectangle size disagree.
*/

/*!
    \fn void QPainter::drawImage(const QPointF &point, const QImage &image)

    \overload

    Draws the given \a image at the given \a point.
*/

/*!
    \fn void QPainter::drawImage(const QPoint &point, const QImage &image)

    \overload

    Draws the given \a image at the given \a point.
*/

/*!
    \fn void QPainter::drawImage(const QPointF &point, const QImage &image, const QRectF &source,
                                 Qt::ImageConversionFlags flags = 0)

    \overload

    Draws the rectangular portion \a source of the given \a image with
    its origin at the given \a point.
*/

/*!
    \fn void QPainter::drawImage(const QPoint &point, const QImage &image, const QRect &source,
                                 Qt::ImageConversionFlags flags = 0)
    \overload

    Draws the rectangular portion \a source of the given \a image with
    its origin at the given \a point.
*/

/*!
    \fn void QPainter::drawImage(const QRectF &rectangle, const QImage &image)

    \overload

    Draws the given \a image into the given \a rectangle.

    \note The image is scaled to fit the rectangle, if both the image and rectangle size disagree.
*/

/*!
    \fn void QPainter::drawImage(const QRect &rectangle, const QImage &image)

    \overload

    Draws the given \a image into the given \a rectangle.

   \note The image is scaled to fit the rectangle, if both the image and rectangle size disagree.
*/

/*!
    \fn void QPainter::drawImage(int x, int y, const QImage &image,
                                 int sx, int sy, int sw, int sh,
                                 Qt::ImageConversionFlags flags)
    \overload

    Draws an image at (\a{x}, \a{y}) by copying a part of \a image into
    the paint device.

    (\a{x}, \a{y}) specifies the top-left point in the paint device that is
    to be drawn onto. (\a{sx}, \a{sy}) specifies the top-left point in \a
    image that is to be drawn. The default is (0, 0).

    (\a{sw}, \a{sh}) specifies the size of the image that is to be drawn.
    The default, (0, 0) (and negative) means all the way to the
    bottom-right of the image.
*/

/*!
    \fn void QPainter::redirect(QPaintDevice *pdev, QPaintDevice *replacement)

    Use setRedirected() instead.
*/

/*!
    \fn QPaintDevice *QPainter::redirect(QPaintDevice *pdev)

    Use redirected() instead.
*/

/*!
    \fn QRect QPainter::boundingRect(const QRect &rectangle, int flags,
                                     const QString &text, int length)
    \compat

    Returns the bounding rectangle for the given \a length of the \a
    text constrained by the provided \a rectangle.

    Use boundingRect() combined with QString::left() instead.

    \oldcode
        QRect rectangle = boundingRect(rect, flags, text, length);
    \newcode
        QRect rectangle = boundingRect(rect, flags, text.left(length));
    \endcode
*/

/*!
    \fn void QPainter::drawText(const QRect &rectangle, int flags, const QString &text,
                                int length, QRect *br)
    \compat

    Use drawText() combined with QString::left() instead.

    \oldcode
        QPainter painter(this);
        painter.drawText(rectangle, flags, text, length, br );
    \newcode
        QPainter painter(this);
        painter.drawText(rectangle, flags, text.left(length), br );
    \endcode
*/

/*!
    \fn QRect QPainter::boundingRect(int x, int y, int width, int height, int flags,
                                     const QString &text, int length);

    \compat

    Returns the bounding rectangle for the given \a length of the \a
    text constrained by the rectangle that begins at point (\a{x},
    \a{y}) with the given \a width and \a height.

    Use boundingRect() combined with QString::left() instead.

    \oldcode
        QRect rectangle = boundingRect(x, y, width, height, flags, text, length);
    \newcode
        QRect rectangle = boundingRect(x, y, width, height, flags, text.left(length));
    \endcode
*/

/*!
    \fn void QPainter::drawText(int x, int y, int width, int height, int flags,
                                const QString &text, int length, QRect *br)

    \compat

    Use drawText() combined with QString::left() instead.

    \oldcode
        QPainter painter(this);
        painter.drawText(x, y, width, height, flags, text, length, br );
    \newcode
        QPainter painter(this);
        painter.drawText(x, y, width, height, flags, text.left(length), br );
    \endcode
*/


/*!
    \class QPaintEngineState
    \since 4.1

    \brief The QPaintEngineState class provides information about the
    active paint engine's current state.
    \reentrant

    QPaintEngineState records which properties that have changed since
    the last time the paint engine was updated, as well as their
    current value.

    Which properties that have changed can at any time be retrieved
    using the state() function. This function returns an instance of
    the QPaintEngine::DirtyFlags type which stores an OR combination
    of QPaintEngine::DirtyFlag values. The QPaintEngine::DirtyFlag
    enum defines whether a property has changed since the last update
    or not.

    If a property is marked with a dirty flag, its current value can
    be retrieved using the corresponding get function:

    \target GetFunction

    \table
    \header \o Property Flag \o Current Property Value
    \row \o QPaintEngine::DirtyBackground \o backgroundBrush()
    \row \o QPaintEngine::DirtyBackgroundMode \o backgroundMode()
    \row \o QPaintEngine::DirtyBrush \o brush()
    \row \o QPaintEngine::DirtyBrushOrigin \o brushOrigin()
    \row \o QPaintEngine::DirtyClipRegion \e or QPaintEngine::DirtyClipPath
         \o clipOperation()
    \row \o QPaintEngine::DirtyClipPath \o clipPath()
    \row \o QPaintEngine::DirtyClipRegion \o clipRegion()
    \row \o QPaintEngine::DirtyCompositionMode \o compositionMode()
    \row \o QPaintEngine::DirtyFont \o font()
    \row \o QPaintEngine::DirtyTransform \o transform()
    \row \o QPaintEngine::DirtyClipEnabled \o isClipEnabled()
    \row \o QPaintEngine::DirtyPen \o pen()
    \row \o QPaintEngine::DirtyHints \o renderHints()
    \endtable

    The QPaintEngineState class also provide the painter() function
    which returns a pointer to the painter that is currently updating
    the paint engine.

    An instance of this class, representing the current state of the
    active paint engine, is passed as argument to the
    QPaintEngine::updateState() function. The only situation in which
    you will have to use this class directly is when implementing your
    own paint engine.

    \sa QPaintEngine
*/


/*!
    \fn QPaintEngine::DirtyFlags QPaintEngineState::state() const

    Returns a combination of flags identifying the set of properties
    that need to be updated when updating the paint engine's state
    (i.e. during a call to the QPaintEngine::updateState() function).

    \sa QPaintEngine::updateState()
*/


/*!
    Returns the pen in the current paint engine state.

    This variable should only be used when the state() returns a
    combination which includes the QPaintEngine::DirtyPen flag.

    \sa state(), QPaintEngine::updateState()
*/

QPen QPaintEngineState::pen() const
{
    return static_cast<const QPainterState *>(this)->pen;
}

/*!
    Returns the brush in the current paint engine state.

    This variable should only be used when the state() returns a
    combination which includes the QPaintEngine::DirtyBrush flag.

    \sa state(), QPaintEngine::updateState()
*/

QBrush QPaintEngineState::brush() const
{
    return static_cast<const QPainterState *>(this)->brush;
}

/*!
    Returns the brush origin in the current paint engine state.

    This variable should only be used when the state() returns a
    combination which includes the QPaintEngine::DirtyBrushOrigin flag.

    \sa state(), QPaintEngine::updateState()
*/

QPointF QPaintEngineState::brushOrigin() const
{
    return static_cast<const QPainterState *>(this)->brushOrigin;
}

/*!
    Returns the background brush in the current paint engine state.

    This variable should only be used when the state() returns a
    combination which includes the QPaintEngine::DirtyBackground flag.

    \sa state(), QPaintEngine::updateState()
*/

QBrush QPaintEngineState::backgroundBrush() const
{
    return static_cast<const QPainterState *>(this)->bgBrush;
}

/*!
    Returns the background mode in the current paint engine
    state.

    This variable should only be used when the state() returns a
    combination which includes the QPaintEngine::DirtyBackgroundMode flag.

    \sa state(), QPaintEngine::updateState()
*/

Qt::BGMode QPaintEngineState::backgroundMode() const
{
    return static_cast<const QPainterState *>(this)->bgMode;
}

/*!
    Returns the font in the current paint engine
    state.

    This variable should only be used when the state() returns a
    combination which includes the QPaintEngine::DirtyFont flag.

    \sa state(), QPaintEngine::updateState()
*/

QFont QPaintEngineState::font() const
{
    return static_cast<const QPainterState *>(this)->font;
}

/*!
    \since 4.2
    \obsolete

    Returns the matrix in the current paint engine
    state.

    \note It is advisable to use transform() instead of this function to
    preserve the properties of perspective transformations.

    This variable should only be used when the state() returns a
    combination which includes the QPaintEngine::DirtyTransform flag.

    \sa state(), QPaintEngine::updateState()
*/

QMatrix QPaintEngineState::matrix() const
{
    const QPainterState *st = static_cast<const QPainterState *>(this);

    return st->matrix.toAffine();
}

/*!
    \since 4.3

    Returns the matrix in the current paint engine state.

    This variable should only be used when the state() returns a
    combination which includes the QPaintEngine::DirtyTransform flag.

    \sa state(), QPaintEngine::updateState()
*/


QTransform QPaintEngineState::transform() const
{
    const QPainterState *st = static_cast<const QPainterState *>(this);

    return st->matrix;
}


/*!
    Returns the clip operation in the current paint engine
    state.

    This variable should only be used when the state() returns a
    combination which includes either the QPaintEngine::DirtyClipPath
    or the QPaintEngine::DirtyClipRegion flag.

    \sa state(), QPaintEngine::updateState()
*/

Qt::ClipOperation QPaintEngineState::clipOperation() const
{
    return static_cast<const QPainterState *>(this)->clipOperation;
}

/*!
    \since 4.3

    Returns whether the coordinate of the fill have been specified
    as bounded by the current rendering operation and have to be
    resolved (about the currently rendered primitive).
*/
bool QPaintEngineState::brushNeedsResolving() const
{
    const QBrush &brush = static_cast<const QPainterState *>(this)->brush;
    return needsResolving(brush);
}


/*!
    \since 4.3

    Returns whether the coordinate of the stroke have been specified
    as bounded by the current rendering operation and have to be
    resolved (about the currently rendered primitive).
*/
bool QPaintEngineState::penNeedsResolving() const
{
    const QPen &pen = static_cast<const QPainterState *>(this)->pen;
    return needsResolving(pen.brush());
}

/*!
    Returns the clip region in the current paint engine state.

    This variable should only be used when the state() returns a
    combination which includes the QPaintEngine::DirtyClipRegion flag.

    \sa state(), QPaintEngine::updateState()
*/

QRegion QPaintEngineState::clipRegion() const
{
    return static_cast<const QPainterState *>(this)->clipRegion;
}

/*!
    Returns the clip path in the current paint engine state.

    This variable should only be used when the state() returns a
    combination which includes the QPaintEngine::DirtyClipPath flag.

    \sa state(), QPaintEngine::updateState()
*/

QPainterPath QPaintEngineState::clipPath() const
{
    return static_cast<const QPainterState *>(this)->clipPath;
}

/*!
    Returns whether clipping is enabled or not in the current paint
    engine state.

    This variable should only be used when the state() returns a
    combination which includes the QPaintEngine::DirtyClipEnabled
    flag.

    \sa state(), QPaintEngine::updateState()
*/

bool QPaintEngineState::isClipEnabled() const
{
    return static_cast<const QPainterState *>(this)->clipEnabled;
}

/*!
    Returns the render hints in the current paint engine state.

    This variable should only be used when the state() returns a
    combination which includes the QPaintEngine::DirtyHints
    flag.

    \sa state(), QPaintEngine::updateState()
*/

QPainter::RenderHints QPaintEngineState::renderHints() const
{
    return static_cast<const QPainterState *>(this)->renderHints;
}

/*!
    Returns the composition mode in the current paint engine state.

    This variable should only be used when the state() returns a
    combination which includes the QPaintEngine::DirtyCompositionMode
    flag.

    \sa state(), QPaintEngine::updateState()
*/

QPainter::CompositionMode QPaintEngineState::compositionMode() const
{
    return static_cast<const QPainterState *>(this)->composition_mode;
}


/*!
    Returns a pointer to the painter currently updating the paint
    engine.
*/

QPainter *QPaintEngineState::painter() const
{
    return static_cast<const QPainterState *>(this)->painter;
}


/*!
    \since 4.2

    Returns the opacity in the current paint engine state.
*/

qreal QPaintEngineState::opacity() const
{
    return static_cast<const QPainterState *>(this)->opacity;
}

/*!
    \since 4.3

    Sets the world transformation matrix.
    If \a combine is true, the specified \a transform is combined with
    the current matrix; otherwise it replaces the current matrix.

    \sa transform() setWorldTransform()
*/

void QPainter::setTransform(const QTransform &transform, bool combine )
{
    setWorldTransform(transform, combine);
}

/*!
    Returns the world transformation matrix.

    \sa worldTransform()
*/

const QTransform & QPainter::transform() const
{
    return worldTransform();
}


/*!
    Returns the matrix that transforms from logical coordinates to
    device coordinates of the platform dependent paint device.

    This function is \e only needed when using platform painting
    commands on the platform dependent handle (Qt::HANDLE), and the
    platform does not do transformations nativly.

    The QPaintEngine::PaintEngineFeature enum can be queried to
    determine whether the platform performs the transformations or
    not.

    \sa worldTransform(), QPaintEngine::hasFeature(),
*/

const QTransform & QPainter::deviceTransform() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::deviceTransform: Painter not active");
        return d->fakeState()->transform;
    }
    return d->state->matrix;
}


/*!
    Resets any transformations that were made using translate(),
    scale(), shear(), rotate(), setWorldTransform(), setViewport()
    and setWindow().

    \sa {Coordinate Transformations}
*/

void QPainter::resetTransform()
{
     Q_D(QPainter);
#ifdef QT_DEBUG_DRAW
    if (qt_show_painter_debug_output)
        printf("QPainter::resetMatrix()\n");
#endif
    if (!d->engine) {
        qWarning("QPainter::resetMatrix: Painter not active");
        return;
    }

    d->state->wx = d->state->wy = d->state->vx = d->state->vy = 0;                        // default view origins
    d->state->ww = d->state->vw = d->device->metric(QPaintDevice::PdmWidth);
    d->state->wh = d->state->vh = d->device->metric(QPaintDevice::PdmHeight);
    d->state->worldMatrix = QTransform();
    setMatrixEnabled(false);
    setViewTransformEnabled(false);
    if (d->extended)
        d->extended->transformChanged();
    else
        d->state->dirtyFlags |= QPaintEngine::DirtyTransform;
}

/*!
    Sets the world transformation matrix.
    If \a combine is true, the specified \a matrix is combined with the current matrix;
    otherwise it replaces the current matrix.

    \sa transform(), setTransform()
*/

void QPainter::setWorldTransform(const QTransform &matrix, bool combine )
{
    Q_D(QPainter);

    if (!d->engine) {
        qWarning("QPainter::setWorldTransform: Painter not active");
        return;
    }

    if (combine)
        d->state->worldMatrix = matrix * d->state->worldMatrix;                        // combines
    else
        d->state->worldMatrix = matrix;                                // set new matrix

    d->state->WxF = true;
    d->updateMatrix();
}

/*!
    Returns the world transformation matrix.
*/

const QTransform & QPainter::worldTransform() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::worldTransform: Painter not active");
        return d->fakeState()->transform;
    }
    return d->state->worldMatrix;
}

/*!
    Returns the transformation matrix combining the current
    window/viewport and world transformation.

    \sa setWorldTransform(), setWindow(), setViewport()
*/

QTransform QPainter::combinedTransform() const
{
    Q_D(const QPainter);
    if (!d->engine) {
        qWarning("QPainter::combinedTransform: Painter not active");
        return QTransform();
    }
    return d->state->worldMatrix * d->viewTransform();
}

/*!
    \since 4.7

    This function is used to draw \a pixmap, or a sub-rectangle of \a pixmap,
    at multiple positions with different scale, rotation and opacity. \a
    fragments is an array of \a fragmentCount elements specifying the
    parameters used to draw each pixmap fragment. The \a hints
    parameter can be used to pass in drawing hints.

    This function is potentially faster than multiple calls to drawPixmap(),
    since the backend can optimize state changes.

    \sa QPainter::PixmapFragment, QPainter::PixmapFragmentHint
*/

void QPainter::drawPixmapFragments(const PixmapFragment *fragments, int fragmentCount,
                                   const QPixmap &pixmap, PixmapFragmentHints hints)
{
    Q_D(QPainter);

    if (!d->engine || pixmap.isNull())
        return;

#ifndef QT_NO_DEBUG
    for (int i = 0; i < fragmentCount; ++i) {
        QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop,
                          fragments[i].width, fragments[i].height);
        if (!(QRectF(pixmap.rect()).contains(sourceRect)))
            qWarning("QPainter::drawPixmapFragments - the source rect is not contained by the pixmap's rectangle");
    }
#endif

    if (d->engine->isExtended()) {
        d->extended->drawPixmapFragments(fragments, fragmentCount, pixmap, hints);
    } else {
        qreal oldOpacity = opacity();
        QTransform oldTransform = transform();

        for (int i = 0; i < fragmentCount; ++i) {
            QTransform transform = oldTransform;
            qreal xOffset = 0;
            qreal yOffset = 0;
            if (fragments[i].rotation == 0) {
                xOffset = fragments[i].x;
                yOffset = fragments[i].y;
            } else {
                transform.translate(fragments[i].x, fragments[i].y);
                transform.rotate(fragments[i].rotation);
            }
            setOpacity(oldOpacity * fragments[i].opacity);
            setTransform(transform);

            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 + xOffset, -0.5 * h + yOffset, w, h), pixmap, sourceRect);
        }

        setOpacity(oldOpacity);
        setTransform(oldTransform);
    }
}

/*!
    \since 4.7
    \class QPainter::PixmapFragment

    \brief This class is used in conjunction with the
    QPainter::drawPixmapFragments() function to specify how a pixmap, or
    sub-rect of a pixmap, is drawn.

    The \a sourceLeft, \a sourceTop, \a width and \a height variables are used
    as a source rectangle within the pixmap passed into the
    QPainter::drawPixmapFragments() function. The variables \a x, \a y, \a
    width and \a height are used to calculate the target rectangle that is
    drawn. \a x and \a y denotes the center of the target rectangle. The \a
    width and \a height in the target rectangle is scaled by the \a scaleX and
    \a scaleY values. The resulting target rectangle is then rotated \a
    rotation degrees around the \a x, \a y center point.

    \sa QPainter::drawPixmapFragments()
*/

/*!
    \since 4.7

    This is a convenience function that returns a QPainter::PixmapFragment that is
    initialized with the \a pos, \a sourceRect, \a scaleX, \a scaleY, \a
    rotation, \a opacity parameters.
*/

QPainter::PixmapFragment QPainter::PixmapFragment::create(const QPointF &pos, const QRectF &sourceRect,
                                              qreal scaleX, qreal scaleY, qreal rotation,
                                              qreal opacity)
{
    PixmapFragment fragment = {pos.x(), pos.y(), sourceRect.x(), sourceRect.y(), sourceRect.width(),
                               sourceRect.height(), scaleX, scaleY, rotation, opacity};
    return fragment;
}

/*!
    \variable QPainter::PixmapFragment::x
    \brief the x coordinate of center point in the target rectangle.
*/

/*!
    \variable QPainter::PixmapFragment::y
    \brief the y coordinate of the center point in the target rectangle.
*/

/*!
    \variable QPainter::PixmapFragment::sourceLeft
    \brief the left coordinate of the source rectangle.
*/

/*!
    \variable QPainter::PixmapFragment::sourceTop
    \brief the top coordinate of the source rectangle.
*/

/*!
    \variable QPainter::PixmapFragment::width

    \brief the width of the source rectangle and is used to calculate the width
    of the target rectangle.
*/

/*!
    \variable QPainter::PixmapFragment::height

    \brief the height of the source rectangle and is used to calculate the
    height of the target rectangle.
*/

/*!
    \variable QPainter::PixmapFragment::scaleX
    \brief the horizontal scale of the target rectangle.
*/

/*!
    \variable QPainter::PixmapFragment::scaleY
    \brief the vertical scale of the target rectangle.
*/

/*!
    \variable QPainter::PixmapFragment::rotation

    \brief the rotation of the target rectangle in degrees. The target
    rectangle is rotated after it has been scaled.
*/

/*!
    \variable QPainter::PixmapFragment::opacity

    \brief the opacity of the target rectangle, where 0.0 is fully transparent
    and 1.0 is fully opaque.
*/

/*!
    \since 4.7

    \enum QPainter::PixmapFragmentHint

    \value OpaqueHint Indicates that the pixmap fragments to be drawn are
    opaque. Opaque fragments are potentially faster to draw.

    \sa QPainter::drawPixmapFragments(), QPainter::PixmapFragment
*/

void qt_draw_helper(QPainterPrivate *p, const QPainterPath &path, QPainterPrivate::DrawOperation operation)
{
    p->draw_helper(path, operation);
}

/*! \fn Display *QPaintDevice::x11Display() const
    Use QX11Info::display() instead.

    \oldcode
        Display *display = widget->x11Display();
    \newcode
        Display *display = QX11Info::display();
    \endcode

    \sa QWidget::x11Info(), QX11Info::display()
*/

/*! \fn int QPaintDevice::x11Screen() const
    Use QX11Info::screen() instead.

    \oldcode
        int screen = widget->x11Screen();
    \newcode
        int screen = widget->x11Info().screen();
    \endcode

    \sa QWidget::x11Info(), QPixmap::x11Info()
*/

/*! \fn void *QPaintDevice::x11Visual() const
    Use QX11Info::visual() instead.

    \oldcode
        void *visual = widget->x11Visual();
    \newcode
        void *visual = widget->x11Info().visual();
    \endcode

    \sa QWidget::x11Info(), QPixmap::x11Info()
*/

/*! \fn int QPaintDevice::x11Depth() const
    Use QX11Info::depth() instead.

    \oldcode
        int depth = widget->x11Depth();
    \newcode
        int depth = widget->x11Info().depth();
    \endcode

    \sa QWidget::x11Info(), QPixmap::x11Info()
*/

/*! \fn int QPaintDevice::x11Cells() const
    Use QX11Info::cells() instead.

    \oldcode
        int cells = widget->x11Cells();
    \newcode
        int cells = widget->x11Info().cells();
    \endcode

    \sa QWidget::x11Info(), QPixmap::x11Info()
*/

/*! \fn Qt::HANDLE QPaintDevice::x11Colormap() const
    Use QX11Info::colormap() instead.

    \oldcode
        unsigned long screen = widget->x11Colormap();
    \newcode
        unsigned long screen = widget->x11Info().colormap();
    \endcode

    \sa QWidget::x11Info(), QPixmap::x11Info()
*/

/*! \fn bool QPaintDevice::x11DefaultColormap() const
    Use QX11Info::defaultColormap() instead.

    \oldcode
        bool isDefault = widget->x11DefaultColormap();
    \newcode
        bool isDefault = widget->x11Info().defaultColormap();
    \endcode

    \sa QWidget::x11Info(), QPixmap::x11Info()
*/

/*! \fn bool QPaintDevice::x11DefaultVisual() const
    Use QX11Info::defaultVisual() instead.

    \oldcode
        bool isDefault = widget->x11DefaultVisual();
    \newcode
        bool isDefault = widget->x11Info().defaultVisual();
    \endcode

    \sa QWidget::x11Info(), QPixmap::x11Info()
*/

/*! \fn void *QPaintDevice::x11AppVisual(int screen)
    Use QX11Info::visual() instead.

    \oldcode
        void *visual = QPaintDevice::x11AppVisual(screen);
    \newcode
        void *visual = qApp->x11Info(screen).visual();
    \endcode

    \sa QWidget::x11Info(), QPixmap::x11Info()
*/

/*! \fn Qt::HANDLE QPaintDevice::x11AppColormap(int screen)
    Use QX11Info::colormap() instead.

    \oldcode
        unsigned long colormap = QPaintDevice::x11AppColormap(screen);
    \newcode
        unsigned long colormap = qApp->x11Info(screen).colormap();
    \endcode

    \sa QWidget::x11Info(), QPixmap::x11Info()
*/

/*! \fn Display *QPaintDevice::x11AppDisplay()
    Use QX11Info::display() instead.

    \oldcode
        Display *display = QPaintDevice::x11AppDisplay();
    \newcode
        Display *display = qApp->x11Info().display();
    \endcode

    \sa QWidget::x11Info(), QPixmap::x11Info()
*/

/*! \fn int QPaintDevice::x11AppScreen()
    Use QX11Info::screen() instead.

    \oldcode
        int screen = QPaintDevice::x11AppScreen();
    \newcode
        int screen = qApp->x11Info().screen();
    \endcode

    \sa QWidget::x11Info(), QPixmap::x11Info()
*/

/*! \fn int QPaintDevice::x11AppDepth(int screen)
    Use QX11Info::depth() instead.

    \oldcode
        int depth = QPaintDevice::x11AppDepth(screen);
    \newcode
        int depth = qApp->x11Info(screen).depth();
    \endcode

    \sa QWidget::x11Info(), QPixmap::x11Info()
*/

/*! \fn int QPaintDevice::x11AppCells(int screen)
    Use QX11Info::cells() instead.

    \oldcode
        int cells = QPaintDevice::x11AppCells(screen);
    \newcode
        int cells = qApp->x11Info(screen).cells();
    \endcode

    \sa QWidget::x11Info(), QPixmap::x11Info()
*/

/*! \fn Qt::HANDLE QPaintDevice::x11AppRootWindow(int screen)
    Use QX11Info::appRootWindow() instead.

    \oldcode
        unsigned long window = QPaintDevice::x11AppRootWindow(screen);
    \newcode
        unsigned long window = qApp->x11Info(screen).appRootWindow();
    \endcode

    \sa QWidget::x11Info(), QPixmap::x11Info()
*/

/*! \fn bool QPaintDevice::x11AppDefaultColormap(int screen)
    Use QX11Info::defaultColormap() instead.

    \oldcode
        bool isDefault = QPaintDevice::x11AppDefaultColormap(screen);
    \newcode
        bool isDefault = qApp->x11Info(screen).defaultColormap();
    \endcode

    \sa QWidget::x11Info(), QPixmap::x11Info()
*/

/*! \fn bool QPaintDevice::x11AppDefaultVisual(int screen)
    Use QX11Info::defaultVisual() instead.

    \oldcode
        bool isDefault = QPaintDevice::x11AppDefaultVisual(screen);
    \newcode
        bool isDefault = qApp->x11Info(screen).defaultVisual();
    \endcode

    \sa QWidget::x11Info(), QPixmap::x11Info()
*/

/*! \fn void QPaintDevice::x11SetAppDpiX(int dpi, int screen)
    Use QX11Info::setAppDpiX() instead.
*/

/*! \fn void QPaintDevice::x11SetAppDpiY(int dpi, int screen)
    Use QX11Info::setAppDpiY() instead.
*/

/*! \fn int QPaintDevice::x11AppDpiX(int screen)
    Use QX11Info::appDpiX() instead.

    \oldcode
        bool isDefault = QPaintDevice::x11AppDpiX(screen);
    \newcode
        bool isDefault = qApp->x11Info(screen).appDpiX();
    \endcode

    \sa QWidget::x11Info(), QPixmap::x11Info()
*/

/*! \fn int QPaintDevice::x11AppDpiY(int screen)
    Use QX11Info::appDpiY() instead.

    \oldcode
        bool isDefault = QPaintDevice::x11AppDpiY(screen);
    \newcode
        bool isDefault = qApp->x11Info(screen).appDpiY();
    \endcode

    \sa QWidget::x11Info(), QPixmap::x11Info()
*/

/*! \fn HDC QPaintDevice::getDC() const
  \internal
*/

/*! \fn void QPaintDevice::releaseDC(HDC) const
  \internal
*/

/*! \fn QWSDisplay *QPaintDevice::qwsDisplay()
    \internal
*/

QT_END_NAMESPACE
