Make QPen default to 1-width non-cosmetic.
[profile/ivi/qtbase.git] / src / gui / painting / qpainter.cpp
index 811e59b..090faf1 100644 (file)
@@ -1,38 +1,38 @@
 /****************************************************************************
 **
-** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
-** All rights reserved.
-** Contact: Nokia Corporation (qt-info@nokia.com)
+** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
+** Contact: http://www.qt-project.org/legal
 **
 ** This file is part of the QtGui module of the Qt Toolkit.
 **
 ** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia.  For licensing terms and
+** conditions see http://qt.digia.com/licensing.  For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
 ** 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.
+** Alternatively, 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
+** In addition, as a special exception, Digia gives you certain additional
+** rights.  These rights are described in the Digia 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.
-**
-**
-**
+** 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.
 **
 **
 ** $QT_END_LICENSE$
 #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 "qstatictext.h"
 #include "qglyphrun.h"
 
+#include <qpa/qplatformtheme.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 <private/qstatictext_p.h>
 #include <private/qglyphrun_p.h>
-#include <private/qstylehelper_p.h>
+#include <private/qhexstring_p.h>
+#include <private/qguiapplication_p.h>
 #include <private/qrawfont_p.h>
 
 QT_BEGIN_NAMESPACE
@@ -93,7 +92,7 @@ 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,
+static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe, QTextEngine *textEngine,
                                    QTextCharFormat::UnderlineStyle underlineStyle,
                                    QTextItem::RenderFlags flags, qreal width,
                                    const QTextCharFormat &charFormat);
@@ -152,14 +151,6 @@ static inline uint line_emulation(uint emulation)
                         | QPaintEngine_OpaqueBackground);
 }
 
-static bool qt_paintengine_supports_transformations(QPaintEngine::Type type)
-{
-    return type == QPaintEngine::OpenGL2
-            || type == QPaintEngine::OpenVG
-            || type == QPaintEngine::OpenGL
-            || type == QPaintEngine::CoreGraphics;
-}
-
 #ifndef QT_NO_DEBUG
 static bool qt_painter_thread_test(int devType, const char *what, bool extraCondition = false)
 {
@@ -168,15 +159,9 @@ static bool qt_painter_thread_test(int devType, const char *what, bool extraCond
     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:
-#ifdef Q_WS_X11
-        if (QApplication::testAttribute(Qt::AA_X11InitThreads))
-            return true;
-#endif
         if (!extraCondition && QThread::currentThread() != qApp->thread()) {
             qWarning("QPainter: It is not safe to use %s outside the GUI thread", what);
             return false;
@@ -250,34 +235,10 @@ 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())
+    QPainter *sp = pdev->sharedPainter();
+    if (!sp)
         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();
@@ -301,14 +262,14 @@ bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev)
     Q_ASSERT(q->d_ptr->state);
 
     // Now initialize the painter with correct widget properties.
-    q->initFrom(widget);
+    q->initFrom(pdev);
     QPoint offset;
-    widget->d_func()->redirected(&offset);
+    pdev->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();
+    q->d_ptr->state->ww = q->d_ptr->state->vw = pdev->width();
+    q->d_ptr->state->wh = q->d_ptr->state->vh = pdev->height();
 
     // Update matrix.
     if (q->d_ptr->state->WxF) {
@@ -322,13 +283,13 @@ bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev)
     q->d_ptr->updateMatrix();
 
     QPaintEnginePrivate *enginePrivate = q->d_ptr->engine->d_func();
-    if (enginePrivate->currentClipWidget == widget) {
+    if (enginePrivate->currentClipDevice == pdev) {
         enginePrivate->systemStateChanged();
         return true;
     }
 
     // Update system transform and clip.
-    enginePrivate->currentClipWidget = widget;
+    enginePrivate->currentClipDevice = pdev;
     enginePrivate->setSystemTransform(q->d_ptr->state->matrix);
     return true;
 }
@@ -936,26 +897,8 @@ 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);
-        }
+        updateStateImpl(newState);
     }
 }
 
@@ -965,6 +908,7 @@ void QPainterPrivate::updateState(QPainterState *newState)
     \brief The QPainter class performs low-level painting on widgets and
     other paint devices.
 
+    \inmodule QtGui
     \ingroup painting
 
     \reentrant
@@ -982,7 +926,7 @@ void QPainterPrivate::updateState(QPainterState *newState)
     painter. Then draw. Remember to destroy the QPainter object after
     drawing. For example:
 
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 0
+    \snippet 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
@@ -1011,10 +955,7 @@ void QPainterPrivate::updateState(QPainterState *newState)
 
     \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.
+    paintEvent().
 
     \tableofcontents
 
@@ -1025,41 +966,41 @@ void QPainterPrivate::updateState(QPainterState *newState)
 
     \list
 
-    \o font() is the font used for drawing text. If the painter
+    \li 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
+    \li brush() defines the color or pattern that is used for filling
        shapes.
 
-    \o pen() defines the color or stipple that is used for drawing
+    \li pen() defines the color or stipple that is used for drawing
        lines or boundaries.
 
-    \o backgroundMode() defines whether there is a background() or
+    \li 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
+    \li 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
+    \li 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
+    \li 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
+    \li 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
+    \li layoutDirection() defines the layout direction used by the
        painter when drawing text.
 
-    \o worldMatrixEnabled() tells whether world transformation is enabled.
+    \li worldMatrixEnabled() tells whether world transformation is enabled.
 
-    \o viewTransformEnabled() tells whether view transformation is
+    \li viewTransformEnabled() tells whether view transformation is
         enabled.
 
     \endlist
@@ -1093,9 +1034,9 @@ void QPainterPrivate::updateState(QPainterState *newState)
 
     \table 100%
     \row
-    \o \inlineimage qpainter-basicdrawing.png
-    \o
-    \bold {Basic Drawing Example}
+    \li \inlineimage qpainter-basicdrawing.png
+    \li
+    \b {Basic Drawing Example}
 
     The \l {painting/basicdrawing}{Basic Drawing} example shows how to
     display basic graphics primitives in a variety of styles using the
@@ -1109,8 +1050,8 @@ void QPainterPrivate::updateState(QPainterState *newState)
 
     \table 100%
     \row
-    \o
-    \bold {Painter Paths example}
+    \li
+    \b {Painter Paths example}
 
     The QPainterPath class provides a container for painting
     operations, enabling graphical shapes to be constructed and
@@ -1119,7 +1060,7 @@ void QPainterPrivate::updateState(QPainterState *newState)
     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
+    \li \inlineimage qpainter-painterpaths.png
     \endtable
 
     QPainter also provides the fillPath() function which fills the
@@ -1127,23 +1068,23 @@ void QPainterPrivate::updateState(QPainterState *newState)
     function that draws the outline of the given path (i.e. strokes
     the path).
 
-    See also the \l {demos/deform}{Vector Deformation} demo which
+    See also the \l {painting/deform}{Vector Deformation} example which
     shows how to use advanced vector techniques to draw text using a
-    QPainterPath, the \l {demos/gradients}{Gradients} demo which shows
+    QPainterPath, the \l {painting/gradients}{Gradients} example 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
+    {painting/pathstroke}{Path Stroking} example 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}
+    \li \l {painting/deform}{Vector Deformation}
+    \li \l {painting/gradients}{Gradients}
+    \li \l {painting/pathstroke}{Path Stroking}
     \row
-    \o \inlineimage qpainter-vectordeformation.png
-    \o \inlineimage qpainter-gradients.png
-    \o \inlineimage qpainter-pathstroking.png
+    \li \inlineimage qpainter-vectordeformation.png
+    \li \inlineimage qpainter-gradients.png
+    \li \inlineimage qpainter-pathstroking.png
     \endtable
 
 
@@ -1177,9 +1118,9 @@ void QPainterPrivate::updateState(QPainterState *newState)
 
     \table 100%
     \row
-    \o \inlineimage qpainter-concentriccircles.png
-    \o
-    \bold {Concentric Circles Example}
+    \li \inlineimage qpainter-concentriccircles.png
+    \li
+    \b {Concentric Circles Example}
 
     The \l {painting/concentriccircles}{Concentric Circles} example
     shows the improved rendering quality that can be obtained using
@@ -1217,12 +1158,12 @@ void QPainterPrivate::updateState(QPainterState *newState)
 
     \table
     \header
-    \o  nop \o rotate() \o scale() \o translate()
+    \li  nop \li rotate() \li scale() \li translate()
     \row
-    \o \inlineimage qpainter-clock.png
-    \o \inlineimage qpainter-rotation.png
-    \o \inlineimage qpainter-scale.png
-    \o \inlineimage qpainter-translation.png
+    \li \inlineimage qpainter-clock.png
+    \li \inlineimage qpainter-rotation.png
+    \li \inlineimage qpainter-scale.png
+    \li \inlineimage qpainter-translation.png
     \endtable
 
     The most commonly used transformations are scaling, rotation,
@@ -1231,7 +1172,7 @@ void QPainterPrivate::updateState(QPainterState *newState)
     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
+    {painting/affine}{Affine Transformations} example for a visualization of
     a sheared coordinate system.
 
     See also the \l {painting/transformations}{Transformations}
@@ -1241,15 +1182,15 @@ void QPainterPrivate::updateState(QPainterState *newState)
 
     \table 100%
     \row
-    \o
-    \bold {Affine Transformations Demo}
+    \li
+    \b {Affine Transformations Example}
 
-    The \l {demos/affine}{Affine Transformations} demo show Qt's
+    The \l {painting/affine}{Affine Transformations} example shows 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
+    \li \inlineimage qpainter-affinetransformations.png
     \endtable
 
     All the tranformation operations operate on the transformation
@@ -1323,13 +1264,13 @@ void QPainterPrivate::updateState(QPainterState *newState)
 
     \table 100%
     \row
-    \o \inlineimage qpainter-compositiondemo.png
+    \li \inlineimage qpainter-compositiondemo.png
 
-    \o
-    \bold {Composition Modes Demo}
+    \li
+    \b {Composition Modes Example}
 
-    The \l {demos/composition}{Composition Modes} demo, available in
-    Qt's demo directory, allows you to experiment with the various
+    The \l {painting/composition}{Composition Modes} example, available in
+    Qt's examples directory, allows you to experiment with the various
     composition modes and see the results immediately.
 
     \endtable
@@ -1374,25 +1315,22 @@ void QPainterPrivate::updateState(QPainterState *newState)
 
     \list
 
-    \o Raster - This backend implements all rendering in pure software
+    \li 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
+    performance. This engine is used by default for QWidget and QPixmap.
 
-    \o OpenGL 2.0 (ES) - This backend is the primary backend for
+    \li 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
+    onto a QOpenGLWidget 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
+    \li 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
@@ -1404,26 +1342,26 @@ void QPainterPrivate::updateState(QPainterState *newState)
 
     \list
 
-    \o Simple transformations, meaning translation and scaling, pluss
+    \li Simple transformations, meaning translation and scaling, pluss
     0, 90, 180, 270 degree rotations.
 
-    \o \c drawPixmap() in combination with simple transformations and
+    \li \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
+    \li Rectangle fills with solid color, two-color linear gradients
     and simple transforms.
 
-    \o Rectangular clipping with simple transformations and intersect
+    \li Rectangular clipping with simple transformations and intersect
     clip.
 
-    \o Composition Modes \c QPainter::CompositionMode_Source and
+    \li Composition Modes \c QPainter::CompositionMode_Source and
     QPainter::CompositionMode_SourceOver
 
-    \o Rounded rectangle filling using solid color and two-color
+    \li Rounded rectangle filling using solid color and two-color
     linear gradients fills.
 
-    \o 3x3 patched pixmaps, via qDrawBorderPixmap.
+    \li 3x3 patched pixmaps, via qDrawBorderPixmap.
 
     \endlist
 
@@ -1461,9 +1399,13 @@ void QPainterPrivate::updateState(QPainterState *newState)
     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.
+    \value NonCosmeticDefaultPen This value is obsolete, the default for QPen
+    is now non-cosmetic.
+
+    \value Qt4CompatiblePainting Compatibility hint telling the engine to use the
+    same X11 based fill rules as in Qt 4, where aliased rendering is offset
+    by slightly less than half a pixel. Also will treat default constructed pens
+    as cosmetic. Potentially useful when porting a Qt 4 application to Qt 5.
 
     \sa renderHints(), setRenderHint(), {QPainter#Rendering
     Quality}{Rendering Quality}, {Concentric Circles Example}
@@ -1493,10 +1435,10 @@ QPainter::QPainter()
     automatically calls end().
 
     Here's an example using begin() and end():
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 1
+    \snippet code/src_gui_painting_qpainter.cpp 1
 
     The same example using this constructor:
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 2
+    \snippet 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
@@ -1550,8 +1492,8 @@ QPainter::~QPainter()
 QPaintDevice *QPainter::device() const
 {
     Q_D(const QPainter);
-    if (isActive() && d->engine->d_func()->currentClipWidget)
-        return d->engine->d_func()->currentClipWidget;
+    if (isActive() && d->engine->d_func()->currentClipDevice)
+        return d->engine->d_func()->currentClipDevice;
     return d->original_device;
 }
 
@@ -1570,25 +1512,23 @@ bool QPainter::isActive() const
 
 /*!
     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.
+    the given \a device.
+
+    \obsolete
 
     \sa begin(), {QPainter#Settings}{Settings}
 */
-void QPainter::initFrom(const QWidget *widget)
+void QPainter::initFrom(const QPaintDevice *device)
 {
-    Q_ASSERT_X(widget, "QPainter::initFrom(const QWidget *widget)", "Widget cannot be 0");
+    Q_ASSERT_X(device, "QPainter::initFrom(const QPaintDevice *device)", "QPaintDevice 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;
+    device->initPainter(this);
+
     if (d->extended) {
         d->extended->penChanged();
     } else if (d->engine) {
@@ -1716,7 +1656,7 @@ void QPainter::restore()
 
     The errors that can occur are serious problems, such as these:
 
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 3
+    \snippet 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
@@ -1761,22 +1701,9 @@ bool QPainter::begin(QPaintDevice *pd)
 
     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);
-
+    QPaintDevice *rpd = pd->redirected(&redirectionOffset);
     if (rpd)
         pd = rpd;
 
@@ -1819,29 +1746,6 @@ bool QPainter::begin(QPaintDevice *pd)
         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);
@@ -1902,8 +1806,7 @@ bool QPainter::begin(QPaintDevice *pd)
     // 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);
+        initFrom(d->original_device);
     } else {
         d->state->layoutDirection = Qt::LayoutDirectionAuto;
         // make sure we have a font compatible with the paintdevice
@@ -2027,14 +1930,14 @@ QPaintEngine *QPainter::paintEngine() const
     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
+    \li blending is disabled
+    \li the depth, stencil and scissor tests are disabled
+    \li the active texture unit is reset to 0
+    \li 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
+    \li the stencil mask, stencil operation and stencil function are reset to
     their default values
-     \i the current color is reset to solid white
+     \li the current color is reset to solid white
     \endlist
 
     If, for example, the OpenGL polygon mode is changed by the user inside a
@@ -2042,7 +1945,7 @@ QPaintEngine *QPainter::paintEngine() const
     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
+    \snippet code/src_gui_painting_qpainter.cpp 21
 
     \sa endNativePainting()
 */
@@ -2265,7 +2168,7 @@ void QPainter::setBrushOrigin(const QPointF &p)
     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_Premultiplied} or
     \l {QImage::Format}{Format_ARGB32} for the composition modes to have
     any effect. For performance the premultiplied version is the preferred
     format.
@@ -2403,6 +2306,23 @@ void QPainter::setBrushOrigin(const QPointF &p)
     where the source is AND'ed with the inverted destination pixels
     (src AND (NOT dst)).
 
+    \value RasterOp_NotSourceOrDestination Does a bitwise operation
+    where the source is inverted and then OR'ed with the destination
+    ((NOT src) OR dst).
+
+    \value RasterOp_ClearDestination The pixels in the destination are
+    cleared (set to 0) independent of the source.
+
+    \value RasterOp_SetDestination The pixels in the destination are
+    set (set to 1) independent of the source.
+
+    \value RasterOp_NotDestination Does a bitwise operation
+    where the destination pixels are inverted (NOT dst).
+
+    \value RasterOp_SourceOrNotDestination Does a bitwise operation
+    where the source is OR'ed with the inverted destination pixels
+    (src OR (NOT dst)).
+
     \sa compositionMode(), setCompositionMode(), {QPainter#Composition
     Modes}{Composition Modes}, {Image Composition Example}
 */
@@ -2584,8 +2504,6 @@ QRegion QPainter::clipRegion() const
             }
             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();
@@ -2605,9 +2523,6 @@ QRegion QPainter::clipRegion() const
             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();
@@ -2631,8 +2546,6 @@ QRegion QPainter::clipRegion() const
                     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();
@@ -2655,8 +2568,6 @@ QRegion QPainter::clipRegion() const
                     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();
@@ -2745,7 +2656,7 @@ QRectF QPainter::clipBoundingRect() const
     }
 
     // Accumulate the bounding box in device space. This is not 100%
-    // precise, but it fits within the guarantee and it is resonably
+    // precise, but it fits within the guarantee and it is reasonably
     // fast.
     QRectF bounds;
     for (int i=0; i<d->state->clipInfo.size(); ++i) {
@@ -2767,8 +2678,6 @@ QRectF QPainter::clipBoundingRect() const
              bounds = r;
          else if (info.operation == Qt::IntersectClip)
              bounds &= r;
-         else if (info.operation == Qt::UniteClip)
-             bounds |= r;
     }
 
 
@@ -2797,7 +2706,7 @@ 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))
+        if ((!d->state->clipEnabled && op != Qt::NoClip))
             op = Qt::ReplaceClip;
 
         if (!d->engine) {
@@ -2855,7 +2764,7 @@ void QPainter::setClipRect(const QRect &rect, Qt::ClipOperation op)
         return;
     }
 
-    if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip))
+    if ((!d->state->clipEnabled && op != Qt::NoClip))
         op = Qt::ReplaceClip;
 
     if (d->extended) {
@@ -2868,6 +2777,9 @@ void QPainter::setClipRect(const QRect &rect, Qt::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)
@@ -2910,7 +2822,7 @@ void QPainter::setClipRegion(const QRegion &r, Qt::ClipOperation op)
         return;
     }
 
-    if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip))
+    if ((!d->state->clipEnabled && op != Qt::NoClip))
         op = Qt::ReplaceClip;
 
     if (d->extended) {
@@ -2923,6 +2835,9 @@ void QPainter::setClipRegion(const QRegion &r, Qt::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)
@@ -2954,15 +2869,15 @@ void QPainter::setClipRegion(const QRegion &r, Qt::ClipOperation op)
     The following functions can transform the coordinate system without using
     a QMatrix:
     \list
-    \i translate()
-    \i scale()
-    \i shear()
-    \i rotate()
+    \li translate()
+    \li scale()
+    \li shear()
+    \li 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
+    \snippet 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
@@ -3176,8 +3091,7 @@ bool QPainter::matrixEnabled() const
 /*!
     Scales the coordinate system by (\a{sx}, \a{sy}).
 
-    \sa setWorldTransform() {QPainter#Coordinate Transformations}{Coordinate
-    Transformations}
+    \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate Transformations}
 */
 
 void QPainter::scale(qreal sx, qreal sy)
@@ -3200,8 +3114,7 @@ void QPainter::scale(qreal sx, qreal sy)
 /*!
     Shears the coordinate system by (\a{sh}, \a{sv}).
 
-    \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate
-    Transformations}
+    \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate Transformations}
 */
 
 void QPainter::shear(qreal sh, qreal sv)
@@ -3224,10 +3137,9 @@ void QPainter::shear(qreal sh, qreal sv)
 /*!
     \fn void QPainter::rotate(qreal angle)
 
-    Rotates the coordinate system the given \a angle clockwise.
+    Rotates the coordinate system clockwise. The given \a angle parameter uses degree unit.
 
-    \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate
-    Transformations}
+    \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate Transformations}
 */
 
 void QPainter::rotate(qreal a)
@@ -3251,8 +3163,7 @@ void QPainter::rotate(qreal a)
     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}
+    \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate Transformations}
 */
 void QPainter::translate(const QPointF &offset)
 {
@@ -3315,7 +3226,7 @@ void QPainter::setClipPath(const QPainterPath &path, Qt::ClipOperation op)
         return;
     }
 
-    if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip))
+    if ((!d->state->clipEnabled && op != Qt::NoClip))
         op = Qt::ReplaceClip;
 
     if (d->extended) {
@@ -3328,6 +3239,9 @@ void QPainter::setClipPath(const QPainterPath &path, Qt::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)
@@ -3426,13 +3340,13 @@ void QPainter::fillPath(const QPainterPath &path, const QBrush &brush)
 
     \table 100%
     \row
-    \o \inlineimage qpainter-path.png
-    \o
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 5
+    \li \inlineimage qpainter-path.png
+    \li
+    \snippet code/src_gui_painting_qpainter.cpp 5
     \endtable
 
     \sa {painting/painterpaths}{the Painter Paths
-    example},{demos/deform}{the Vector Deformation demo}
+    example},{painting/deform}{the Vector Deformation example}
 */
 void QPainter::drawPath(const QPainterPath &path)
 {
@@ -3471,9 +3385,9 @@ void QPainter::drawPath(const QPainterPath &path)
 
     \table 100%
     \row
-    \o \inlineimage qpainter-line.png
-    \o
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 6
+    \li \inlineimage qpainter-line.png
+    \li
+    \snippet code/src_gui_painting_qpainter.cpp 6
     \endtable
 
     \sa drawLines(), drawPolyline(), {Coordinate System}
@@ -3518,9 +3432,9 @@ void QPainter::drawPath(const QPainterPath &path)
 
     \table 100%
     \row
-    \o \inlineimage qpainter-rectangle.png
-    \o
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 7
+    \li \inlineimage qpainter-rectangle.png
+    \li
+    \snippet code/src_gui_painting_qpainter.cpp 7
     \endtable
 
     \sa drawRects(), drawPolygon(), {Coordinate System}
@@ -3845,29 +3759,6 @@ void QPainter::drawPoints(const QPoint *points, int pointCount)
 */
 
 /*!
-    \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
@@ -3939,13 +3830,10 @@ void QPainter::setPen(const QColor &color)
         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));
 
-    QPen pen(color.isValid() ? color : QColor(Qt::black), 0, Qt::SolidLine);
+    if (d->state->pen == pen)
+        return;
 
     d->state->pen = pen;
     if (d->extended)
@@ -3994,7 +3882,7 @@ void QPainter::setPen(const QPen &pen)
 /*!
     \overload
 
-    Sets the painter's pen to have the given \a style, width 0 and
+    Sets the painter's pen to have the given \a style, width 1 and
     black color.
 */
 
@@ -4006,15 +3894,12 @@ void QPainter::setPen(Qt::PenStyle style)
         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))))
+    QPen pen = QPen(style);
+
+    if (d->state->pen == pen)
         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);
+    d->state->pen = pen;
 
     if (d->extended)
         d->extended->penChanged();
@@ -4210,9 +4095,9 @@ const QFont &QPainter::font() const
 
     \table 100%
     \row
-    \o \inlineimage qpainter-roundrect.png
-    \o
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 8
+    \li \inlineimage qpainter-roundrect.png
+    \li
+    \snippet code/src_gui_painting_qpainter.cpp 8
     \endtable
 
     \sa drawRect(), QPen
@@ -4310,9 +4195,9 @@ void QPainter::drawRoundRect(const QRectF &r, int xRnd, int yRnd)
 
     \table 100%
     \row
-    \o \inlineimage qpainter-ellipse.png
-    \o
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 9
+    \li \inlineimage qpainter-ellipse.png
+    \li
+    \snippet code/src_gui_painting_qpainter.cpp 9
     \endtable
 
     \sa drawPie(), {Coordinate System}
@@ -4436,9 +4321,9 @@ void QPainter::drawEllipse(const QRect &r)
 
     \table 100%
     \row
-    \o \inlineimage qpainter-arc.png
-    \o
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 10
+    \li \inlineimage qpainter-arc.png
+    \li
+    \snippet code/src_gui_painting_qpainter.cpp 10
     \endtable
 
     \sa drawPie(), drawChord(), {Coordinate System}
@@ -4487,8 +4372,7 @@ void QPainter::drawArc(const QRectF &r, int a, int alen)
 /*!
     \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.
+    Draws a pie defined by the given \a rectangle, \a startAngle and \a spanAngle.
 
     The pie is filled with the current brush().
 
@@ -4500,9 +4384,9 @@ void QPainter::drawArc(const QRectF &r, int a, int alen)
 
     \table 100%
     \row
-    \o \inlineimage qpainter-pie.png
-    \o
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 11
+    \li \inlineimage qpainter-pie.png
+    \li
+    \snippet code/src_gui_painting_qpainter.cpp 11
     \endtable
 
     \sa drawEllipse(), drawChord(), {Coordinate System}
@@ -4569,9 +4453,9 @@ void QPainter::drawPie(const QRectF &r, int a, int alen)
 
     \table 100%
     \row
-    \o \inlineimage qpainter-chord.png
-    \o
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 12
+    \li \inlineimage qpainter-chord.png
+    \li
+    \snippet code/src_gui_painting_qpainter.cpp 12
     \endtable
 
     \sa drawArc(), drawPie(), {Coordinate System}
@@ -4616,82 +4500,6 @@ void QPainter::drawChord(const QRectF &r, int a, int alen)
    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
@@ -4861,8 +4669,8 @@ void QPainter::drawLines(const QPoint *pointPairs, int lineCount)
 
     \table 100%
     \row
-    \o
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 13
+    \li
+    \snippet code/src_gui_painting_qpainter.cpp 13
     \endtable
 
     \sa drawLines(), drawPolygon(), {Coordinate System}
@@ -4944,29 +4752,6 @@ void QPainter::drawPolyline(const QPoint *points, int pointCount)
 }
 
 /*!
-    \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
@@ -4990,9 +4775,9 @@ void QPainter::drawPolyline(const QPoint *points, int pointCount)
 
     \table 100%
     \row
-    \o \inlineimage qpainter-polygon.png
-    \o
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 14
+    \li \inlineimage qpainter-polygon.png
+    \li
+    \snippet code/src_gui_painting_qpainter.cpp 14
     \endtable
 
     The first point is implicitly connected to the last point, and the
@@ -5004,7 +4789,7 @@ void QPainter::drawPolyline(const QPoint *points, int pointCount)
     \l{Qt::FillRule} for a more detailed description of these fill
     rules.
 
-    \sa  drawConvexPolygon(), drawPolyline(), {Coordinate System}
+    \sa drawConvexPolygon(), drawPolyline(), {Coordinate System}
 */
 void QPainter::drawPolygon(const QPointF *points, int pointCount, Qt::FillRule fillRule)
 {
@@ -5079,45 +4864,6 @@ void QPainter::drawPolygon(const QPoint *points, int pointCount, Qt::FillRule fi
     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
@@ -5142,9 +4888,9 @@ void QPainter::drawPolygon(const QPoint *points, int pointCount, Qt::FillRule fi
 
     \table 100%
     \row
-    \o \inlineimage qpainter-polygon.png
-    \o
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 15
+    \li \inlineimage qpainter-polygon.png
+    \li
+    \snippet code/src_gui_painting_qpainter.cpp 15
     \endtable
 
     The first point is implicitly connected to the last point, and the
@@ -5183,48 +4929,6 @@ void QPainter::drawPolygon(const QPoint *points, int pointCount, Qt::FillRule fi
     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
@@ -5308,8 +5012,8 @@ static inline QPointF roundInDeviceCoordinates(const QPointF &p, const QTransfor
 
     \table 100%
     \row
-    \o
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 16
+    \li
+    \snippet code/src_gui_painting_qpainter.cpp 16
     \endtable
 
     If \a pixmap is a QBitmap it is drawn with the bits that are "set"
@@ -5792,6 +5496,8 @@ void QPainter::drawImage(const QRectF &targetRect, const QImage &image, const QR
 }
 
 /*!
+    \fn void QPainter::drawGlyphRun(const QPointF &position, const QGlyphRun &glyphs)
+
     Draws the glyphs represented by \a glyphs at \a position. The \a position gives the
     edge of the baseline for the string of glyphs. The glyphs will be retrieved from the font
     selected on \a glyphs and at offsets given by the positions in \a glyphs.
@@ -5809,35 +5515,32 @@ void QPainter::drawGlyphRun(const QPointF &position, const QGlyphRun &glyphRun)
     if (!font.isValid())
         return;
 
-    QVector<quint32> glyphIndexes = glyphRun.glyphIndexes();
-    QVector<QPointF> glyphPositions = glyphRun.positions();
+    QGlyphRunPrivate *glyphRun_d = QGlyphRunPrivate::get(glyphRun);
 
-    int count = qMin(glyphIndexes.size(), glyphPositions.size());
-    QVarLengthArray<QFixedPoint, 128> fixedPointPositions(count);
+    const quint32 *glyphIndexes = glyphRun_d->glyphIndexData;
+    const QPointF *glyphPositions = glyphRun_d->glyphPositionData;
 
-    bool paintEngineSupportsTransformations =
-            d->extended != 0
-            ? qt_paintengine_supports_transformations(d->extended->type())
-            : qt_paintengine_supports_transformations(d->engine->type());
+    int count = qMin(glyphRun_d->glyphIndexDataSize, glyphRun_d->glyphPositionDataSize);
+    QVarLengthArray<QFixedPoint, 128> fixedPointPositions(count);
 
-    // If the matrix is not affine, the paint engine will fall back to
-    // drawing the glyphs as paths, which in turn means we should not
-    // preprocess the glyph positions
-    if (!d->state->matrix.isAffine())
-        paintEngineSupportsTransformations = true;
+    QRawFontPrivate *fontD = QRawFontPrivate::get(font);
+    bool supportsTransformations = d->extended
+        ? d->extended->supportsTransformations(fontD->fontEngine, d->state->matrix)
+        : d->engine->type() == QPaintEngine::CoreGraphics || d->state->matrix.isAffine();
 
     for (int i=0; i<count; ++i) {
-        QPointF processedPosition = position + glyphPositions.at(i);
-        if (!paintEngineSupportsTransformations)
+        QPointF processedPosition = position + glyphPositions[i];
+        if (!supportsTransformations)
             processedPosition = d->state->transform().map(processedPosition);
         fixedPointPositions[i] = QFixedPoint::fromPointF(processedPosition);
     }
 
-    d->drawGlyphs(glyphIndexes.data(), fixedPointPositions.data(), count, font, glyphRun.overline(),
+    d->drawGlyphs(glyphIndexes, fixedPointPositions.data(), count, font, glyphRun.overline(),
                   glyphRun.underline(), glyphRun.strikeOut());
 }
 
-void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, int glyphCount,
+void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, QFixedPoint *positions,
+                                 int glyphCount,
                                  const QRawFont &font, bool overline, bool underline,
                                  bool strikeOut)
 {
@@ -5886,9 +5589,9 @@ void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, in
         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));
+        memset(glyphAttributes.data(), 0, glyphAttributes.size() * sizeof(HB_GlyphAttributes));
+        memset(advances.data(), 0, advances.size() * sizeof(QFixed));
+        memset(glyphJustifications.data(), 0, glyphJustifications.size() * sizeof(QGlyphJustification));
 
         textItem.glyphs.numGlyphs = glyphCount;
         textItem.glyphs.glyphs = reinterpret_cast<HB_Glyph *>(const_cast<quint32 *>(glyphArray));
@@ -5911,6 +5614,7 @@ void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, in
 
     drawTextItemDecoration(q, QPointF(leftMost.toReal(), baseLine.toReal()),
                            fontEngine,
+                           0, // textEngine
                            (underline
                               ? QTextCharFormat::SingleUnderline
                               : QTextCharFormat::NoUnderline),
@@ -5946,7 +5650,7 @@ void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, in
     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
+    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
@@ -5955,6 +5659,8 @@ void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, in
     By default, QPainter draws text anti-aliased.
 
     \note The y-position is used as the baseline of the font.
+
+    \sa setFont(), setPen()
 */
 
 void QPainter::drawText(const QPointF &p, const QString &str)
@@ -6004,11 +5710,15 @@ void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText
         return;
     }
 
-    bool paintEngineSupportsTransformations = qt_paintengine_supports_transformations(d->extended->type());
-    if (paintEngineSupportsTransformations && !staticText_d->untransformedCoordinates) {
+    QFontEngine *fe = staticText_d->font.d->engineForScript(QUnicodeTables::Common);
+    if (fe->type() == QFontEngine::Multi)
+        fe = static_cast<QFontEngineMulti *>(fe)->engine(0);
+    bool supportsTransformations = d->extended->supportsTransformations(fe,
+                                                                        d->state->matrix);
+    if (supportsTransformations && !staticText_d->untransformedCoordinates) {
         staticText_d->untransformedCoordinates = true;
         staticText_d->needsRelayout = true;
-    } else if (!paintEngineSupportsTransformations && staticText_d->untransformedCoordinates) {
+    } else if (!supportsTransformations && staticText_d->untransformedCoordinates) {
         staticText_d->untransformedCoordinates = false;
         staticText_d->needsRelayout = true;
     }
@@ -6206,6 +5916,7 @@ void QPainter::drawText(const QRect &r, int flags, const QString &str, QRect *br
 
     \note The y-position is used as the baseline of the font.
 
+    \sa setFont(), setPen()
 */
 
 /*!
@@ -6213,12 +5924,13 @@ void QPainter::drawText(const QRect &r, int flags, const QString &str, QRect *br
     \overload
 
     Draws the given \a text within the provided \a rectangle.
+    The \a rectangle along with alignment \a flags defines the anchors for the \a text.
 
     \table 100%
     \row
-    \o \inlineimage qpainter-text.png
-    \o
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 17
+    \li \inlineimage qpainter-text.png
+    \li
+    \snippet code/src_gui_painting_qpainter.cpp 17
     \endtable
 
     The \a boundingRect (if not null) is set to the what the bounding rectangle
@@ -6226,20 +5938,20 @@ void QPainter::drawText(const QRect &r, int flags, const QString &str, QRect *br
     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
+    \li Qt::AlignLeft
+    \li Qt::AlignRight
+    \li Qt::AlignHCenter
+    \li Qt::AlignJustify
+    \li Qt::AlignTop
+    \li Qt::AlignBottom
+    \li Qt::AlignVCenter
+    \li Qt::AlignCenter
+    \li Qt::TextDontClip
+    \li Qt::TextSingleLine
+    \li Qt::TextExpandTabs
+    \li Qt::TextShowMnemonic
+    \li Qt::TextWordWrap
+    \li Qt::TextIncludeTrailingSpaces
     \endlist
 
     \sa Qt::AlignmentFlag, Qt::TextFlag, boundingRect(), layoutDirection()
@@ -6278,6 +5990,8 @@ void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF *
     By default, QPainter draws text anti-aliased.
 
     \note The y-coordinate of \a rectangle is used as the top of the font.
+
+    \sa setFont(), setPen()
 */
 
 /*!
@@ -6292,6 +6006,7 @@ void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF *
 
     \note The y-position is used as the baseline of the font.
 
+    \sa setFont(), setPen()
 */
 
 /*!
@@ -6308,25 +6023,25 @@ void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF *
     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
+    \li Qt::AlignLeft
+    \li Qt::AlignRight
+    \li Qt::AlignHCenter
+    \li Qt::AlignJustify
+    \li Qt::AlignTop
+    \li Qt::AlignBottom
+    \li Qt::AlignVCenter
+    \li Qt::AlignCenter
+    \li Qt::TextSingleLine
+    \li Qt::TextExpandTabs
+    \li Qt::TextShowMnemonic
+    \li 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
+    \sa Qt::AlignmentFlag, Qt::TextFlag, setFont(), setPen()
 */
 
 /*!
@@ -6340,6 +6055,8 @@ void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF *
     By default, QPainter draws text anti-aliased.
 
     \note The y-coordinate of \a rectangle is used as the top of the font.
+
+    \sa setFont(), setPen()
 */
 void QPainter::drawText(const QRectF &r, const QString &text, const QTextOption &o)
 {
@@ -6399,7 +6116,7 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
 {
     const qreal radiusBase = qMax(qreal(1), maxRadius);
 
-    QString key = QLatin1Literal("WaveUnderline-")
+    QString key = QLatin1String("WaveUnderline-")
                   % pen.color().name()
                   % HexString<qreal>(radiusBase);
 
@@ -6446,7 +6163,7 @@ static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
     return pixmap;
 }
 
-static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe,
+static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe, QTextEngine *textEngine,
                                    QTextCharFormat::UnderlineStyle underlineStyle,
                                    QTextItem::RenderFlags flags, qreal width,
                                    const QTextCharFormat &charFormat)
@@ -6468,11 +6185,12 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
     const qreal underlineOffset = fe->underlinePosition().toReal();
     // deliberately ceil the offset to avoid the underline coming too close to
     // the text above it.
-    const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
-    const qreal underlinePos = pos.y() + qCeil(underlineOffset) - aliasedCoordinateDelta;
+    const qreal underlinePos = pos.y() + qCeil(underlineOffset);
 
     if (underlineStyle == QTextCharFormat::SpellCheckUnderline) {
-        underlineStyle = QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle));
+        QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
+        if (theme)
+            underlineStyle = QTextCharFormat::UnderlineStyle(theme->themeHint(QPlatformTheme::SpellCheckUnderlineStyle).toInt());
     }
 
     if (underlineStyle == QTextCharFormat::WaveUnderline) {
@@ -6491,15 +6209,17 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
         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);
+        QLineF underline(line.x1(), underlinePos, line.x2(), underlinePos);
+        if (textEngine)
+            textEngine->addUnderline(painter, underline);
+        else
+            painter->drawLine(underline);
     }
 
     pen.setStyle(Qt::SolidLine);
@@ -6509,14 +6229,20 @@ static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const
         QLineF strikeOutLine = line;
         strikeOutLine.translate(0., - fe->ascent().toReal() / 3.);
         painter->setPen(pen);
-        painter->drawLine(strikeOutLine);
+        if (textEngine)
+            textEngine->addStrikeOut(painter, strikeOutLine);
+        else
+            painter->drawLine(strikeOutLine);
     }
 
     if (flags & QTextItem::Overline) {
-        QLineF overLine = line;
-        overLine.translate(0., - fe->ascent().toReal());
+        QLineF overline = line;
+        overline.translate(0., - fe->ascent().toReal());
         painter->setPen(pen);
-        painter->drawLine(overLine);
+        if (textEngine)
+            textEngine->addOverline(painter, overline);
+        else
+            painter->drawLine(overline);
     }
 
     painter->setPen(oldPen);
@@ -6541,7 +6267,7 @@ Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t
 
         // 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.
+        // and do a drawTextItemDecoration call per cluster.
         if (i == 0 || baseLine < positions[i].y)
             baseLine = positions[i].y;
 
@@ -6562,12 +6288,20 @@ Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t
 
     drawTextItemDecoration(painter, QPointF(leftMost.toReal(), baseLine.toReal()),
                            fontEngine,
+                           0, // textEngine
                            font.underline() ? QTextCharFormat::SingleUnderline
                                             : QTextCharFormat::NoUnderline, flags,
                            width.toReal(), charFormat);
 }
 
-void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
+void QPainter::drawTextItem(const QPointF &p, const QTextItem &ti)
+{
+    Q_D(QPainter);
+
+    d->drawTextItem(p, ti, static_cast<QTextEngine *>(0));
+}
+
+void QPainterPrivate::drawTextItem(const QPointF &p, const QTextItem &_ti, QTextEngine *textEngine)
 {
 #ifdef QT_DEBUG_DRAW
     if (qt_show_painter_debug_output)
@@ -6575,35 +6309,35 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
                p.x(), p.y(), qPrintable(_ti.text()));
 #endif
 
-    Q_D(QPainter);
+    Q_Q(QPainter);
 
-    if (!d->engine)
+    if (!engine)
         return;
 
 #ifndef QT_NO_DEBUG
-    qt_painter_thread_test(d->device->devType(),
+    qt_painter_thread_test(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) {
+    if (!extended && 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);
+        q->fillRect(rect, state->bgBrush);
     }
 
-    if (pen().style() == Qt::NoPen)
+    if (q->pen().style() == Qt::NoPen)
         return;
 
-    const RenderHints oldRenderHints = d->state->renderHints;
-    if (!d->state->renderHints & QPainter::Antialiasing && d->state->matrix.type() >= QTransform::TxScale) {
+    const QPainter::RenderHints oldRenderHints = state->renderHints;
+    if (!state->renderHints & QPainter::Antialiasing && 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) {
+        const QTransform &m = state->matrix;
+        if (state->matrix.type() < QTransform::TxShear) {
             bool isPlain90DegreeRotation =
                 (qFuzzyIsNull(m.m11())
                  && qFuzzyIsNull(m.m12() - qreal(1))
@@ -6626,11 +6360,11 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
             aa = !isPlain90DegreeRotation;
         }
         if (aa)
-            setRenderHint(QPainter::Antialiasing, true);
+            q->setRenderHint(QPainter::Antialiasing, true);
     }
 
-    if (!d->extended)
-        d->updateState(d->state);
+    if (!extended)
+        updateState(state);
 
     if (!ti.glyphs.numGlyphs) {
         // nothing to do
@@ -6643,6 +6377,10 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
         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) {
@@ -6659,14 +6397,19 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
                 ti2.width += ti.glyphs.effectiveAdvance(i);
             }
 
-            d->engine->drawTextItem(QPointF(x, y), ti2);
+            if (rtl)
+                x -= ti2.width.toReal();
+
+            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];
             }
-            x += ti2.width.toReal();
 
             // change engine
             start = end;
@@ -6681,10 +6424,13 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
             ti2.width += ti.glyphs.effectiveAdvance(i);
         }
 
-        if (d->extended)
-            d->extended->drawTextItem(QPointF(x, y), ti2);
+        if (rtl)
+            x -= ti2.width.toReal();
+
+        if (extended)
+            extended->drawTextItem(QPointF(x, y), ti2);
         else
-            d->engine->drawTextItem(QPointF(x,y), ti2);
+            engine->drawTextItem(QPointF(x,y), ti2);
 
         // reset the high byte for all glyphs
         const int hi = which << 24;
@@ -6692,20 +6438,20 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
             glyphs.glyphs[i] = hi | glyphs.glyphs[i];
 
     } else {
-        if (d->extended)
-            d->extended->drawTextItem(p, ti);
+        if (extended)
+            extended->drawTextItem(p, ti);
         else
-            d->engine->drawTextItem(p, ti);
+            engine->drawTextItem(p, ti);
     }
-    drawTextItemDecoration(this, p, ti.fontEngine, ti.underlineStyle, ti.flags, ti.width.toReal(),
-                           ti.charFormat);
+    drawTextItemDecoration(q, p, ti.fontEngine, textEngine, ti.underlineStyle,
+                           ti.flags, ti.width.toReal(), ti.charFormat);
 
-    if (d->state->renderHints != oldRenderHints) {
-        d->state->renderHints = oldRenderHints;
-        if (d->extended)
-            d->extended->renderHintsChanged();
+    if (state->renderHints != oldRenderHints) {
+        state->renderHints = oldRenderHints;
+        if (extended)
+            extended->renderHintsChanged();
         else
-            d->state->dirtyFlags |= QPaintEngine::DirtyHints;
+            state->dirtyFlags |= QPaintEngine::DirtyHints;
     }
 }
 
@@ -6724,18 +6470,18 @@ void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
 
     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
+         \li Qt::AlignLeft
+         \li Qt::AlignRight
+         \li Qt::AlignHCenter
+         \li Qt::AlignTop
+         \li Qt::AlignBottom
+         \li Qt::AlignVCenter
+         \li Qt::AlignCenter
+         \li Qt::TextSingleLine
+         \li Qt::TextExpandTabs
+         \li Qt::TextShowMnemonic
+         \li Qt::TextWordWrap
+         \li Qt::TextIncludeTrailingSpaces
     \endlist
     If several of the horizontal or several of the vertical alignment
     flags are set, the resulting alignment is undefined.
@@ -6943,8 +6689,8 @@ void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPo
 
     \table 100%
     \row
-    \o
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 18
+    \li
+    \snippet code/src_gui_painting_qpainter.cpp 18
     \endtable
 
     \sa QPicture::play()
@@ -6987,7 +6733,7 @@ void QPainter::drawPicture(const QPointF &p, const QPicture &picture)
 
     Erases the area inside the given \a rectangle. Equivalent to
     calling
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 19
+    \snippet code/src_gui_painting_qpainter.cpp 19
 
     \sa fillRect()
 */
@@ -7402,7 +7148,7 @@ QRect QPainter::window() const
     The default viewport rectangle is the same as the device's
     rectangle.
 
-    \sa viewport(), viewTransformEnabled() {Coordinate
+    \sa viewport(), viewTransformEnabled(), {Coordinate
     System#Window-Viewport Conversion}{Window-Viewport Conversion}
 */
 
@@ -7453,35 +7199,6 @@ QRect QPainter::viewport() const
     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.
@@ -7511,435 +7228,72 @@ void QPainter::setViewTransformEnabled(bool enable)
     d->updateMatrix();
 }
 
-#ifdef QT3_SUPPORT
-
 /*!
+    \threadsafe
+
     \obsolete
 
-    Use the worldTransform() combined with QTransform::dx() instead.
+    Please use QWidget::render() 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();
-}
+    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.
 
-/*!
-    \obsolete
+    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.
 
-    Use the worldTransform() combined with QTransform::dy() instead.
+    \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.
 
-    \oldcode
-        QPainter painter(this);
-        qreal y = painter.translationY();
-    \newcode
-        QPainter painter(this);
-        qreal y = painter.worldTransform().dy();
-    \endcode
+    \sa redirected(), restoreRedirected()
 */
-qreal QPainter::translationY() const
+void QPainter::setRedirected(const QPaintDevice *device,
+                             QPaintDevice *replacement,
+                             const QPoint &offset)
 {
-    Q_D(const QPainter);
-    if (!d->engine) {
-        qWarning("QPainter::translationY: Painter not active");
-        return 0.0;
-    }
-    return d->state->worldMatrix.dy();
+    Q_ASSERT(device != 0);
+    Q_UNUSED(device)
+    Q_UNUSED(replacement)
+    Q_UNUSED(offset)
+    qWarning("QPainter::setRedirected(): ignoring call to deprecated function, use QWidget::render() instead");
 }
 
 /*!
-    \fn void QPainter::map(int x, int y, int *rx, int *ry) const
+    \threadsafe
 
-    \internal
+    \obsolete
 
-    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();
-}
+    Using QWidget::render() obsoletes the use of this function.
 
-/*!
-    \fn QPoint QPainter::xForm(const QPoint &point) const
+    Restores the previous redirection for the given \a device after a
+    call to setRedirected().
 
-    Use combinedTransform() instead.
-*/
+    \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.
 
-QPoint QPainter::xForm(const QPoint &p) const
+    \sa redirected()
+ */
+void QPainter::restoreRedirected(const QPaintDevice *device)
 {
-    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();
+    Q_UNUSED(device)
+    qWarning("QPainter::restoreRedirected(): ignoring call to deprecated function, use QWidget::render() instead");
 }
 
-
 /*!
-    \fn QRect QPainter::xForm(const QRect &rectangle) const
-    \overload
+    \threadsafe
 
-    Use combinedTransform() instead of this function and call
-    mapRect() on the result to obtain a QRect.
-*/
+    \obsolete
 
-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);
-}
+    Using QWidget::render() obsoletes the use of this function.
 
-/*!
-    \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.
+    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
@@ -7950,61 +7304,11 @@ void QPainter::restoreRedirected(const QPaintDevice *device)
 */
 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);
+    Q_UNUSED(device)
+    Q_UNUSED(offset)
     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,
@@ -8056,7 +7360,7 @@ void qt_format_text(const QFont &fnt, const QRectF &_r,
     else
         layout_direction = Qt::LeftToRight;
 
-    tf = QStyle::visualAlignment(layout_direction, QFlag(tf));
+    tf = QGuiApplicationPrivate::visualAlignment(layout_direction, QFlag(tf));
 
     bool isRightToLeft = layout_direction == Qt::RightToLeft;
     bool expandtabs = ((tf & Qt::TextExpandTabs) &&
@@ -8245,11 +7549,12 @@ start_lengthVariant:
 
         for (int i = 0; i < textLayout.lineCount(); i++) {
             QTextLine line = textLayout.lineAt(i);
+            QTextEngine *eng = textLayout.engine();
+            eng->enableDelayDecorations();
 
             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();
             }
@@ -8257,6 +7562,7 @@ start_lengthVariant:
                 xoff = (r.width() - advance) / 2;
 
             line.draw(painter, QPointF(r.x() + xoff, r.y() + yoff));
+            eng->drawDecorations(painter);
         }
 
         if (restore) {
@@ -8316,7 +7622,7 @@ QPainterState::QPainterState()
       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()),
+      layoutDirection(QGuiApplication::layoutDirection()),
       composition_mode(QPainter::CompositionMode_SourceOver),
       emulationSpecifier(0), changeFlags(0)
 {
@@ -8346,7 +7652,7 @@ void QPainterState::init(QPainter *p) {
     clipInfo.clear();
     worldMatrix.reset();
     matrix.reset();
-    layoutDirection = QApplication::layoutDirection();
+    layoutDirection = QGuiApplication::layoutDirection();
     composition_mode = QPainter::CompositionMode_SourceOver;
     emulationSpecifier = 0;
     dirtyFlags = 0;
@@ -8355,147 +7661,6 @@ void QPainterState::init(QPainter *p) {
     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)
@@ -8511,8 +7676,8 @@ void bitBlt(QPaintDevice *dst, int dx, int dy,
 
     \table 100%
     \row
-    \o
-    \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 20
+    \li
+    \snippet code/src_gui_painting_qpainter.cpp 20
     \endtable
 
     \sa drawPixmap()
@@ -8603,90 +7768,9 @@ void bitBlt(QPaintDevice *dst, int dx, int dy,
 */
 
 /*!
-    \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
+    \inmodule QtGui
 
     \brief The QPaintEngineState class provides information about the
     active paint engine's current state.
@@ -8709,21 +7793,21 @@ void bitBlt(QPaintDevice *dst, int dx, int dy,
     \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()
+    \header \li Property Flag \li Current Property Value
+    \row \li QPaintEngine::DirtyBackground \li backgroundBrush()
+    \row \li QPaintEngine::DirtyBackgroundMode \li backgroundMode()
+    \row \li QPaintEngine::DirtyBrush \li brush()
+    \row \li QPaintEngine::DirtyBrushOrigin \li brushOrigin()
+    \row \li QPaintEngine::DirtyClipRegion \e or QPaintEngine::DirtyClipPath
+         \li clipOperation()
+    \row \li QPaintEngine::DirtyClipPath \li clipPath()
+    \row \li QPaintEngine::DirtyClipRegion \li clipRegion()
+    \row \li QPaintEngine::DirtyCompositionMode \li compositionMode()
+    \row \li QPaintEngine::DirtyFont \li font()
+    \row \li QPaintEngine::DirtyTransform \li transform()
+    \row \li QPaintEngine::DirtyClipEnabled \li isClipEnabled()
+    \row \li QPaintEngine::DirtyPen \li pen()
+    \row \li QPaintEngine::DirtyHints \li renderHints()
     \endtable
 
     The QPaintEngineState class also provide the painter() function
@@ -9027,7 +8111,7 @@ qreal QPaintEngineState::opacity() const
     If \a combine is true, the specified \a transform is combined with
     the current matrix; otherwise it replaces the current matrix.
 
-    \sa transform() setWorldTransform()
+    \sa transform(), setWorldTransform()
 */
 
 void QPainter::setTransform(const QTransform &transform, bool combine )
@@ -9229,6 +8313,7 @@ void QPainter::drawPixmapFragments(const PixmapFragment *fragments, int fragment
 /*!
     \since 4.7
     \class QPainter::PixmapFragment
+    \inmodule QtGui
 
     \brief This class is used in conjunction with the
     QPainter::drawPixmapFragments() function to specify how a pixmap, or
@@ -9337,252 +8422,4 @@ void qt_draw_helper(QPainterPrivate *p, const QPainterPath &path, QPainterPrivat
     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