Merge remote-tracking branch 'mainline/master' into earth
[profile/ivi/qtbase.git] / src / gui / painting / qpainter.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** No Commercial Usage
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU Lesser
18 ** General Public License version 2.1 as published by the Free Software
19 ** Foundation and appearing in the file LICENSE.LGPL included in the
20 ** packaging of this file.  Please review the following information to
21 ** ensure the GNU Lesser General Public License version 2.1 requirements
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23 **
24 ** In addition, as a special exception, Nokia gives you certain additional
25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27 **
28 ** If you have questions regarding the use of this file, please contact
29 ** Nokia at qt-info@nokia.com.
30 **
31 **
32 **
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 // QtCore
43 #include <qdebug.h>
44 #include <qmath.h>
45 #include <qmutex.h>
46
47 // QtGui
48 #include "qbitmap.h"
49 #include "qimage.h"
50 #include "qpaintdevice.h"
51 #include "qpaintengine.h"
52 #include "qpainter.h"
53 #include "qpainter_p.h"
54 #include "qpainterpath.h"
55 #include "qpicture.h"
56 #include "qpixmapcache.h"
57 #include "qpolygon.h"
58 #include "qtextlayout.h"
59 #include "qwidget.h"
60 #include "qapplication.h"
61 #include "qstyle.h"
62 #include "qthread.h"
63 #include "qvarlengtharray.h"
64 #include "qstatictext.h"
65 #include "qglyphs.h"
66
67 #include <private/qfontengine_p.h>
68 #include <private/qpaintengine_p.h>
69 #include <private/qemulationpaintengine_p.h>
70 #include <private/qpainterpath_p.h>
71 #include <private/qtextengine_p.h>
72 #include <private/qwidget_p.h>
73 #include <private/qpaintengine_raster_p.h>
74 #include <private/qmath_p.h>
75 #include <private/qstatictext_p.h>
76 #include <private/qglyphs_p.h>
77 #include <private/qstylehelper_p.h>
78 #include <private/qrawfont_p.h>
79
80 QT_BEGIN_NAMESPACE
81
82 #define QGradient_StretchToDevice 0x10000000
83 #define QPaintEngine_OpaqueBackground 0x40000000
84
85 // #define QT_DEBUG_DRAW
86 #ifdef QT_DEBUG_DRAW
87 bool qt_show_painter_debug_output = true;
88 #endif
89
90 extern QPixmap qt_pixmapForBrush(int style, bool invert);
91
92 void qt_format_text(const QFont &font,
93                     const QRectF &_r, int tf, const QTextOption *option, const QString& str, QRectF *brect,
94                     int tabstops, int* tabarray, int tabarraylen,
95                     QPainter *painter);
96 static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe,
97                                    QTextCharFormat::UnderlineStyle underlineStyle,
98                                    QTextItem::RenderFlags flags, qreal width,
99                                    const QTextCharFormat &charFormat);
100 // Helper function to calculate left most position, width and flags for decoration drawing
101 Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray,
102                                                 const QFixedPoint *positions, int glyphCount,
103                                                 QFontEngine *fontEngine, const QFont &font,
104                                                 const QTextCharFormat &charFormat);
105
106 static inline QGradient::CoordinateMode coordinateMode(const QBrush &brush)
107 {
108     switch (brush.style()) {
109     case Qt::LinearGradientPattern:
110     case Qt::RadialGradientPattern:
111     case Qt::ConicalGradientPattern:
112         return brush.gradient()->coordinateMode();
113     default:
114         ;
115     }
116     return QGradient::LogicalMode;
117 }
118
119 /* Returns true if the gradient requires stretch to device...*/
120 static inline bool check_gradient(const QBrush &brush)
121 {
122     return coordinateMode(brush) == QGradient::StretchToDeviceMode;
123 }
124
125 extern bool qHasPixmapTexture(const QBrush &);
126
127 static inline bool is_brush_transparent(const QBrush &brush) {
128     Qt::BrushStyle s = brush.style();
129     bool brushBitmap = qHasPixmapTexture(brush)
130                        ? brush.texture().isQBitmap()
131                        : (brush.textureImage().depth() == 1);
132     return ((s >= Qt::Dense1Pattern && s <= Qt::DiagCrossPattern)
133             || (s == Qt::TexturePattern && brushBitmap));
134 }
135
136 static inline bool is_pen_transparent(const QPen &pen) {
137     return pen.style() > Qt::SolidLine || is_brush_transparent(pen.brush());
138 }
139
140 /* Discards the emulation flags that are not relevant for line drawing
141    and returns the result
142 */
143 static inline uint line_emulation(uint emulation)
144 {
145     return emulation & (QPaintEngine::PrimitiveTransform
146                         | QPaintEngine::AlphaBlend
147                         | QPaintEngine::Antialiasing
148                         | QPaintEngine::BrushStroke
149                         | QPaintEngine::ConstantOpacity
150                         | QGradient_StretchToDevice
151                         | QPaintEngine::ObjectBoundingModeGradients
152                         | QPaintEngine_OpaqueBackground);
153 }
154
155 static bool qt_paintengine_supports_transformations(QPaintEngine::Type type)
156 {
157     return type == QPaintEngine::OpenGL2
158             || type == QPaintEngine::OpenVG
159             || type == QPaintEngine::OpenGL
160             || type == QPaintEngine::CoreGraphics;
161 }
162
163 #ifndef QT_NO_DEBUG
164 static bool qt_painter_thread_test(int devType, const char *what, bool extraCondition = false)
165 {
166     switch (devType) {
167     case QInternal::Image:
168     case QInternal::Printer:
169     case QInternal::Picture:
170         // can be drawn onto these devices safely from any thread
171 #ifndef Q_WS_WIN
172         if (extraCondition)
173 #endif
174             break;
175     default:
176 #ifdef Q_WS_X11
177         if (QApplication::testAttribute(Qt::AA_X11InitThreads))
178             return true;
179 #endif
180         if (!extraCondition && QThread::currentThread() != qApp->thread()) {
181             qWarning("QPainter: It is not safe to use %s outside the GUI thread", what);
182             return false;
183         }
184         break;
185     }
186     return true;
187 }
188 #endif
189
190 void QPainterPrivate::checkEmulation()
191 {
192     Q_ASSERT(extended);
193     if (extended->flags() & QPaintEngineEx::DoNotEmulate)
194         return;
195
196     bool doEmulation = false;
197     if (state->bgMode == Qt::OpaqueMode)
198         doEmulation = true;
199
200     const QGradient *bg = state->brush.gradient();
201     if (bg && bg->coordinateMode() > QGradient::LogicalMode)
202         doEmulation = true;
203
204     const QGradient *pg = qpen_brush(state->pen).gradient();
205     if (pg && pg->coordinateMode() > QGradient::LogicalMode)
206         doEmulation = true;
207
208     if (doEmulation) {
209         if (extended != emulationEngine) {
210             if (!emulationEngine)
211                 emulationEngine = new QEmulationPaintEngine(extended);
212             extended = emulationEngine;
213             extended->setState(state);
214         }
215     } else if (emulationEngine == extended) {
216         extended = emulationEngine->real_engine;
217     }
218 }
219
220
221 QPainterPrivate::~QPainterPrivate()
222 {
223     delete emulationEngine;
224     for (int i=0; i<states.size(); ++i)
225         delete states.at(i);
226
227     if (dummyState)
228         delete dummyState;
229 }
230
231
232 QTransform QPainterPrivate::viewTransform() const
233 {
234     if (state->VxF) {
235         qreal scaleW = qreal(state->vw)/qreal(state->ww);
236         qreal scaleH = qreal(state->vh)/qreal(state->wh);
237         return QTransform(scaleW, 0, 0, scaleH,
238                           state->vx - state->wx*scaleW, state->vy - state->wy*scaleH);
239     }
240     return QTransform();
241 }
242
243
244 /*
245    \internal
246    Returns true if using a shared painter; otherwise false.
247 */
248 bool QPainterPrivate::attachPainterPrivate(QPainter *q, QPaintDevice *pdev)
249 {
250     Q_ASSERT(q);
251     Q_ASSERT(pdev);
252
253     if (pdev->devType() != QInternal::Widget)
254         return false;
255
256     QWidget *widget = static_cast<QWidget *>(pdev);
257     Q_ASSERT(widget);
258
259     // Someone either called QPainter::setRedirected in the widget's paint event
260     // right before this painter was created (or begin was called) or
261     // sent a paint event directly to the widget.
262     if (!widget->d_func()->redirectDev)
263         return false;
264
265     QPainter *sp = widget->d_func()->sharedPainter();
266     if (!sp || !sp->isActive())
267         return false;
268
269     if (sp->paintEngine()->paintDevice() != widget->d_func()->redirectDev)
270         return false;
271
272     // Check if we're attempting to paint outside a paint event.
273     if (!sp->d_ptr->engine->hasFeature(QPaintEngine::PaintOutsidePaintEvent)
274         && !widget->testAttribute(Qt::WA_PaintOutsidePaintEvent)
275         && !widget->testAttribute(Qt::WA_WState_InPaintEvent)) {
276
277         qWarning("QPainter::begin: Widget painting can only begin as a result of a paintEvent");
278         return false;
279     }
280
281     // Save the current state of the shared painter and assign
282     // the current d_ptr to the shared painter's d_ptr.
283     sp->save();
284     if (!sp->d_ptr->d_ptrs) {
285         // Allocate space for 4 d-pointers (enough for up to 4 sub-sequent
286         // redirections within the same paintEvent(), which should be enough
287         // in 99% of all cases). E.g: A renders B which renders C which renders D.
288         sp->d_ptr->d_ptrs_size = 4;
289         sp->d_ptr->d_ptrs = (QPainterPrivate **)malloc(4 * sizeof(QPainterPrivate *));
290         Q_CHECK_PTR(sp->d_ptr->d_ptrs);
291     } else if (sp->d_ptr->refcount - 1 == sp->d_ptr->d_ptrs_size) {
292         // However, to support corner cases we grow the array dynamically if needed.
293         sp->d_ptr->d_ptrs_size <<= 1;
294         const int newSize = sp->d_ptr->d_ptrs_size * sizeof(QPainterPrivate *);
295         sp->d_ptr->d_ptrs = q_check_ptr((QPainterPrivate **)realloc(sp->d_ptr->d_ptrs, newSize));
296     }
297     sp->d_ptr->d_ptrs[++sp->d_ptr->refcount - 2] = q->d_ptr.data();
298     q->d_ptr.take();
299     q->d_ptr.reset(sp->d_ptr.data());
300
301     Q_ASSERT(q->d_ptr->state);
302
303     // Now initialize the painter with correct widget properties.
304     q->initFrom(widget);
305     QPoint offset;
306     widget->d_func()->redirected(&offset);
307     offset += q->d_ptr->engine->coordinateOffset();
308
309     // Update system rect.
310     q->d_ptr->state->ww = q->d_ptr->state->vw = widget->width();
311     q->d_ptr->state->wh = q->d_ptr->state->vh = widget->height();
312
313     // Update matrix.
314     if (q->d_ptr->state->WxF) {
315         q->d_ptr->state->redirectionMatrix = q->d_ptr->state->matrix;
316         q->d_ptr->state->redirectionMatrix.translate(-offset.x(), -offset.y());
317         q->d_ptr->state->worldMatrix = QTransform();
318         q->d_ptr->state->WxF = false;
319     } else {
320         q->d_ptr->state->redirectionMatrix = QTransform::fromTranslate(-offset.x(), -offset.y());
321     }
322     q->d_ptr->updateMatrix();
323
324     QPaintEnginePrivate *enginePrivate = q->d_ptr->engine->d_func();
325     if (enginePrivate->currentClipWidget == widget) {
326         enginePrivate->systemStateChanged();
327         return true;
328     }
329
330     // Update system transform and clip.
331     enginePrivate->currentClipWidget = widget;
332     enginePrivate->setSystemTransform(q->d_ptr->state->matrix);
333     return true;
334 }
335
336 void QPainterPrivate::detachPainterPrivate(QPainter *q)
337 {
338     Q_ASSERT(refcount > 1);
339     Q_ASSERT(q);
340
341     QPainterPrivate *original = d_ptrs[--refcount - 1];
342     if (inDestructor) {
343         inDestructor = false;
344         if (original)
345             original->inDestructor = true;
346     } else if (!original) {
347         original = new QPainterPrivate(q);
348     }
349
350     d_ptrs[refcount - 1] = 0;
351     q->restore();
352     q->d_ptr.take();
353     q->d_ptr.reset(original);
354
355     if (emulationEngine) {
356         extended = emulationEngine->real_engine;
357         delete emulationEngine;
358         emulationEngine = 0;
359     }
360 }
361
362
363 void QPainterPrivate::draw_helper(const QPainterPath &originalPath, DrawOperation op)
364 {
365 #ifdef QT_DEBUG_DRAW
366     if (qt_show_painter_debug_output) {
367         printf("QPainter::drawHelper\n");
368     }
369 #endif
370
371     if (originalPath.isEmpty())
372         return;
373
374     QPaintEngine::PaintEngineFeatures gradientStretch =
375         QPaintEngine::PaintEngineFeatures(QGradient_StretchToDevice
376                                           | QPaintEngine::ObjectBoundingModeGradients);
377
378     const bool mustEmulateObjectBoundingModeGradients = extended
379                                                         || ((state->emulationSpecifier & QPaintEngine::ObjectBoundingModeGradients)
380                                                             && !engine->hasFeature(QPaintEngine::PatternTransform));
381
382     if (!(state->emulationSpecifier & ~gradientStretch)
383         && !mustEmulateObjectBoundingModeGradients) {
384         drawStretchedGradient(originalPath, op);
385         return;
386     } else if (state->emulationSpecifier & QPaintEngine_OpaqueBackground) {
387         drawOpaqueBackground(originalPath, op);
388         return;
389     }
390
391     Q_Q(QPainter);
392
393     qreal strokeOffsetX = 0, strokeOffsetY = 0;
394
395     QPainterPath path = originalPath * state->matrix;
396     QRectF pathBounds = path.boundingRect();
397     QRectF strokeBounds;
398     bool doStroke = (op & StrokeDraw) && (state->pen.style() != Qt::NoPen);
399     if (doStroke) {
400         qreal penWidth = state->pen.widthF();
401         if (penWidth == 0) {
402             strokeOffsetX = 1;
403             strokeOffsetY = 1;
404         } else {
405             // In case of complex xform
406             if (state->matrix.type() > QTransform::TxScale) {
407                 QPainterPathStroker stroker;
408                 stroker.setWidth(penWidth);
409                 stroker.setJoinStyle(state->pen.joinStyle());
410                 stroker.setCapStyle(state->pen.capStyle());
411                 QPainterPath stroke = stroker.createStroke(originalPath);
412                 strokeBounds = (stroke * state->matrix).boundingRect();
413             } else {
414                 strokeOffsetX = qAbs(penWidth * state->matrix.m11() / 2.0);
415                 strokeOffsetY = qAbs(penWidth * state->matrix.m22() / 2.0);
416             }
417         }
418     }
419
420     QRect absPathRect;
421     if (!strokeBounds.isEmpty()) {
422         absPathRect = strokeBounds.intersected(QRectF(0, 0, device->width(), device->height())).toAlignedRect();
423     } else {
424         absPathRect = pathBounds.adjusted(-strokeOffsetX, -strokeOffsetY, strokeOffsetX, strokeOffsetY)
425             .intersected(QRectF(0, 0, device->width(), device->height())).toAlignedRect();
426     }
427
428     if (q->hasClipping()) {
429         bool hasPerspectiveTransform = false;
430         for (int i = 0; i < state->clipInfo.size(); ++i) {
431             const QPainterClipInfo &info = state->clipInfo.at(i);
432             if (info.matrix.type() == QTransform::TxProject) {
433                 hasPerspectiveTransform = true;
434                 break;
435             }
436         }
437         // avoid mapping QRegions with perspective transforms
438         if (!hasPerspectiveTransform) {
439             // The trick with txinv and invMatrix is done in order to
440             // avoid transforming the clip to logical coordinates, and
441             // then back to device coordinates. This is a problem with
442             // QRegion/QRect based clips, since they use integer
443             // coordinates and converting to/from logical coordinates will
444             // lose precision.
445             bool old_txinv = txinv;
446             QTransform old_invMatrix = invMatrix;
447             txinv = true;
448             invMatrix = QTransform();
449             QPainterPath clipPath = q->clipPath();
450             QRectF r = clipPath.boundingRect().intersected(absPathRect);
451             absPathRect = r.toAlignedRect();
452             txinv = old_txinv;
453             invMatrix = old_invMatrix;
454         }
455     }
456
457 //     qDebug("\nQPainterPrivate::draw_helper(), x=%d, y=%d, w=%d, h=%d",
458 //            devMinX, devMinY, device->width(), device->height());
459 //     qDebug() << " - matrix" << state->matrix;
460 //     qDebug() << " - originalPath.bounds" << originalPath.boundingRect();
461 //     qDebug() << " - path.bounds" << path.boundingRect();
462
463     if (absPathRect.width() <= 0 || absPathRect.height() <= 0)
464         return;
465
466     QImage image(absPathRect.width(), absPathRect.height(), QImage::Format_ARGB32_Premultiplied);
467     image.fill(0);
468
469     QPainter p(&image);
470
471     p.d_ptr->helper_device = helper_device;
472
473     p.setOpacity(state->opacity);
474     p.translate(-absPathRect.x(), -absPathRect.y());
475     p.setTransform(state->matrix, true);
476     p.setPen(doStroke ? state->pen : QPen(Qt::NoPen));
477     p.setBrush((op & FillDraw) ? state->brush : QBrush(Qt::NoBrush));
478     p.setBackground(state->bgBrush);
479     p.setBackgroundMode(state->bgMode);
480     p.setBrushOrigin(state->brushOrigin);
481
482     p.setRenderHint(QPainter::Antialiasing, state->renderHints & QPainter::Antialiasing);
483     p.setRenderHint(QPainter::SmoothPixmapTransform,
484                     state->renderHints & QPainter::SmoothPixmapTransform);
485
486     p.drawPath(originalPath);
487
488 #ifndef QT_NO_DEBUG
489     static bool do_fallback_overlay = qgetenv("QT_PAINT_FALLBACK_OVERLAY").size() > 0;
490     if (do_fallback_overlay) {
491         QImage block(8, 8, QImage::Format_ARGB32_Premultiplied);
492         QPainter pt(&block);
493         pt.fillRect(0, 0, 8, 8, QColor(196, 0, 196));
494         pt.drawLine(0, 0, 8, 8);
495         pt.end();
496         p.resetTransform();
497         p.setCompositionMode(QPainter::CompositionMode_SourceAtop);
498         p.setOpacity(0.5);
499         p.fillRect(0, 0, image.width(), image.height(), QBrush(block));
500     }
501 #endif
502
503     p.end();
504
505     q->save();
506     state->matrix = QTransform();
507     state->dirtyFlags |= QPaintEngine::DirtyTransform;
508     updateState(state);
509     engine->drawImage(absPathRect,
510                  image,
511                  QRectF(0, 0, absPathRect.width(), absPathRect.height()),
512                  Qt::OrderedDither | Qt::OrderedAlphaDither);
513     q->restore();
514 }
515
516 void QPainterPrivate::drawOpaqueBackground(const QPainterPath &path, DrawOperation op)
517 {
518     Q_Q(QPainter);
519
520     q->setBackgroundMode(Qt::TransparentMode);
521
522     if (op & FillDraw && state->brush.style() != Qt::NoBrush) {
523         q->fillPath(path, state->bgBrush.color());
524         q->fillPath(path, state->brush);
525     }
526
527     if (op & StrokeDraw && state->pen.style() != Qt::NoPen) {
528         q->strokePath(path, QPen(state->bgBrush.color(), state->pen.width()));
529         q->strokePath(path, state->pen);
530     }
531
532     q->setBackgroundMode(Qt::OpaqueMode);
533 }
534
535 static inline QBrush stretchGradientToUserSpace(const QBrush &brush, const QRectF &boundingRect)
536 {
537     Q_ASSERT(brush.style() >= Qt::LinearGradientPattern
538              && brush.style() <= Qt::ConicalGradientPattern);
539
540     QTransform gradientToUser(boundingRect.width(), 0, 0, boundingRect.height(),
541                               boundingRect.x(), boundingRect.y());
542
543     QGradient g = *brush.gradient();
544     g.setCoordinateMode(QGradient::LogicalMode);
545
546     QBrush b(g);
547     b.setTransform(gradientToUser * b.transform());
548     return b;
549 }
550
551 void QPainterPrivate::drawStretchedGradient(const QPainterPath &path, DrawOperation op)
552 {
553     Q_Q(QPainter);
554
555     const qreal sw = helper_device->width();
556     const qreal sh = helper_device->height();
557
558     bool changedPen = false;
559     bool changedBrush = false;
560     bool needsFill = false;
561
562     const QPen pen = state->pen;
563     const QBrush brush = state->brush;
564
565     const QGradient::CoordinateMode penMode = coordinateMode(pen.brush());
566     const QGradient::CoordinateMode brushMode = coordinateMode(brush);
567
568     QRectF boundingRect;
569
570     // Draw the xformed fill if the brush is a stretch gradient.
571     if ((op & FillDraw) && brush.style() != Qt::NoBrush) {
572         if (brushMode == QGradient::StretchToDeviceMode) {
573             q->setPen(Qt::NoPen);
574             changedPen = pen.style() != Qt::NoPen;
575             q->scale(sw, sh);
576             updateState(state);
577
578             const qreal isw = 1.0 / sw;
579             const qreal ish = 1.0 / sh;
580             QTransform inv(isw, 0, 0, ish, 0, 0);
581             engine->drawPath(path * inv);
582             q->scale(isw, ish);
583         } else {
584             needsFill = true;
585
586             if (brushMode == QGradient::ObjectBoundingMode) {
587                 Q_ASSERT(engine->hasFeature(QPaintEngine::PatternTransform));
588                 boundingRect = path.boundingRect();
589                 q->setBrush(stretchGradientToUserSpace(brush, boundingRect));
590                 changedBrush = true;
591             }
592         }
593     }
594
595     if ((op & StrokeDraw) && pen.style() != Qt::NoPen) {
596         // Draw the xformed outline if the pen is a stretch gradient.
597         if (penMode == QGradient::StretchToDeviceMode) {
598             q->setPen(Qt::NoPen);
599             changedPen = true;
600
601             if (needsFill) {
602                 updateState(state);
603                 engine->drawPath(path);
604             }
605
606             q->scale(sw, sh);
607             q->setBrush(pen.brush());
608             changedBrush = true;
609             updateState(state);
610
611             QPainterPathStroker stroker;
612             stroker.setDashPattern(pen.style());
613             stroker.setWidth(pen.widthF());
614             stroker.setJoinStyle(pen.joinStyle());
615             stroker.setCapStyle(pen.capStyle());
616             stroker.setMiterLimit(pen.miterLimit());
617             QPainterPath stroke = stroker.createStroke(path);
618
619             const qreal isw = 1.0 / sw;
620             const qreal ish = 1.0 / sh;
621             QTransform inv(isw, 0, 0, ish, 0, 0);
622             engine->drawPath(stroke * inv);
623             q->scale(isw, ish);
624         } else {
625             if (!needsFill && brush.style() != Qt::NoBrush) {
626                 q->setBrush(Qt::NoBrush);
627                 changedBrush = true;
628             }
629
630             if (penMode == QGradient::ObjectBoundingMode) {
631                 Q_ASSERT(engine->hasFeature(QPaintEngine::PatternTransform));
632
633                 // avoid computing the bounding rect twice
634                 if (!needsFill || brushMode != QGradient::ObjectBoundingMode)
635                     boundingRect = path.boundingRect();
636
637                 QPen p = pen;
638                 p.setBrush(stretchGradientToUserSpace(pen.brush(), boundingRect));
639                 q->setPen(p);
640                 changedPen = true;
641             } else if (changedPen) {
642                 q->setPen(pen);
643                 changedPen = false;
644             }
645
646             updateState(state);
647             engine->drawPath(path);
648         }
649     } else if (needsFill) {
650         if (pen.style() != Qt::NoPen) {
651             q->setPen(Qt::NoPen);
652             changedPen = true;
653         }
654
655         updateState(state);
656         engine->drawPath(path);
657     }
658
659     if (changedPen)
660         q->setPen(pen);
661     if (changedBrush)
662         q->setBrush(brush);
663 }
664
665
666 void QPainterPrivate::updateMatrix()
667 {
668     state->matrix = state->WxF ? state->worldMatrix : QTransform();
669     if (state->VxF)
670         state->matrix *= viewTransform();
671
672     txinv = false;                                // no inverted matrix
673     state->matrix *= state->redirectionMatrix;
674     if (extended)
675         extended->transformChanged();
676     else
677         state->dirtyFlags |= QPaintEngine::DirtyTransform;
678
679 //     printf("VxF=%d, WxF=%d\n", state->VxF, state->WxF);
680 //     qDebug() << " --- using matrix" << state->matrix << redirection_offset;
681 }
682
683 /*! \internal */
684 void QPainterPrivate::updateInvMatrix()
685 {
686     Q_ASSERT(txinv == false);
687     txinv = true;                                // creating inverted matrix
688     invMatrix = state->matrix.inverted();
689 }
690
691 void QPainterPrivate::updateEmulationSpecifier(QPainterState *s)
692 {
693     bool alpha = false;
694     bool linearGradient = false;
695     bool radialGradient = false;
696     bool conicalGradient = false;
697     bool patternBrush = false;
698     bool xform = false;
699     bool complexXform = false;
700
701     bool skip = true;
702
703     // Pen and brush properties (we have to check both if one changes because the
704     // one that's unchanged can still be in a state which requires emulation)
705     if (s->state() & (QPaintEngine::DirtyPen | QPaintEngine::DirtyBrush | QPaintEngine::DirtyHints)) {
706         // Check Brush stroke emulation
707         if (!s->pen.isSolid() && !engine->hasFeature(QPaintEngine::BrushStroke))
708             s->emulationSpecifier |= QPaintEngine::BrushStroke;
709         else
710             s->emulationSpecifier &= ~QPaintEngine::BrushStroke;
711
712         skip = false;
713
714         QBrush penBrush = (qpen_style(s->pen) == Qt::NoPen) ? QBrush(Qt::NoBrush) : qpen_brush(s->pen);
715         Qt::BrushStyle brushStyle = qbrush_style(s->brush);
716         Qt::BrushStyle penBrushStyle = qbrush_style(penBrush);
717         alpha = (penBrushStyle != Qt::NoBrush
718                  && (penBrushStyle < Qt::LinearGradientPattern && penBrush.color().alpha() != 255)
719                  && !penBrush.isOpaque())
720                 || (brushStyle != Qt::NoBrush
721                     && (brushStyle < Qt::LinearGradientPattern && s->brush.color().alpha() != 255)
722                     && !s->brush.isOpaque());
723         linearGradient = ((penBrushStyle == Qt::LinearGradientPattern) ||
724                            (brushStyle == Qt::LinearGradientPattern));
725         radialGradient = ((penBrushStyle == Qt::RadialGradientPattern) ||
726                            (brushStyle == Qt::RadialGradientPattern));
727         conicalGradient = ((penBrushStyle == Qt::ConicalGradientPattern) ||
728                             (brushStyle == Qt::ConicalGradientPattern));
729         patternBrush = (((penBrushStyle > Qt::SolidPattern
730                            && penBrushStyle < Qt::LinearGradientPattern)
731                           || penBrushStyle == Qt::TexturePattern) ||
732                          ((brushStyle > Qt::SolidPattern
733                            && brushStyle < Qt::LinearGradientPattern)
734                           || brushStyle == Qt::TexturePattern));
735
736         bool penTextureAlpha = false;
737         if (penBrush.style() == Qt::TexturePattern)
738             penTextureAlpha = qHasPixmapTexture(penBrush)
739                               ? (penBrush.texture().depth() > 1) && penBrush.texture().hasAlpha()
740                               : penBrush.textureImage().hasAlphaChannel();
741         bool brushTextureAlpha = false;
742         if (s->brush.style() == Qt::TexturePattern) {
743             brushTextureAlpha = qHasPixmapTexture(s->brush)
744                                 ? (s->brush.texture().depth() > 1) && s->brush.texture().hasAlpha()
745                                 : s->brush.textureImage().hasAlphaChannel();
746         }
747         if (((penBrush.style() == Qt::TexturePattern && penTextureAlpha)
748              || (s->brush.style() == Qt::TexturePattern && brushTextureAlpha))
749             && !engine->hasFeature(QPaintEngine::MaskedBrush))
750             s->emulationSpecifier |= QPaintEngine::MaskedBrush;
751         else
752             s->emulationSpecifier &= ~QPaintEngine::MaskedBrush;
753     }
754
755     if (s->state() & (QPaintEngine::DirtyHints
756                       | QPaintEngine::DirtyOpacity
757                       | QPaintEngine::DirtyBackgroundMode)) {
758         skip = false;
759     }
760
761     if (skip)
762         return;
763
764 #if 0
765     qDebug("QPainterPrivate::updateEmulationSpecifier, state=%p\n"
766            " - alpha: %d\n"
767            " - linearGradient: %d\n"
768            " - radialGradient: %d\n"
769            " - conicalGradient: %d\n"
770            " - patternBrush: %d\n"
771            " - hints: %x\n"
772            " - xform: %d\n",
773            s,
774            alpha,
775            linearGradient,
776            radialGradient,
777            conicalGradient,
778            patternBrush,
779            uint(s->renderHints),
780            xform);
781 #endif
782
783     // XForm properties
784     if (s->state() & QPaintEngine::DirtyTransform) {
785         xform = !s->matrix.isIdentity();
786         complexXform = !s->matrix.isAffine();
787     } else if (s->matrix.type() >= QTransform::TxTranslate) {
788         xform = true;
789         complexXform = !s->matrix.isAffine();
790     }
791
792     const bool brushXform = (!s->brush.transform().type() == QTransform::TxNone);
793     const bool penXform = (!s->pen.brush().transform().type() == QTransform::TxNone);
794
795     const bool patternXform = patternBrush && (xform || brushXform || penXform);
796
797     // Check alphablending
798     if (alpha && !engine->hasFeature(QPaintEngine::AlphaBlend))
799         s->emulationSpecifier |= QPaintEngine::AlphaBlend;
800     else
801         s->emulationSpecifier &= ~QPaintEngine::AlphaBlend;
802
803     // Linear gradient emulation
804     if (linearGradient && !engine->hasFeature(QPaintEngine::LinearGradientFill))
805         s->emulationSpecifier |= QPaintEngine::LinearGradientFill;
806     else
807         s->emulationSpecifier &= ~QPaintEngine::LinearGradientFill;
808
809     // Radial gradient emulation
810     if (radialGradient && !engine->hasFeature(QPaintEngine::RadialGradientFill))
811         s->emulationSpecifier |= QPaintEngine::RadialGradientFill;
812     else
813         s->emulationSpecifier &= ~QPaintEngine::RadialGradientFill;
814
815     // Conical gradient emulation
816     if (conicalGradient && !engine->hasFeature(QPaintEngine::ConicalGradientFill))
817         s->emulationSpecifier |= QPaintEngine::ConicalGradientFill;
818     else
819         s->emulationSpecifier &= ~QPaintEngine::ConicalGradientFill;
820
821     // Pattern brushes
822     if (patternBrush && !engine->hasFeature(QPaintEngine::PatternBrush))
823         s->emulationSpecifier |= QPaintEngine::PatternBrush;
824     else
825         s->emulationSpecifier &= ~QPaintEngine::PatternBrush;
826
827     // Pattern XForms
828     if (patternXform && !engine->hasFeature(QPaintEngine::PatternTransform))
829         s->emulationSpecifier |= QPaintEngine::PatternTransform;
830     else
831         s->emulationSpecifier &= ~QPaintEngine::PatternTransform;
832
833     // Primitive XForms
834     if (xform && !engine->hasFeature(QPaintEngine::PrimitiveTransform))
835         s->emulationSpecifier |= QPaintEngine::PrimitiveTransform;
836     else
837         s->emulationSpecifier &= ~QPaintEngine::PrimitiveTransform;
838
839     // Perspective XForms
840     if (complexXform && !engine->hasFeature(QPaintEngine::PerspectiveTransform))
841         s->emulationSpecifier |= QPaintEngine::PerspectiveTransform;
842     else
843         s->emulationSpecifier &= ~QPaintEngine::PerspectiveTransform;
844
845     // Constant opacity
846     if (state->opacity != 1 && !engine->hasFeature(QPaintEngine::ConstantOpacity))
847         s->emulationSpecifier |= QPaintEngine::ConstantOpacity;
848     else
849         s->emulationSpecifier &= ~QPaintEngine::ConstantOpacity;
850
851     bool gradientStretch = false;
852     bool objectBoundingMode = false;
853     if (linearGradient || conicalGradient || radialGradient) {
854         QGradient::CoordinateMode brushMode = coordinateMode(s->brush);
855         QGradient::CoordinateMode penMode = coordinateMode(s->pen.brush());
856
857         gradientStretch |= (brushMode == QGradient::StretchToDeviceMode);
858         gradientStretch |= (penMode == QGradient::StretchToDeviceMode);
859
860         objectBoundingMode |= (brushMode == QGradient::ObjectBoundingMode);
861         objectBoundingMode |= (penMode == QGradient::ObjectBoundingMode);
862     }
863     if (gradientStretch)
864         s->emulationSpecifier |= QGradient_StretchToDevice;
865     else
866         s->emulationSpecifier &= ~QGradient_StretchToDevice;
867
868     if (objectBoundingMode && !engine->hasFeature(QPaintEngine::ObjectBoundingModeGradients))
869         s->emulationSpecifier |= QPaintEngine::ObjectBoundingModeGradients;
870     else
871         s->emulationSpecifier &= ~QPaintEngine::ObjectBoundingModeGradients;
872
873     // Opaque backgrounds...
874     if (s->bgMode == Qt::OpaqueMode &&
875         (is_pen_transparent(s->pen) || is_brush_transparent(s->brush)))
876         s->emulationSpecifier |= QPaintEngine_OpaqueBackground;
877     else
878         s->emulationSpecifier &= ~QPaintEngine_OpaqueBackground;
879
880 #if 0
881     //won't be correct either way because the device can already have
882     // something rendered to it in which case subsequent emulation
883     // on a fully transparent qimage and then blitting the results
884     // won't produce correct results
885     // Blend modes
886     if (state->composition_mode > QPainter::CompositionMode_Xor &&
887         !engine->hasFeature(QPaintEngine::BlendModes))
888         s->emulationSpecifier |= QPaintEngine::BlendModes;
889     else
890         s->emulationSpecifier &= ~QPaintEngine::BlendModes;
891 #endif
892 }
893
894 void QPainterPrivate::updateStateImpl(QPainterState *newState)
895 {
896     // ### we might have to call QPainter::begin() here...
897     if (!engine->state) {
898         engine->state = newState;
899         engine->setDirty(QPaintEngine::AllDirty);
900     }
901
902     if (engine->state->painter() != newState->painter)
903         // ### this could break with clip regions vs paths.
904         engine->setDirty(QPaintEngine::AllDirty);
905
906     // Upon restore, revert all changes since last save
907     else if (engine->state != newState)
908         newState->dirtyFlags |= QPaintEngine::DirtyFlags(static_cast<QPainterState *>(engine->state)->changeFlags);
909
910     // We need to store all changes made so that restore can deal with them
911     else
912         newState->changeFlags |= newState->dirtyFlags;
913
914     updateEmulationSpecifier(newState);
915
916     // Unset potential dirty background mode
917     newState->dirtyFlags &= ~(QPaintEngine::DirtyBackgroundMode
918             | QPaintEngine::DirtyBackground);
919
920     engine->state = newState;
921     engine->updateState(*newState);
922     engine->clearDirty(QPaintEngine::AllDirty);
923
924 }
925
926 void QPainterPrivate::updateState(QPainterState *newState)
927 {
928
929     if (!newState) {
930         engine->state = newState;
931
932     } else if (newState->state() || engine->state!=newState) {
933         bool setNonCosmeticPen = (newState->renderHints & QPainter::NonCosmeticDefaultPen)
934                                  && newState->pen.widthF() == 0;
935         if (setNonCosmeticPen) {
936             // Override the default pen's cosmetic state if the
937             // NonCosmeticDefaultPen render hint is used.
938             QPen oldPen = newState->pen;
939             newState->pen.setWidth(1);
940             newState->pen.setCosmetic(false);
941             newState->dirtyFlags |= QPaintEngine::DirtyPen;
942
943             updateStateImpl(newState);
944
945             // Restore the state pen back to its default to preserve visible
946             // state.
947             newState->pen = oldPen;
948         } else {
949             updateStateImpl(newState);
950         }
951     }
952 }
953
954
955 /*!
956     \class QPainter
957     \brief The QPainter class performs low-level painting on widgets and
958     other paint devices.
959
960     \ingroup painting
961
962     \reentrant
963
964     QPainter provides highly optimized functions to do most of the
965     drawing GUI programs require. It can draw everything from simple
966     lines to complex shapes like pies and chords. It can also draw
967     aligned text and pixmaps. Normally, it draws in a "natural"
968     coordinate system, but it can also do view and world
969     transformation. QPainter can operate on any object that inherits
970     the QPaintDevice class.
971
972     The common use of QPainter is inside a widget's paint event:
973     Construct and customize (e.g. set the pen or the brush) the
974     painter. Then draw. Remember to destroy the QPainter object after
975     drawing. For example:
976
977     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 0
978
979     The core functionality of QPainter is drawing, but the class also
980     provide several functions that allows you to customize QPainter's
981     settings and its rendering quality, and others that enable
982     clipping. In addition you can control how different shapes are
983     merged together by specifying the painter's composition mode.
984
985     The isActive() function indicates whether the painter is active. A
986     painter is activated by the begin() function and the constructor
987     that takes a QPaintDevice argument. The end() function, and the
988     destructor, deactivates it.
989
990     Together with the QPaintDevice and QPaintEngine classes, QPainter
991     form the basis for Qt's paint system. QPainter is the class used
992     to perform drawing operations. QPaintDevice represents a device
993     that can be painted on using a QPainter. QPaintEngine provides the
994     interface that the painter uses to draw onto different types of
995     devices. If the painter is active, device() returns the paint
996     device on which the painter paints, and paintEngine() returns the
997     paint engine that the painter is currently operating on. For more
998     information, see the \l {Paint System}.
999
1000     Sometimes it is desirable to make someone else paint on an unusual
1001     QPaintDevice. QPainter supports a static function to do this,
1002     setRedirected().
1003
1004     \warning When the paintdevice is a widget, QPainter can only be
1005     used inside a paintEvent() function or in a function called by
1006     paintEvent(); that is unless the Qt::WA_PaintOutsidePaintEvent
1007     widget attribute is set. On Mac OS X and Windows, you can only
1008     paint in a paintEvent() function regardless of this attribute's
1009     setting.
1010
1011     \tableofcontents
1012
1013     \section1 Settings
1014
1015     There are several settings that you can customize to make QPainter
1016     draw according to your preferences:
1017
1018     \list
1019
1020     \o font() is the font used for drawing text. If the painter
1021         isActive(), you can retrieve information about the currently set
1022         font, and its metrics, using the fontInfo() and fontMetrics()
1023         functions respectively.
1024
1025     \o brush() defines the color or pattern that is used for filling
1026        shapes.
1027
1028     \o pen() defines the color or stipple that is used for drawing
1029        lines or boundaries.
1030
1031     \o backgroundMode() defines whether there is a background() or
1032        not, i.e it is either Qt::OpaqueMode or Qt::TransparentMode.
1033
1034     \o background() only applies when backgroundMode() is \l
1035        Qt::OpaqueMode and pen() is a stipple. In that case, it
1036        describes the color of the background pixels in the stipple.
1037
1038     \o brushOrigin() defines the origin of the tiled brushes, normally
1039        the origin of widget's background.
1040
1041     \o viewport(), window(), worldTransform() make up the painter's coordinate
1042         transformation system. For more information, see the \l
1043         {Coordinate Transformations} section and the \l {Coordinate
1044         System} documentation.
1045
1046     \o hasClipping() tells whether the painter clips at all. (The paint
1047        device clips, too.) If the painter clips, it clips to clipRegion().
1048
1049     \o layoutDirection() defines the layout direction used by the
1050        painter when drawing text.
1051
1052     \o worldMatrixEnabled() tells whether world transformation is enabled.
1053
1054     \o viewTransformEnabled() tells whether view transformation is
1055         enabled.
1056
1057     \endlist
1058
1059     Note that some of these settings mirror settings in some paint
1060     devices, e.g.  QWidget::font(). The QPainter::begin() function (or
1061     equivalently the QPainter constructor) copies these attributes
1062     from the paint device.
1063
1064     You can at any time save the QPainter's state by calling the
1065     save() function which saves all the available settings on an
1066     internal stack. The restore() function pops them back.
1067
1068     \section1 Drawing
1069
1070     QPainter provides functions to draw most primitives: drawPoint(),
1071     drawPoints(), drawLine(), drawRect(), drawRoundedRect(),
1072     drawEllipse(), drawArc(), drawPie(), drawChord(), drawPolyline(),
1073     drawPolygon(), drawConvexPolygon() and drawCubicBezier().  The two
1074     convenience functions, drawRects() and drawLines(), draw the given
1075     number of rectangles or lines in the given array of \l
1076     {QRect}{QRects} or \l {QLine}{QLines} using the current pen and
1077     brush.
1078
1079     The QPainter class also provides the fillRect() function which
1080     fills the given QRect, with the given QBrush, and the eraseRect()
1081     function that erases the area inside the given rectangle.
1082
1083     All of these functions have both integer and floating point
1084     versions.
1085
1086     \table 100%
1087     \row
1088     \o \inlineimage qpainter-basicdrawing.png
1089     \o
1090     \bold {Basic Drawing Example}
1091
1092     The \l {painting/basicdrawing}{Basic Drawing} example shows how to
1093     display basic graphics primitives in a variety of styles using the
1094     QPainter class.
1095
1096     \endtable
1097
1098     If you need to draw a complex shape, especially if you need to do
1099     so repeatedly, consider creating a QPainterPath and drawing it
1100     using drawPath().
1101
1102     \table 100%
1103     \row
1104     \o
1105     \bold {Painter Paths example}
1106
1107     The QPainterPath class provides a container for painting
1108     operations, enabling graphical shapes to be constructed and
1109     reused.
1110
1111     The \l {painting/painterpaths}{Painter Paths} example shows how
1112     painter paths can be used to build complex shapes for rendering.
1113
1114     \o \inlineimage qpainter-painterpaths.png
1115     \endtable
1116
1117     QPainter also provides the fillPath() function which fills the
1118     given QPainterPath with the given QBrush, and the strokePath()
1119     function that draws the outline of the given path (i.e. strokes
1120     the path).
1121
1122     See also the \l {demos/deform}{Vector Deformation} demo which
1123     shows how to use advanced vector techniques to draw text using a
1124     QPainterPath, the \l {demos/gradients}{Gradients} demo which shows
1125     the different types of gradients that are available in Qt, and the \l
1126     {demos/pathstroke}{Path Stroking} demo which shows Qt's built-in
1127     dash patterns and shows how custom patterns can be used to extend
1128     the range of available patterns.
1129
1130     \table
1131     \header
1132     \o \l {demos/deform}{Vector Deformation}
1133     \o \l {demos/gradients}{Gradients}
1134     \o \l {demos/pathstroke}{Path Stroking}
1135     \row
1136     \o \inlineimage qpainter-vectordeformation.png
1137     \o \inlineimage qpainter-gradients.png
1138     \o \inlineimage qpainter-pathstroking.png
1139     \endtable
1140
1141
1142     There are functions to draw pixmaps/images, namely drawPixmap(),
1143     drawImage() and drawTiledPixmap(). Both drawPixmap() and drawImage()
1144     produce the same result, except that drawPixmap() is faster
1145     on-screen while drawImage() may be faster on a QPrinter or other
1146     devices.
1147
1148     Text drawing is done using drawText(). When you need
1149     fine-grained positioning, boundingRect() tells you where a given
1150     drawText() command will draw.
1151
1152     There is a drawPicture() function that draws the contents of an
1153     entire QPicture. The drawPicture() function is the only function
1154     that disregards all the painter's settings as QPicture has its own
1155     settings.
1156
1157     \section1 Rendering Quality
1158
1159     To get the optimal rendering result using QPainter, you should use
1160     the platform independent QImage as paint device; i.e. using QImage
1161     will ensure that the result has an identical pixel representation
1162     on any platform.
1163
1164     The QPainter class also provides a means of controlling the
1165     rendering quality through its RenderHint enum and the support for
1166     floating point precision: All the functions for drawing primitives
1167     has a floating point version. These are often used in combination
1168     with the \l {RenderHint}{QPainter::Antialiasing} render hint.
1169
1170     \table 100%
1171     \row
1172     \o \inlineimage qpainter-concentriccircles.png
1173     \o
1174     \bold {Concentric Circles Example}
1175
1176     The \l {painting/concentriccircles}{Concentric Circles} example
1177     shows the improved rendering quality that can be obtained using
1178     floating point precision and anti-aliasing when drawing custom
1179     widgets.
1180
1181     The application's main window displays several widgets which are
1182     drawn using the various combinations of precision and
1183     anti-aliasing.
1184
1185     \endtable
1186
1187     The RenderHint enum specifies flags to QPainter that may or may
1188     not be respected by any given engine.  \l
1189     {RenderHint}{QPainter::Antialiasing} indicates that the engine
1190     should antialias edges of primitives if possible, \l
1191     {RenderHint}{QPainter::TextAntialiasing} indicates that the engine
1192     should antialias text if possible, and the \l
1193     {RenderHint}{QPainter::SmoothPixmapTransform} indicates that the
1194     engine should use a smooth pixmap transformation algorithm.
1195     \l {RenderHint}{HighQualityAntialiasing} is an OpenGL-specific rendering hint
1196     indicating that the engine should use fragment programs and offscreen
1197     rendering for antialiasing.
1198
1199     The renderHints() function returns a flag that specifies the
1200     rendering hints that are set for this painter.  Use the
1201     setRenderHint() function to set or clear the currently set
1202     RenderHints.
1203
1204     \section1 Coordinate Transformations
1205
1206     Normally, the QPainter operates on the device's own coordinate
1207     system (usually pixels), but QPainter has good support for
1208     coordinate transformations.
1209
1210     \table
1211     \header
1212     \o  nop \o rotate() \o scale() \o translate()
1213     \row
1214     \o \inlineimage qpainter-clock.png
1215     \o \inlineimage qpainter-rotation.png
1216     \o \inlineimage qpainter-scale.png
1217     \o \inlineimage qpainter-translation.png
1218     \endtable
1219
1220     The most commonly used transformations are scaling, rotation,
1221     translation and shearing. Use the scale() function to scale the
1222     coordinate system by a given offset, the rotate() function to
1223     rotate it clockwise and translate() to translate it (i.e. adding a
1224     given offset to the points). You can also twist the coordinate
1225     system around the origin using the shear() function. See the \l
1226     {demos/affine}{Affine Transformations} demo for a visualization of
1227     a sheared coordinate system.
1228
1229     See also the \l {painting/transformations}{Transformations}
1230     example which shows how transformations influence the way that
1231     QPainter renders graphics primitives. In particular it shows how
1232     the order of transformations affects the result.
1233
1234     \table 100%
1235     \row
1236     \o
1237     \bold {Affine Transformations Demo}
1238
1239     The \l {demos/affine}{Affine Transformations} demo show Qt's
1240     ability to perform affine transformations on painting
1241     operations. The demo also allows the user to experiment with the
1242     transformation operations and see the results immediately.
1243
1244     \o \inlineimage qpainter-affinetransformations.png
1245     \endtable
1246
1247     All the tranformation operations operate on the transformation
1248     worldTransform(). A matrix transforms a point in the plane to another
1249     point. For more information about the transformation matrix, see
1250     the \l {Coordinate System} and QTransform documentation.
1251
1252     The setWorldTransform() function can replace or add to the currently
1253     set worldTransform(). The resetTransform() function resets any
1254     transformations that were made using translate(), scale(),
1255     shear(), rotate(), setWorldTransform(), setViewport() and setWindow()
1256     functions. The deviceTransform() returns the matrix that transforms
1257     from logical coordinates to device coordinates of the platform
1258     dependent paint device. The latter function is only needed when
1259     using platform painting commands on the platform dependent handle,
1260     and the platform does not do transformations nativly.
1261
1262     When drawing with QPainter, we specify points using logical
1263     coordinates which then are converted into the physical coordinates
1264     of the paint device. The mapping of the logical coordinates to the
1265     physical coordinates are handled by QPainter's combinedTransform(), a
1266     combination of viewport() and window() and worldTransform(). The
1267     viewport() represents the physical coordinates specifying an
1268     arbitrary rectangle, the window() describes the same rectangle in
1269     logical coordinates, and the worldTransform() is identical with the
1270     transformation matrix.
1271
1272     See also \l {Coordinate System}
1273
1274     \section1 Clipping
1275
1276     QPainter can clip any drawing operation to a rectangle, a region,
1277     or a vector path. The current clip is available using the
1278     functions clipRegion() and clipPath(). Whether paths or regions are
1279     preferred (faster) depends on the underlying paintEngine(). For
1280     example, the QImage paint engine prefers paths while the X11 paint
1281     engine prefers regions. Setting a clip is done in the painters
1282     logical coordinates.
1283
1284     After QPainter's clipping, the paint device may also clip. For
1285     example, most widgets clip away the pixels used by child widgets,
1286     and most printers clip away an area near the edges of the paper.
1287     This additional clipping is not reflected by the return value of
1288     clipRegion() or hasClipping().
1289
1290     \section1 Composition Modes
1291     \target Composition Modes
1292
1293     QPainter provides the CompositionMode enum which defines the
1294     Porter-Duff rules for digital image compositing; it describes a
1295     model for combining the pixels in one image, the source, with the
1296     pixels in another image, the destination.
1297
1298     The two most common forms of composition are \l
1299     {QPainter::CompositionMode}{Source} and \l
1300     {QPainter::CompositionMode}{SourceOver}.  \l
1301     {QPainter::CompositionMode}{Source} is used to draw opaque objects
1302     onto a paint device. In this mode, each pixel in the source
1303     replaces the corresponding pixel in the destination. In \l
1304     {QPainter::CompositionMode}{SourceOver} composition mode, the
1305     source object is transparent and is drawn on top of the
1306     destination.
1307
1308     Note that composition transformation operates pixelwise. For that
1309     reason, there is a difference between using the graphic primitive
1310     itself and its bounding rectangle: The bounding rect contains
1311     pixels with alpha == 0 (i.e the pixels surrounding the
1312     primitive). These pixels will overwrite the other image's pixels,
1313     affectively clearing those, while the primitive only overwrites
1314     its own area.
1315
1316     \table 100%
1317     \row
1318     \o \inlineimage qpainter-compositiondemo.png
1319
1320     \o
1321     \bold {Composition Modes Demo}
1322
1323     The \l {demos/composition}{Composition Modes} demo, available in
1324     Qt's demo directory, allows you to experiment with the various
1325     composition modes and see the results immediately.
1326
1327     \endtable
1328
1329     \section1 Limitations
1330     \target Limitations
1331
1332     If you are using coordinates with Qt's raster-based paint engine, it is
1333     important to note that, while coordinates greater than +/- 2\sup 15 can
1334     be used, any painting performed with coordinates outside this range is not
1335     guaranteed to be shown; the drawing may be clipped. This is due to the
1336     use of \c{short int} in the implementation.
1337
1338     The outlines generated by Qt's stroker are only an approximation when dealing
1339     with curved shapes. It is in most cases impossible to represent the outline of
1340     a bezier curve segment using another bezier curve segment, and so Qt approximates
1341     the curve outlines by using several smaller curves. For performance reasons there
1342     is a limit to how many curves Qt uses for these outlines, and thus when using
1343     large pen widths or scales the outline error increases. To generate outlines with
1344     smaller errors it is possible to use the QPainterPathStroker class, which has the
1345     setCurveThreshold member function which let's the user specify the error tolerance.
1346     Another workaround is to convert the paths to polygons first and then draw the
1347     polygons instead.
1348
1349     \section1 Performance
1350
1351     QPainter is a rich framework that allows developers to do a great
1352     variety of graphical operations, such as gradients, composition
1353     modes and vector graphics. And QPainter can do this across a
1354     variety of different hardware and software stacks. Naturally the
1355     underlying combination of hardware and software has some
1356     implications for performance, and ensuring that every single
1357     operation is fast in combination with all the various combinations
1358     of composition modes, brushes, clipping, transformation, etc, is
1359     close to an impossible task because of the number of
1360     permutations. As a compromise we have selected a subset of the
1361     QPainter API and backends, where performance is guaranteed to be as
1362     good as we can sensibly get it for the given combination of
1363     hardware and software.
1364
1365     The backends we focus on as high-performance engines are:
1366
1367     \list
1368
1369     \o Raster - This backend implements all rendering in pure software
1370     and is always used to render into QImages. For optimal performance
1371     only use the format types QImage::Format_ARGB32_Premultiplied,
1372     QImage::Format_RGB32 or QImage::Format_RGB16. Any other format,
1373     including QImage::Format_ARGB32, has significantly worse
1374     performance. This engine is also used by default on Windows and on
1375     QWS. It can be used as default graphics system on any
1376     OS/hardware/software combination by passing \c {-graphicssystem
1377     raster} on the command line
1378
1379     \o OpenGL 2.0 (ES) - This backend is the primary backend for
1380     hardware accelerated graphics. It can be run on desktop machines
1381     and embedded devices supporting the OpenGL 2.0 or OpenGL/ES 2.0
1382     specification. This includes most graphics chips produced in the
1383     last couple of years. The engine can be enabled by using QPainter
1384     onto a QGLWidget or by passing \c {-graphicssystem opengl} on the
1385     command line when the underlying system supports it.
1386
1387     \o OpenVG - This backend implements the Khronos standard for 2D
1388     and Vector Graphics. It is primarily for embedded devices with
1389     hardware support for OpenVG.  The engine can be enabled by
1390     passing \c {-graphicssystem openvg} on the command line when
1391     the underlying system supports it.
1392
1393     \endlist
1394
1395     These operations are:
1396
1397     \list
1398
1399     \o Simple transformations, meaning translation and scaling, pluss
1400     0, 90, 180, 270 degree rotations.
1401
1402     \o \c drawPixmap() in combination with simple transformations and
1403     opacity with non-smooth transformation mode
1404     (\c QPainter::SmoothPixmapTransform not enabled as a render hint).
1405
1406     \o Rectangle fills with solid color, two-color linear gradients
1407     and simple transforms.
1408
1409     \o Rectangular clipping with simple transformations and intersect
1410     clip.
1411
1412     \o Composition Modes \c QPainter::CompositionMode_Source and
1413     QPainter::CompositionMode_SourceOver
1414
1415     \o Rounded rectangle filling using solid color and two-color
1416     linear gradients fills.
1417
1418     \o 3x3 patched pixmaps, via qDrawBorderPixmap.
1419
1420     \endlist
1421
1422     This list gives an indication of which features to safely use in
1423     an application where performance is critical. For certain setups,
1424     other operations may be fast too, but before making extensive use
1425     of them, it is recommended to benchmark and verify them on the
1426     system where the software will run in the end. There are also
1427     cases where expensive operations are ok to use, for instance when
1428     the result is cached in a QPixmap.
1429
1430     \sa QPaintDevice, QPaintEngine, {QtSvg Module}, {Basic Drawing Example},
1431         {Drawing Utility Functions}
1432 */
1433
1434 /*!
1435     \enum QPainter::RenderHint
1436
1437     Renderhints are used to specify flags to QPainter that may or
1438     may not be respected by any given engine.
1439
1440     \value Antialiasing Indicates that the engine should antialias
1441     edges of primitives if possible.
1442
1443     \value TextAntialiasing Indicates that the engine should antialias
1444     text if possible. To forcibly disable antialiasing for text, do not
1445     use this hint. Instead, set QFont::NoAntialias on your font's style
1446     strategy.
1447
1448     \value SmoothPixmapTransform Indicates that the engine should use
1449     a smooth pixmap transformation algorithm (such as bilinear) rather
1450     than nearest neighbor.
1451
1452     \value HighQualityAntialiasing An OpenGL-specific rendering hint
1453     indicating that the engine should use fragment programs and offscreen
1454     rendering for antialiasing.
1455
1456     \value NonCosmeticDefaultPen The engine should interpret pens with a width
1457     of 0 (which otherwise enables QPen::isCosmetic()) as being a non-cosmetic
1458     pen with a width of 1.
1459
1460     \sa renderHints(), setRenderHint(), {QPainter#Rendering
1461     Quality}{Rendering Quality}, {Concentric Circles Example}
1462
1463 */
1464
1465 /*!
1466     Constructs a painter.
1467
1468     \sa begin(), end()
1469 */
1470
1471 QPainter::QPainter()
1472     : d_ptr(new QPainterPrivate(this))
1473 {
1474 }
1475
1476 /*!
1477     \fn QPainter::QPainter(QPaintDevice *device)
1478
1479     Constructs a painter that begins painting the paint \a device
1480     immediately.
1481
1482     This constructor is convenient for short-lived painters, e.g. in a
1483     QWidget::paintEvent() and should be used only once. The
1484     constructor calls begin() for you and the QPainter destructor
1485     automatically calls end().
1486
1487     Here's an example using begin() and end():
1488     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 1
1489
1490     The same example using this constructor:
1491     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 2
1492
1493     Since the constructor cannot provide feedback when the initialization
1494     of the painter failed you should rather use begin() and end() to paint
1495     on external devices, e.g. printers.
1496
1497     \sa begin(), end()
1498 */
1499
1500 QPainter::QPainter(QPaintDevice *pd)
1501     : d_ptr(0)
1502 {
1503     Q_ASSERT(pd != 0);
1504     if (!QPainterPrivate::attachPainterPrivate(this, pd)) {
1505         d_ptr.reset(new QPainterPrivate(this));
1506         begin(pd);
1507     }
1508     Q_ASSERT(d_ptr);
1509 }
1510
1511 /*!
1512     Destroys the painter.
1513 */
1514 QPainter::~QPainter()
1515 {
1516     d_ptr->inDestructor = true;
1517     QT_TRY {
1518         if (isActive())
1519             end();
1520         else if (d_ptr->refcount > 1)
1521             d_ptr->detachPainterPrivate(this);
1522     } QT_CATCH(...) {
1523         // don't throw anything in the destructor.
1524     }
1525     if (d_ptr) {
1526         // Make sure we haven't messed things up.
1527         Q_ASSERT(d_ptr->inDestructor);
1528         d_ptr->inDestructor = false;
1529         Q_ASSERT(d_ptr->refcount == 1);
1530         if (d_ptr->d_ptrs)
1531             free(d_ptr->d_ptrs);
1532     }
1533 }
1534
1535 /*!
1536     Returns the paint device on which this painter is currently
1537     painting, or 0 if the painter is not active.
1538
1539     \sa isActive()
1540 */
1541
1542 QPaintDevice *QPainter::device() const
1543 {
1544     Q_D(const QPainter);
1545     if (isActive() && d->engine->d_func()->currentClipWidget)
1546         return d->engine->d_func()->currentClipWidget;
1547     return d->original_device;
1548 }
1549
1550 /*!
1551     Returns true if begin() has been called and end() has not yet been
1552     called; otherwise returns false.
1553
1554     \sa begin(), QPaintDevice::paintingActive()
1555 */
1556
1557 bool QPainter::isActive() const
1558 {
1559     Q_D(const QPainter);
1560     return d->engine;
1561 }
1562
1563 /*!
1564     Initializes the painters pen, background and font to the same as
1565     the given \a widget. This function is called automatically when the
1566     painter is opened on a QWidget.
1567
1568     \sa begin(), {QPainter#Settings}{Settings}
1569 */
1570 void QPainter::initFrom(const QWidget *widget)
1571 {
1572     Q_ASSERT_X(widget, "QPainter::initFrom(const QWidget *widget)", "Widget cannot be 0");
1573     Q_D(QPainter);
1574     if (!d->engine) {
1575         qWarning("QPainter::initFrom: Painter not active, aborted");
1576         return;
1577     }
1578
1579     const QPalette &pal = widget->palette();
1580     d->state->pen = QPen(pal.brush(widget->foregroundRole()), 0);
1581     d->state->bgBrush = pal.brush(widget->backgroundRole());
1582     d->state->deviceFont = QFont(widget->font(), const_cast<QWidget*> (widget));
1583     d->state->font = d->state->deviceFont;
1584     if (d->extended) {
1585         d->extended->penChanged();
1586     } else if (d->engine) {
1587         d->engine->setDirty(QPaintEngine::DirtyPen);
1588         d->engine->setDirty(QPaintEngine::DirtyBrush);
1589         d->engine->setDirty(QPaintEngine::DirtyFont);
1590     }
1591 }
1592
1593
1594 /*!
1595     Saves the current painter state (pushes the state onto a stack). A
1596     save() must be followed by a corresponding restore(); the end()
1597     function unwinds the stack.
1598
1599     \sa restore()
1600 */
1601
1602 void QPainter::save()
1603 {
1604 #ifdef QT_DEBUG_DRAW
1605     if (qt_show_painter_debug_output)
1606         printf("QPainter::save()\n");
1607 #endif
1608     Q_D(QPainter);
1609     if (!d->engine) {
1610         qWarning("QPainter::save: Painter not active");
1611         return;
1612     }
1613
1614     if (d->extended) {
1615         d->state = d->extended->createState(d->states.back());
1616         d->extended->setState(d->state);
1617     } else {
1618         d->updateState(d->state);
1619         d->state = new QPainterState(d->states.back());
1620         d->engine->state = d->state;
1621     }
1622     d->states.push_back(d->state);
1623 }
1624
1625 /*!
1626     Restores the current painter state (pops a saved state off the
1627     stack).
1628
1629     \sa save()
1630 */
1631
1632 void QPainter::restore()
1633 {
1634 #ifdef QT_DEBUG_DRAW
1635     if (qt_show_painter_debug_output)
1636         printf("QPainter::restore()\n");
1637 #endif
1638     Q_D(QPainter);
1639     if (d->states.size()<=1) {
1640         qWarning("QPainter::restore: Unbalanced save/restore");
1641         return;
1642     } else if (!d->engine) {
1643         qWarning("QPainter::restore: Painter not active");
1644         return;
1645     }
1646
1647     QPainterState *tmp = d->state;
1648     d->states.pop_back();
1649     d->state = d->states.back();
1650     d->txinv = false;
1651
1652     if (d->extended) {
1653         d->checkEmulation();
1654         d->extended->setState(d->state);
1655         delete tmp;
1656         return;
1657     }
1658
1659     // trigger clip update if the clip path/region has changed since
1660     // last save
1661     if (!d->state->clipInfo.isEmpty()
1662         && (tmp->changeFlags & (QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyClipPath))) {
1663         // reuse the tmp state to avoid any extra allocs...
1664         tmp->dirtyFlags = QPaintEngine::DirtyClipPath;
1665         tmp->clipOperation = Qt::NoClip;
1666         tmp->clipPath = QPainterPath();
1667         d->engine->updateState(*tmp);
1668         // replay the list of clip states,
1669         for (int i=0; i<d->state->clipInfo.size(); ++i) {
1670             const QPainterClipInfo &info = d->state->clipInfo.at(i);
1671             tmp->matrix = info.matrix;
1672             tmp->matrix *= d->state->redirectionMatrix;
1673             tmp->clipOperation = info.operation;
1674             if (info.clipType == QPainterClipInfo::RectClip) {
1675                 tmp->dirtyFlags = QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyTransform;
1676                 tmp->clipRegion = info.rect;
1677             } else if (info.clipType == QPainterClipInfo::RegionClip) {
1678                 tmp->dirtyFlags = QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyTransform;
1679                 tmp->clipRegion = info.region;
1680             } else { // clipType == QPainterClipInfo::PathClip
1681                 tmp->dirtyFlags = QPaintEngine::DirtyClipPath | QPaintEngine::DirtyTransform;
1682                 tmp->clipPath = info.path;
1683             }
1684             d->engine->updateState(*tmp);
1685         }
1686
1687
1688         //Since we've updated the clip region anyway, pretend that the clip path hasn't changed:
1689         d->state->dirtyFlags &= ~(QPaintEngine::DirtyClipPath | QPaintEngine::DirtyClipRegion);
1690         tmp->changeFlags &= ~(QPaintEngine::DirtyClipPath | QPaintEngine::DirtyClipRegion);
1691         tmp->changeFlags |= QPaintEngine::DirtyTransform;
1692     }
1693
1694     d->updateState(d->state);
1695     delete tmp;
1696 }
1697
1698
1699 /*!
1700
1701     \fn bool QPainter::begin(QPaintDevice *device)
1702
1703     Begins painting the paint \a device and returns true if
1704     successful; otherwise returns false.
1705
1706     Notice that all painter settings (setPen(), setBrush() etc.) are reset
1707     to default values when begin() is called.
1708
1709     The errors that can occur are serious problems, such as these:
1710
1711     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 3
1712
1713     Note that most of the time, you can use one of the constructors
1714     instead of begin(), and that end() is automatically done at
1715     destruction.
1716
1717     \warning A paint device can only be painted by one painter at a
1718     time.
1719
1720     \warning Painting on a QImage with the format
1721     QImage::Format_Indexed8 is not supported.
1722
1723     \sa end(), QPainter()
1724 */
1725
1726 static inline void qt_cleanup_painter_state(QPainterPrivate *d)
1727 {
1728     d->states.clear();
1729     delete d->state;
1730     d->state = 0;
1731     d->engine = 0;
1732     d->device = 0;
1733 }
1734
1735 bool QPainter::begin(QPaintDevice *pd)
1736 {
1737     Q_ASSERT(pd);
1738
1739     if (pd->painters > 0) {
1740         qWarning("QPainter::begin: A paint device can only be painted by one painter at a time.");
1741         return false;
1742     }
1743
1744     if (d_ptr->engine) {
1745         qWarning("QPainter::begin: Painter already active");
1746         return false;
1747     }
1748
1749     if (QPainterPrivate::attachPainterPrivate(this, pd))
1750         return true;
1751
1752     Q_D(QPainter);
1753
1754     d->helper_device = pd;
1755     d->original_device = pd;
1756     QPaintDevice *rpd = 0;
1757
1758     QPoint redirectionOffset;
1759     // We know for sure that redirection is broken when the widget is inside
1760     // its paint event, so it's safe to use our hard-coded redirection. However,
1761     // there IS one particular case we still need to support, and that's
1762     // when people call QPainter::setRedirected in the widget's paint event right
1763     // before any painter is created (or QPainter::begin is called). In that
1764     // particular case our hard-coded redirection is restored and the redirection
1765     // is retrieved from QPainter::redirected (as before).
1766     if (pd->devType() == QInternal::Widget)
1767         rpd = static_cast<QWidget *>(pd)->d_func()->redirected(&redirectionOffset);
1768
1769     if (!rpd)
1770         rpd = redirected(pd, &redirectionOffset);
1771
1772     if (rpd)
1773         pd = rpd;
1774
1775 #ifdef QT_DEBUG_DRAW
1776     if (qt_show_painter_debug_output)
1777         printf("QPainter::begin(), device=%p, type=%d\n", pd, pd->devType());
1778 #endif
1779
1780     if (pd->devType() == QInternal::Pixmap)
1781         static_cast<QPixmap *>(pd)->detach();
1782     else if (pd->devType() == QInternal::Image)
1783         static_cast<QImage *>(pd)->detach();
1784
1785     d->engine = pd->paintEngine();
1786
1787     if (!d->engine) {
1788         qWarning("QPainter::begin: Paint device returned engine == 0, type: %d", pd->devType());
1789         return false;
1790     }
1791
1792     d->device = pd;
1793
1794     d->extended = d->engine->isExtended() ? static_cast<QPaintEngineEx *>(d->engine) : 0;
1795     if (d->emulationEngine)
1796         d->emulationEngine->real_engine = d->extended;
1797
1798     // Setup new state...
1799     Q_ASSERT(!d->state);
1800     d->state = d->extended ? d->extended->createState(0) : new QPainterState;
1801     d->state->painter = this;
1802     d->states.push_back(d->state);
1803
1804     d->state->redirectionMatrix.translate(-redirectionOffset.x(), -redirectionOffset.y());
1805     d->state->brushOrigin = QPointF();
1806
1807     // Slip a painter state into the engine before we do any other operations
1808     if (d->extended)
1809         d->extended->setState(d->state);
1810     else
1811         d->engine->state = d->state;
1812
1813     switch (pd->devType()) {
1814         case QInternal::Widget:
1815         {
1816             const QWidget *widget = static_cast<const QWidget *>(pd);
1817             Q_ASSERT(widget);
1818
1819             const bool paintOutsidePaintEvent = widget->testAttribute(Qt::WA_PaintOutsidePaintEvent);
1820             const bool inPaintEvent = widget->testAttribute(Qt::WA_WState_InPaintEvent);
1821             if(!d->engine->hasFeature(QPaintEngine::PaintOutsidePaintEvent)
1822                 && !paintOutsidePaintEvent && !inPaintEvent) {
1823                 qWarning("QPainter::begin: Widget painting can only begin as a "
1824                          "result of a paintEvent");
1825                 qt_cleanup_painter_state(d);
1826                 return false;
1827             }
1828
1829             // Adjust offset for alien widgets painting outside the paint event.
1830             if (!inPaintEvent && paintOutsidePaintEvent && !widget->internalWinId()
1831                 && widget->testAttribute(Qt::WA_WState_Created)) {
1832                 const QPoint offset = widget->mapTo(widget->nativeParentWidget(), QPoint());
1833                 d->state->redirectionMatrix.translate(offset.x(), offset.y());
1834             }
1835             break;
1836         }
1837         case QInternal::Pixmap:
1838         {
1839             QPixmap *pm = static_cast<QPixmap *>(pd);
1840             Q_ASSERT(pm);
1841             if (pm->isNull()) {
1842                 qWarning("QPainter::begin: Cannot paint on a null pixmap");
1843                 qt_cleanup_painter_state(d);
1844                 return false;
1845             }
1846
1847             if (pm->depth() == 1) {
1848                 d->state->pen = QPen(Qt::color1);
1849                 d->state->brush = QBrush(Qt::color0);
1850             }
1851             break;
1852         }
1853         case QInternal::Image:
1854         {
1855             QImage *img = static_cast<QImage *>(pd);
1856             Q_ASSERT(img);
1857             if (img->isNull()) {
1858                 qWarning("QPainter::begin: Cannot paint on a null image");
1859                 qt_cleanup_painter_state(d);
1860                 return false;
1861             } else if (img->format() == QImage::Format_Indexed8) {
1862                 // Painting on indexed8 images is not supported.
1863                 qWarning("QPainter::begin: Cannot paint on an image with the QImage::Format_Indexed8 format");
1864                 qt_cleanup_painter_state(d);
1865                 return false;
1866             }
1867             if (img->depth() == 1) {
1868                 d->state->pen = QPen(Qt::color1);
1869                 d->state->brush = QBrush(Qt::color0);
1870             }
1871             break;
1872         }
1873         default:
1874             break;
1875     }
1876     if (d->state->ww == 0) // For compat with 3.x painter defaults
1877         d->state->ww = d->state->wh = d->state->vw = d->state->vh = 1024;
1878
1879     d->engine->setPaintDevice(pd);
1880
1881     bool begun = d->engine->begin(pd);
1882     if (!begun) {
1883         qWarning("QPainter::begin(): Returned false");
1884         if (d->engine->isActive()) {
1885             end();
1886         } else {
1887             qt_cleanup_painter_state(d);
1888         }
1889         return false;
1890     } else {
1891         d->engine->setActive(begun);
1892     }
1893
1894     // Copy painter properties from original paint device,
1895     // required for QPixmap::grabWidget()
1896     if (d->original_device->devType() == QInternal::Widget) {
1897         QWidget *widget = static_cast<QWidget *>(d->original_device);
1898         initFrom(widget);
1899     } else {
1900         d->state->layoutDirection = Qt::LayoutDirectionAuto;
1901         // make sure we have a font compatible with the paintdevice
1902         d->state->deviceFont = d->state->font = QFont(d->state->deviceFont, device());
1903     }
1904
1905     QRect systemRect = d->engine->systemRect();
1906     if (!systemRect.isEmpty()) {
1907         d->state->ww = d->state->vw = systemRect.width();
1908         d->state->wh = d->state->vh = systemRect.height();
1909     } else {
1910         d->state->ww = d->state->vw = pd->metric(QPaintDevice::PdmWidth);
1911         d->state->wh = d->state->vh = pd->metric(QPaintDevice::PdmHeight);
1912     }
1913
1914     const QPoint coordinateOffset = d->engine->coordinateOffset();
1915     d->state->redirectionMatrix.translate(-coordinateOffset.x(), -coordinateOffset.y());
1916
1917     Q_ASSERT(d->engine->isActive());
1918
1919     if (!d->state->redirectionMatrix.isIdentity())
1920         d->updateMatrix();
1921
1922     Q_ASSERT(d->engine->isActive());
1923     d->state->renderHints = QPainter::TextAntialiasing;
1924     ++d->device->painters;
1925
1926     d->state->emulationSpecifier = 0;
1927
1928     return true;
1929 }
1930
1931 /*!
1932     Ends painting. Any resources used while painting are released. You
1933     don't normally need to call this since it is called by the
1934     destructor.
1935
1936     Returns true if the painter is no longer active; otherwise returns false.
1937
1938     \sa begin(), isActive()
1939 */
1940
1941 bool QPainter::end()
1942 {
1943 #ifdef QT_DEBUG_DRAW
1944     if (qt_show_painter_debug_output)
1945         printf("QPainter::end()\n");
1946 #endif
1947     Q_D(QPainter);
1948
1949     if (!d->engine) {
1950         qWarning("QPainter::end: Painter not active, aborted");
1951         qt_cleanup_painter_state(d);
1952         return false;
1953     }
1954
1955     if (d->refcount > 1) {
1956         d->detachPainterPrivate(this);
1957         return true;
1958     }
1959
1960     bool ended = true;
1961
1962     if (d->engine->isActive()) {
1963         ended = d->engine->end();
1964         d->updateState(0);
1965
1966         --d->device->painters;
1967         if (d->device->painters == 0) {
1968             d->engine->setPaintDevice(0);
1969             d->engine->setActive(false);
1970         }
1971     }
1972
1973     if (d->states.size() > 1) {
1974         qWarning("QPainter::end: Painter ended with %d saved states",
1975                  d->states.size());
1976     }
1977
1978     if (d->engine->autoDestruct()) {
1979         delete d->engine;
1980     }
1981
1982     if (d->emulationEngine) {
1983         delete d->emulationEngine;
1984         d->emulationEngine = 0;
1985     }
1986
1987     if (d->extended) {
1988         d->extended = 0;
1989     }
1990
1991     qt_cleanup_painter_state(d);
1992
1993     return ended;
1994 }
1995
1996
1997 /*!
1998     Returns the paint engine that the painter is currently operating
1999     on if the painter is active; otherwise 0.
2000
2001     \sa isActive()
2002 */
2003 QPaintEngine *QPainter::paintEngine() const
2004 {
2005     Q_D(const QPainter);
2006     return d->engine;
2007 }
2008
2009 /*!
2010     \since 4.6
2011
2012     Flushes the painting pipeline and prepares for the user issuing commands
2013     directly to the underlying graphics context. Must be followed by a call to
2014     endNativePainting().
2015
2016     Note that only the states the underlying paint engine changes will be reset
2017     to their respective default states. The states we reset may change from
2018     release to release. The following states are currently reset in the OpenGL
2019     2 engine:
2020
2021     \list
2022     \i blending is disabled
2023     \i the depth, stencil and scissor tests are disabled
2024     \i the active texture unit is reset to 0
2025     \i the depth mask, depth function and the clear depth are reset to their
2026     default values
2027     \i the stencil mask, stencil operation and stencil function are reset to
2028     their default values
2029      \i the current color is reset to solid white
2030     \endlist
2031
2032     If, for example, the OpenGL polygon mode is changed by the user inside a
2033     beginNativePaint()/endNativePainting() block, it will not be reset to the
2034     default state by endNativePainting(). Here is an example that shows
2035     intermixing of painter commands and raw OpenGL commands:
2036
2037     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 21
2038
2039     \sa endNativePainting()
2040 */
2041 void QPainter::beginNativePainting()
2042 {
2043     Q_D(QPainter);
2044     if (!d->engine) {
2045         qWarning("QPainter::beginNativePainting: Painter not active");
2046         return;
2047     }
2048
2049     if (d->extended)
2050         d->extended->beginNativePainting();
2051 }
2052
2053 /*!
2054     \since 4.6
2055
2056     Restores the painter after manually issuing native painting commands. Lets
2057     the painter restore any native state that it relies on before calling any
2058     other painter commands.
2059
2060     \sa beginNativePainting()
2061 */
2062 void QPainter::endNativePainting()
2063 {
2064     Q_D(const QPainter);
2065     if (!d->engine) {
2066         qWarning("QPainter::beginNativePainting: Painter not active");
2067         return;
2068     }
2069
2070     if (d->extended)
2071         d->extended->endNativePainting();
2072     else
2073         d->engine->syncState();
2074 }
2075
2076 /*!
2077     Returns the font metrics for the painter if the painter is
2078     active. Otherwise, the return value is undefined.
2079
2080     \sa font(), isActive(), {QPainter#Settings}{Settings}
2081 */
2082
2083 QFontMetrics QPainter::fontMetrics() const
2084 {
2085     Q_D(const QPainter);
2086     if (!d->engine) {
2087         qWarning("QPainter::fontMetrics: Painter not active");
2088         return QFontMetrics(QFont());
2089     }
2090     return QFontMetrics(d->state->font);
2091 }
2092
2093
2094 /*!
2095     Returns the font info for the painter if the painter is
2096     active. Otherwise, the return value is undefined.
2097
2098     \sa font(), isActive(), {QPainter#Settings}{Settings}
2099 */
2100
2101 QFontInfo QPainter::fontInfo() const
2102 {
2103     Q_D(const QPainter);
2104     if (!d->engine) {
2105         qWarning("QPainter::fontInfo: Painter not active");
2106         return QFontInfo(QFont());
2107     }
2108     return QFontInfo(d->state->font);
2109 }
2110
2111 /*!
2112     \since 4.2
2113
2114     Returns the opacity of the painter. The default value is
2115     1.
2116 */
2117
2118 qreal QPainter::opacity() const
2119 {
2120     Q_D(const QPainter);
2121     if (!d->engine) {
2122         qWarning("QPainter::opacity: Painter not active");
2123         return 1.0;
2124     }
2125     return d->state->opacity;
2126 }
2127
2128 /*!
2129     \since 4.2
2130
2131     Sets the opacity of the painter to \a opacity. The value should
2132     be in the range 0.0 to 1.0, where 0.0 is fully transparent and
2133     1.0 is fully opaque.
2134
2135     Opacity set on the painter will apply to all drawing operations
2136     individually.
2137 */
2138
2139 void QPainter::setOpacity(qreal opacity)
2140 {
2141     Q_D(QPainter);
2142
2143     if (!d->engine) {
2144         qWarning("QPainter::setOpacity: Painter not active");
2145         return;
2146     }
2147
2148     opacity = qMin(qreal(1), qMax(qreal(0), opacity));
2149
2150     if (opacity == d->state->opacity)
2151         return;
2152
2153     d->state->opacity = opacity;
2154
2155     if (d->extended)
2156         d->extended->opacityChanged();
2157     else
2158         d->state->dirtyFlags |= QPaintEngine::DirtyOpacity;
2159 }
2160
2161
2162 /*!
2163     Returns the currently set brush origin.
2164
2165     \sa setBrushOrigin(), {QPainter#Settings}{Settings}
2166 */
2167
2168 QPoint QPainter::brushOrigin() const
2169 {
2170     Q_D(const QPainter);
2171     if (!d->engine) {
2172         qWarning("QPainter::brushOrigin: Painter not active");
2173         return QPoint();
2174     }
2175     return QPointF(d->state->brushOrigin).toPoint();
2176 }
2177
2178 /*!
2179     \fn void QPainter::setBrushOrigin(const QPointF &position)
2180
2181     Sets the brush origin to \a position.
2182
2183     The brush origin specifies the (0, 0) coordinate of the painter's
2184     brush.
2185
2186     Note that while the brushOrigin() was necessary to adopt the
2187     parent's background for a widget in Qt 3, this is no longer the
2188     case since the Qt 4 painter doesn't paint the background unless
2189     you explicitly tell it to do so by setting the widget's \l
2190     {QWidget::autoFillBackground}{autoFillBackground} property to
2191     true.
2192
2193     \sa brushOrigin(), {QPainter#Settings}{Settings}
2194 */
2195
2196 void QPainter::setBrushOrigin(const QPointF &p)
2197 {
2198     Q_D(QPainter);
2199 #ifdef QT_DEBUG_DRAW
2200     if (qt_show_painter_debug_output)
2201         printf("QPainter::setBrushOrigin(), (%.2f,%.2f)\n", p.x(), p.y());
2202 #endif
2203
2204     if (!d->engine) {
2205         qWarning("QPainter::setBrushOrigin: Painter not active");
2206         return;
2207     }
2208
2209     d->state->brushOrigin = p;
2210
2211     if (d->extended) {
2212         d->extended->brushOriginChanged();
2213         return;
2214     }
2215
2216     d->state->dirtyFlags |= QPaintEngine::DirtyBrushOrigin;
2217 }
2218
2219 /*!
2220     \fn void QPainter::setBrushOrigin(const QPoint &position)
2221     \overload
2222
2223     Sets the brush's origin to the given \a position.
2224 */
2225
2226 /*!
2227     \fn void QPainter::setBrushOrigin(int x, int y)
2228
2229     \overload
2230
2231     Sets the brush's origin to point (\a x, \a y).
2232 */
2233
2234 /*!
2235     \enum QPainter::CompositionMode
2236
2237     Defines the modes supported for digital image compositing.
2238     Composition modes are used to specify how the pixels in one image,
2239     the source, are merged with the pixel in another image, the
2240     destination.
2241
2242     Please note that the bitwise raster operation modes, denoted with
2243     a RasterOp prefix, are only natively supported in the X11 and
2244     raster paint engines. This means that the only way to utilize
2245     these modes on the Mac is via a QImage. The RasterOp denoted blend
2246     modes are \e not supported for pens and brushes with alpha
2247     components. Also, turning on the QPainter::Antialiasing render
2248     hint will effectively disable the RasterOp modes.
2249
2250
2251      \image qpainter-compositionmode1.png
2252      \image qpainter-compositionmode2.png
2253
2254     The most common type is SourceOver (often referred to as just
2255     alpha blending) where the source pixel is blended on top of the
2256     destination pixel in such a way that the alpha component of the
2257     source defines the translucency of the pixel.
2258
2259     When the paint device is a QImage, the image format must be set to
2260     \l {QImage::Format}{Format_ARGB32Premultiplied} or
2261     \l {QImage::Format}{Format_ARGB32} for the composition modes to have
2262     any effect. For performance the premultiplied version is the preferred
2263     format.
2264
2265     When a composition mode is set it applies to all painting
2266     operator, pens, brushes, gradients and pixmap/image drawing.
2267
2268     \value CompositionMode_SourceOver This is the default mode. The
2269     alpha of the source is used to blend the pixel on top of the
2270     destination.
2271
2272     \value CompositionMode_DestinationOver The alpha of the
2273     destination is used to blend it on top of the source pixels. This
2274     mode is the inverse of CompositionMode_SourceOver.
2275
2276     \value CompositionMode_Clear The pixels in the destination are
2277     cleared (set to fully transparent) independent of the source.
2278
2279     \value CompositionMode_Source The output is the source
2280     pixel. (This means a basic copy operation and is identical to
2281     SourceOver when the source pixel is opaque).
2282
2283     \value CompositionMode_Destination The output is the destination
2284     pixel. This means that the blending has no effect. This mode is
2285     the inverse of CompositionMode_Source.
2286
2287     \value CompositionMode_SourceIn The output is the source, where
2288     the alpha is reduced by that of the destination.
2289
2290     \value CompositionMode_DestinationIn The output is the
2291     destination, where the alpha is reduced by that of the
2292     source. This mode is the inverse of CompositionMode_SourceIn.
2293
2294     \value CompositionMode_SourceOut The output is the source, where
2295     the alpha is reduced by the inverse of destination.
2296
2297     \value CompositionMode_DestinationOut The output is the
2298     destination, where the alpha is reduced by the inverse of the
2299     source. This mode is the inverse of CompositionMode_SourceOut.
2300
2301     \value CompositionMode_SourceAtop The source pixel is blended on
2302     top of the destination, with the alpha of the source pixel reduced
2303     by the alpha of the destination pixel.
2304
2305     \value CompositionMode_DestinationAtop The destination pixel is
2306     blended on top of the source, with the alpha of the destination
2307     pixel is reduced by the alpha of the destination pixel. This mode
2308     is the inverse of CompositionMode_SourceAtop.
2309
2310     \value CompositionMode_Xor The source, whose alpha is reduced with
2311     the inverse of the destination alpha, is merged with the
2312     destination, whose alpha is reduced by the inverse of the source
2313     alpha. CompositionMode_Xor is not the same as the bitwise Xor.
2314
2315     \value CompositionMode_Plus Both the alpha and color of the source
2316     and destination pixels are added together.
2317
2318     \value CompositionMode_Multiply The output is the source color
2319     multiplied by the destination. Multiplying a color with white
2320     leaves the color unchanged, while multiplying a color
2321     with black produces black.
2322
2323     \value CompositionMode_Screen The source and destination colors
2324     are inverted and then multiplied. Screening a color with white
2325     produces white, whereas screening a color with black leaves the
2326     color unchanged.
2327
2328     \value CompositionMode_Overlay Multiplies or screens the colors
2329     depending on the destination color. The destination color is mixed
2330     with the source color to reflect the lightness or darkness of the
2331     destination.
2332
2333     \value CompositionMode_Darken The darker of the source and
2334     destination colors is selected.
2335
2336     \value CompositionMode_Lighten The lighter of the source and
2337     destination colors is selected.
2338
2339     \value CompositionMode_ColorDodge The destination color is
2340     brightened to reflect the source color. A black source color
2341     leaves the destination color unchanged.
2342
2343     \value CompositionMode_ColorBurn The destination color is darkened
2344     to reflect the source color. A white source color leaves the
2345     destination color unchanged.
2346
2347     \value CompositionMode_HardLight Multiplies or screens the colors
2348     depending on the source color. A light source color will lighten
2349     the destination color, whereas a dark source color will darken the
2350     destination color.
2351
2352     \value CompositionMode_SoftLight Darkens or lightens the colors
2353     depending on the source color. Similar to
2354     CompositionMode_HardLight.
2355
2356     \value CompositionMode_Difference Subtracts the darker of the
2357     colors from the lighter.  Painting with white inverts the
2358     destination color, whereas painting with black leaves the
2359     destination color unchanged.
2360
2361     \value CompositionMode_Exclusion Similar to
2362     CompositionMode_Difference, but with a lower contrast. Painting
2363     with white inverts the destination color, whereas painting with
2364     black leaves the destination color unchanged.
2365
2366     \value RasterOp_SourceOrDestination Does a bitwise OR operation on
2367     the source and destination pixels (src OR dst).
2368
2369     \value RasterOp_SourceAndDestination Does a bitwise AND operation
2370     on the source and destination pixels (src AND dst).
2371
2372     \value RasterOp_SourceXorDestination Does a bitwise XOR operation
2373     on the source and destination pixels (src XOR dst).
2374
2375     \value RasterOp_NotSourceAndNotDestination Does a bitwise NOR
2376     operation on the source and destination pixels ((NOT src) AND (NOT
2377     dst)).
2378
2379     \value RasterOp_NotSourceOrNotDestination Does a bitwise NAND
2380     operation on the source and destination pixels ((NOT src) OR (NOT
2381     dst)).
2382
2383     \value RasterOp_NotSourceXorDestination Does a bitwise operation
2384     where the source pixels are inverted and then XOR'ed with the
2385     destination ((NOT src) XOR dst).
2386
2387     \value RasterOp_NotSource Does a bitwise operation where the
2388     source pixels are inverted (NOT src).
2389
2390     \value RasterOp_NotSourceAndDestination Does a bitwise operation
2391     where the source is inverted and then AND'ed with the destination
2392     ((NOT src) AND dst).
2393
2394     \value RasterOp_SourceAndNotDestination Does a bitwise operation
2395     where the source is AND'ed with the inverted destination pixels
2396     (src AND (NOT dst)).
2397
2398     \sa compositionMode(), setCompositionMode(), {QPainter#Composition
2399     Modes}{Composition Modes}, {Image Composition Example}
2400 */
2401
2402 /*!
2403     Sets the composition mode to the given \a mode.
2404
2405     \warning Only a QPainter operating on a QImage fully supports all
2406     composition modes. The RasterOp modes are supported for X11 as
2407     described in compositionMode().
2408
2409     \sa compositionMode()
2410 */
2411 void QPainter::setCompositionMode(CompositionMode mode)
2412 {
2413     Q_D(QPainter);
2414     if (!d->engine) {
2415         qWarning("QPainter::setCompositionMode: Painter not active");
2416         return;
2417     }
2418     if (d->state->composition_mode == mode)
2419         return;
2420     if (d->extended) {
2421         d->state->composition_mode = mode;
2422         d->extended->compositionModeChanged();
2423         return;
2424     }
2425
2426     if (mode >= QPainter::RasterOp_SourceOrDestination) {
2427         if (!d->engine->hasFeature(QPaintEngine::RasterOpModes)) {
2428             qWarning("QPainter::setCompositionMode: "
2429                      "Raster operation modes not supported on device");
2430             return;
2431         }
2432     } else if (mode >= QPainter::CompositionMode_Plus) {
2433         if (!d->engine->hasFeature(QPaintEngine::BlendModes)) {
2434             qWarning("QPainter::setCompositionMode: "
2435                      "Blend modes not supported on device");
2436             return;
2437         }
2438     } else if (!d->engine->hasFeature(QPaintEngine::PorterDuff)) {
2439         if (mode != CompositionMode_Source && mode != CompositionMode_SourceOver) {
2440             qWarning("QPainter::setCompositionMode: "
2441                      "PorterDuff modes not supported on device");
2442             return;
2443         }
2444     }
2445
2446     d->state->composition_mode = mode;
2447     d->state->dirtyFlags |= QPaintEngine::DirtyCompositionMode;
2448 }
2449
2450 /*!
2451   Returns the current composition mode.
2452
2453   \sa CompositionMode, setCompositionMode()
2454 */
2455 QPainter::CompositionMode QPainter::compositionMode() const
2456 {
2457     Q_D(const QPainter);
2458     if (!d->engine) {
2459         qWarning("QPainter::compositionMode: Painter not active");
2460         return QPainter::CompositionMode_SourceOver;
2461     }
2462     return d->state->composition_mode;
2463 }
2464
2465 /*!
2466     Returns the current background brush.
2467
2468     \sa setBackground(), {QPainter#Settings}{Settings}
2469 */
2470
2471 const QBrush &QPainter::background() const
2472 {
2473     Q_D(const QPainter);
2474     if (!d->engine) {
2475         qWarning("QPainter::background: Painter not active");
2476         return d->fakeState()->brush;
2477     }
2478     return d->state->bgBrush;
2479 }
2480
2481
2482 /*!
2483     Returns true if clipping has been set; otherwise returns false.
2484
2485     \sa setClipping(), {QPainter#Clipping}{Clipping}
2486 */
2487
2488 bool QPainter::hasClipping() const
2489 {
2490     Q_D(const QPainter);
2491     if (!d->engine) {
2492         qWarning("QPainter::hasClipping: Painter not active");
2493         return false;
2494     }
2495     return d->state->clipEnabled && d->state->clipOperation != Qt::NoClip;
2496 }
2497
2498
2499 /*!
2500     Enables clipping if  \a enable is true, or disables clipping if  \a
2501     enable is false.
2502
2503     \sa hasClipping(), {QPainter#Clipping}{Clipping}
2504 */
2505
2506 void QPainter::setClipping(bool enable)
2507 {
2508     Q_D(QPainter);
2509 #ifdef QT_DEBUG_DRAW
2510     if (qt_show_painter_debug_output)
2511         printf("QPainter::setClipping(), enable=%s, was=%s\n",
2512                enable ? "on" : "off",
2513                hasClipping() ? "on" : "off");
2514 #endif
2515     if (!d->engine) {
2516         qWarning("QPainter::setClipping: Painter not active, state will be reset by begin");
2517         return;
2518     }
2519
2520     if (hasClipping() == enable)
2521         return;
2522
2523     // we can't enable clipping if we don't have a clip
2524     if (enable
2525         && (d->state->clipInfo.isEmpty() || d->state->clipInfo.last().operation == Qt::NoClip))
2526         return;
2527     d->state->clipEnabled = enable;
2528
2529     if (d->extended) {
2530         d->extended->clipEnabledChanged();
2531         return;
2532     }
2533
2534     d->state->dirtyFlags |= QPaintEngine::DirtyClipEnabled;
2535     d->updateState(d->state);
2536 }
2537
2538
2539 /*!
2540     Returns the currently set clip region. Note that the clip region
2541     is given in logical coordinates.
2542
2543     \warning QPainter does not store the combined clip explicitly as
2544     this is handled by the underlying QPaintEngine, so the path is
2545     recreated on demand and transformed to the current logical
2546     coordinate system. This is potentially an expensive operation.
2547
2548     \sa setClipRegion(), clipPath(), setClipping()
2549 */
2550
2551 QRegion QPainter::clipRegion() const
2552 {
2553     Q_D(const QPainter);
2554     if (!d->engine) {
2555         qWarning("QPainter::clipRegion: Painter not active");
2556         return QRegion();
2557     }
2558
2559     QRegion region;
2560     bool lastWasNothing = true;
2561
2562     if (!d->txinv)
2563         const_cast<QPainter *>(this)->d_ptr->updateInvMatrix();
2564
2565     // ### Falcon: Use QPainterPath
2566     for (int i=0; i<d->state->clipInfo.size(); ++i) {
2567         const QPainterClipInfo &info = d->state->clipInfo.at(i);
2568         switch (info.clipType) {
2569
2570         case QPainterClipInfo::RegionClip: {
2571             QTransform matrix = (info.matrix * d->invMatrix);
2572             if (lastWasNothing) {
2573                 region = info.region * matrix;
2574                 lastWasNothing = false;
2575                 continue;
2576             }
2577             if (info.operation == Qt::IntersectClip)
2578                 region &= info.region * matrix;
2579             else if (info.operation == Qt::UniteClip)
2580                 region |= info.region * matrix;
2581             else if (info.operation == Qt::NoClip) {
2582                 lastWasNothing = true;
2583                 region = QRegion();
2584             } else
2585                 region = info.region * matrix;
2586             break;
2587         }
2588
2589         case QPainterClipInfo::PathClip: {
2590             QTransform matrix = (info.matrix * d->invMatrix);
2591             if (lastWasNothing) {
2592                 region = QRegion((info.path * matrix).toFillPolygon().toPolygon(),
2593                                  info.path.fillRule());
2594                 lastWasNothing = false;
2595                 continue;
2596             }
2597             if (info.operation == Qt::IntersectClip) {
2598                 region &= QRegion((info.path * matrix).toFillPolygon().toPolygon(),
2599                                   info.path.fillRule());
2600             } else if (info.operation == Qt::UniteClip) {
2601                 region |= QRegion((info.path * matrix).toFillPolygon().toPolygon(),
2602                                   info.path.fillRule());
2603             } else if (info.operation == Qt::NoClip) {
2604                 lastWasNothing = true;
2605                 region = QRegion();
2606             } else {
2607                 region = QRegion((info.path * matrix).toFillPolygon().toPolygon(),
2608                                  info.path.fillRule());
2609             }
2610             break;
2611         }
2612
2613         case QPainterClipInfo::RectClip: {
2614             QTransform matrix = (info.matrix * d->invMatrix);
2615             if (lastWasNothing) {
2616                 region = QRegion(info.rect) * matrix;
2617                 lastWasNothing = false;
2618                 continue;
2619             }
2620             if (info.operation == Qt::IntersectClip) {
2621                 // Use rect intersection if possible.
2622                 if (matrix.type() <= QTransform::TxScale)
2623                     region &= matrix.mapRect(info.rect);
2624                 else
2625                     region &= matrix.map(QRegion(info.rect));
2626             } else if (info.operation == Qt::UniteClip) {
2627                 region |= QRegion(info.rect) * matrix;
2628             } else if (info.operation == Qt::NoClip) {
2629                 lastWasNothing = true;
2630                 region = QRegion();
2631             } else {
2632                 region = QRegion(info.rect) * matrix;
2633             }
2634             break;
2635         }
2636
2637         case QPainterClipInfo::RectFClip: {
2638             QTransform matrix = (info.matrix * d->invMatrix);
2639             if (lastWasNothing) {
2640                 region = QRegion(info.rectf.toRect()) * matrix;
2641                 lastWasNothing = false;
2642                 continue;
2643             }
2644             if (info.operation == Qt::IntersectClip) {
2645                 // Use rect intersection if possible.
2646                 if (matrix.type() <= QTransform::TxScale)
2647                     region &= matrix.mapRect(info.rectf.toRect());
2648                 else
2649                     region &= matrix.map(QRegion(info.rectf.toRect()));
2650             } else if (info.operation == Qt::UniteClip) {
2651                 region |= QRegion(info.rectf.toRect()) * matrix;
2652             } else if (info.operation == Qt::NoClip) {
2653                 lastWasNothing = true;
2654                 region = QRegion();
2655             } else {
2656                 region = QRegion(info.rectf.toRect()) * matrix;
2657             }
2658             break;
2659         }
2660         }
2661     }
2662
2663     return region;
2664 }
2665
2666 extern QPainterPath qt_regionToPath(const QRegion &region);
2667
2668 /*!
2669     Returns the currently clip as a path. Note that the clip path is
2670     given in logical coordinates.
2671
2672     \warning QPainter does not store the combined clip explicitly as
2673     this is handled by the underlying QPaintEngine, so the path is
2674     recreated on demand and transformed to the current logical
2675     coordinate system. This is potentially an expensive operation.
2676
2677     \sa setClipPath(), clipRegion(), setClipping()
2678 */
2679 QPainterPath QPainter::clipPath() const
2680 {
2681     Q_D(const QPainter);
2682
2683     // ### Since we do not support path intersections and path unions yet,
2684     // we just use clipRegion() here...
2685     if (!d->engine) {
2686         qWarning("QPainter::clipPath: Painter not active");
2687         return QPainterPath();
2688     }
2689
2690     // No clip, return empty
2691     if (d->state->clipInfo.size() == 0) {
2692         return QPainterPath();
2693     } else {
2694
2695         // Update inverse matrix, used below.
2696         if (!d->txinv)
2697             const_cast<QPainter *>(this)->d_ptr->updateInvMatrix();
2698
2699         // For the simple case avoid conversion.
2700         if (d->state->clipInfo.size() == 1
2701             && d->state->clipInfo.at(0).clipType == QPainterClipInfo::PathClip) {
2702             QTransform matrix = (d->state->clipInfo.at(0).matrix * d->invMatrix);
2703             return d->state->clipInfo.at(0).path * matrix;
2704
2705         } else if (d->state->clipInfo.size() == 1
2706                    && d->state->clipInfo.at(0).clipType == QPainterClipInfo::RectClip) {
2707             QTransform matrix = (d->state->clipInfo.at(0).matrix * d->invMatrix);
2708             QPainterPath path;
2709             path.addRect(d->state->clipInfo.at(0).rect);
2710             return path * matrix;
2711         } else {
2712             // Fallback to clipRegion() for now, since we don't have isect/unite for paths
2713             return qt_regionToPath(clipRegion());
2714         }
2715     }
2716 }
2717
2718 /*!
2719     Returns the bounding rectangle of the current clip if there is a clip;
2720     otherwise returns an empty rectangle. Note that the clip region is
2721     given in logical coordinates.
2722
2723     The bounding rectangle is not guaranteed to be tight.
2724
2725     \sa setClipRect(), setClipPath(), setClipRegion()
2726
2727     \since 4.8
2728  */
2729
2730 QRectF QPainter::clipBoundingRect() const
2731 {
2732     Q_D(const QPainter);
2733
2734     if (!d->engine) {
2735         qWarning("QPainter::clipBoundingRect: Painter not active");
2736         return QRectF();
2737     }
2738
2739     // Accumulate the bounding box in device space. This is not 100%
2740     // precise, but it fits within the guarantee and it is resonably
2741     // fast.
2742     QRectF bounds;
2743     for (int i=0; i<d->state->clipInfo.size(); ++i) {
2744          QRectF r;
2745          const QPainterClipInfo &info = d->state->clipInfo.at(i);
2746
2747          if (info.clipType == QPainterClipInfo::RectClip)
2748              r = info.rect;
2749          else if (info.clipType == QPainterClipInfo::RectFClip)
2750              r = info.rectf;
2751          else if (info.clipType == QPainterClipInfo::RegionClip)
2752              r = info.region.boundingRect();
2753          else
2754              r = info.path.boundingRect();
2755
2756          r = info.matrix.mapRect(r);
2757
2758          if (i == 0)
2759              bounds = r;
2760          else if (info.operation == Qt::IntersectClip)
2761              bounds &= r;
2762          else if (info.operation == Qt::UniteClip)
2763              bounds |= r;
2764     }
2765
2766
2767     // Map the rectangle back into logical space using the inverse
2768     // matrix.
2769     if (!d->txinv)
2770         const_cast<QPainter *>(this)->d_ptr->updateInvMatrix();
2771
2772     return d->invMatrix.mapRect(bounds);
2773 }
2774
2775 /*!
2776     \fn void QPainter::setClipRect(const QRectF &rectangle, Qt::ClipOperation operation)
2777
2778     Enables clipping, and sets the clip region to the given \a
2779     rectangle using the given clip \a operation. The default operation
2780     is to replace the current clip rectangle.
2781
2782     Note that the clip rectangle is specified in logical (painter)
2783     coordinates.
2784
2785     \sa clipRegion(), setClipping(), {QPainter#Clipping}{Clipping}
2786 */
2787 void QPainter::setClipRect(const QRectF &rect, Qt::ClipOperation op)
2788 {
2789     Q_D(QPainter);
2790
2791     if (d->extended) {
2792         if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip))
2793             op = Qt::ReplaceClip;
2794
2795         if (!d->engine) {
2796             qWarning("QPainter::setClipRect: Painter not active");
2797             return;
2798         }
2799         qreal right = rect.x() + rect.width();
2800         qreal bottom = rect.y() + rect.height();
2801         qreal pts[] = { rect.x(), rect.y(),
2802                         right, rect.y(),
2803                         right, bottom,
2804                         rect.x(), bottom };
2805         QVectorPath vp(pts, 4, 0, QVectorPath::RectangleHint);
2806         d->state->clipEnabled = true;
2807         d->extended->clip(vp, op);
2808         if (op == Qt::ReplaceClip || op == Qt::NoClip)
2809             d->state->clipInfo.clear();
2810         d->state->clipInfo << QPainterClipInfo(rect, op, d->state->matrix);
2811         d->state->clipOperation = op;
2812         return;
2813     }
2814
2815     if (qreal(int(rect.top())) == rect.top()
2816         && qreal(int(rect.bottom())) == rect.bottom()
2817         && qreal(int(rect.left())) == rect.left()
2818         && qreal(int(rect.right())) == rect.right())
2819     {
2820         setClipRect(rect.toRect(), op);
2821         return;
2822     }
2823
2824     if (rect.isEmpty()) {
2825         setClipRegion(QRegion(), op);
2826         return;
2827     }
2828
2829     QPainterPath path;
2830     path.addRect(rect);
2831     setClipPath(path, op);
2832 }
2833
2834 /*!
2835     \fn void QPainter::setClipRect(const QRect &rectangle, Qt::ClipOperation operation)
2836     \overload
2837
2838     Enables clipping, and sets the clip region to the given \a rectangle using the given
2839     clip \a operation.
2840 */
2841 void QPainter::setClipRect(const QRect &rect, Qt::ClipOperation op)
2842 {
2843     Q_D(QPainter);
2844
2845     if (!d->engine) {
2846         qWarning("QPainter::setClipRect: Painter not active");
2847         return;
2848     }
2849
2850     if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip))
2851         op = Qt::ReplaceClip;
2852
2853     if (d->extended) {
2854         d->state->clipEnabled = true;
2855         d->extended->clip(rect, op);
2856         if (op == Qt::ReplaceClip || op == Qt::NoClip)
2857             d->state->clipInfo.clear();
2858         d->state->clipInfo << QPainterClipInfo(rect, op, d->state->matrix);
2859         d->state->clipOperation = op;
2860         return;
2861     }
2862
2863     d->state->clipRegion = rect;
2864     d->state->clipOperation = op;
2865     if (op == Qt::NoClip || op == Qt::ReplaceClip)
2866         d->state->clipInfo.clear();
2867     d->state->clipInfo << QPainterClipInfo(rect, op, d->state->matrix);
2868     d->state->clipEnabled = true;
2869     d->state->dirtyFlags |= QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyClipEnabled;
2870     d->updateState(d->state);
2871 }
2872
2873 /*!
2874     \fn void QPainter::setClipRect(int x, int y, int width, int height, Qt::ClipOperation operation)
2875
2876     Enables clipping, and sets the clip region to the rectangle beginning at (\a x, \a y)
2877     with the given \a width and \a height.
2878 */
2879
2880 /*!
2881     \fn void QPainter::setClipRegion(const QRegion &region, Qt::ClipOperation operation)
2882
2883     Sets the clip region to the given \a region using the specified clip
2884     \a operation. The default clip operation is to replace the current
2885     clip region.
2886
2887     Note that the clip region is given in logical coordinates.
2888
2889     \sa clipRegion(), setClipRect(), {QPainter#Clipping}{Clipping}
2890 */
2891 void QPainter::setClipRegion(const QRegion &r, Qt::ClipOperation op)
2892 {
2893     Q_D(QPainter);
2894 #ifdef QT_DEBUG_DRAW
2895     QRect rect = r.boundingRect();
2896     if (qt_show_painter_debug_output)
2897         printf("QPainter::setClipRegion(), size=%d, [%d,%d,%d,%d]\n",
2898            r.rects().size(), rect.x(), rect.y(), rect.width(), rect.height());
2899 #endif
2900     if (!d->engine) {
2901         qWarning("QPainter::setClipRegion: Painter not active");
2902         return;
2903     }
2904
2905     if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip))
2906         op = Qt::ReplaceClip;
2907
2908     if (d->extended) {
2909         d->state->clipEnabled = true;
2910         d->extended->clip(r, op);
2911         if (op == Qt::NoClip || op == Qt::ReplaceClip)
2912             d->state->clipInfo.clear();
2913         d->state->clipInfo << QPainterClipInfo(r, op, d->state->matrix);
2914         d->state->clipOperation = op;
2915         return;
2916     }
2917
2918     d->state->clipRegion = r;
2919     d->state->clipOperation = op;
2920     if (op == Qt::NoClip || op == Qt::ReplaceClip)
2921         d->state->clipInfo.clear();
2922     d->state->clipInfo << QPainterClipInfo(r, op, d->state->matrix);
2923     d->state->clipEnabled = true;
2924     d->state->dirtyFlags |= QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyClipEnabled;
2925     d->updateState(d->state);
2926 }
2927
2928 /*!
2929     \since 4.2
2930     \obsolete
2931
2932     Sets the transformation matrix to \a matrix and enables transformations.
2933
2934     \note It is advisable to use setWorldTransform() instead of this function to
2935     preserve the properties of perspective transformations.
2936
2937     If \a combine is true, then \a matrix is combined with the current
2938     transformation matrix; otherwise \a matrix replaces the current
2939     transformation matrix.
2940
2941     If \a matrix is the identity matrix and \a combine is false, this
2942     function calls setWorldMatrixEnabled(false). (The identity matrix is the
2943     matrix where QMatrix::m11() and QMatrix::m22() are 1.0 and the
2944     rest are 0.0.)
2945
2946     The following functions can transform the coordinate system without using
2947     a QMatrix:
2948     \list
2949     \i translate()
2950     \i scale()
2951     \i shear()
2952     \i rotate()
2953     \endlist
2954
2955     They operate on the painter's worldMatrix() and are implemented like this:
2956
2957     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 4
2958
2959     Note that when using setWorldMatrix() function you should always have
2960     \a combine be true when you are drawing into a QPicture. Otherwise
2961     it may not be possible to replay the picture with additional
2962     transformations; using the translate(), scale(), etc. convenience
2963     functions is safe.
2964
2965     For more information about the coordinate system, transformations
2966     and window-viewport conversion, see \l {Coordinate System}.
2967
2968     \sa setWorldTransform(), QTransform
2969 */
2970
2971 void QPainter::setWorldMatrix(const QMatrix &matrix, bool combine)
2972 {
2973     setWorldTransform(QTransform(matrix), combine);
2974 }
2975
2976 /*!
2977     \since 4.2
2978     \obsolete
2979
2980     Returns the world transformation matrix.
2981
2982     It is advisable to use worldTransform() because worldMatrix() does not
2983     preserve the properties of perspective transformations.
2984
2985     \sa {QPainter#Coordinate Transformations}{Coordinate Transformations},
2986     {Coordinate System}
2987 */
2988
2989 const QMatrix &QPainter::worldMatrix() const
2990 {
2991     Q_D(const QPainter);
2992     if (!d->engine) {
2993         qWarning("QPainter::worldMatrix: Painter not active");
2994         return d->fakeState()->transform.toAffine();
2995     }
2996     return d->state->worldMatrix.toAffine();
2997 }
2998
2999 /*!
3000     \obsolete
3001
3002     Use setWorldTransform() instead.
3003
3004     \sa setWorldTransform()
3005 */
3006
3007 void QPainter::setMatrix(const QMatrix &matrix, bool combine)
3008 {
3009     setWorldTransform(QTransform(matrix), combine);
3010 }
3011
3012 /*!
3013     \obsolete
3014
3015     Use worldTransform() instead.
3016
3017     \sa worldTransform()
3018 */
3019
3020 const QMatrix &QPainter::matrix() const
3021 {
3022     return worldMatrix();
3023 }
3024
3025
3026 /*!
3027     \since 4.2
3028     \obsolete
3029
3030     Returns the transformation matrix combining the current
3031     window/viewport and world transformation.
3032
3033     It is advisable to use combinedTransform() instead of this
3034     function to preserve the properties of perspective transformations.
3035
3036     \sa setWorldTransform(), setWindow(), setViewport()
3037 */
3038 QMatrix QPainter::combinedMatrix() const
3039 {
3040     return combinedTransform().toAffine();
3041 }
3042
3043
3044 /*!
3045     \obsolete
3046
3047     Returns the matrix that transforms from logical coordinates to
3048     device coordinates of the platform dependent paint device.
3049
3050     \note It is advisable to use deviceTransform() instead of this
3051     function to preserve the properties of perspective transformations.
3052
3053     This function is \e only needed when using platform painting
3054     commands on the platform dependent handle (Qt::HANDLE), and the
3055     platform does not do transformations nativly.
3056
3057     The QPaintEngine::PaintEngineFeature enum can be queried to
3058     determine whether the platform performs the transformations or
3059     not.
3060
3061     \sa worldMatrix(), QPaintEngine::hasFeature(),
3062 */
3063 const QMatrix &QPainter::deviceMatrix() const
3064 {
3065     Q_D(const QPainter);
3066     if (!d->engine) {
3067         qWarning("QPainter::deviceMatrix: Painter not active");
3068         return d->fakeState()->transform.toAffine();
3069     }
3070     return d->state->matrix.toAffine();
3071 }
3072
3073 /*!
3074     \obsolete
3075
3076     Resets any transformations that were made using translate(), scale(),
3077     shear(), rotate(), setWorldMatrix(), setViewport() and
3078     setWindow().
3079
3080     It is advisable to use resetTransform() instead of this function
3081     to preserve the properties of perspective transformations.
3082
3083     \sa {QPainter#Coordinate Transformations}{Coordinate
3084     Transformations}
3085 */
3086
3087 void QPainter::resetMatrix()
3088 {
3089     resetTransform();
3090 }
3091
3092
3093 /*!
3094     \since 4.2
3095
3096     Enables transformations if \a enable is true, or disables
3097     transformations if \a enable is false. The world transformation
3098     matrix is not changed.
3099
3100     \sa worldMatrixEnabled(), worldTransform(), {QPainter#Coordinate
3101     Transformations}{Coordinate Transformations}
3102 */
3103
3104 void QPainter::setWorldMatrixEnabled(bool enable)
3105 {
3106     Q_D(QPainter);
3107 #ifdef QT_DEBUG_DRAW
3108     if (qt_show_painter_debug_output)
3109         printf("QPainter::setMatrixEnabled(), enable=%d\n", enable);
3110 #endif
3111
3112     if (!d->engine) {
3113         qWarning("QPainter::setMatrixEnabled: Painter not active");
3114         return;
3115     }
3116     if (enable == d->state->WxF)
3117         return;
3118
3119     d->state->WxF = enable;
3120     d->updateMatrix();
3121 }
3122
3123 /*!
3124     \since 4.2
3125
3126     Returns true if world transformation is enabled; otherwise returns
3127     false.
3128
3129     \sa setWorldMatrixEnabled(), worldTransform(), {Coordinate System}
3130 */
3131
3132 bool QPainter::worldMatrixEnabled() const
3133 {
3134     Q_D(const QPainter);
3135     if (!d->engine) {
3136         qWarning("QPainter::worldMatrixEnabled: Painter not active");
3137         return false;
3138     }
3139     return d->state->WxF;
3140 }
3141
3142 /*!
3143     \obsolete
3144
3145     Use setWorldMatrixEnabled() instead.
3146
3147     \sa setWorldMatrixEnabled()
3148 */
3149
3150 void QPainter::setMatrixEnabled(bool enable)
3151 {
3152     setWorldMatrixEnabled(enable);
3153 }
3154
3155 /*!
3156     \obsolete
3157
3158     Use worldMatrixEnabled() instead
3159
3160     \sa worldMatrixEnabled()
3161 */
3162
3163 bool QPainter::matrixEnabled() const
3164 {
3165     return worldMatrixEnabled();
3166 }
3167
3168 /*!
3169     Scales the coordinate system by (\a{sx}, \a{sy}).
3170
3171     \sa setWorldTransform() {QPainter#Coordinate Transformations}{Coordinate
3172     Transformations}
3173 */
3174
3175 void QPainter::scale(qreal sx, qreal sy)
3176 {
3177 #ifdef QT_DEBUG_DRAW
3178     if (qt_show_painter_debug_output)
3179         printf("QPainter::scale(), sx=%f, sy=%f\n", sx, sy);
3180 #endif
3181     Q_D(QPainter);
3182     if (!d->engine) {
3183         qWarning("QPainter::scale: Painter not active");
3184         return;
3185     }
3186
3187     d->state->worldMatrix.scale(sx,sy);
3188     d->state->WxF = true;
3189     d->updateMatrix();
3190 }
3191
3192 /*!
3193     Shears the coordinate system by (\a{sh}, \a{sv}).
3194
3195     \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate
3196     Transformations}
3197 */
3198
3199 void QPainter::shear(qreal sh, qreal sv)
3200 {
3201 #ifdef QT_DEBUG_DRAW
3202     if (qt_show_painter_debug_output)
3203         printf("QPainter::shear(), sh=%f, sv=%f\n", sh, sv);
3204 #endif
3205     Q_D(QPainter);
3206     if (!d->engine) {
3207         qWarning("QPainter::shear: Painter not active");
3208         return;
3209     }
3210
3211     d->state->worldMatrix.shear(sh, sv);
3212     d->state->WxF = true;
3213     d->updateMatrix();
3214 }
3215
3216 /*!
3217     \fn void QPainter::rotate(qreal angle)
3218
3219     Rotates the coordinate system the given \a angle clockwise.
3220
3221     \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate
3222     Transformations}
3223 */
3224
3225 void QPainter::rotate(qreal a)
3226 {
3227 #ifdef QT_DEBUG_DRAW
3228     if (qt_show_painter_debug_output)
3229         printf("QPainter::rotate(), angle=%f\n", a);
3230 #endif
3231     Q_D(QPainter);
3232     if (!d->engine) {
3233         qWarning("QPainter::rotate: Painter not active");
3234         return;
3235     }
3236
3237     d->state->worldMatrix.rotate(a);
3238     d->state->WxF = true;
3239     d->updateMatrix();
3240 }
3241
3242 /*!
3243     Translates the coordinate system by the given \a offset; i.e. the
3244     given \a offset is added to points.
3245
3246     \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate
3247     Transformations}
3248 */
3249 void QPainter::translate(const QPointF &offset)
3250 {
3251     qreal dx = offset.x();
3252     qreal dy = offset.y();
3253 #ifdef QT_DEBUG_DRAW
3254     if (qt_show_painter_debug_output)
3255         printf("QPainter::translate(), dx=%f, dy=%f\n", dx, dy);
3256 #endif
3257     Q_D(QPainter);
3258     if (!d->engine) {
3259         qWarning("QPainter::translate: Painter not active");
3260         return;
3261     }
3262
3263     d->state->worldMatrix.translate(dx, dy);
3264     d->state->WxF = true;
3265     d->updateMatrix();
3266 }
3267
3268 /*!
3269     \fn void QPainter::translate(const QPoint &offset)
3270     \overload
3271
3272     Translates the coordinate system by the given \a offset.
3273 */
3274
3275 /*!
3276     \fn void QPainter::translate(qreal dx, qreal dy)
3277     \overload
3278
3279     Translates the coordinate system by the vector (\a dx, \a dy).
3280 */
3281
3282 /*!
3283     \fn void QPainter::setClipPath(const QPainterPath &path, Qt::ClipOperation operation)
3284
3285     Enables clipping, and sets the clip path for the painter to the
3286     given \a path, with the clip \a operation.
3287
3288     Note that the clip path is specified in logical (painter)
3289     coordinates.
3290
3291     \sa clipPath(), clipRegion(), {QPainter#Clipping}{Clipping}
3292
3293 */
3294 void QPainter::setClipPath(const QPainterPath &path, Qt::ClipOperation op)
3295 {
3296 #ifdef QT_DEBUG_DRAW
3297     if (qt_show_painter_debug_output) {
3298         QRectF b = path.boundingRect();
3299         printf("QPainter::setClipPath(), size=%d, op=%d, bounds=[%.2f,%.2f,%.2f,%.2f]\n",
3300                path.elementCount(), op, b.x(), b.y(), b.width(), b.height());
3301     }
3302 #endif
3303     Q_D(QPainter);
3304
3305     if (!d->engine) {
3306         qWarning("QPainter::setClipPath: Painter not active");
3307         return;
3308     }
3309
3310     if ((!d->state->clipEnabled && op != Qt::NoClip) || (d->state->clipOperation == Qt::NoClip && op == Qt::UniteClip))
3311         op = Qt::ReplaceClip;
3312
3313     if (d->extended) {
3314         d->state->clipEnabled = true;
3315         d->extended->clip(path, op);
3316         if (op == Qt::NoClip || op == Qt::ReplaceClip)
3317             d->state->clipInfo.clear();
3318         d->state->clipInfo << QPainterClipInfo(path, op, d->state->matrix);
3319         d->state->clipOperation = op;
3320         return;
3321     }
3322
3323     d->state->clipPath = path;
3324     d->state->clipOperation = op;
3325     if (op == Qt::NoClip || op == Qt::ReplaceClip)
3326         d->state->clipInfo.clear();
3327     d->state->clipInfo << QPainterClipInfo(path, op, d->state->matrix);
3328     d->state->clipEnabled = true;
3329     d->state->dirtyFlags |= QPaintEngine::DirtyClipPath | QPaintEngine::DirtyClipEnabled;
3330     d->updateState(d->state);
3331 }
3332
3333 /*!
3334     Draws the outline (strokes) the path \a path with the pen specified
3335     by \a pen
3336
3337     \sa fillPath(), {QPainter#Drawing}{Drawing}
3338 */
3339 void QPainter::strokePath(const QPainterPath &path, const QPen &pen)
3340 {
3341     Q_D(QPainter);
3342
3343     if (!d->engine) {
3344         qWarning("QPainter::strokePath: Painter not active");
3345         return;
3346     }
3347
3348     if (path.isEmpty())
3349         return;
3350
3351     if (d->extended) {
3352         const QGradient *g = qpen_brush(pen).gradient();
3353         if (!g || g->coordinateMode() == QGradient::LogicalMode) {
3354             d->extended->stroke(qtVectorPathForPath(path), pen);
3355             return;
3356         }
3357     }
3358
3359     QBrush oldBrush = d->state->brush;
3360     QPen oldPen = d->state->pen;
3361
3362     setPen(pen);
3363     setBrush(Qt::NoBrush);
3364
3365     drawPath(path);
3366
3367     // Reset old state
3368     setPen(oldPen);
3369     setBrush(oldBrush);
3370 }
3371
3372 /*!
3373     Fills the given \a path using the given \a brush. The outline is
3374     not drawn.
3375
3376     Alternatively, you can specify a QColor instead of a QBrush; the
3377     QBrush constructor (taking a QColor argument) will automatically
3378     create a solid pattern brush.
3379
3380     \sa drawPath()
3381 */
3382 void QPainter::fillPath(const QPainterPath &path, const QBrush &brush)
3383 {
3384     Q_D(QPainter);
3385
3386     if (!d->engine) {
3387         qWarning("QPainter::fillPath: Painter not active");
3388         return;
3389     }
3390
3391     if (path.isEmpty())
3392         return;
3393
3394     if (d->extended) {
3395         const QGradient *g = brush.gradient();
3396         if (!g || g->coordinateMode() == QGradient::LogicalMode) {
3397             d->extended->fill(qtVectorPathForPath(path), brush);
3398             return;
3399         }
3400     }
3401
3402     QBrush oldBrush = d->state->brush;
3403     QPen oldPen = d->state->pen;
3404
3405     setPen(Qt::NoPen);
3406     setBrush(brush);
3407
3408     drawPath(path);
3409
3410     // Reset old state
3411     setPen(oldPen);
3412     setBrush(oldBrush);
3413 }
3414
3415 /*!
3416     Draws the given painter \a path using the current pen for outline
3417     and the current brush for filling.
3418
3419     \table 100%
3420     \row
3421     \o \inlineimage qpainter-path.png
3422     \o
3423     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 5
3424     \endtable
3425
3426     \sa {painting/painterpaths}{the Painter Paths
3427     example},{demos/deform}{the Vector Deformation demo}
3428 */
3429 void QPainter::drawPath(const QPainterPath &path)
3430 {
3431 #ifdef QT_DEBUG_DRAW
3432     QRectF pathBounds = path.boundingRect();
3433     if (qt_show_painter_debug_output)
3434         printf("QPainter::drawPath(), size=%d, [%.2f,%.2f,%.2f,%.2f]\n",
3435                path.elementCount(),
3436                pathBounds.x(), pathBounds.y(), pathBounds.width(), pathBounds.height());
3437 #endif
3438
3439     Q_D(QPainter);
3440
3441     if (!d->engine) {
3442         qWarning("QPainter::drawPath: Painter not active");
3443         return;
3444     }
3445
3446     if (d->extended) {
3447         d->extended->drawPath(path);
3448         return;
3449     }
3450     d->updateState(d->state);
3451
3452     if (d->engine->hasFeature(QPaintEngine::PainterPaths) && d->state->emulationSpecifier == 0) {
3453         d->engine->drawPath(path);
3454     } else {
3455         d->draw_helper(path);
3456     }
3457 }
3458
3459 /*!
3460     \fn void QPainter::drawLine(const QLineF &line)
3461
3462     Draws a line defined by \a line.
3463
3464     \table 100%
3465     \row
3466     \o \inlineimage qpainter-line.png
3467     \o
3468     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 6
3469     \endtable
3470
3471     \sa drawLines(), drawPolyline(), {Coordinate System}
3472 */
3473
3474 /*!
3475     \fn void QPainter::drawLine(const QLine &line)
3476     \overload
3477
3478     Draws a line defined by \a line.
3479 */
3480
3481 /*!
3482     \fn void QPainter::drawLine(const QPoint &p1, const QPoint &p2)
3483     \overload
3484
3485     Draws a line from \a p1 to \a p2.
3486 */
3487
3488 /*!
3489     \fn void QPainter::drawLine(const QPointF &p1, const QPointF &p2)
3490     \overload
3491
3492     Draws a line from \a p1 to \a p2.
3493 */
3494
3495 /*!
3496     \fn void QPainter::drawLine(int x1, int y1, int x2, int y2)
3497     \overload
3498
3499     Draws a line from (\a x1, \a y1) to (\a x2, \a y2) and sets the
3500     current pen position to (\a x2, \a y2).
3501 */
3502
3503 /*!
3504     \fn void QPainter::drawRect(const QRectF &rectangle)
3505
3506     Draws the current \a rectangle with the current pen and brush.
3507
3508     A filled rectangle has a size of \a{rectangle}.size(). A stroked
3509     rectangle has a size of \a{rectangle}.size() plus the pen width.
3510
3511     \table 100%
3512     \row
3513     \o \inlineimage qpainter-rectangle.png
3514     \o
3515     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 7
3516     \endtable
3517
3518     \sa drawRects(), drawPolygon(), {Coordinate System}
3519 */
3520
3521 /*!
3522     \fn void QPainter::drawRect(const QRect &rectangle)
3523
3524     \overload
3525
3526     Draws the current \a rectangle with the current pen and brush.
3527 */
3528
3529 /*!
3530     \fn void QPainter::drawRect(int x, int y, int width, int height)
3531
3532     \overload
3533
3534     Draws a rectangle with upper left corner at (\a{x}, \a{y}) and
3535     with the given \a width and \a height.
3536 */
3537
3538 /*!
3539     \fn void QPainter::drawRects(const QRectF *rectangles, int rectCount)
3540
3541     Draws the first \a rectCount of the given \a rectangles using the
3542     current pen and brush.
3543
3544     \sa drawRect()
3545 */
3546 void QPainter::drawRects(const QRectF *rects, int rectCount)
3547 {
3548 #ifdef QT_DEBUG_DRAW
3549     if (qt_show_painter_debug_output)
3550         printf("QPainter::drawRects(), count=%d\n", rectCount);
3551 #endif
3552     Q_D(QPainter);
3553
3554     if (!d->engine) {
3555         qWarning("QPainter::drawRects: Painter not active");
3556         return;
3557     }
3558
3559     if (rectCount <= 0)
3560         return;
3561
3562     if (d->extended) {
3563         d->extended->drawRects(rects, rectCount);
3564         return;
3565     }
3566
3567     d->updateState(d->state);
3568
3569     if (!d->state->emulationSpecifier) {
3570         d->engine->drawRects(rects, rectCount);
3571         return;
3572     }
3573
3574     if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
3575         && d->state->matrix.type() == QTransform::TxTranslate) {
3576         for (int i=0; i<rectCount; ++i) {
3577             QRectF r(rects[i].x() + d->state->matrix.dx(),
3578                      rects[i].y() + d->state->matrix.dy(),
3579                      rects[i].width(),
3580                      rects[i].height());
3581             d->engine->drawRects(&r, 1);
3582         }
3583     } else {
3584         if (d->state->brushNeedsResolving() || d->state->penNeedsResolving()) {
3585             for (int i=0; i<rectCount; ++i) {
3586                 QPainterPath rectPath;
3587                 rectPath.addRect(rects[i]);
3588                 d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
3589             }
3590         } else {
3591             QPainterPath rectPath;
3592             for (int i=0; i<rectCount; ++i)
3593                 rectPath.addRect(rects[i]);
3594             d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
3595         }
3596     }
3597 }
3598
3599 /*!
3600     \fn void QPainter::drawRects(const QRect *rectangles, int rectCount)
3601     \overload
3602
3603     Draws the first \a rectCount of the given \a rectangles using the
3604     current pen and brush.
3605 */
3606 void QPainter::drawRects(const QRect *rects, int rectCount)
3607 {
3608 #ifdef QT_DEBUG_DRAW
3609     if (qt_show_painter_debug_output)
3610         printf("QPainter::drawRects(), count=%d\n", rectCount);
3611 #endif
3612     Q_D(QPainter);
3613
3614     if (!d->engine) {
3615         qWarning("QPainter::drawRects: Painter not active");
3616         return;
3617     }
3618
3619     if (rectCount <= 0)
3620         return;
3621
3622     if (d->extended) {
3623         d->extended->drawRects(rects, rectCount);
3624         return;
3625     }
3626
3627     d->updateState(d->state);
3628
3629     if (!d->state->emulationSpecifier) {
3630         d->engine->drawRects(rects, rectCount);
3631         return;
3632     }
3633
3634     if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
3635         && d->state->matrix.type() == QTransform::TxTranslate) {
3636         for (int i=0; i<rectCount; ++i) {
3637             QRectF r(rects[i].x() + d->state->matrix.dx(),
3638                      rects[i].y() + d->state->matrix.dy(),
3639                      rects[i].width(),
3640                      rects[i].height());
3641
3642             d->engine->drawRects(&r, 1);
3643         }
3644     } else {
3645         if (d->state->brushNeedsResolving() || d->state->penNeedsResolving()) {
3646             for (int i=0; i<rectCount; ++i) {
3647                 QPainterPath rectPath;
3648                 rectPath.addRect(rects[i]);
3649                 d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
3650             }
3651         } else {
3652             QPainterPath rectPath;
3653             for (int i=0; i<rectCount; ++i)
3654                 rectPath.addRect(rects[i]);
3655
3656             d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
3657         }
3658     }
3659 }
3660
3661 /*!
3662     \fn void QPainter::drawRects(const QVector<QRectF> &rectangles)
3663     \overload
3664
3665     Draws the given \a rectangles using the current pen and brush.
3666 */
3667
3668 /*!
3669     \fn void QPainter::drawRects(const QVector<QRect> &rectangles)
3670
3671     \overload
3672
3673     Draws the given \a rectangles using the current pen and brush.
3674 */
3675
3676 /*!
3677   \fn void QPainter::drawPoint(const QPointF &position)
3678
3679     Draws a single point at the given \a position using the current
3680     pen's color.
3681
3682     \sa {Coordinate System}
3683 */
3684
3685 /*!
3686     \fn void QPainter::drawPoint(const QPoint &position)
3687     \overload
3688
3689     Draws a single point at the given \a position using the current
3690     pen's color.
3691 */
3692
3693 /*! \fn void QPainter::drawPoint(int x, int y)
3694
3695     \overload
3696
3697     Draws a single point at position (\a x, \a y).
3698 */
3699
3700 /*!
3701     Draws the first \a pointCount points in the array \a points using
3702     the current pen's color.
3703
3704     \sa {Coordinate System}
3705 */
3706 void QPainter::drawPoints(const QPointF *points, int pointCount)
3707 {
3708 #ifdef QT_DEBUG_DRAW
3709     if (qt_show_painter_debug_output)
3710         printf("QPainter::drawPoints(), count=%d\n", pointCount);
3711 #endif
3712     Q_D(QPainter);
3713
3714     if (!d->engine) {
3715         qWarning("QPainter::drawPoints: Painter not active");
3716         return;
3717     }
3718
3719     if (pointCount <= 0)
3720         return;
3721
3722     if (d->extended) {
3723         d->extended->drawPoints(points, pointCount);
3724         return;
3725     }
3726
3727     d->updateState(d->state);
3728
3729     if (!d->state->emulationSpecifier) {
3730         d->engine->drawPoints(points, pointCount);
3731         return;
3732     }
3733
3734     if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
3735         && d->state->matrix.type() == QTransform::TxTranslate) {
3736         // ### use drawPoints function
3737         for (int i=0; i<pointCount; ++i) {
3738             QPointF pt(points[i].x() + d->state->matrix.dx(),
3739                        points[i].y() + d->state->matrix.dy());
3740             d->engine->drawPoints(&pt, 1);
3741         }
3742     } else {
3743         QPen pen = d->state->pen;
3744         bool flat_pen = pen.capStyle() == Qt::FlatCap;
3745         if (flat_pen) {
3746             save();
3747             pen.setCapStyle(Qt::SquareCap);
3748             setPen(pen);
3749         }
3750         QPainterPath path;
3751         for (int i=0; i<pointCount; ++i) {
3752             path.moveTo(points[i].x(), points[i].y());
3753             path.lineTo(points[i].x() + 0.0001, points[i].y());
3754         }
3755         d->draw_helper(path, QPainterPrivate::StrokeDraw);
3756         if (flat_pen)
3757             restore();
3758     }
3759 }
3760
3761 /*!
3762     \overload
3763
3764     Draws the first \a pointCount points in the array \a points using
3765     the current pen's color.
3766 */
3767
3768 void QPainter::drawPoints(const QPoint *points, int pointCount)
3769 {
3770 #ifdef QT_DEBUG_DRAW
3771     if (qt_show_painter_debug_output)
3772         printf("QPainter::drawPoints(), count=%d\n", pointCount);
3773 #endif
3774     Q_D(QPainter);
3775
3776     if (!d->engine) {
3777         qWarning("QPainter::drawPoints: Painter not active");
3778         return;
3779     }
3780
3781     if (pointCount <= 0)
3782         return;
3783
3784     if (d->extended) {
3785         d->extended->drawPoints(points, pointCount);
3786         return;
3787     }
3788
3789     d->updateState(d->state);
3790
3791     if (!d->state->emulationSpecifier) {
3792         d->engine->drawPoints(points, pointCount);
3793         return;
3794     }
3795
3796     if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
3797         && d->state->matrix.type() == QTransform::TxTranslate) {
3798         // ### use drawPoints function
3799         for (int i=0; i<pointCount; ++i) {
3800             QPointF pt(points[i].x() + d->state->matrix.dx(),
3801                        points[i].y() + d->state->matrix.dy());
3802             d->engine->drawPoints(&pt, 1);
3803         }
3804     } else {
3805         QPen pen = d->state->pen;
3806         bool flat_pen = (pen.capStyle() == Qt::FlatCap);
3807         if (flat_pen) {
3808             save();
3809             pen.setCapStyle(Qt::SquareCap);
3810             setPen(pen);
3811         }
3812         QPainterPath path;
3813         for (int i=0; i<pointCount; ++i) {
3814             path.moveTo(points[i].x(), points[i].y());
3815             path.lineTo(points[i].x() + 0.0001, points[i].y());
3816         }
3817         d->draw_helper(path, QPainterPrivate::StrokeDraw);
3818         if (flat_pen)
3819             restore();
3820     }
3821 }
3822
3823 /*!
3824     \fn void QPainter::drawPoints(const QPolygonF &points)
3825
3826     \overload
3827
3828     Draws the points in the vector  \a points.
3829 */
3830
3831 /*!
3832     \fn void QPainter::drawPoints(const QPolygon &points)
3833
3834     \overload
3835
3836     Draws the points in the vector  \a points.
3837 */
3838
3839 /*!
3840     \fn void QPainter::drawPoints(const QPolygon &polygon, int index,
3841     int count)
3842
3843     \overload
3844     \compat
3845
3846     Draws \a count points in the vector \a polygon starting on \a index
3847     using the current pen.
3848
3849     Use drawPoints() combined with QPolygon::constData() instead.
3850
3851     \oldcode
3852         QPainter painter(this);
3853         painter.drawPoints(polygon, index, count);
3854     \newcode
3855         int pointCount = (count == -1) ?  polygon.size() - index : count;
3856
3857         QPainter painter(this);
3858         painter.drawPoints(polygon.constData() + index, pointCount);
3859     \endcode
3860 */
3861
3862 /*!
3863     Sets the background mode of the painter to the given \a mode
3864
3865     Qt::TransparentMode (the default) draws stippled lines and text
3866     without setting the background pixels.  Qt::OpaqueMode fills these
3867     space with the current background color.
3868
3869     Note that in order to draw a bitmap or pixmap transparently, you
3870     must use QPixmap::setMask().
3871
3872     \sa backgroundMode(), setBackground(),
3873     {QPainter#Settings}{Settings}
3874 */
3875
3876 void QPainter::setBackgroundMode(Qt::BGMode mode)
3877 {
3878 #ifdef QT_DEBUG_DRAW
3879     if (qt_show_painter_debug_output)
3880         printf("QPainter::setBackgroundMode(), mode=%d\n", mode);
3881 #endif
3882
3883     Q_D(QPainter);
3884     if (!d->engine) {
3885         qWarning("QPainter::setBackgroundMode: Painter not active");
3886         return;
3887     }
3888     if (d->state->bgMode == mode)
3889         return;
3890
3891     d->state->bgMode = mode;
3892     if (d->extended) {
3893         d->checkEmulation();
3894     } else {
3895         d->state->dirtyFlags |= QPaintEngine::DirtyBackgroundMode;
3896     }
3897 }
3898
3899 /*!
3900     Returns the current background mode.
3901
3902     \sa setBackgroundMode(), {QPainter#Settings}{Settings}
3903 */
3904 Qt::BGMode QPainter::backgroundMode() const
3905 {
3906     Q_D(const QPainter);
3907     if (!d->engine) {
3908         qWarning("QPainter::backgroundMode: Painter not active");
3909         return Qt::TransparentMode;
3910     }
3911     return d->state->bgMode;
3912 }
3913
3914
3915 /*!
3916     \overload
3917
3918     Sets the painter's pen to have style Qt::SolidLine, width 0 and the
3919     specified \a color.
3920 */
3921
3922 void QPainter::setPen(const QColor &color)
3923 {
3924 #ifdef QT_DEBUG_DRAW
3925     if (qt_show_painter_debug_output)
3926         printf("QPainter::setPen(), color=%04x\n", color.rgb());
3927 #endif
3928     Q_D(QPainter);
3929     if (!d->engine) {
3930         qWarning("QPainter::setPen: Painter not active");
3931         return;
3932     }
3933
3934     if (d->state->pen.style() == Qt::SolidLine
3935         && d->state->pen.widthF() == 0
3936         && d->state->pen.isSolid()
3937         && d->state->pen.color() == color)
3938         return;
3939
3940     QPen pen(color.isValid() ? color : QColor(Qt::black), 0, Qt::SolidLine);
3941
3942     d->state->pen = pen;
3943     if (d->extended)
3944         d->extended->penChanged();
3945     else
3946         d->state->dirtyFlags |= QPaintEngine::DirtyPen;
3947 }
3948
3949 /*!
3950     Sets the painter's pen to be the given \a pen.
3951
3952     The \a pen defines how to draw lines and outlines, and it also
3953     defines the text color.
3954
3955     \sa pen(), {QPainter#Settings}{Settings}
3956 */
3957
3958 void QPainter::setPen(const QPen &pen)
3959 {
3960
3961 #ifdef QT_DEBUG_DRAW
3962     if (qt_show_painter_debug_output)
3963         printf("QPainter::setPen(), color=%04x, (brushStyle=%d) style=%d, cap=%d, join=%d\n",
3964            pen.color().rgb(), pen.brush().style(), pen.style(), pen.capStyle(), pen.joinStyle());
3965 #endif
3966     Q_D(QPainter);
3967     if (!d->engine) {
3968         qWarning("QPainter::setPen: Painter not active");
3969         return;
3970     }
3971
3972     if (d->state->pen == pen)
3973         return;
3974
3975     d->state->pen = pen;
3976
3977     if (d->extended) {
3978         d->checkEmulation();
3979         d->extended->penChanged();
3980         return;
3981     }
3982
3983     d->state->dirtyFlags |= QPaintEngine::DirtyPen;
3984 }
3985
3986 /*!
3987     \overload
3988
3989     Sets the painter's pen to have the given \a style, width 0 and
3990     black color.
3991 */
3992
3993 void QPainter::setPen(Qt::PenStyle style)
3994 {
3995     Q_D(QPainter);
3996     if (!d->engine) {
3997         qWarning("QPainter::setPen: Painter not active");
3998         return;
3999     }
4000
4001     if (d->state->pen.style() == style
4002         && (style == Qt::NoPen || (d->state->pen.widthF() == 0
4003                                    && d->state->pen.isSolid()
4004                                    && d->state->pen.color() == QColor(Qt::black))))
4005         return;
4006
4007     // QPen(Qt::NoPen) is to avoid creating QPenData, including its brush (from the color)
4008     // Note that this works well as long as QPen(Qt::NoPen) returns a black, zero-width pen
4009     d->state->pen = (style == Qt::NoPen) ? QPen(Qt::NoPen) : QPen(Qt::black, 0, style);
4010
4011     if (d->extended)
4012         d->extended->penChanged();
4013     else
4014         d->state->dirtyFlags |= QPaintEngine::DirtyPen;
4015
4016 }
4017
4018 /*!
4019     Returns the painter's current pen.
4020
4021     \sa setPen(), {QPainter#Settings}{Settings}
4022 */
4023
4024 const QPen &QPainter::pen() const
4025 {
4026     Q_D(const QPainter);
4027     if (!d->engine) {
4028         qWarning("QPainter::pen: Painter not active");
4029         return d->fakeState()->pen;
4030     }
4031     return d->state->pen;
4032 }
4033
4034
4035 /*!
4036     Sets the painter's brush to the given \a brush.
4037
4038     The painter's brush defines how shapes are filled.
4039
4040     \sa brush(), {QPainter#Settings}{Settings}
4041 */
4042
4043 void QPainter::setBrush(const QBrush &brush)
4044 {
4045 #ifdef QT_DEBUG_DRAW
4046     if (qt_show_painter_debug_output)
4047         printf("QPainter::setBrush(), color=%04x, style=%d\n", brush.color().rgb(), brush.style());
4048 #endif
4049     Q_D(QPainter);
4050     if (!d->engine) {
4051         qWarning("QPainter::setBrush: Painter not active");
4052         return;
4053     }
4054
4055     if (d->state->brush.d == brush.d)
4056         return;
4057
4058     if (d->extended) {
4059         d->state->brush = brush;
4060         d->checkEmulation();
4061         d->extended->brushChanged();
4062         return;
4063     }
4064
4065     d->state->brush = brush;
4066     d->state->dirtyFlags |= QPaintEngine::DirtyBrush;
4067 }
4068
4069
4070 /*!
4071     \overload
4072
4073     Sets the painter's brush to black color and the specified \a
4074     style.
4075 */
4076
4077 void QPainter::setBrush(Qt::BrushStyle style)
4078 {
4079     Q_D(QPainter);
4080     if (!d->engine) {
4081         qWarning("QPainter::setBrush: Painter not active");
4082         return;
4083     }
4084     if (d->state->brush.style() == style &&
4085         (style == Qt::NoBrush
4086          || (style == Qt::SolidPattern && d->state->brush.color() == QColor(0, 0, 0))))
4087         return;
4088     d->state->brush = QBrush(Qt::black, style);
4089     if (d->extended)
4090         d->extended->brushChanged();
4091     else
4092         d->state->dirtyFlags |= QPaintEngine::DirtyBrush;
4093 }
4094
4095 /*!
4096     Returns the painter's current brush.
4097
4098     \sa QPainter::setBrush(), {QPainter#Settings}{Settings}
4099 */
4100
4101 const QBrush &QPainter::brush() const
4102 {
4103     Q_D(const QPainter);
4104     if (!d->engine) {
4105         qWarning("QPainter::brush: Painter not active");
4106         return d->fakeState()->brush;
4107     }
4108     return d->state->brush;
4109 }
4110
4111 /*!
4112     \fn void QPainter::setBackground(const QBrush &brush)
4113
4114     Sets the background brush of the painter to the given \a brush.
4115
4116     The background brush is the brush that is filled in when drawing
4117     opaque text, stippled lines and bitmaps. The background brush has
4118     no effect in transparent background mode (which is the default).
4119
4120     \sa background(), setBackgroundMode(),
4121     {QPainter#Settings}{Settings}
4122 */
4123
4124 void QPainter::setBackground(const QBrush &bg)
4125 {
4126 #ifdef QT_DEBUG_DRAW
4127     if (qt_show_painter_debug_output)
4128         printf("QPainter::setBackground(), color=%04x, style=%d\n", bg.color().rgb(), bg.style());
4129 #endif
4130
4131     Q_D(QPainter);
4132     if (!d->engine) {
4133         qWarning("QPainter::setBackground: Painter not active");
4134         return;
4135     }
4136     d->state->bgBrush = bg;
4137     if (!d->extended)
4138         d->state->dirtyFlags |= QPaintEngine::DirtyBackground;
4139 }
4140
4141 /*!
4142     Sets the painter's font to the given \a font.
4143
4144     This font is used by subsequent drawText() functions. The text
4145     color is the same as the pen color.
4146
4147     If you set a font that isn't available, Qt finds a close match.
4148     font() will return what you set using setFont() and fontInfo() returns the
4149     font actually being used (which may be the same).
4150
4151     \sa font(), drawText(), {QPainter#Settings}{Settings}
4152 */
4153
4154 void QPainter::setFont(const QFont &font)
4155 {
4156     Q_D(QPainter);
4157
4158 #ifdef QT_DEBUG_DRAW
4159     if (qt_show_painter_debug_output)
4160         printf("QPainter::setFont(), family=%s, pointSize=%d\n", font.family().toLatin1().constData(), font.pointSize());
4161 #endif
4162
4163     if (!d->engine) {
4164         qWarning("QPainter::setFont: Painter not active");
4165         return;
4166     }
4167
4168     d->state->font = QFont(font.resolve(d->state->deviceFont), device());
4169     if (!d->extended)
4170         d->state->dirtyFlags |= QPaintEngine::DirtyFont;
4171 }
4172
4173 /*!
4174     Returns the currently set font used for drawing text.
4175
4176     \sa setFont(), drawText(), {QPainter#Settings}{Settings}
4177 */
4178 const QFont &QPainter::font() const
4179 {
4180     Q_D(const QPainter);
4181     if (!d->engine) {
4182         qWarning("QPainter::font: Painter not active");
4183         return d->fakeState()->font;
4184     }
4185     return d->state->font;
4186 }
4187
4188 /*!
4189     \since 4.4
4190
4191     Draws the given rectangle \a rect with rounded corners.
4192
4193     The \a xRadius and \a yRadius arguments specify the radii
4194     of the ellipses defining the corners of the rounded rectangle.
4195     When \a mode is Qt::RelativeSize, \a xRadius and
4196     \a yRadius are specified in percentage of half the rectangle's
4197     width and height respectively, and should be in the range
4198     0.0 to 100.0.
4199
4200     A filled rectangle has a size of rect.size(). A stroked rectangle
4201     has a size of rect.size() plus the pen width.
4202
4203     \table 100%
4204     \row
4205     \o \inlineimage qpainter-roundrect.png
4206     \o
4207     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 8
4208     \endtable
4209
4210     \sa drawRect(), QPen
4211 */
4212 void QPainter::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode)
4213 {
4214 #ifdef QT_DEBUG_DRAW
4215     if (qt_show_painter_debug_output)
4216         printf("QPainter::drawRoundedRect(), [%.2f,%.2f,%.2f,%.2f]\n", rect.x(), rect.y(), rect.width(), rect.height());
4217 #endif
4218     Q_D(QPainter);
4219
4220     if (!d->engine)
4221         return;
4222
4223     if (xRadius <= 0 || yRadius <= 0) {             // draw normal rectangle
4224         drawRect(rect);
4225         return;
4226     }
4227
4228     if (d->extended) {
4229         d->extended->drawRoundedRect(rect, xRadius, yRadius, mode);
4230         return;
4231     }
4232
4233     QPainterPath path;
4234     path.addRoundedRect(rect, xRadius, yRadius, mode);
4235     drawPath(path);
4236 }
4237
4238 /*!
4239     \fn void QPainter::drawRoundedRect(const QRect &rect, qreal xRadius, qreal yRadius,
4240                                        Qt::SizeMode mode = Qt::AbsoluteSize);
4241     \since 4.4
4242     \overload
4243
4244     Draws the given rectangle \a rect with rounded corners.
4245 */
4246
4247 /*!
4248     \fn void QPainter::drawRoundedRect(int x, int y, int w, int h, qreal xRadius, qreal yRadius,
4249                                        Qt::SizeMode mode = Qt::AbsoluteSize);
4250     \since 4.4
4251     \overload
4252
4253     Draws the given rectangle \a x, \a y, \a w, \a h with rounded corners.
4254 */
4255
4256 /*!
4257     \obsolete
4258
4259     Draws a rectangle \a r with rounded corners.
4260
4261     The \a xRnd and \a yRnd arguments specify how rounded the corners
4262     should be. 0 is angled corners, 99 is maximum roundedness.
4263
4264     A filled rectangle has a size of r.size(). A stroked rectangle
4265     has a size of r.size() plus the pen width.
4266
4267     \sa drawRoundedRect()
4268 */
4269 void QPainter::drawRoundRect(const QRectF &r, int xRnd, int yRnd)
4270 {
4271     drawRoundedRect(r, xRnd, yRnd, Qt::RelativeSize);
4272 }
4273
4274
4275 /*!
4276     \fn void QPainter::drawRoundRect(const QRect &r, int xRnd = 25, int yRnd = 25)
4277
4278     \overload
4279     \obsolete
4280
4281     Draws the rectangle \a r with rounded corners.
4282 */
4283
4284 /*!
4285     \obsolete
4286
4287     \fn QPainter::drawRoundRect(int x, int y, int w, int h, int xRnd, int yRnd)
4288
4289     \overload
4290
4291     Draws the rectangle \a x, \a y, \a w, \a h with rounded corners.
4292 */
4293
4294 /*!
4295     \fn void QPainter::drawEllipse(const QRectF &rectangle)
4296
4297     Draws the ellipse defined by the given \a rectangle.
4298
4299     A filled ellipse has a size of \a{rectangle}.\l
4300     {QRect::size()}{size()}. A stroked ellipse has a size of
4301     \a{rectangle}.\l {QRect::size()}{size()} plus the pen width.
4302
4303     \table 100%
4304     \row
4305     \o \inlineimage qpainter-ellipse.png
4306     \o
4307     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 9
4308     \endtable
4309
4310     \sa drawPie(), {Coordinate System}
4311 */
4312 void QPainter::drawEllipse(const QRectF &r)
4313 {
4314 #ifdef QT_DEBUG_DRAW
4315     if (qt_show_painter_debug_output)
4316         printf("QPainter::drawEllipse(), [%.2f,%.2f,%.2f,%.2f]\n", r.x(), r.y(), r.width(), r.height());
4317 #endif
4318     Q_D(QPainter);
4319
4320     if (!d->engine)
4321         return;
4322
4323     QRectF rect(r.normalized());
4324
4325     if (d->extended) {
4326         d->extended->drawEllipse(rect);
4327         return;
4328     }
4329
4330     d->updateState(d->state);
4331     if (d->state->emulationSpecifier) {
4332         if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
4333             && d->state->matrix.type() == QTransform::TxTranslate) {
4334             rect.translate(QPointF(d->state->matrix.dx(), d->state->matrix.dy()));
4335         } else {
4336             QPainterPath path;
4337             path.addEllipse(rect);
4338             d->draw_helper(path, QPainterPrivate::StrokeAndFillDraw);
4339             return;
4340         }
4341     }
4342
4343     d->engine->drawEllipse(rect);
4344 }
4345
4346 /*!
4347     \fn QPainter::drawEllipse(const QRect &rectangle)
4348
4349     \overload
4350
4351     Draws the ellipse defined by the given \a rectangle.
4352 */
4353 void QPainter::drawEllipse(const QRect &r)
4354 {
4355 #ifdef QT_DEBUG_DRAW
4356     if (qt_show_painter_debug_output)
4357         printf("QPainter::drawEllipse(), [%d,%d,%d,%d]\n", r.x(), r.y(), r.width(), r.height());
4358 #endif
4359     Q_D(QPainter);
4360
4361     if (!d->engine)
4362         return;
4363
4364     QRect rect(r.normalized());
4365
4366     if (d->extended) {
4367         d->extended->drawEllipse(rect);
4368         return;
4369     }
4370
4371     d->updateState(d->state);
4372
4373     if (d->state->emulationSpecifier) {
4374         if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
4375             && d->state->matrix.type() == QTransform::TxTranslate) {
4376             rect.translate(QPoint(qRound(d->state->matrix.dx()), qRound(d->state->matrix.dy())));
4377         } else {
4378             QPainterPath path;
4379             path.addEllipse(rect);
4380             d->draw_helper(path, QPainterPrivate::StrokeAndFillDraw);
4381             return;
4382         }
4383     }
4384
4385     d->engine->drawEllipse(rect);
4386 }
4387
4388 /*!
4389     \fn QPainter::drawEllipse(int x, int y, int width, int height)
4390
4391     \overload
4392
4393     Draws the ellipse defined by the rectangle beginning at (\a{x},
4394     \a{y}) with the given \a width and \a height.
4395 */
4396
4397 /*!
4398     \since 4.4
4399
4400     \fn QPainter::drawEllipse(const QPointF &center, qreal rx, qreal ry)
4401
4402     \overload
4403
4404     Draws the ellipse positioned at \a{center} with radii \a{rx} and \a{ry}.
4405 */
4406
4407 /*!
4408     \since 4.4
4409
4410     \fn QPainter::drawEllipse(const QPoint &center, int rx, int ry)
4411
4412     \overload
4413
4414     Draws the ellipse positioned at \a{center} with radii \a{rx} and \a{ry}.
4415 */
4416
4417 /*!
4418     \fn void QPainter::drawArc(const QRectF &rectangle, int startAngle, int spanAngle)
4419
4420     Draws the arc defined by the given \a rectangle, \a startAngle and
4421     \a spanAngle.
4422
4423     The \a startAngle and \a spanAngle must be specified in 1/16th of
4424     a degree, i.e. a full circle equals 5760 (16 * 360). Positive
4425     values for the angles mean counter-clockwise while negative values
4426     mean the clockwise direction. Zero degrees is at the 3 o'clock
4427     position.
4428
4429     \table 100%
4430     \row
4431     \o \inlineimage qpainter-arc.png
4432     \o
4433     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 10
4434     \endtable
4435
4436     \sa drawPie(), drawChord(), {Coordinate System}
4437 */
4438
4439 void QPainter::drawArc(const QRectF &r, int a, int alen)
4440 {
4441 #ifdef QT_DEBUG_DRAW
4442     if (qt_show_painter_debug_output)
4443         printf("QPainter::drawArc(), [%.2f,%.2f,%.2f,%.2f], angle=%d, sweep=%d\n",
4444            r.x(), r.y(), r.width(), r.height(), a/16, alen/16);
4445 #endif
4446     Q_D(QPainter);
4447
4448     if (!d->engine)
4449         return;
4450
4451     QRectF rect = r.normalized();
4452
4453     QPainterPath path;
4454     path.arcMoveTo(rect, a/16.0);
4455     path.arcTo(rect, a/16.0, alen/16.0);
4456     strokePath(path, d->state->pen);
4457 }
4458
4459 /*! \fn void QPainter::drawArc(const QRect &rectangle, int startAngle,
4460                                int spanAngle)
4461
4462     \overload
4463
4464     Draws the arc defined by the given \a rectangle, \a startAngle and
4465     \a spanAngle.
4466 */
4467
4468 /*!
4469     \fn void QPainter::drawArc(int x, int y, int width, int height,
4470                                int startAngle, int spanAngle)
4471
4472     \overload
4473
4474     Draws the arc defined by the rectangle beginning at (\a x, \a y)
4475     with the specified \a width and \a height, and the given \a
4476     startAngle and \a spanAngle.
4477 */
4478
4479 /*!
4480     \fn void QPainter::drawPie(const QRectF &rectangle, int startAngle, int spanAngle)
4481
4482     Draws a pie defined by the given \a rectangle, \a startAngle and
4483     and \a spanAngle.
4484
4485     The pie is filled with the current brush().
4486
4487     The startAngle and spanAngle must be specified in 1/16th of a
4488     degree, i.e. a full circle equals 5760 (16 * 360). Positive values
4489     for the angles mean counter-clockwise while negative values mean
4490     the clockwise direction. Zero degrees is at the 3 o'clock
4491     position.
4492
4493     \table 100%
4494     \row
4495     \o \inlineimage qpainter-pie.png
4496     \o
4497     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 11
4498     \endtable
4499
4500     \sa drawEllipse(), drawChord(), {Coordinate System}
4501 */
4502 void QPainter::drawPie(const QRectF &r, int a, int alen)
4503 {
4504 #ifdef QT_DEBUG_DRAW
4505     if (qt_show_painter_debug_output)
4506         printf("QPainter::drawPie(), [%.2f,%.2f,%.2f,%.2f], angle=%d, sweep=%d\n",
4507            r.x(), r.y(), r.width(), r.height(), a/16, alen/16);
4508 #endif
4509     Q_D(QPainter);
4510
4511     if (!d->engine)
4512         return;
4513
4514     if (a > (360*16)) {
4515         a = a % (360*16);
4516     } else if (a < 0) {
4517         a = a % (360*16);
4518         if (a < 0) a += (360*16);
4519     }
4520
4521     QRectF rect = r.normalized();
4522
4523     QPainterPath path;
4524     path.moveTo(rect.center());
4525     path.arcTo(rect.x(), rect.y(), rect.width(), rect.height(), a/16.0, alen/16.0);
4526     path.closeSubpath();
4527     drawPath(path);
4528
4529 }
4530
4531 /*!
4532     \fn void QPainter::drawPie(const QRect &rectangle, int startAngle, int spanAngle)
4533     \overload
4534
4535     Draws a pie defined by the given \a rectangle, \a startAngle and
4536     and \a spanAngle.
4537 */
4538
4539 /*!
4540     \fn void QPainter::drawPie(int x, int y, int width, int height, int
4541     startAngle, int spanAngle)
4542
4543     \overload
4544
4545     Draws the pie defined by the rectangle beginning at (\a x, \a y) with
4546     the specified \a width and \a height, and the given \a startAngle and
4547     \a spanAngle.
4548 */
4549
4550 /*!
4551     \fn void QPainter::drawChord(const QRectF &rectangle, int startAngle, int spanAngle)
4552
4553     Draws the chord defined by the given \a rectangle, \a startAngle and
4554     \a spanAngle.  The chord is filled with the current brush().
4555
4556     The startAngle and spanAngle must be specified in 1/16th of a
4557     degree, i.e. a full circle equals 5760 (16 * 360). Positive values
4558     for the angles mean counter-clockwise while negative values mean
4559     the clockwise direction. Zero degrees is at the 3 o'clock
4560     position.
4561
4562     \table 100%
4563     \row
4564     \o \inlineimage qpainter-chord.png
4565     \o
4566     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 12
4567     \endtable
4568
4569     \sa drawArc(), drawPie(), {Coordinate System}
4570 */
4571 void QPainter::drawChord(const QRectF &r, int a, int alen)
4572 {
4573 #ifdef QT_DEBUG_DRAW
4574     if (qt_show_painter_debug_output)
4575         printf("QPainter::drawChord(), [%.2f,%.2f,%.2f,%.2f], angle=%d, sweep=%d\n",
4576            r.x(), r.y(), r.width(), r.height(), a/16, alen/16);
4577 #endif
4578     Q_D(QPainter);
4579
4580     if (!d->engine)
4581         return;
4582
4583     QRectF rect = r.normalized();
4584
4585     QPainterPath path;
4586     path.arcMoveTo(rect, a/16.0);
4587     path.arcTo(rect, a/16.0, alen/16.0);
4588     path.closeSubpath();
4589     drawPath(path);
4590 }
4591 /*!
4592     \fn void QPainter::drawChord(const QRect &rectangle, int startAngle, int spanAngle)
4593
4594     \overload
4595
4596     Draws the chord defined by the given \a rectangle, \a startAngle and
4597     \a spanAngle.
4598 */
4599
4600 /*!
4601     \fn void QPainter::drawChord(int x, int y, int width, int height, int
4602     startAngle, int spanAngle)
4603
4604     \overload
4605
4606    Draws the chord defined by the rectangle beginning at (\a x, \a y)
4607    with the specified \a width and \a height, and the given \a
4608    startAngle and \a spanAngle.
4609 */
4610
4611 #ifdef QT3_SUPPORT
4612 /*!
4613     \fn void QPainter::drawLineSegments(const QPolygon &polygon, int
4614     index, int count)
4615
4616     Draws \a count separate lines from points defined by the \a
4617     polygon, starting at \a{polygon}\e{[index]} (\a index defaults to
4618     0). If \a count is -1 (the default) all points until the end of
4619     the array are used.
4620
4621     Use drawLines() combined with QPolygon::constData() instead.
4622
4623     \oldcode
4624         QPainter painter(this);
4625         painter.drawLineSegments(polygon, index, count);
4626     \newcode
4627         int lineCount = (count == -1) ?  (polygon.size() - index) / 2  : count;
4628
4629         QPainter painter(this);
4630         painter.drawLines(polygon.constData() + index * 2, lineCount);
4631     \endcode
4632 */
4633
4634 void QPainter::drawLineSegments(const QPolygon &a, int index, int nlines)
4635 {
4636 #ifdef QT_DEBUG_DRAW
4637     if (qt_show_painter_debug_output)
4638         printf("QPainter::drawLineSegments(), count=%d\n", a.size()/2);
4639 #endif
4640     Q_D(QPainter);
4641
4642     if (!d->engine)
4643         return;
4644
4645     if (nlines < 0)
4646         nlines = a.size()/2 - index/2;
4647     if (index + nlines*2 > (int)a.size())
4648         nlines = (a.size() - index)/2;
4649     if (nlines < 1 || index < 0)
4650         return;
4651
4652     if (d->extended) {
4653         // FALCON: Use QVectorPath
4654         QVector<QLineF> lines;
4655         for (int i=index; i<index + nlines*2; i+=2)
4656             lines << QLineF(a.at(i), a.at(i+1));
4657         d->extended->drawLines(lines.data(), lines.size());
4658         return;
4659     }
4660
4661     d->updateState(d->state);
4662
4663     QVector<QLineF> lines;
4664     if (d->state->emulationSpecifier) {
4665         if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
4666             && d->state->matrix.type() == QTransform::TxTranslate) {
4667             QPointF offset(d->state->matrix.dx(), d->state->matrix.dy());
4668             for (int i=index; i<index + nlines*2; i+=2)
4669                 lines << QLineF(a.at(i) + offset, a.at(i+1) + offset);
4670         } else {
4671             QPainterPath linesPath;
4672             for (int i=index; i<index + nlines*2; i+=2) {
4673                 linesPath.moveTo(a.at(i));
4674                 linesPath.lineTo(a.at(i+1));
4675             }
4676             d->draw_helper(linesPath, QPainterPrivate::StrokeDraw);
4677             return;
4678         }
4679     } else {
4680         for (int i=index; i<index + nlines*2; i+=2)
4681             lines << QLineF(a.at(i), a.at(i+1));
4682     }
4683
4684     d->engine->drawLines(lines.data(), lines.size());
4685 }
4686 #endif // QT3_SUPPORT
4687
4688 /*!
4689     Draws the first \a lineCount lines in the array \a lines
4690     using the current pen.
4691
4692     \sa drawLine(), drawPolyline()
4693 */
4694 void QPainter::drawLines(const QLineF *lines, int lineCount)
4695 {
4696 #ifdef QT_DEBUG_DRAW
4697     if (qt_show_painter_debug_output)
4698         printf("QPainter::drawLines(), line count=%d\n", lineCount);
4699 #endif
4700
4701     Q_D(QPainter);
4702
4703     if (!d->engine || lineCount < 1)
4704         return;
4705
4706     if (d->extended) {
4707         d->extended->drawLines(lines, lineCount);
4708         return;
4709     }
4710
4711     d->updateState(d->state);
4712
4713     uint lineEmulation = line_emulation(d->state->emulationSpecifier);
4714
4715     if (lineEmulation) {
4716         if (lineEmulation == QPaintEngine::PrimitiveTransform
4717             && d->state->matrix.type() == QTransform::TxTranslate) {
4718             for (int i = 0; i < lineCount; ++i) {
4719                 QLineF line = lines[i];
4720                 line.translate(d->state->matrix.dx(), d->state->matrix.dy());
4721                 d->engine->drawLines(&line, 1);
4722             }
4723         } else {
4724             QPainterPath linePath;
4725             for (int i = 0; i < lineCount; ++i) {
4726                 linePath.moveTo(lines[i].p1());
4727                 linePath.lineTo(lines[i].p2());
4728             }
4729             d->draw_helper(linePath, QPainterPrivate::StrokeDraw);
4730         }
4731         return;
4732     }
4733     d->engine->drawLines(lines, lineCount);
4734 }
4735
4736 /*!
4737     \fn void QPainter::drawLines(const QLine *lines, int lineCount)
4738     \overload
4739
4740     Draws the first \a lineCount lines in the array \a lines
4741     using the current pen.
4742 */
4743 void QPainter::drawLines(const QLine *lines, int lineCount)
4744 {
4745 #ifdef QT_DEBUG_DRAW
4746     if (qt_show_painter_debug_output)
4747         printf("QPainter::drawLine(), line count=%d\n", lineCount);
4748 #endif
4749
4750     Q_D(QPainter);
4751
4752     if (!d->engine || lineCount < 1)
4753         return;
4754
4755     if (d->extended) {
4756         d->extended->drawLines(lines, lineCount);
4757         return;
4758     }
4759
4760     d->updateState(d->state);
4761
4762     uint lineEmulation = line_emulation(d->state->emulationSpecifier);
4763
4764     if (lineEmulation) {
4765         if (lineEmulation == QPaintEngine::PrimitiveTransform
4766             && d->state->matrix.type() == QTransform::TxTranslate) {
4767             for (int i = 0; i < lineCount; ++i) {
4768                 QLineF line = lines[i];
4769                 line.translate(d->state->matrix.dx(), d->state->matrix.dy());
4770                 d->engine->drawLines(&line, 1);
4771             }
4772         } else {
4773             QPainterPath linePath;
4774             for (int i = 0; i < lineCount; ++i) {
4775                 linePath.moveTo(lines[i].p1());
4776                 linePath.lineTo(lines[i].p2());
4777             }
4778             d->draw_helper(linePath, QPainterPrivate::StrokeDraw);
4779         }
4780         return;
4781     }
4782     d->engine->drawLines(lines, lineCount);
4783 }
4784
4785 /*!
4786     \overload
4787
4788     Draws the first \a lineCount lines in the array \a pointPairs
4789     using the current pen.  The lines are specified as pairs of points
4790     so the number of entries in \a pointPairs must be at least \a
4791     lineCount * 2.
4792 */
4793 void QPainter::drawLines(const QPointF *pointPairs, int lineCount)
4794 {
4795     Q_ASSERT(sizeof(QLineF) == 2*sizeof(QPointF));
4796
4797     drawLines((QLineF*)pointPairs, lineCount);
4798 }
4799
4800 /*!
4801     \overload
4802
4803     Draws the first \a lineCount lines in the array \a pointPairs
4804     using the current pen.
4805 */
4806 void QPainter::drawLines(const QPoint *pointPairs, int lineCount)
4807 {
4808     Q_ASSERT(sizeof(QLine) == 2*sizeof(QPoint));
4809
4810     drawLines((QLine*)pointPairs, lineCount);
4811 }
4812
4813
4814 /*!
4815     \fn void QPainter::drawLines(const QVector<QPointF> &pointPairs)
4816     \overload
4817
4818     Draws a line for each pair of points in the vector \a pointPairs
4819     using the current pen. If there is an odd number of points in the
4820     array, the last point will be ignored.
4821 */
4822
4823 /*!
4824     \fn void QPainter::drawLines(const QVector<QPoint> &pointPairs)
4825     \overload
4826
4827     Draws a line for each pair of points in the vector \a pointPairs
4828     using the current pen.
4829 */
4830
4831 /*!
4832     \fn void QPainter::drawLines(const QVector<QLineF> &lines)
4833     \overload
4834
4835     Draws the set of lines defined by the list \a lines using the
4836     current pen and brush.
4837 */
4838
4839 /*!
4840     \fn void QPainter::drawLines(const QVector<QLine> &lines)
4841     \overload
4842
4843     Draws the set of lines defined by the list \a lines using the
4844     current pen and brush.
4845 */
4846
4847 /*!
4848     Draws the polyline defined by the first \a pointCount points in \a
4849     points using the current pen.
4850
4851     Note that unlike the drawPolygon() function the last point is \e
4852     not connected to the first, neither is the polyline filled.
4853
4854     \table 100%
4855     \row
4856     \o
4857     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 13
4858     \endtable
4859
4860     \sa drawLines(), drawPolygon(), {Coordinate System}
4861 */
4862 void QPainter::drawPolyline(const QPointF *points, int pointCount)
4863 {
4864 #ifdef QT_DEBUG_DRAW
4865     if (qt_show_painter_debug_output)
4866         printf("QPainter::drawPolyline(), count=%d\n", pointCount);
4867 #endif
4868     Q_D(QPainter);
4869
4870     if (!d->engine || pointCount < 2)
4871         return;
4872
4873     if (d->extended) {
4874         d->extended->drawPolygon(points, pointCount, QPaintEngine::PolylineMode);
4875         return;
4876     }
4877
4878     d->updateState(d->state);
4879
4880     uint lineEmulation = line_emulation(d->state->emulationSpecifier);
4881
4882     if (lineEmulation) {
4883         // ###
4884 //         if (lineEmulation == QPaintEngine::PrimitiveTransform
4885 //             && d->state->matrix.type() == QTransform::TxTranslate) {
4886 //         } else {
4887         QPainterPath polylinePath(points[0]);
4888         for (int i=1; i<pointCount; ++i)
4889             polylinePath.lineTo(points[i]);
4890         d->draw_helper(polylinePath, QPainterPrivate::StrokeDraw);
4891 //         }
4892     } else {
4893         d->engine->drawPolygon(points, pointCount, QPaintEngine::PolylineMode);
4894     }
4895 }
4896
4897 /*!
4898     \overload
4899
4900     Draws the polyline defined by the first \a pointCount points in \a
4901     points using the current pen.
4902  */
4903 void QPainter::drawPolyline(const QPoint *points, int pointCount)
4904 {
4905 #ifdef QT_DEBUG_DRAW
4906     if (qt_show_painter_debug_output)
4907         printf("QPainter::drawPolyline(), count=%d\n", pointCount);
4908 #endif
4909     Q_D(QPainter);
4910
4911     if (!d->engine || pointCount < 2)
4912         return;
4913
4914     if (d->extended) {
4915         d->extended->drawPolygon(points, pointCount, QPaintEngine::PolylineMode);
4916         return;
4917     }
4918
4919     d->updateState(d->state);
4920
4921     uint lineEmulation = line_emulation(d->state->emulationSpecifier);
4922
4923     if (lineEmulation) {
4924         // ###
4925 //         if (lineEmulation == QPaintEngine::PrimitiveTransform
4926 //             && d->state->matrix.type() == QTransform::TxTranslate) {
4927 //         } else {
4928         QPainterPath polylinePath(points[0]);
4929         for (int i=1; i<pointCount; ++i)
4930             polylinePath.lineTo(points[i]);
4931         d->draw_helper(polylinePath, QPainterPrivate::StrokeDraw);
4932 //         }
4933     } else {
4934         d->engine->drawPolygon(points, pointCount, QPaintEngine::PolylineMode);
4935     }
4936 }
4937
4938 /*!
4939     \fn void QPainter::drawPolyline(const QPolygon &polygon, int index, int
4940     count)
4941
4942     \overload
4943     \compat
4944
4945     Draws the polyline defined by the \a count lines of the given \a
4946     polygon starting at \a index (\a index defaults to 0).
4947
4948     Use drawPolyline() combined with QPolygon::constData() instead.
4949
4950     \oldcode
4951         QPainter painter(this);
4952         painter.drawPolyline(polygon, index, count);
4953     \newcode
4954         int pointCount = (count == -1) ?  polygon.size() - index : count;
4955
4956         QPainter painter(this);
4957         painter.drawPolyline(polygon.constData() + index, pointCount);
4958     \endcode
4959 */
4960
4961 /*!
4962     \fn void QPainter::drawPolyline(const QPolygonF &points)
4963
4964     \overload
4965
4966     Draws the polyline defined by the given \a points using the
4967     current pen.
4968 */
4969
4970 /*!
4971     \fn void QPainter::drawPolyline(const QPolygon &points)
4972
4973     \overload
4974
4975     Draws the polyline defined by the given \a points using the
4976     current pen.
4977 */
4978
4979 /*!
4980     Draws the polygon defined by the first \a pointCount points in the
4981     array \a points using the current pen and brush.
4982
4983     \table 100%
4984     \row
4985     \o \inlineimage qpainter-polygon.png
4986     \o
4987     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 14
4988     \endtable
4989
4990     The first point is implicitly connected to the last point, and the
4991     polygon is filled with the current brush().
4992
4993     If \a fillRule is Qt::WindingFill, the polygon is filled using the
4994     winding fill algorithm.  If \a fillRule is Qt::OddEvenFill, the
4995     polygon is filled using the odd-even fill algorithm. See
4996     \l{Qt::FillRule} for a more detailed description of these fill
4997     rules.
4998
4999     \sa  drawConvexPolygon(), drawPolyline(), {Coordinate System}
5000 */
5001 void QPainter::drawPolygon(const QPointF *points, int pointCount, Qt::FillRule fillRule)
5002 {
5003 #ifdef QT_DEBUG_DRAW
5004     if (qt_show_painter_debug_output)
5005         printf("QPainter::drawPolygon(), count=%d\n", pointCount);
5006 #endif
5007
5008     Q_D(QPainter);
5009
5010     if (!d->engine || pointCount < 2)
5011         return;
5012
5013     if (d->extended) {
5014         d->extended->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
5015         return;
5016     }
5017
5018     d->updateState(d->state);
5019
5020     uint emulationSpecifier = d->state->emulationSpecifier;
5021
5022     if (emulationSpecifier) {
5023         QPainterPath polygonPath(points[0]);
5024         for (int i=1; i<pointCount; ++i)
5025             polygonPath.lineTo(points[i]);
5026         polygonPath.closeSubpath();
5027         polygonPath.setFillRule(fillRule);
5028         d->draw_helper(polygonPath);
5029         return;
5030     }
5031
5032     d->engine->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
5033 }
5034
5035 /*! \overload
5036
5037     Draws the polygon defined by the first \a pointCount points in the
5038     array \a points.
5039 */
5040 void QPainter::drawPolygon(const QPoint *points, int pointCount, Qt::FillRule fillRule)
5041 {
5042 #ifdef QT_DEBUG_DRAW
5043     if (qt_show_painter_debug_output)
5044         printf("QPainter::drawPolygon(), count=%d\n", pointCount);
5045 #endif
5046
5047     Q_D(QPainter);
5048
5049     if (!d->engine || pointCount < 2)
5050         return;
5051
5052     if (d->extended) {
5053         d->extended->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
5054         return;
5055     }
5056
5057     d->updateState(d->state);
5058
5059     uint emulationSpecifier = d->state->emulationSpecifier;
5060
5061     if (emulationSpecifier) {
5062         QPainterPath polygonPath(points[0]);
5063         for (int i=1; i<pointCount; ++i)
5064             polygonPath.lineTo(points[i]);
5065         polygonPath.closeSubpath();
5066         polygonPath.setFillRule(fillRule);
5067         d->draw_helper(polygonPath);
5068         return;
5069     }
5070
5071     d->engine->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
5072 }
5073
5074 /*! \fn void QPainter::drawPolygon(const QPolygonF &polygon, bool winding, int index = 0,
5075                                    int count = -1)
5076     \compat
5077     \overload
5078
5079     Use drawPolygon() combined with QPolygonF::constData() instead.
5080
5081     \oldcode
5082         QPainter painter(this);
5083         painter.drawPolygon(polygon, winding, index, count);
5084     \newcode
5085         int pointCount = (count == -1) ?  polygon.size() - index : count;
5086         int fillRule = winding ? Qt::WindingFill : Qt::OddEvenFill;
5087
5088         QPainter painter(this);
5089         painter.drawPolygon( polygon.constData() + index, pointCount, fillRule);
5090     \endcode
5091 */
5092
5093 /*! \fn void QPainter::drawPolygon(const QPolygon &polygon, bool winding,
5094                                    int index = 0, int count = -1)
5095
5096     \compat
5097     \overload
5098
5099     Use drawPolygon() combined with QPolygon::constData() instead.
5100
5101     \oldcode
5102         QPainter painter(this);
5103         painter.drawPolygon(polygon, winding, index, count);
5104     \newcode
5105         int pointCount = (count == -1) ?  polygon.size() - index : count;
5106         int fillRule = winding ? Qt::WindingFill : Qt::OddEvenFill;
5107
5108         QPainter painter(this);
5109         painter.drawPolygon( polygon.constData() + index, pointCount, fillRule);
5110     \endcode
5111 */
5112
5113 /*! \fn void QPainter::drawPolygon(const QPolygonF &points, Qt::FillRule fillRule)
5114
5115     \overload
5116
5117     Draws the polygon defined by the given \a points using the fill
5118     rule \a fillRule.
5119 */
5120
5121 /*! \fn void QPainter::drawPolygon(const QPolygon &points, Qt::FillRule fillRule)
5122
5123     \overload
5124
5125     Draws the polygon defined by the given \a points using the fill
5126     rule \a fillRule.
5127 */
5128
5129 /*!
5130     \fn void QPainter::drawConvexPolygon(const QPointF *points, int pointCount)
5131
5132     Draws the convex polygon defined by the first \a pointCount points
5133     in the array \a points using the current pen.
5134
5135     \table 100%
5136     \row
5137     \o \inlineimage qpainter-polygon.png
5138     \o
5139     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 15
5140     \endtable
5141
5142     The first point is implicitly connected to the last point, and the
5143     polygon is filled with the current brush().  If the supplied
5144     polygon is not convex, i.e. it contains at least one angle larger
5145     than 180 degrees, the results are undefined.
5146
5147     On some platforms (e.g. X11), the drawConvexPolygon() function can
5148     be faster than the drawPolygon() function.
5149
5150     \sa drawPolygon(), drawPolyline(), {Coordinate System}
5151 */
5152
5153 /*!
5154     \fn void QPainter::drawConvexPolygon(const QPoint *points, int pointCount)
5155     \overload
5156
5157     Draws the convex polygon defined by the first \a pointCount points
5158     in the array \a points using the current pen.
5159 */
5160
5161 /*!
5162     \fn void QPainter::drawConvexPolygon(const QPolygonF &polygon)
5163
5164     \overload
5165
5166     Draws the convex polygon defined by \a polygon using the current
5167     pen and brush.
5168 */
5169
5170 /*!
5171     \fn void QPainter::drawConvexPolygon(const QPolygon &polygon)
5172     \overload
5173
5174     Draws the convex polygon defined by \a polygon using the current
5175     pen and brush.
5176 */
5177
5178 /*!
5179     \fn void QPainter::drawConvexPolygon(const QPolygonF &polygon, int
5180     index, int count)
5181
5182     \compat
5183     \overload
5184
5185     Use drawConvexPolygon() combined with QPolygonF::constData()
5186     instead.
5187
5188     \oldcode
5189         QPainter painter(this);
5190         painter.drawConvexPolygon(polygon, index, count);
5191     \newcode
5192         int pointCount = (count == -1) ?  polygon.size() - index : count;
5193
5194         QPainter painter(this);
5195         painter.drawConvexPolygon(polygon.constData() + index, pointCount);
5196     \endcode
5197 */
5198
5199 /*!
5200     \fn void QPainter::drawConvexPolygon(const QPolygon &polygon, int
5201     index, int count)
5202
5203     \compat
5204     \overload
5205
5206     Use drawConvexPolygon() combined with QPolygon::constData()
5207     instead.
5208
5209     \oldcode
5210         QPainter painter(this);
5211         painter.drawConvexPolygon(polygon, index, count);
5212     \newcode
5213         int pointCount = (count == -1) ?  polygon.size() - index : count;
5214
5215         QPainter painter(this);
5216         painter.drawConvexPolygon(polygon.constData() + index, pointCount);
5217     \endcode
5218 */
5219
5220 void QPainter::drawConvexPolygon(const QPoint *points, int pointCount)
5221 {
5222 #ifdef QT_DEBUG_DRAW
5223     if (qt_show_painter_debug_output)
5224         printf("QPainter::drawConvexPolygon(), count=%d\n", pointCount);
5225 #endif
5226
5227     Q_D(QPainter);
5228
5229     if (!d->engine || pointCount < 2)
5230         return;
5231
5232     if (d->extended) {
5233         d->extended->drawPolygon(points, pointCount, QPaintEngine::ConvexMode);
5234         return;
5235     }
5236
5237     d->updateState(d->state);
5238
5239     uint emulationSpecifier = d->state->emulationSpecifier;
5240
5241     if (emulationSpecifier) {
5242         QPainterPath polygonPath(points[0]);
5243         for (int i=1; i<pointCount; ++i)
5244             polygonPath.lineTo(points[i]);
5245         polygonPath.closeSubpath();
5246         polygonPath.setFillRule(Qt::WindingFill);
5247         d->draw_helper(polygonPath);
5248         return;
5249     }
5250
5251     d->engine->drawPolygon(points, pointCount, QPaintEngine::ConvexMode);
5252 }
5253
5254 void QPainter::drawConvexPolygon(const QPointF *points, int pointCount)
5255 {
5256 #ifdef QT_DEBUG_DRAW
5257     if (qt_show_painter_debug_output)
5258         printf("QPainter::drawConvexPolygon(), count=%d\n", pointCount);
5259 #endif
5260
5261     Q_D(QPainter);
5262
5263     if (!d->engine || pointCount < 2)
5264         return;
5265
5266     if (d->extended) {
5267         d->extended->drawPolygon(points, pointCount, QPaintEngine::ConvexMode);
5268         return;
5269     }
5270
5271     d->updateState(d->state);
5272
5273     uint emulationSpecifier = d->state->emulationSpecifier;
5274
5275     if (emulationSpecifier) {
5276         QPainterPath polygonPath(points[0]);
5277         for (int i=1; i<pointCount; ++i)
5278             polygonPath.lineTo(points[i]);
5279         polygonPath.closeSubpath();
5280         polygonPath.setFillRule(Qt::WindingFill);
5281         d->draw_helper(polygonPath);
5282         return;
5283     }
5284
5285     d->engine->drawPolygon(points, pointCount, QPaintEngine::ConvexMode);
5286 }
5287
5288 static inline QPointF roundInDeviceCoordinates(const QPointF &p, const QTransform &m)
5289 {
5290     return m.inverted().map(QPointF(m.map(p).toPoint()));
5291 }
5292
5293 /*!
5294     \fn void QPainter::drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
5295
5296     Draws the rectangular portion \a source of the given \a pixmap
5297     into the given \a target in the paint device.
5298
5299     \note The pixmap is scaled to fit the rectangle, if both the pixmap and rectangle size disagree.
5300
5301     \table 100%
5302     \row
5303     \o
5304     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 16
5305     \endtable
5306
5307     If \a pixmap is a QBitmap it is drawn with the bits that are "set"
5308     using the pens color. If backgroundMode is Qt::OpaqueMode, the
5309     "unset" bits are drawn using the color of the background brush; if
5310     backgroundMode is Qt::TransparentMode, the "unset" bits are
5311     transparent. Drawing bitmaps with gradient or texture colors is
5312     not supported.
5313
5314     \sa drawImage()
5315 */
5316 void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
5317 {
5318 #if defined QT_DEBUG_DRAW
5319     if (qt_show_painter_debug_output)
5320         printf("QPainter::drawPixmap(), p=[%.2f,%.2f], pix=[%d,%d]\n",
5321                p.x(), p.y(),
5322                pm.width(), pm.height());
5323 #endif
5324
5325     Q_D(QPainter);
5326
5327     if (!d->engine || pm.isNull())
5328         return;
5329
5330 #ifndef QT_NO_DEBUG
5331     qt_painter_thread_test(d->device->devType(), "drawPixmap()", true);
5332 #endif
5333
5334     if (d->extended) {
5335         d->extended->drawPixmap(p, pm);
5336         return;
5337     }
5338
5339     qreal x = p.x();
5340     qreal y = p.y();
5341
5342     int w = pm.width();
5343     int h = pm.height();
5344
5345     if (w <= 0)
5346         return;
5347
5348     // Emulate opaque background for bitmaps
5349     if (d->state->bgMode == Qt::OpaqueMode && pm.isQBitmap()) {
5350         fillRect(QRectF(x, y, w, h), d->state->bgBrush.color());
5351     }
5352
5353     d->updateState(d->state);
5354
5355     if ((d->state->matrix.type() > QTransform::TxTranslate
5356          && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
5357         || (!d->state->matrix.isAffine() && !d->engine->hasFeature(QPaintEngine::PerspectiveTransform))
5358         || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity)))
5359     {
5360         save();
5361         // If there is no rotation involved we have to make sure we use the
5362         // antialiased and not the aliased coordinate system by rounding the coordinates.
5363         if (d->state->matrix.type() <= QTransform::TxScale) {
5364             const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
5365             x = p.x();
5366             y = p.y();
5367         }
5368         translate(x, y);
5369         setBackgroundMode(Qt::TransparentMode);
5370         setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
5371         QBrush brush(d->state->pen.color(), pm);
5372         setBrush(brush);
5373         setPen(Qt::NoPen);
5374         setBrushOrigin(QPointF(0, 0));
5375
5376         drawRect(pm.rect());
5377         restore();
5378     } else {
5379         if (!d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
5380             x += d->state->matrix.dx();
5381             y += d->state->matrix.dy();
5382         }
5383         d->engine->drawPixmap(QRectF(x, y, w, h), pm, QRectF(0, 0, w, h));
5384     }
5385 }
5386
5387 void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
5388 {
5389 #if defined QT_DEBUG_DRAW
5390     if (qt_show_painter_debug_output)
5391         printf("QPainter::drawPixmap(), target=[%.2f,%.2f,%.2f,%.2f], pix=[%d,%d], source=[%.2f,%.2f,%.2f,%.2f]\n",
5392                r.x(), r.y(), r.width(), r.height(),
5393                pm.width(), pm.height(),
5394                sr.x(), sr.y(), sr.width(), sr.height());
5395 #endif
5396
5397     Q_D(QPainter);
5398     if (!d->engine || pm.isNull())
5399         return;
5400 #ifndef QT_NO_DEBUG
5401     qt_painter_thread_test(d->device->devType(), "drawPixmap()", true);
5402 #endif
5403
5404     qreal x = r.x();
5405     qreal y = r.y();
5406     qreal w = r.width();
5407     qreal h = r.height();
5408     qreal sx = sr.x();
5409     qreal sy = sr.y();
5410     qreal sw = sr.width();
5411     qreal sh = sr.height();
5412
5413     // Sanity-check clipping
5414     if (sw <= 0)
5415         sw = pm.width() - sx;
5416
5417     if (sh <= 0)
5418         sh = pm.height() - sy;
5419
5420     if (w < 0)
5421         w = sw;
5422     if (h < 0)
5423         h = sh;
5424
5425     if (sx < 0) {
5426         qreal w_ratio = sx * w/sw;
5427         x -= w_ratio;
5428         w += w_ratio;
5429         sw += sx;
5430         sx = 0;
5431     }
5432
5433     if (sy < 0) {
5434         qreal h_ratio = sy * h/sh;
5435         y -= h_ratio;
5436         h += h_ratio;
5437         sh += sy;
5438         sy = 0;
5439     }
5440
5441     if (sw + sx > pm.width()) {
5442         qreal delta = sw - (pm.width() - sx);
5443         qreal w_ratio = delta * w/sw;
5444         sw -= delta;
5445         w -= w_ratio;
5446     }
5447
5448     if (sh + sy > pm.height()) {
5449         qreal delta = sh - (pm.height() - sy);
5450         qreal h_ratio = delta * h/sh;
5451         sh -= delta;
5452         h -= h_ratio;
5453     }
5454
5455     if (w == 0 || h == 0 || sw <= 0 || sh <= 0)
5456         return;
5457
5458     if (d->extended) {
5459         d->extended->drawPixmap(QRectF(x, y, w, h), pm, QRectF(sx, sy, sw, sh));
5460         return;
5461     }
5462
5463     // Emulate opaque background for bitmaps
5464     if (d->state->bgMode == Qt::OpaqueMode && pm.isQBitmap())
5465         fillRect(QRectF(x, y, w, h), d->state->bgBrush.color());
5466
5467     d->updateState(d->state);
5468
5469     if ((d->state->matrix.type() > QTransform::TxTranslate
5470          && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
5471         || (!d->state->matrix.isAffine() && !d->engine->hasFeature(QPaintEngine::PerspectiveTransform))
5472         || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity))
5473         || ((sw != w || sh != h) && !d->engine->hasFeature(QPaintEngine::PixmapTransform)))
5474     {
5475         save();
5476         // If there is no rotation involved we have to make sure we use the
5477         // antialiased and not the aliased coordinate system by rounding the coordinates.
5478         if (d->state->matrix.type() <= QTransform::TxScale) {
5479             const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
5480             x = p.x();
5481             y = p.y();
5482         }
5483
5484         if (d->state->matrix.type() <= QTransform::TxTranslate && sw == w && sh == h) {
5485             sx = qRound(sx);
5486             sy = qRound(sy);
5487             sw = qRound(sw);
5488             sh = qRound(sh);
5489         }
5490
5491         translate(x, y);
5492         scale(w / sw, h / sh);
5493         setBackgroundMode(Qt::TransparentMode);
5494         setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
5495         QBrush brush;
5496
5497         if (sw == pm.width() && sh == pm.height())
5498             brush = QBrush(d->state->pen.color(), pm);
5499         else
5500             brush = QBrush(d->state->pen.color(), pm.copy(sx, sy, sw, sh));
5501
5502         setBrush(brush);
5503         setPen(Qt::NoPen);
5504
5505         drawRect(QRectF(0, 0, sw, sh));
5506         restore();
5507     } else {
5508         if (!d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
5509             x += d->state->matrix.dx();
5510             y += d->state->matrix.dy();
5511         }
5512         d->engine->drawPixmap(QRectF(x, y, w, h), pm, QRectF(sx, sy, sw, sh));
5513     }
5514 }
5515
5516
5517 /*!
5518     \fn void QPainter::drawPixmap(const QRect &target, const QPixmap &pixmap,
5519                                   const QRect &source)
5520     \overload
5521
5522     Draws the rectangular portion \a source of the given \a pixmap
5523     into the given \a target in the paint device.
5524
5525     \note The pixmap is scaled to fit the rectangle, if both the pixmap and rectangle size disagree.
5526 */
5527
5528 /*!
5529     \fn void QPainter::drawPixmap(const QPointF &point, const QPixmap &pixmap,
5530                                   const QRectF &source)
5531     \overload
5532
5533     Draws the rectangular portion \a source of the given \a pixmap
5534     with its origin at the given \a point.
5535 */
5536
5537 /*!
5538     \fn void QPainter::drawPixmap(const QPoint &point, const QPixmap &pixmap,
5539                                   const QRect &source)
5540
5541     \overload
5542
5543     Draws the rectangular portion \a source of the given \a pixmap
5544     with its origin at the given \a point.
5545 */
5546
5547 /*!
5548     \fn void QPainter::drawPixmap(const QPointF &point, const QPixmap &pixmap)
5549     \overload
5550
5551     Draws the given \a pixmap with its origin at the given \a point.
5552 */
5553
5554 /*!
5555     \fn void QPainter::drawPixmap(const QPoint &point, const QPixmap &pixmap)
5556     \overload
5557
5558     Draws the given \a pixmap with its origin at the given \a point.
5559 */
5560
5561 /*!
5562     \fn void QPainter::drawPixmap(int x, int y, const QPixmap &pixmap)
5563
5564     \overload
5565
5566     Draws the given \a pixmap at position (\a{x}, \a{y}).
5567 */
5568
5569 /*!
5570     \fn void QPainter::drawPixmap(const QRect &rectangle, const QPixmap &pixmap)
5571     \overload
5572
5573     Draws the given \a  pixmap into the given \a rectangle.
5574
5575     \note The pixmap is scaled to fit the rectangle, if both the pixmap and rectangle size disagree.
5576 */
5577
5578 /*!
5579     \fn void QPainter::drawPixmap(int x, int y, int width, int height,
5580     const QPixmap &pixmap)
5581
5582     \overload
5583
5584     Draws the \a pixmap into the rectangle at position (\a{x}, \a{y})
5585     with  the given \a width and \a height.
5586 */
5587
5588 /*!
5589     \fn void QPainter::drawPixmap(int x, int y, int w, int h, const QPixmap &pixmap,
5590                                   int sx, int sy, int sw, int sh)
5591
5592     \overload
5593
5594     Draws the rectangular portion with the origin (\a{sx}, \a{sy}),
5595     width \a sw and height \a sh, of the given \a pixmap , at the
5596     point (\a{x}, \a{y}), with a width of \a w and a height of \a h.
5597     If sw or sh are equal to zero the width/height of the pixmap
5598     is used and adjusted by the offset sx/sy;
5599 */
5600
5601 /*!
5602     \fn void QPainter::drawPixmap(int x, int y, const QPixmap &pixmap,
5603                                   int sx, int sy, int sw, int sh)
5604
5605     \overload
5606
5607     Draws a pixmap at (\a{x}, \a{y}) by copying a part of the given \a
5608     pixmap into the paint device.
5609
5610     (\a{x}, \a{y}) specifies the top-left point in the paint device that is
5611     to be drawn onto. (\a{sx}, \a{sy}) specifies the top-left point in \a
5612     pixmap that is to be drawn. The default is (0, 0).
5613
5614     (\a{sw}, \a{sh}) specifies the size of the pixmap that is to be drawn.
5615     The default, (0, 0) (and negative) means all the way to the
5616     bottom-right of the pixmap.
5617 */
5618
5619 void QPainter::drawImage(const QPointF &p, const QImage &image)
5620 {
5621     Q_D(QPainter);
5622
5623     if (!d->engine || image.isNull())
5624         return;
5625
5626     if (d->extended) {
5627         d->extended->drawImage(p, image);
5628         return;
5629     }
5630
5631     qreal x = p.x();
5632     qreal y = p.y();
5633
5634     int w = image.width();
5635     int h = image.height();
5636
5637     d->updateState(d->state);
5638
5639     if (((d->state->matrix.type() > QTransform::TxTranslate)
5640          && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
5641         || (!d->state->matrix.isAffine() && !d->engine->hasFeature(QPaintEngine::PerspectiveTransform))
5642         || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity)))
5643     {
5644         save();
5645         // If there is no rotation involved we have to make sure we use the
5646         // antialiased and not the aliased coordinate system by rounding the coordinates.
5647         if (d->state->matrix.type() <= QTransform::TxScale) {
5648             const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
5649             x = p.x();
5650             y = p.y();
5651         }
5652         translate(x, y);
5653         setBackgroundMode(Qt::TransparentMode);
5654         setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
5655         QBrush brush(image);
5656         setBrush(brush);
5657         setPen(Qt::NoPen);
5658         setBrushOrigin(QPointF(0, 0));
5659
5660         drawRect(image.rect());
5661         restore();
5662         return;
5663     }
5664
5665     if (d->state->matrix.type() == QTransform::TxTranslate
5666         && !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
5667         x += d->state->matrix.dx();
5668         y += d->state->matrix.dy();
5669     }
5670
5671     d->engine->drawImage(QRectF(x, y, w, h), image, QRectF(0, 0, w, h), Qt::AutoColor);
5672 }
5673
5674 void QPainter::drawImage(const QRectF &targetRect, const QImage &image, const QRectF &sourceRect,
5675                          Qt::ImageConversionFlags flags)
5676 {
5677     Q_D(QPainter);
5678
5679     if (!d->engine || image.isNull())
5680         return;
5681
5682     qreal x = targetRect.x();
5683     qreal y = targetRect.y();
5684     qreal w = targetRect.width();
5685     qreal h = targetRect.height();
5686     qreal sx = sourceRect.x();
5687     qreal sy = sourceRect.y();
5688     qreal sw = sourceRect.width();
5689     qreal sh = sourceRect.height();
5690
5691     // Sanity-check clipping
5692     if (sw <= 0)
5693         sw = image.width() - sx;
5694
5695     if (sh <= 0)
5696         sh = image.height() - sy;
5697
5698     if (w < 0)
5699         w = sw;
5700     if (h < 0)
5701         h = sh;
5702
5703     if (sx < 0) {
5704         qreal w_ratio = sx * w/sw;
5705         x -= w_ratio;
5706         w += w_ratio;
5707         sw += sx;
5708         sx = 0;
5709     }
5710
5711     if (sy < 0) {
5712         qreal h_ratio = sy * h/sh;
5713         y -= h_ratio;
5714         h += h_ratio;
5715         sh += sy;
5716         sy = 0;
5717     }
5718
5719     if (sw + sx > image.width()) {
5720         qreal delta = sw - (image.width() - sx);
5721         qreal w_ratio = delta * w/sw;
5722         sw -= delta;
5723         w -= w_ratio;
5724     }
5725
5726     if (sh + sy > image.height()) {
5727         qreal delta = sh - (image.height() - sy);
5728         qreal h_ratio = delta * h/sh;
5729         sh -= delta;
5730         h -= h_ratio;
5731     }
5732
5733     if (w == 0 || h == 0 || sw <= 0 || sh <= 0)
5734         return;
5735
5736     if (d->extended) {
5737         d->extended->drawImage(QRectF(x, y, w, h), image, QRectF(sx, sy, sw, sh), flags);
5738         return;
5739     }
5740
5741     d->updateState(d->state);
5742
5743     if (((d->state->matrix.type() > QTransform::TxTranslate || (sw != w || sh != h))
5744          && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
5745         || (!d->state->matrix.isAffine() && !d->engine->hasFeature(QPaintEngine::PerspectiveTransform))
5746         || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity)))
5747     {
5748         save();
5749         // If there is no rotation involved we have to make sure we use the
5750         // antialiased and not the aliased coordinate system by rounding the coordinates.
5751         if (d->state->matrix.type() <= QTransform::TxScale) {
5752             const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
5753             x = p.x();
5754             y = p.y();
5755         }
5756
5757         if (d->state->matrix.type() <= QTransform::TxTranslate && sw == w && sh == h) {
5758             sx = qRound(sx);
5759             sy = qRound(sy);
5760             sw = qRound(sw);
5761             sh = qRound(sh);
5762         }
5763         translate(x, y);
5764         scale(w / sw, h / sh);
5765         setBackgroundMode(Qt::TransparentMode);
5766         setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
5767         QBrush brush(image);
5768         setBrush(brush);
5769         setPen(Qt::NoPen);
5770         setBrushOrigin(QPointF(-sx, -sy));
5771
5772         drawRect(QRectF(0, 0, sw, sh));
5773         restore();
5774         return;
5775     }
5776
5777     if (d->state->matrix.type() == QTransform::TxTranslate
5778         && !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
5779         x += d->state->matrix.dx();
5780         y += d->state->matrix.dy();
5781     }
5782
5783     d->engine->drawImage(QRectF(x, y, w, h), image, QRectF(sx, sy, sw, sh), flags);
5784 }
5785
5786 /*!
5787     Draws the glyphs represented by \a glyphs at \a position. The \a position gives the
5788     edge of the baseline for the string of glyphs. The glyphs will be retrieved from the font
5789     selected on \a glyphs and at offsets given by the positions in \a glyphs.
5790
5791     \since 4.8
5792
5793     \sa QGlyphs::setFont(), QGlyphs::setPositions(), QGlyphs::setGlyphIndexes()
5794 */
5795 #if !defined(QT_NO_RAWFONT)
5796 void QPainter::drawGlyphs(const QPointF &position, const QGlyphs &glyphs)
5797 {
5798     Q_D(QPainter);
5799
5800     QRawFont font = glyphs.font();
5801     if (!font.isValid())
5802         return;
5803
5804     QVector<quint32> glyphIndexes = glyphs.glyphIndexes();
5805     QVector<QPointF> glyphPositions = glyphs.positions();
5806
5807     int count = qMin(glyphIndexes.size(), glyphPositions.size());
5808     QVarLengthArray<QFixedPoint, 128> fixedPointPositions(count);
5809
5810     bool paintEngineSupportsTransformations =
5811             d->extended != 0
5812             ? qt_paintengine_supports_transformations(d->extended->type())
5813             : qt_paintengine_supports_transformations(d->engine->type());
5814     for (int i=0; i<count; ++i) {
5815         QPointF processedPosition = position + glyphPositions.at(i);
5816         if (!paintEngineSupportsTransformations)
5817             processedPosition = d->state->transform().map(processedPosition);
5818         fixedPointPositions[i] = QFixedPoint::fromPointF(processedPosition);
5819     }
5820
5821     d->drawGlyphs(glyphIndexes.data(), fixedPointPositions.data(), count, font, glyphs.overline(),
5822                   glyphs.underline(), glyphs.strikeOut());
5823 }
5824
5825 void QPainterPrivate::drawGlyphs(quint32 *glyphArray, QFixedPoint *positions, int glyphCount,
5826                                  const QRawFont &font, bool overline, bool underline,
5827                                  bool strikeOut)
5828 {
5829     Q_Q(QPainter);
5830
5831     updateState(state);
5832
5833     QRawFontPrivate *fontD = QRawFontPrivate::get(font);
5834     QFontEngine *fontEngine = fontD->fontEngine;
5835
5836     QFixed leftMost;
5837     QFixed rightMost;
5838     QFixed baseLine;
5839     for (int i=0; i<glyphCount; ++i) {
5840         glyph_metrics_t gm = fontEngine->boundingBox(glyphArray[i]);
5841         if (i == 0 || leftMost > positions[i].x)
5842             leftMost = positions[i].x;
5843
5844         // We don't support glyphs that do not share a common baseline. If this turns out to
5845         // be a relevant use case, then we need to find clusters of glyphs that share a baseline
5846         // and do a drawTextItemDecorations call per cluster.
5847         if (i == 0 || baseLine < positions[i].y)
5848             baseLine = positions[i].y;
5849
5850         // We use the advance rather than the actual bounds to match the algorithm in drawText()
5851         if (i == 0 || rightMost < positions[i].x + gm.xoff)
5852             rightMost = positions[i].x + gm.xoff;
5853     }
5854
5855     QFixed width = rightMost - leftMost;
5856
5857     if (extended != 0) {
5858         QStaticTextItem staticTextItem;
5859         staticTextItem.color = state->pen.color();
5860         staticTextItem.font = state->font;
5861         staticTextItem.setFontEngine(fontEngine);
5862         staticTextItem.numGlyphs = glyphCount;
5863         staticTextItem.glyphs = reinterpret_cast<glyph_t *>(const_cast<glyph_t *>(glyphArray));
5864         staticTextItem.glyphPositions = positions;
5865
5866         extended->drawStaticTextItem(&staticTextItem);
5867     } else {
5868         QTextItemInt textItem;
5869         textItem.fontEngine = fontEngine;
5870
5871         QVarLengthArray<QFixed, 128> advances(glyphCount);
5872         QVarLengthArray<QGlyphJustification, 128> glyphJustifications(glyphCount);
5873         QVarLengthArray<HB_GlyphAttributes, 128> glyphAttributes(glyphCount);
5874         qMemSet(glyphAttributes.data(), 0, glyphAttributes.size() * sizeof(HB_GlyphAttributes));
5875         qMemSet(advances.data(), 0, advances.size() * sizeof(QFixed));
5876         qMemSet(glyphJustifications.data(), 0, glyphJustifications.size() * sizeof(QGlyphJustification));
5877
5878         textItem.glyphs.numGlyphs = glyphCount;
5879         textItem.glyphs.glyphs = reinterpret_cast<HB_Glyph *>(const_cast<quint32 *>(glyphArray));
5880         textItem.glyphs.offsets = positions;
5881         textItem.glyphs.advances_x = advances.data();
5882         textItem.glyphs.advances_y = advances.data();
5883         textItem.glyphs.justifications = glyphJustifications.data();
5884         textItem.glyphs.attributes = glyphAttributes.data();
5885
5886         engine->drawTextItem(QPointF(0, 0), textItem);
5887     }
5888
5889     QTextItemInt::RenderFlags flags;
5890     if (underline)
5891         flags |= QTextItemInt::Underline;
5892     if (overline)
5893         flags |= QTextItemInt::Overline;
5894     if (strikeOut)
5895         flags |= QTextItemInt::StrikeOut;
5896
5897     drawTextItemDecoration(q, QPointF(leftMost.toReal(), baseLine.toReal()),
5898                            fontEngine,
5899                            (underline
5900                               ? QTextCharFormat::SingleUnderline
5901                               : QTextCharFormat::NoUnderline),
5902                            flags, width.toReal(), QTextCharFormat());
5903 }
5904 #endif // QT_NO_RAWFONT
5905
5906 /*!
5907
5908     \fn void QPainter::drawStaticText(const QPoint &topLeftPosition, const QStaticText &staticText)
5909     \since 4.7
5910     \overload
5911
5912     Draws the \a staticText at the \a topLeftPosition.
5913
5914     \note The y-position is used as the top of the font.
5915
5916 */
5917
5918 /*!
5919     \fn void QPainter::drawStaticText(int left, int top, const QStaticText &staticText)
5920     \since 4.7
5921     \overload
5922
5923     Draws the \a staticText at coordinates \a left and \a top.
5924
5925     \note The y-position is used as the top of the font.
5926 */
5927
5928 /*!
5929     \fn void QPainter::drawText(const QPointF &position, const QString &text)
5930
5931     Draws the given \a text with the currently defined text direction,
5932     beginning at the given \a position.
5933
5934     This function does not handle the newline character (\n), as it cannot
5935     break text into multiple lines, and it cannot display the newline character.
5936     Use the QPainter::drawText() overload that takes a rectangle instead
5937     if you want to draw multiple lines of text with the newline character, or
5938     if you want the text to be wrapped.
5939
5940     By default, QPainter draws text anti-aliased.
5941
5942     \note The y-position is used as the baseline of the font.
5943 */
5944
5945 void QPainter::drawText(const QPointF &p, const QString &str)
5946 {
5947     drawText(p, str, 0, 0);
5948 }
5949
5950 /*!
5951     \since 4.7
5952
5953     Draws the given \a staticText at the given \a topLeftPosition.
5954
5955     The text will be drawn using the font and the transformation set on the painter. If the
5956     font and/or transformation set on the painter are different from the ones used to initialize
5957     the layout of the QStaticText, then the layout will have to be recalculated. Use
5958     QStaticText::prepare() to initialize \a staticText with the font and transformation with which
5959     it will later be drawn.
5960
5961     If \a topLeftPosition is not the same as when \a staticText was initialized, or when it was
5962     last drawn, then there will be a slight overhead when translating the text to its new position.
5963
5964     \note If the painter's transformation is not affine, then \a staticText will be drawn using
5965     regular calls to drawText(), losing any potential for performance improvement.
5966
5967     \note The y-position is used as the top of the font.
5968
5969     \sa QStaticText
5970 */
5971 void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText &staticText)
5972 {
5973     Q_D(QPainter);
5974     if (!d->engine || staticText.text().isEmpty() || pen().style() == Qt::NoPen)
5975         return;
5976
5977     QStaticTextPrivate *staticText_d =
5978             const_cast<QStaticTextPrivate *>(QStaticTextPrivate::get(&staticText));
5979
5980     if (font() != staticText_d->font) {
5981         staticText_d->font = font();
5982         staticText_d->needsRelayout = true;
5983     }
5984
5985     // If we don't have an extended paint engine, or if the painter is projected,
5986     // we go through standard code path
5987     if (d->extended == 0 || !d->state->matrix.isAffine()) {
5988         staticText_d->paintText(topLeftPosition, this);
5989         return;
5990     }
5991
5992     bool paintEngineSupportsTransformations = qt_paintengine_supports_transformations(d->extended->type());
5993     if (paintEngineSupportsTransformations && !staticText_d->untransformedCoordinates) {
5994         staticText_d->untransformedCoordinates = true;
5995         staticText_d->needsRelayout = true;
5996     } else if (!paintEngineSupportsTransformations && staticText_d->untransformedCoordinates) {
5997         staticText_d->untransformedCoordinates = false;
5998         staticText_d->needsRelayout = true;
5999     }
6000
6001     // Don't recalculate entire layout because of translation, rather add the dx and dy
6002     // into the position to move each text item the correct distance.
6003     QPointF transformedPosition = topLeftPosition;
6004     if (!staticText_d->untransformedCoordinates)
6005         transformedPosition = transformedPosition * d->state->matrix;
6006     QTransform oldMatrix;
6007
6008     // The translation has been applied to transformedPosition. Remove translation
6009     // component from matrix.
6010     if (d->state->matrix.isTranslating() && !staticText_d->untransformedCoordinates) {
6011         qreal m11 = d->state->matrix.m11();
6012         qreal m12 = d->state->matrix.m12();
6013         qreal m13 = d->state->matrix.m13();
6014         qreal m21 = d->state->matrix.m21();
6015         qreal m22 = d->state->matrix.m22();
6016         qreal m23 = d->state->matrix.m23();
6017         qreal m33 = d->state->matrix.m33();
6018
6019         oldMatrix = d->state->matrix;
6020         d->state->matrix.setMatrix(m11, m12, m13,
6021                                    m21, m22, m23,
6022                                    0.0, 0.0, m33);
6023     }
6024
6025     // If the transform is not identical to the text transform,
6026     // we have to relayout the text (for other transformations than plain translation)
6027     bool staticTextNeedsReinit = staticText_d->needsRelayout;
6028     if (!staticText_d->untransformedCoordinates && staticText_d->matrix != d->state->matrix) {
6029         staticText_d->matrix = d->state->matrix;
6030         staticTextNeedsReinit = true;
6031     }
6032
6033     // Recreate the layout of the static text because the matrix or font has changed
6034     if (staticTextNeedsReinit)
6035         staticText_d->init();
6036
6037     if (transformedPosition != staticText_d->position) { // Translate to actual position
6038         QFixed fx = QFixed::fromReal(transformedPosition.x());
6039         QFixed fy = QFixed::fromReal(transformedPosition.y());
6040         QFixed oldX = QFixed::fromReal(staticText_d->position.x());
6041         QFixed oldY = QFixed::fromReal(staticText_d->position.y());
6042         for (int item=0; item<staticText_d->itemCount;++item) {
6043             QStaticTextItem *textItem = staticText_d->items + item;
6044             for (int i=0; i<textItem->numGlyphs; ++i) {
6045                 textItem->glyphPositions[i].x += fx - oldX;
6046                 textItem->glyphPositions[i].y += fy - oldY;
6047             }
6048             textItem->userDataNeedsUpdate = true;
6049         }
6050
6051         staticText_d->position = transformedPosition;
6052     }
6053
6054     QPen oldPen = d->state->pen;
6055     QColor currentColor = oldPen.color();
6056     for (int i=0; i<staticText_d->itemCount; ++i) {
6057         QStaticTextItem *item = staticText_d->items + i;
6058         if (item->color.isValid() && currentColor != item->color) {
6059             setPen(item->color);
6060             currentColor = item->color;
6061         }
6062         d->extended->drawStaticTextItem(item);
6063
6064         qt_draw_decoration_for_glyphs(this, item->glyphs, item->glyphPositions,
6065                                       item->numGlyphs, item->fontEngine(), staticText_d->font,
6066                                       QTextCharFormat());
6067     }
6068     if (currentColor != oldPen.color())
6069         setPen(oldPen);
6070
6071     if (!staticText_d->untransformedCoordinates && oldMatrix.isTranslating())
6072         d->state->matrix = oldMatrix;
6073 }
6074
6075 /*!
6076    \internal
6077 */
6078 void QPainter::drawText(const QPointF &p, const QString &str, int tf, int justificationPadding)
6079 {
6080 #ifdef QT_DEBUG_DRAW
6081     if (qt_show_painter_debug_output)
6082         printf("QPainter::drawText(), pos=[%.2f,%.2f], str='%s'\n", p.x(), p.y(), str.toLatin1().constData());
6083 #endif
6084
6085     Q_D(QPainter);
6086
6087     if (!d->engine || str.isEmpty() || pen().style() == Qt::NoPen)
6088         return;
6089
6090     if (tf & Qt::TextBypassShaping) {
6091         // Skip harfbuzz complex shaping, shape using glyph advances only
6092         int len = str.length();
6093         int numGlyphs = len;
6094         QVarLengthGlyphLayoutArray glyphs(len);
6095         QFontEngine *fontEngine = d->state->font.d->engineForScript(QUnicodeTables::Common);
6096         if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0)) {
6097             glyphs.resize(numGlyphs);
6098             if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0))
6099                 Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice");
6100         }
6101
6102         QTextItemInt gf(glyphs, &d->state->font, str.data(), len, fontEngine);
6103         drawTextItem(p, gf);
6104         return;
6105     }
6106
6107     QStackTextEngine engine(str, d->state->font);
6108     engine.option.setTextDirection(d->state->layoutDirection);
6109     if (tf & (Qt::TextForceLeftToRight|Qt::TextForceRightToLeft)) {
6110         engine.ignoreBidi = true;
6111         engine.option.setTextDirection((tf & Qt::TextForceLeftToRight) ? Qt::LeftToRight : Qt::RightToLeft);
6112     }
6113     engine.itemize();
6114     QScriptLine line;
6115     line.length = str.length();
6116     engine.shapeLine(line);
6117
6118     int nItems = engine.layoutData->items.size();
6119     QVarLengthArray<int> visualOrder(nItems);
6120     QVarLengthArray<uchar> levels(nItems);
6121     for (int i = 0; i < nItems; ++i)
6122         levels[i] = engine.layoutData->items[i].analysis.bidiLevel;
6123     QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());
6124
6125     if (justificationPadding > 0) {
6126         engine.option.setAlignment(Qt::AlignJustify);
6127         engine.forceJustification = true;
6128         // this works because justify() is only interested in the difference between width and textWidth
6129         line.width = justificationPadding;
6130         engine.justify(line);
6131     }
6132     QFixed x = QFixed::fromReal(p.x());
6133
6134     for (int i = 0; i < nItems; ++i) {
6135         int item = visualOrder[i];
6136         const QScriptItem &si = engine.layoutData->items.at(item);
6137         if (si.analysis.flags >= QScriptAnalysis::TabOrObject) {
6138             x += si.width;
6139             continue;
6140         }
6141         QFont f = engine.font(si);
6142         QTextItemInt gf(si, &f);
6143         gf.glyphs = engine.shapedGlyphs(&si);
6144         gf.chars = engine.layoutData->string.unicode() + si.position;
6145         gf.num_chars = engine.length(item);
6146         if (engine.forceJustification) {
6147             for (int j=0; j<gf.glyphs.numGlyphs; ++j)
6148                 gf.width += gf.glyphs.effectiveAdvance(j);
6149         } else {
6150             gf.width = si.width;
6151         }
6152         gf.logClusters = engine.logClusters(&si);
6153
6154         drawTextItem(QPointF(x.toReal(), p.y()), gf);
6155
6156         x += gf.width;
6157     }
6158 }
6159
6160 void QPainter::drawText(const QRect &r, int flags, const QString &str, QRect *br)
6161 {
6162 #ifdef QT_DEBUG_DRAW
6163     if (qt_show_painter_debug_output)
6164         printf("QPainter::drawText(), r=[%d,%d,%d,%d], flags=%d, str='%s'\n",
6165            r.x(), r.y(), r.width(), r.height(), flags, str.toLatin1().constData());
6166 #endif
6167
6168     Q_D(QPainter);
6169
6170     if (!d->engine || str.length() == 0 || pen().style() == Qt::NoPen)
6171         return;
6172
6173     if (!d->extended)
6174         d->updateState(d->state);
6175
6176     QRectF bounds;
6177     qt_format_text(d->state->font, r, flags, 0, str, br ? &bounds : 0, 0, 0, 0, this);
6178     if (br)
6179         *br = bounds.toAlignedRect();
6180 }
6181
6182 /*!
6183     \fn void QPainter::drawText(const QPoint &position, const QString &text)
6184
6185     \overload
6186
6187     Draws the given \a text with the currently defined text direction,
6188     beginning at the given \a position.
6189
6190     By default, QPainter draws text anti-aliased.
6191
6192     \note The y-position is used as the baseline of the font.
6193
6194 */
6195
6196 /*!
6197     \fn void QPainter::drawText(const QRectF &rectangle, int flags, const QString &text, QRectF *boundingRect)
6198     \overload
6199
6200     Draws the given \a text within the provided \a rectangle.
6201
6202     \table 100%
6203     \row
6204     \o \inlineimage qpainter-text.png
6205     \o
6206     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 17
6207     \endtable
6208
6209     The \a boundingRect (if not null) is set to the what the bounding rectangle
6210     should be in order to enclose the whole text. The \a flags argument is a bitwise
6211     OR of the following flags:
6212
6213     \list
6214     \o Qt::AlignLeft
6215     \o Qt::AlignRight
6216     \o Qt::AlignHCenter
6217     \o Qt::AlignJustify
6218     \o Qt::AlignTop
6219     \o Qt::AlignBottom
6220     \o Qt::AlignVCenter
6221     \o Qt::AlignCenter
6222     \o Qt::TextDontClip
6223     \o Qt::TextSingleLine
6224     \o Qt::TextExpandTabs
6225     \o Qt::TextShowMnemonic
6226     \o Qt::TextWordWrap
6227     \o Qt::TextIncludeTrailingSpaces
6228     \endlist
6229
6230     \sa Qt::AlignmentFlag, Qt::TextFlag, boundingRect(), layoutDirection()
6231
6232     By default, QPainter draws text anti-aliased.
6233
6234     \note The y-coordinate of \a rectangle is used as the top of the font.
6235 */
6236 void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF *br)
6237 {
6238 #ifdef QT_DEBUG_DRAW
6239     if (qt_show_painter_debug_output)
6240         printf("QPainter::drawText(), r=[%.2f,%.2f,%.2f,%.2f], flags=%d, str='%s'\n",
6241            r.x(), r.y(), r.width(), r.height(), flags, str.toLatin1().constData());
6242 #endif
6243
6244     Q_D(QPainter);
6245
6246     if (!d->engine || str.length() == 0 || pen().style() == Qt::NoPen)
6247         return;
6248
6249     if (!d->extended)
6250         d->updateState(d->state);
6251
6252     qt_format_text(d->state->font, r, flags, 0, str, br, 0, 0, 0, this);
6253 }
6254
6255 /*!
6256     \fn void QPainter::drawText(const QRect &rectangle, int flags, const QString &text, QRect *boundingRect)
6257     \overload
6258
6259     Draws the given \a text within the provided \a rectangle according
6260     to the specified \a flags. The \a boundingRect (if not null) is set to
6261     the what the bounding rectangle should be in order to enclose the whole text.
6262
6263     By default, QPainter draws text anti-aliased.
6264
6265     \note The y-coordinate of \a rectangle is used as the top of the font.
6266 */
6267
6268 /*!
6269     \fn void QPainter::drawText(int x, int y, const QString &text)
6270
6271     \overload
6272
6273     Draws the given \a text at position (\a{x}, \a{y}), using the painter's
6274     currently defined text direction.
6275
6276     By default, QPainter draws text anti-aliased.
6277
6278     \note The y-position is used as the baseline of the font.
6279
6280 */
6281
6282 /*!
6283     \fn void QPainter::drawText(int x, int y, int width, int height, int flags,
6284                                 const QString &text, QRect *boundingRect)
6285
6286     \overload
6287
6288     Draws the given \a text within the rectangle with origin (\a{x},
6289     \a{y}), \a width and \a height.
6290
6291     The \a boundingRect (if not null) is set to the actual bounding
6292     rectangle of the output.  The \a flags argument is a bitwise OR of
6293     the following flags:
6294
6295     \list
6296     \o Qt::AlignLeft
6297     \o Qt::AlignRight
6298     \o Qt::AlignHCenter
6299     \o Qt::AlignJustify
6300     \o Qt::AlignTop
6301     \o Qt::AlignBottom
6302     \o Qt::AlignVCenter
6303     \o Qt::AlignCenter
6304     \o Qt::TextSingleLine
6305     \o Qt::TextExpandTabs
6306     \o Qt::TextShowMnemonic
6307     \o Qt::TextWordWrap
6308     \endlist
6309
6310     By default, QPainter draws text anti-aliased.
6311
6312     \note The y-position is used as the top of the font.
6313
6314     \sa Qt::AlignmentFlag, Qt::TextFlag
6315 */
6316
6317 /*!
6318     \fn void QPainter::drawText(const QRectF &rectangle, const QString &text,
6319         const QTextOption &option)
6320     \overload
6321
6322     Draws the given \a text in the \a rectangle specified using the \a option
6323     to control its positioning and orientation.
6324
6325     By default, QPainter draws text anti-aliased.
6326
6327     \note The y-coordinate of \a rectangle is used as the top of the font.
6328 */
6329 void QPainter::drawText(const QRectF &r, const QString &text, const QTextOption &o)
6330 {
6331 #ifdef QT_DEBUG_DRAW
6332     if (qt_show_painter_debug_output)
6333         printf("QPainter::drawText(), r=[%.2f,%.2f,%.2f,%.2f], str='%s'\n",
6334            r.x(), r.y(), r.width(), r.height(), text.toLatin1().constData());
6335 #endif
6336
6337     Q_D(QPainter);
6338
6339     if (!d->engine || text.length() == 0 || pen().style() == Qt::NoPen)
6340         return;
6341
6342     if (!d->extended)
6343         d->updateState(d->state);
6344
6345     qt_format_text(d->state->font, r, 0, &o, text, 0, 0, 0, 0, this);
6346 }
6347
6348 /*!
6349     \fn void QPainter::drawTextItem(int x, int y, const QTextItem &ti)
6350
6351     \internal
6352     \overload
6353 */
6354
6355 /*!
6356     \fn void QPainter::drawTextItem(const QPoint &p, const QTextItem &ti)
6357
6358     \internal
6359     \overload
6360
6361     Draws the text item \a ti at position \a p.
6362 */
6363
6364 /*!
6365     \fn void QPainter::drawTextItem(const QPointF &p, const QTextItem &ti)
6366
6367     \internal
6368     \since 4.1
6369
6370     Draws the text item \a ti at position \a p.
6371
6372     This method ignores the painters background mode and
6373     color. drawText and qt_format_text have to do it themselves, as
6374     only they know the extents of the complete string.
6375
6376     It ignores the font set on the painter as the text item has one of its own.
6377
6378     The underline and strikeout parameters of the text items font are
6379     ignored aswell. You'll need to pass in the correct flags to get
6380     underlining and strikeout.
6381 */
6382
6383 static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
6384 {
6385     const qreal radiusBase = qMax(qreal(1), maxRadius);
6386
6387     QString key = QLatin1Literal("WaveUnderline-")
6388                   % pen.color().name()
6389                   % HexString<qreal>(radiusBase);
6390
6391     QPixmap pixmap;
6392     if (QPixmapCache::find(key, pixmap))
6393         return pixmap;
6394
6395     const qreal halfPeriod = qMax(qreal(2), qreal(radiusBase * 1.61803399)); // the golden ratio
6396     const int width = qCeil(100 / (2 * halfPeriod)) * (2 * halfPeriod);
6397     const int radius = qFloor(radiusBase);
6398
6399     QPainterPath path;
6400
6401     qreal xs = 0;
6402     qreal ys = radius;
6403
6404     while (xs < width) {
6405         xs += halfPeriod;
6406         ys = -ys;
6407         path.quadTo(xs - halfPeriod / 2, ys, xs, 0);
6408     }
6409
6410     pixmap = QPixmap(width, radius * 2);
6411     pixmap.fill(Qt::transparent);
6412     {
6413         QPen wavePen = pen;
6414         wavePen.setCapStyle(Qt::SquareCap);
6415
6416         // This is to protect against making the line too fat, as happens on Mac OS X
6417         // due to it having a rather thick width for the regular underline.
6418         const qreal maxPenWidth = .8 * radius;
6419         if (wavePen.widthF() > maxPenWidth)
6420             wavePen.setWidth(maxPenWidth);
6421
6422         QPainter imgPainter(&pixmap);
6423         imgPainter.setPen(wavePen);
6424         imgPainter.setRenderHint(QPainter::Antialiasing);
6425         imgPainter.translate(0, radius);
6426         imgPainter.drawPath(path);
6427     }
6428
6429     QPixmapCache::insert(key, pixmap);
6430
6431     return pixmap;
6432 }
6433
6434 static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe,
6435                                    QTextCharFormat::UnderlineStyle underlineStyle,
6436                                    QTextItem::RenderFlags flags, qreal width,
6437                                    const QTextCharFormat &charFormat)
6438 {
6439     if (underlineStyle == QTextCharFormat::NoUnderline
6440         && !(flags & (QTextItem::StrikeOut | QTextItem::Overline)))
6441         return;
6442
6443     const QPen oldPen = painter->pen();
6444     const QBrush oldBrush = painter->brush();
6445     painter->setBrush(Qt::NoBrush);
6446     QPen pen = oldPen;
6447     pen.setStyle(Qt::SolidLine);
6448     pen.setWidthF(fe->lineThickness().toReal());
6449     pen.setCapStyle(Qt::FlatCap);
6450
6451     QLineF line(pos.x(), pos.y(), pos.x() + qFloor(width), pos.y());
6452
6453     const qreal underlineOffset = fe->underlinePosition().toReal();
6454     // deliberately ceil the offset to avoid the underline coming too close to
6455     // the text above it.
6456     const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
6457     const qreal underlinePos = pos.y() + qCeil(underlineOffset) - aliasedCoordinateDelta;
6458
6459     if (underlineStyle == QTextCharFormat::SpellCheckUnderline) {
6460         underlineStyle = QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle));
6461     }
6462
6463     if (underlineStyle == QTextCharFormat::WaveUnderline) {
6464         painter->save();
6465         painter->translate(0, pos.y() + 1);
6466
6467         QColor uc = charFormat.underlineColor();
6468         if (uc.isValid())
6469             pen.setColor(uc);
6470
6471         // Adapt wave to underlineOffset or pen width, whatever is larger, to make it work on all platforms
6472         const QPixmap wave = generateWavyPixmap(qMax(underlineOffset, pen.widthF()), pen);
6473         const int descent = (int) fe->descent().toReal();
6474
6475         painter->setBrushOrigin(painter->brushOrigin().x(), 0);
6476         painter->fillRect(pos.x(), 0, qCeil(width), qMin(wave.height(), descent), wave);
6477         painter->restore();
6478     } else if (underlineStyle != QTextCharFormat::NoUnderline) {
6479         QLineF underLine(line.x1(), underlinePos, line.x2(), underlinePos);
6480
6481         QColor uc = charFormat.underlineColor();
6482         if (uc.isValid())
6483             pen.setColor(uc);
6484
6485         pen.setStyle((Qt::PenStyle)(underlineStyle));
6486         painter->setPen(pen);
6487         painter->drawLine(underLine);
6488     }
6489
6490     pen.setStyle(Qt::SolidLine);
6491     pen.setColor(oldPen.color());
6492
6493     if (flags & QTextItem::StrikeOut) {
6494         QLineF strikeOutLine = line;
6495         strikeOutLine.translate(0., - fe->ascent().toReal() / 3.);
6496         painter->setPen(pen);
6497         painter->drawLine(strikeOutLine);
6498     }
6499
6500     if (flags & QTextItem::Overline) {
6501         QLineF overLine = line;
6502         overLine.translate(0., - fe->ascent().toReal());
6503         painter->setPen(pen);
6504         painter->drawLine(overLine);
6505     }
6506
6507     painter->setPen(oldPen);
6508     painter->setBrush(oldBrush);
6509 }
6510
6511 Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray,
6512                                                 const QFixedPoint *positions, int glyphCount,
6513                                                 QFontEngine *fontEngine, const QFont &font,
6514                                                 const QTextCharFormat &charFormat)
6515 {
6516     if (!(font.underline() || font.strikeOut() || font.overline()))
6517         return;
6518
6519     QFixed leftMost;
6520     QFixed rightMost;
6521     QFixed baseLine;
6522     for (int i=0; i<glyphCount; ++i) {
6523         glyph_metrics_t gm = fontEngine->boundingBox(glyphArray[i]);
6524         if (i == 0 || leftMost > positions[i].x)
6525             leftMost = positions[i].x;
6526
6527         // We don't support glyphs that do not share a common baseline. If this turns out to
6528         // be a relevant use case, then we need to find clusters of glyphs that share a baseline
6529         // and do a drawTextItemDecorations call per cluster.
6530         if (i == 0 || baseLine < positions[i].y)
6531             baseLine = positions[i].y;
6532
6533         // We use the advance rather than the actual bounds to match the algorithm in drawText()
6534         if (i == 0 || rightMost < positions[i].x + gm.xoff)
6535             rightMost = positions[i].x + gm.xoff;
6536     }
6537
6538     QFixed width = rightMost - leftMost;
6539     QTextItem::RenderFlags flags = 0;
6540
6541     if (font.underline())
6542         flags |= QTextItem::Underline;
6543     if (font.overline())
6544         flags |= QTextItem::Overline;
6545     if (font.strikeOut())
6546         flags |= QTextItem::StrikeOut;
6547
6548     drawTextItemDecoration(painter, QPointF(leftMost.toReal(), baseLine.toReal()),
6549                            fontEngine,
6550                            font.underline() ? QTextCharFormat::SingleUnderline
6551                                             : QTextCharFormat::NoUnderline, flags,
6552                            width.toReal(), charFormat);
6553 }
6554
6555 void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
6556 {
6557 #ifdef QT_DEBUG_DRAW
6558     if (qt_show_painter_debug_output)
6559         printf("QPainter::drawTextItem(), pos=[%.f,%.f], str='%s'\n",
6560                p.x(), p.y(), qPrintable(_ti.text()));
6561 #endif
6562
6563     Q_D(QPainter);
6564
6565     if (!d->engine)
6566         return;
6567
6568 #ifndef QT_NO_DEBUG
6569     qt_painter_thread_test(d->device->devType(),
6570                            "text and fonts",
6571                            QFontDatabase::supportsThreadedFontRendering());
6572 #endif
6573
6574     QTextItemInt &ti = const_cast<QTextItemInt &>(static_cast<const QTextItemInt &>(_ti));
6575
6576     if (!d->extended && d->state->bgMode == Qt::OpaqueMode) {
6577         QRectF rect(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent + 1).toReal());
6578         fillRect(rect, d->state->bgBrush);
6579     }
6580
6581     if (pen().style() == Qt::NoPen)
6582         return;
6583
6584     const RenderHints oldRenderHints = d->state->renderHints;
6585     if (!d->state->renderHints & QPainter::Antialiasing && d->state->matrix.type() >= QTransform::TxScale) {
6586         // draw antialias decoration (underline/overline/strikeout) with
6587         // transformed text
6588
6589         bool aa = true;
6590         const QTransform &m = d->state->matrix;
6591         if (d->state->matrix.type() < QTransform::TxShear) {
6592             bool isPlain90DegreeRotation =
6593                 (qFuzzyIsNull(m.m11())
6594                  && qFuzzyIsNull(m.m12() - qreal(1))
6595                  && qFuzzyIsNull(m.m21() + qreal(1))
6596                  && qFuzzyIsNull(m.m22())
6597                     )
6598                 ||
6599                 (qFuzzyIsNull(m.m11() + qreal(1))
6600                  && qFuzzyIsNull(m.m12())
6601                  && qFuzzyIsNull(m.m21())
6602                  && qFuzzyIsNull(m.m22() + qreal(1))
6603                     )
6604                 ||
6605                 (qFuzzyIsNull(m.m11())
6606                  && qFuzzyIsNull(m.m12() + qreal(1))
6607                  && qFuzzyIsNull(m.m21() - qreal(1))
6608                  && qFuzzyIsNull(m.m22())
6609                     )
6610                 ;
6611             aa = !isPlain90DegreeRotation;
6612         }
6613         if (aa)
6614             setRenderHint(QPainter::Antialiasing, true);
6615     }
6616
6617     if (!d->extended)
6618         d->updateState(d->state);
6619
6620     if (!ti.glyphs.numGlyphs) {
6621         // nothing to do
6622     } else if (ti.fontEngine->type() == QFontEngine::Multi) {
6623         QFontEngineMulti *multi = static_cast<QFontEngineMulti *>(ti.fontEngine);
6624
6625         const QGlyphLayout &glyphs = ti.glyphs;
6626         int which = glyphs.glyphs[0] >> 24;
6627
6628         qreal x = p.x();
6629         qreal y = p.y();
6630
6631         int start = 0;
6632         int end, i;
6633         for (end = 0; end < ti.glyphs.numGlyphs; ++end) {
6634             const int e = glyphs.glyphs[end] >> 24;
6635             if (e == which)
6636                 continue;
6637
6638
6639             QTextItemInt ti2 = ti.midItem(multi->engine(which), start, end - start);
6640             ti2.width = 0;
6641             // set the high byte to zero and calc the width
6642             for (i = start; i < end; ++i) {
6643                 glyphs.glyphs[i] = glyphs.glyphs[i] & 0xffffff;
6644                 ti2.width += ti.glyphs.effectiveAdvance(i);
6645             }
6646
6647             d->engine->drawTextItem(QPointF(x, y), ti2);
6648
6649             // reset the high byte for all glyphs and advance to the next sub-string
6650             const int hi = which << 24;
6651             for (i = start; i < end; ++i) {
6652                 glyphs.glyphs[i] = hi | glyphs.glyphs[i];
6653             }
6654             x += ti2.width.toReal();
6655
6656             // change engine
6657             start = end;
6658             which = e;
6659         }
6660
6661         QTextItemInt ti2 = ti.midItem(multi->engine(which), start, end - start);
6662         ti2.width = 0;
6663         // set the high byte to zero and calc the width
6664         for (i = start; i < end; ++i) {
6665             glyphs.glyphs[i] = glyphs.glyphs[i] & 0xffffff;
6666             ti2.width += ti.glyphs.effectiveAdvance(i);
6667         }
6668
6669         if (d->extended)
6670             d->extended->drawTextItem(QPointF(x, y), ti2);
6671         else
6672             d->engine->drawTextItem(QPointF(x,y), ti2);
6673
6674         // reset the high byte for all glyphs
6675         const int hi = which << 24;
6676         for (i = start; i < end; ++i)
6677             glyphs.glyphs[i] = hi | glyphs.glyphs[i];
6678
6679     } else {
6680         if (d->extended)
6681             d->extended->drawTextItem(p, ti);
6682         else
6683             d->engine->drawTextItem(p, ti);
6684     }
6685     drawTextItemDecoration(this, p, ti.fontEngine, ti.underlineStyle, ti.flags, ti.width.toReal(),
6686                            ti.charFormat);
6687
6688     if (d->state->renderHints != oldRenderHints) {
6689         d->state->renderHints = oldRenderHints;
6690         if (d->extended)
6691             d->extended->renderHintsChanged();
6692         else
6693             d->state->dirtyFlags |= QPaintEngine::DirtyHints;
6694     }
6695 }
6696
6697 /*!
6698     \fn QRectF QPainter::boundingRect(const QRectF &rectangle, int flags, const QString &text)
6699
6700     Returns the bounding rectangle of the \a text as it will appear
6701     when drawn inside the given \a rectangle with the specified \a
6702     flags using the currently set font(); i.e the function tells you
6703     where the drawText() function will draw when given the same
6704     arguments.
6705
6706     If the \a text does not fit within the given \a rectangle using
6707     the specified \a flags, the function returns the required
6708     rectangle.
6709
6710     The \a flags argument is a bitwise OR of the following flags:
6711     \list
6712          \o Qt::AlignLeft
6713          \o Qt::AlignRight
6714          \o Qt::AlignHCenter
6715          \o Qt::AlignTop
6716          \o Qt::AlignBottom
6717          \o Qt::AlignVCenter
6718          \o Qt::AlignCenter
6719          \o Qt::TextSingleLine
6720          \o Qt::TextExpandTabs
6721          \o Qt::TextShowMnemonic
6722          \o Qt::TextWordWrap
6723          \o Qt::TextIncludeTrailingSpaces
6724     \endlist
6725     If several of the horizontal or several of the vertical alignment
6726     flags are set, the resulting alignment is undefined.
6727
6728     \sa drawText(), Qt::Alignment, Qt::TextFlag
6729 */
6730
6731 /*!
6732     \fn QRect QPainter::boundingRect(const QRect &rectangle, int flags,
6733                                      const QString &text)
6734
6735     \overload
6736
6737     Returns the bounding rectangle of the \a text as it will appear
6738     when drawn inside the given \a rectangle with the specified \a
6739     flags using the currently set font().
6740 */
6741
6742 /*!
6743     \fn QRect QPainter::boundingRect(int x, int y, int w, int h, int flags,
6744                                      const QString &text);
6745
6746     \overload
6747
6748     Returns the bounding rectangle of the given \a text as it will
6749     appear when drawn inside the rectangle beginning at the point
6750     (\a{x}, \a{y}) with width \a w and height \a h.
6751 */
6752 QRect QPainter::boundingRect(const QRect &rect, int flags, const QString &str)
6753 {
6754     if (str.isEmpty())
6755         return QRect(rect.x(),rect.y(), 0,0);
6756     QRect brect;
6757     drawText(rect, flags | Qt::TextDontPrint, str, &brect);
6758     return brect;
6759 }
6760
6761
6762
6763 QRectF QPainter::boundingRect(const QRectF &rect, int flags, const QString &str)
6764 {
6765     if (str.isEmpty())
6766         return QRectF(rect.x(),rect.y(), 0,0);
6767     QRectF brect;
6768     drawText(rect, flags | Qt::TextDontPrint, str, &brect);
6769     return brect;
6770 }
6771
6772 /*!
6773     \fn QRectF QPainter::boundingRect(const QRectF &rectangle,
6774         const QString &text, const QTextOption &option)
6775
6776     \overload
6777
6778     Instead of specifying flags as a bitwise OR of the
6779     Qt::AlignmentFlag and Qt::TextFlag, this overloaded function takes
6780     an \a option argument. The QTextOption class provides a
6781     description of general rich text properties.
6782
6783     \sa QTextOption
6784 */
6785 QRectF QPainter::boundingRect(const QRectF &r, const QString &text, const QTextOption &o)
6786 {
6787     Q_D(QPainter);
6788
6789     if (!d->engine || text.length() == 0)
6790         return QRectF(r.x(),r.y(), 0,0);
6791
6792     QRectF br;
6793     qt_format_text(d->state->font, r, Qt::TextDontPrint, &o, text, &br, 0, 0, 0, this);
6794     return br;
6795 }
6796
6797 /*!
6798     \fn void QPainter::drawTiledPixmap(const QRectF &rectangle, const QPixmap &pixmap, const QPointF &position)
6799
6800     Draws a tiled \a pixmap, inside the given \a rectangle with its
6801     origin at the given \a position.
6802
6803     Calling drawTiledPixmap() is similar to calling drawPixmap()
6804     several times to fill (tile) an area with a pixmap, but is
6805     potentially much more efficient depending on the underlying window
6806     system.
6807
6808     \sa drawPixmap()
6809 */
6810 void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &sp)
6811 {
6812 #ifdef QT_DEBUG_DRAW
6813     if (qt_show_painter_debug_output)
6814         printf("QPainter::drawTiledPixmap(), target=[%.2f,%.2f,%.2f,%.2f], pix=[%d,%d], offset=[%.2f,%.2f]\n",
6815                r.x(), r.y(), r.width(), r.height(),
6816                pixmap.width(), pixmap.height(),
6817                sp.x(), sp.y());
6818 #endif
6819
6820     Q_D(QPainter);
6821     if (!d->engine || pixmap.isNull() || r.isEmpty())
6822         return;
6823
6824 #ifndef QT_NO_DEBUG
6825     qt_painter_thread_test(d->device->devType(), "drawTiledPixmap()", true);
6826 #endif
6827
6828     qreal sw = pixmap.width();
6829     qreal sh = pixmap.height();
6830     qreal sx = sp.x();
6831     qreal sy = sp.y();
6832     if (sx < 0)
6833         sx = qRound(sw) - qRound(-sx) % qRound(sw);
6834     else
6835         sx = qRound(sx) % qRound(sw);
6836     if (sy < 0)
6837         sy = qRound(sh) - -qRound(sy) % qRound(sh);
6838     else
6839         sy = qRound(sy) % qRound(sh);
6840
6841
6842     if (d->extended) {
6843         d->extended->drawTiledPixmap(r, pixmap, QPointF(sx, sy));
6844         return;
6845     }
6846
6847     if (d->state->bgMode == Qt::OpaqueMode && pixmap.isQBitmap())
6848         fillRect(r, d->state->bgBrush);
6849
6850     d->updateState(d->state);
6851     if ((d->state->matrix.type() > QTransform::TxTranslate
6852         && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
6853         || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity)))
6854     {
6855         save();
6856         setBackgroundMode(Qt::TransparentMode);
6857         setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
6858         setBrush(QBrush(d->state->pen.color(), pixmap));
6859         setPen(Qt::NoPen);
6860
6861         // If there is no rotation involved we have to make sure we use the
6862         // antialiased and not the aliased coordinate system by rounding the coordinates.
6863         if (d->state->matrix.type() <= QTransform::TxScale) {
6864             const QPointF p = roundInDeviceCoordinates(r.topLeft(), d->state->matrix);
6865
6866             if (d->state->matrix.type() <= QTransform::TxTranslate) {
6867                 sx = qRound(sx);
6868                 sy = qRound(sy);
6869             }
6870
6871             setBrushOrigin(QPointF(r.x()-sx, r.y()-sy));
6872             drawRect(QRectF(p, r.size()));
6873         } else {
6874             setBrushOrigin(QPointF(r.x()-sx, r.y()-sy));
6875             drawRect(r);
6876         }
6877         restore();
6878         return;
6879     }
6880
6881     qreal x = r.x();
6882     qreal y = r.y();
6883     if (d->state->matrix.type() == QTransform::TxTranslate
6884         && !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
6885         x += d->state->matrix.dx();
6886         y += d->state->matrix.dy();
6887     }
6888
6889     d->engine->drawTiledPixmap(QRectF(x, y, r.width(), r.height()), pixmap, QPointF(sx, sy));
6890 }
6891
6892 /*!
6893     \fn QPainter::drawTiledPixmap(const QRect &rectangle, const QPixmap &pixmap,
6894                                   const QPoint &position = QPoint())
6895     \overload
6896
6897     Draws a tiled \a pixmap, inside the given \a rectangle with its
6898     origin at the given \a position.
6899 */
6900
6901 /*!
6902     \fn void QPainter::drawTiledPixmap(int x, int y, int width, int height, const
6903          QPixmap &pixmap, int sx, int sy);
6904     \overload
6905
6906     Draws a tiled \a pixmap in the specified rectangle.
6907
6908     (\a{x}, \a{y}) specifies the top-left point in the paint device
6909     that is to be drawn onto; with the given \a width and \a
6910     height. (\a{sx}, \a{sy}) specifies the top-left point in the \a
6911     pixmap that is to be drawn; this defaults to (0, 0).
6912 */
6913
6914 #ifndef QT_NO_PICTURE
6915
6916 /*!
6917     \fn void QPainter::drawPicture(const QPointF &point, const QPicture &picture)
6918
6919     Replays the given \a picture at the given \a point.
6920
6921     The QPicture class is a paint device that records and replays
6922     QPainter commands. A picture serializes the painter commands to an
6923     IO device in a platform-independent format. Everything that can be
6924     painted on a widget or pixmap can also be stored in a picture.
6925
6926     This function does exactly the same as QPicture::play() when
6927     called with \a point = QPoint(0, 0).
6928
6929     \table 100%
6930     \row
6931     \o
6932     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 18
6933     \endtable
6934
6935     \sa QPicture::play()
6936 */
6937
6938 void QPainter::drawPicture(const QPointF &p, const QPicture &picture)
6939 {
6940     Q_D(QPainter);
6941
6942     if (!d->engine)
6943         return;
6944
6945     if (!d->extended)
6946         d->updateState(d->state);
6947
6948     save();
6949     translate(p);
6950     const_cast<QPicture *>(&picture)->play(this);
6951     restore();
6952 }
6953
6954 /*!
6955     \fn void QPainter::drawPicture(const QPoint &point, const QPicture &picture)
6956     \overload
6957
6958     Replays the given \a picture at the given \a point.
6959 */
6960
6961 /*!
6962     \fn void QPainter::drawPicture(int x, int y, const QPicture &picture)
6963     \overload
6964
6965     Draws the given \a picture at point (\a x, \a y).
6966 */
6967
6968 #endif // QT_NO_PICTURE
6969
6970 /*!
6971     \fn void QPainter::eraseRect(const QRectF &rectangle)
6972
6973     Erases the area inside the given \a rectangle. Equivalent to
6974     calling
6975     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 19
6976
6977     \sa fillRect()
6978 */
6979 void QPainter::eraseRect(const QRectF &r)
6980 {
6981     Q_D(QPainter);
6982
6983     fillRect(r, d->state->bgBrush);
6984 }
6985
6986 static inline bool needsResolving(const QBrush &brush)
6987 {
6988     Qt::BrushStyle s = brush.style();
6989     return ((s == Qt::LinearGradientPattern || s == Qt::RadialGradientPattern ||
6990              s == Qt::ConicalGradientPattern) &&
6991             brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode);
6992 }
6993
6994 /*!
6995     \fn void QPainter::eraseRect(const QRect &rectangle)
6996     \overload
6997
6998     Erases the area inside the given  \a rectangle.
6999 */
7000
7001 /*!
7002     \fn void QPainter::eraseRect(int x, int y, int width, int height)
7003     \overload
7004
7005     Erases the area inside the rectangle beginning at (\a x, \a y)
7006     with the given \a width and \a height.
7007 */
7008
7009
7010 /*!
7011     \fn void QPainter::fillRect(int x, int y, int width, int height, Qt::BrushStyle style)
7012     \overload
7013
7014     Fills the rectangle beginning at (\a{x}, \a{y}) with the given \a
7015     width and \a height, using the brush \a style specified.
7016
7017     \since 4.5
7018 */
7019
7020 /*!
7021     \fn void QPainter::fillRect(const QRect &rectangle, Qt::BrushStyle style)
7022     \overload
7023
7024     Fills the given \a rectangle  with the brush \a style specified.
7025
7026     \since 4.5
7027 */
7028
7029 /*!
7030     \fn void QPainter::fillRect(const QRectF &rectangle, Qt::BrushStyle style)
7031     \overload
7032
7033     Fills the given \a rectangle  with the brush \a style specified.
7034
7035     \since 4.5
7036 */
7037
7038 /*!
7039     \fn void QPainter::fillRect(const QRectF &rectangle, const QBrush &brush)
7040
7041     Fills the given \a rectangle  with the \a brush specified.
7042
7043     Alternatively, you can specify a QColor instead of a QBrush; the
7044     QBrush constructor (taking a QColor argument) will automatically
7045     create a solid pattern brush.
7046
7047     \sa drawRect()
7048 */
7049 void QPainter::fillRect(const QRectF &r, const QBrush &brush)
7050 {
7051     Q_D(QPainter);
7052
7053     if (!d->engine)
7054         return;
7055
7056     if (d->extended) {
7057         const QGradient *g = brush.gradient();
7058         if (!g || g->coordinateMode() == QGradient::LogicalMode) {
7059             d->extended->fillRect(r, brush);
7060             return;
7061         }
7062     }
7063
7064     QPen oldPen = pen();
7065     QBrush oldBrush = this->brush();
7066     setPen(Qt::NoPen);
7067     if (brush.style() == Qt::SolidPattern) {
7068         d->colorBrush.setStyle(Qt::SolidPattern);
7069         d->colorBrush.setColor(brush.color());
7070         setBrush(d->colorBrush);
7071     } else {
7072         setBrush(brush);
7073     }
7074
7075     drawRect(r);
7076     setBrush(oldBrush);
7077     setPen(oldPen);
7078 }
7079
7080 /*!
7081     \fn void QPainter::fillRect(const QRect &rectangle, const QBrush &brush)
7082     \overload
7083
7084     Fills the given \a rectangle with the specified \a brush.
7085 */
7086
7087 void QPainter::fillRect(const QRect &r, const QBrush &brush)
7088 {
7089     Q_D(QPainter);
7090
7091     if (!d->engine)
7092         return;
7093
7094     if (d->extended) {
7095         const QGradient *g = brush.gradient();
7096         if (!g || g->coordinateMode() == QGradient::LogicalMode) {
7097             d->extended->fillRect(r, brush);
7098             return;
7099         }
7100     }
7101
7102     QPen oldPen = pen();
7103     QBrush oldBrush = this->brush();
7104     setPen(Qt::NoPen);
7105     if (brush.style() == Qt::SolidPattern) {
7106         d->colorBrush.setStyle(Qt::SolidPattern);
7107         d->colorBrush.setColor(brush.color());
7108         setBrush(d->colorBrush);
7109     } else {
7110         setBrush(brush);
7111     }
7112
7113     drawRect(r);
7114     setBrush(oldBrush);
7115     setPen(oldPen);
7116 }
7117
7118
7119
7120 /*!
7121     \fn void QPainter::fillRect(const QRect &rectangle, const QColor &color)
7122     \overload
7123
7124     Fills the given \a rectangle with the \a color specified.
7125
7126     \since 4.5
7127 */
7128 void QPainter::fillRect(const QRect &r, const QColor &color)
7129 {
7130     Q_D(QPainter);
7131
7132     if (!d->engine)
7133         return;
7134
7135     if (d->extended) {
7136         d->extended->fillRect(r, color);
7137         return;
7138     }
7139
7140     fillRect(r, QBrush(color));
7141 }
7142
7143
7144 /*!
7145     \fn void QPainter::fillRect(const QRectF &rectangle, const QColor &color)
7146     \overload
7147
7148     Fills the given \a rectangle with the \a color specified.
7149
7150     \since 4.5
7151 */
7152 void QPainter::fillRect(const QRectF &r, const QColor &color)
7153 {
7154     Q_D(QPainter);
7155
7156     if (!d->engine)
7157         return;
7158
7159     if (d->extended) {
7160         d->extended->fillRect(r, color);
7161         return;
7162     }
7163
7164     fillRect(r, QBrush(color));
7165 }
7166
7167 /*!
7168     \fn void QPainter::fillRect(int x, int y, int width, int height, const QBrush &brush)
7169
7170     \overload
7171
7172     Fills the rectangle beginning at (\a{x}, \a{y}) with the given \a
7173     width and \a height, using the given \a brush.
7174 */
7175
7176 /*!
7177     \fn void QPainter::fillRect(int x, int y, int width, int height, const QColor &color)
7178
7179     \overload
7180
7181     Fills the rectangle beginning at (\a{x}, \a{y}) with the given \a
7182     width and \a height, using the given \a color.
7183
7184     \since 4.5
7185 */
7186
7187 /*!
7188     \fn void QPainter::fillRect(int x, int y, int width, int height, Qt::GlobalColor color)
7189
7190     \overload
7191
7192     Fills the rectangle beginning at (\a{x}, \a{y}) with the given \a
7193     width and \a height, using the given \a color.
7194
7195     \since 4.5
7196 */
7197
7198 /*!
7199     \fn void QPainter::fillRect(const QRect &rectangle, Qt::GlobalColor color);
7200
7201     \overload
7202
7203     Fills the given \a rectangle with the specified \a color.
7204
7205     \since 4.5
7206 */
7207
7208 /*!
7209     \fn void QPainter::fillRect(const QRectF &rectangle, Qt::GlobalColor color);
7210
7211     \overload
7212
7213     Fills the given \a rectangle with the specified \a color.
7214
7215     \since 4.5
7216 */
7217
7218 /*!
7219     Sets the given render \a hint on the painter if \a on is true;
7220     otherwise clears the render hint.
7221
7222     \sa setRenderHints(), renderHints(), {QPainter#Rendering
7223     Quality}{Rendering Quality}
7224 */
7225 void QPainter::setRenderHint(RenderHint hint, bool on)
7226 {
7227 #ifdef QT_DEBUG_DRAW
7228     if (qt_show_painter_debug_output)
7229         printf("QPainter::setRenderHint: hint=%x, %s\n", hint, on ? "on" : "off");
7230 #endif
7231
7232 #ifndef QT_NO_DEBUG
7233     static const bool antialiasingDisabled = qgetenv("QT_NO_ANTIALIASING").toInt();
7234     if (hint == QPainter::Antialiasing && antialiasingDisabled)
7235         return;
7236 #endif
7237
7238     setRenderHints(hint, on);
7239 }
7240
7241 /*!
7242     \since 4.2
7243
7244     Sets the given render \a hints on the painter if \a on is true;
7245     otherwise clears the render hints.
7246
7247     \sa setRenderHint(), renderHints(), {QPainter#Rendering
7248     Quality}{Rendering Quality}
7249 */
7250
7251 void QPainter::setRenderHints(RenderHints hints, bool on)
7252 {
7253     Q_D(QPainter);
7254
7255     if (!d->engine) {
7256         qWarning("QPainter::setRenderHint: Painter must be active to set rendering hints");
7257         return;
7258     }
7259
7260     if (on)
7261         d->state->renderHints |= hints;
7262     else
7263         d->state->renderHints &= ~hints;
7264
7265     if (d->extended)
7266         d->extended->renderHintsChanged();
7267     else
7268         d->state->dirtyFlags |= QPaintEngine::DirtyHints;
7269 }
7270
7271 /*!
7272     Returns a flag that specifies the rendering hints that are set for
7273     this painter.
7274
7275     \sa testRenderHint(), {QPainter#Rendering Quality}{Rendering Quality}
7276 */
7277 QPainter::RenderHints QPainter::renderHints() const
7278 {
7279     Q_D(const QPainter);
7280
7281     if (!d->engine)
7282         return 0;
7283
7284     return d->state->renderHints;
7285 }
7286
7287 /*!
7288     \fn bool QPainter::testRenderHint(RenderHint hint) const
7289     \since 4.3
7290
7291     Returns true if \a hint is set; otherwise returns false.
7292
7293     \sa renderHints(), setRenderHint()
7294 */
7295
7296 /*!
7297     Returns true if view transformation is enabled; otherwise returns
7298     false.
7299
7300     \sa setViewTransformEnabled(), worldTransform()
7301 */
7302
7303 bool QPainter::viewTransformEnabled() const
7304 {
7305     Q_D(const QPainter);
7306     if (!d->engine) {
7307         qWarning("QPainter::viewTransformEnabled: Painter not active");
7308         return false;
7309     }
7310     return d->state->VxF;
7311 }
7312
7313 /*!
7314     \fn void QPainter::setWindow(const QRect &rectangle)
7315
7316     Sets the painter's window to the given \a rectangle, and enables
7317     view transformations.
7318
7319     The window rectangle is part of the view transformation. The
7320     window specifies the logical coordinate system. Its sister, the
7321     viewport(), specifies the device coordinate system.
7322
7323     The default window rectangle is the same as the device's
7324     rectangle.
7325
7326     \sa window(), viewTransformEnabled(), {Coordinate
7327     System#Window-Viewport Conversion}{Window-Viewport Conversion}
7328 */
7329
7330 /*!
7331     \fn void QPainter::setWindow(int x, int y, int width, int height)
7332     \overload
7333
7334     Sets the painter's window to the rectangle beginning at (\a x, \a
7335     y) and the given \a width and \a height.
7336 */
7337
7338 void QPainter::setWindow(const QRect &r)
7339 {
7340 #ifdef QT_DEBUG_DRAW
7341     if (qt_show_painter_debug_output)
7342         printf("QPainter::setWindow(), [%d,%d,%d,%d]\n", r.x(), r.y(), r.width(), r.height());
7343 #endif
7344
7345     Q_D(QPainter);
7346
7347     if (!d->engine) {
7348         qWarning("QPainter::setWindow: Painter not active");
7349         return;
7350     }
7351
7352     d->state->wx = r.x();
7353     d->state->wy = r.y();
7354     d->state->ww = r.width();
7355     d->state->wh = r.height();
7356
7357     d->state->VxF = true;
7358     d->updateMatrix();
7359 }
7360
7361 /*!
7362     Returns the window rectangle.
7363
7364     \sa setWindow(), setViewTransformEnabled()
7365 */
7366
7367 QRect QPainter::window() const
7368 {
7369     Q_D(const QPainter);
7370     if (!d->engine) {
7371         qWarning("QPainter::window: Painter not active");
7372         return QRect();
7373     }
7374     return QRect(d->state->wx, d->state->wy, d->state->ww, d->state->wh);
7375 }
7376
7377 /*!
7378     \fn void QPainter::setViewport(const QRect &rectangle)
7379
7380     Sets the painter's viewport rectangle to the given \a rectangle,
7381     and enables view transformations.
7382
7383     The viewport rectangle is part of the view transformation. The
7384     viewport specifies the device coordinate system. Its sister, the
7385     window(), specifies the logical coordinate system.
7386
7387     The default viewport rectangle is the same as the device's
7388     rectangle.
7389
7390     \sa viewport(), viewTransformEnabled() {Coordinate
7391     System#Window-Viewport Conversion}{Window-Viewport Conversion}
7392 */
7393
7394 /*!
7395     \fn void QPainter::setViewport(int x, int y, int width, int height)
7396     \overload
7397
7398     Sets the painter's viewport rectangle to be the rectangle
7399     beginning at (\a x, \a y) with the given \a width and \a height.
7400 */
7401
7402 void QPainter::setViewport(const QRect &r)
7403 {
7404 #ifdef QT_DEBUG_DRAW
7405     if (qt_show_painter_debug_output)
7406         printf("QPainter::setViewport(), [%d,%d,%d,%d]\n", r.x(), r.y(), r.width(), r.height());
7407 #endif
7408
7409     Q_D(QPainter);
7410
7411     if (!d->engine) {
7412         qWarning("QPainter::setViewport: Painter not active");
7413         return;
7414     }
7415
7416     d->state->vx = r.x();
7417     d->state->vy = r.y();
7418     d->state->vw = r.width();
7419     d->state->vh = r.height();
7420
7421     d->state->VxF = true;
7422     d->updateMatrix();
7423 }
7424
7425 /*!
7426     Returns the viewport rectangle.
7427
7428     \sa setViewport(), setViewTransformEnabled()
7429 */
7430
7431 QRect QPainter::viewport() const
7432 {
7433     Q_D(const QPainter);
7434     if (!d->engine) {
7435         qWarning("QPainter::viewport: Painter not active");
7436         return QRect();
7437     }
7438     return QRect(d->state->vx, d->state->vy, d->state->vw, d->state->vh);
7439 }
7440
7441 /*! \fn bool QPainter::hasViewXForm() const
7442     \compat
7443
7444     Use viewTransformEnabled() instead.
7445 */
7446
7447 /*! \fn bool QPainter::hasWorldXForm() const
7448     \compat
7449
7450     Use worldMatrixEnabled() instead.
7451 */
7452
7453 /*! \fn void QPainter::resetXForm()
7454     \compat
7455
7456     Use resetTransform() instead.
7457 */
7458
7459 /*! \fn void QPainter::setViewXForm(bool enabled)
7460     \compat
7461
7462     Use setViewTransformEnabled() instead.
7463 */
7464
7465 /*! \fn void QPainter::setWorldXForm(bool enabled)
7466     \compat
7467
7468     Use setWorldMatrixEnabled() instead.
7469 */
7470 /*!
7471     Enables view transformations if \a enable is true, or disables
7472     view transformations if \a enable is false.
7473
7474     \sa viewTransformEnabled(), {Coordinate System#Window-Viewport
7475     Conversion}{Window-Viewport Conversion}
7476 */
7477
7478 void QPainter::setViewTransformEnabled(bool enable)
7479 {
7480 #ifdef QT_DEBUG_DRAW
7481     if (qt_show_painter_debug_output)
7482         printf("QPainter::setViewTransformEnabled(), enable=%d\n", enable);
7483 #endif
7484
7485     Q_D(QPainter);
7486
7487     if (!d->engine) {
7488         qWarning("QPainter::setViewTransformEnabled: Painter not active");
7489         return;
7490     }
7491
7492     if (enable == d->state->VxF)
7493         return;
7494
7495     d->state->VxF = enable;
7496     d->updateMatrix();
7497 }
7498
7499 #ifdef QT3_SUPPORT
7500
7501 /*!
7502     \obsolete
7503
7504     Use the worldTransform() combined with QTransform::dx() instead.
7505
7506     \oldcode
7507         QPainter painter(this);
7508         qreal x = painter.translationX();
7509     \newcode
7510         QPainter painter(this);
7511         qreal x = painter.worldTransform().dx();
7512     \endcode
7513 */
7514 qreal QPainter::translationX() const
7515 {
7516     Q_D(const QPainter);
7517     if (!d->engine) {
7518         qWarning("QPainter::translationX: Painter not active");
7519         return 0.0;
7520     }
7521     return d->state->worldMatrix.dx();
7522 }
7523
7524 /*!
7525     \obsolete
7526
7527     Use the worldTransform() combined with QTransform::dy() instead.
7528
7529     \oldcode
7530         QPainter painter(this);
7531         qreal y = painter.translationY();
7532     \newcode
7533         QPainter painter(this);
7534         qreal y = painter.worldTransform().dy();
7535     \endcode
7536 */
7537 qreal QPainter::translationY() const
7538 {
7539     Q_D(const QPainter);
7540     if (!d->engine) {
7541         qWarning("QPainter::translationY: Painter not active");
7542         return 0.0;
7543     }
7544     return d->state->worldMatrix.dy();
7545 }
7546
7547 /*!
7548     \fn void QPainter::map(int x, int y, int *rx, int *ry) const
7549
7550     \internal
7551
7552     Sets (\a{rx}, \a{ry}) to the point that results from applying the
7553     painter's current transformation on the point (\a{x}, \a{y}).
7554 */
7555 void QPainter::map(int x, int y, int *rx, int *ry) const
7556 {
7557     QPoint p(x, y);
7558     p = p * combinedMatrix();
7559     *rx = p.x();
7560     *ry = p.y();
7561 }
7562
7563 /*!
7564     \fn QPoint QPainter::xForm(const QPoint &point) const
7565
7566     Use combinedTransform() instead.
7567 */
7568
7569 QPoint QPainter::xForm(const QPoint &p) const
7570 {
7571     Q_D(const QPainter);
7572     if (!d->engine) {
7573         qWarning("QPainter::xForm: Painter not active");
7574         return QPoint();
7575     }
7576     if (d->state->matrix.type() == QTransform::TxNone)
7577         return p;
7578     return p * combinedMatrix();
7579 }
7580
7581
7582 /*!
7583     \fn QRect QPainter::xForm(const QRect &rectangle) const
7584     \overload
7585
7586     Use combinedTransform() instead of this function and call
7587     mapRect() on the result to obtain a QRect.
7588 */
7589
7590 QRect QPainter::xForm(const QRect &r) const
7591 {
7592     Q_D(const QPainter);
7593     if (!d->engine) {
7594         qWarning("QPainter::xForm: Painter not active");
7595         return QRect();
7596     }
7597     if (d->state->matrix.type() == QTransform::TxNone)
7598         return r;
7599     return combinedMatrix().mapRect(r);
7600 }
7601
7602 /*!
7603     \fn QPolygon QPainter::xForm(const QPolygon &polygon) const
7604     \overload
7605
7606     Use combinedTransform() instead.
7607 */
7608
7609 QPolygon QPainter::xForm(const QPolygon &a) const
7610 {
7611     Q_D(const QPainter);
7612     if (!d->engine) {
7613         qWarning("QPainter::xForm: Painter not active");
7614         return QPolygon();
7615     }
7616     if (d->state->matrix.type() == QTransform::TxNone)
7617         return a;
7618     return a * combinedMatrix();
7619 }
7620
7621 /*!
7622     \fn QPolygon QPainter::xForm(const QPolygon &polygon, int index, int count) const
7623     \overload
7624
7625     Use combinedTransform() combined with QPolygon::mid() instead.
7626
7627     \oldcode
7628         QPainter painter(this);
7629         QPolygon transformed = painter.xForm(polygon, index, count)
7630     \newcode
7631         QPainter painter(this);
7632         QPolygon transformed = polygon.mid(index, count) * painter.combinedTransform();
7633     \endcode
7634 */
7635
7636 QPolygon QPainter::xForm(const QPolygon &av, int index, int npoints) const
7637 {
7638     int lastPoint = npoints < 0 ? av.size() : index+npoints;
7639     QPolygon a(lastPoint-index);
7640     memcpy(a.data(), av.data()+index, (lastPoint-index)*sizeof(QPoint));
7641     return a * combinedMatrix();
7642 }
7643
7644 /*!
7645     \fn QPoint QPainter::xFormDev(const QPoint &point) const
7646     \overload
7647     \obsolete
7648
7649     Use combinedTransform() combined with QTransform::inverted() instead.
7650
7651     \oldcode
7652         QPainter painter(this);
7653         QPoint transformed = painter.xFormDev(point);
7654     \newcode
7655         QPainter painter(this);
7656         QPoint transformed = point * painter.combinedTransform().inverted();
7657     \endcode
7658 */
7659
7660 QPoint QPainter::xFormDev(const QPoint &p) const
7661 {
7662     Q_D(const QPainter);
7663     if (!d->engine) {
7664         qWarning("QPainter::xFormDev: Painter not active");
7665         return QPoint();
7666     }
7667     if(d->state->matrix.type() == QTransform::TxNone)
7668         return p;
7669     return p * combinedMatrix().inverted();
7670 }
7671
7672 /*!
7673     \fn QRect QPainter::xFormDev(const QRect &rectangle) const
7674     \overload
7675     \obsolete
7676
7677     Use combinedTransform() combined with QTransform::inverted() instead.
7678
7679     \oldcode
7680         QPainter painter(this);
7681         QRect transformed = painter.xFormDev(rectangle);
7682     \newcode
7683         QPainter painter(this);
7684         QRegion region = QRegion(rectangle) * painter.combinedTransform().inverted();
7685         QRect transformed = region.boundingRect();
7686     \endcode
7687 */
7688
7689 QRect QPainter::xFormDev(const QRect &r)  const
7690 {
7691     Q_D(const QPainter);
7692     if (!d->engine) {
7693         qWarning("QPainter::xFormDev: Painter not active");
7694         return QRect();
7695     }
7696     if (d->state->matrix.type() == QTransform::TxNone)
7697         return r;
7698     return combinedMatrix().inverted().mapRect(r);
7699 }
7700
7701 /*!
7702     \overload
7703
7704     \fn QPoint QPainter::xFormDev(const QPolygon &polygon) const
7705     \obsolete
7706
7707     Use  combinedTransform() combined with QTransform::inverted() instead.
7708
7709     \oldcode
7710         QPainter painter(this);
7711         QPolygon transformed = painter.xFormDev(rectangle);
7712     \newcode
7713         QPainter painter(this);
7714         QPolygon transformed = polygon * painter.combinedTransform().inverted();
7715     \endcode
7716 */
7717
7718 QPolygon QPainter::xFormDev(const QPolygon &a) const
7719 {
7720     Q_D(const QPainter);
7721     if (!d->engine) {
7722         qWarning("QPainter::xFormDev: Painter not active");
7723         return QPolygon();
7724     }
7725     if (d->state->matrix.type() == QTransform::TxNone)
7726         return a;
7727     return a * combinedMatrix().inverted();
7728 }
7729
7730 /*!
7731     \fn QPolygon QPainter::xFormDev(const QPolygon &polygon, int index, int count) const
7732     \overload
7733     \obsolete
7734
7735     Use combinedTransform() combined with QPolygon::mid() and QTransform::inverted() instead.
7736
7737     \oldcode
7738         QPainter painter(this);
7739         QPolygon transformed = painter.xFormDev(polygon, index, count);
7740     \newcode
7741         QPainter painter(this);
7742         QPolygon transformed = polygon.mid(index, count) * painter.combinedTransform().inverted();
7743     \endcode
7744 */
7745
7746 QPolygon QPainter::xFormDev(const QPolygon &ad, int index, int npoints) const
7747 {
7748     Q_D(const QPainter);
7749     int lastPoint = npoints < 0 ? ad.size() : index+npoints;
7750     QPolygon a(lastPoint-index);
7751     memcpy(a.data(), ad.data()+index, (lastPoint-index)*sizeof(QPoint));
7752     if (d->state->matrix.type() == QTransform::TxNone)
7753         return a;
7754     return a * combinedMatrix().inverted();
7755 }
7756
7757 /*!
7758     \fn void QPainter::drawCubicBezier(const QPolygon &controlPoints, int index)
7759
7760     Draws a cubic Bezier curve defined by the \a controlPoints,
7761     starting at \a{controlPoints}\e{[index]} (\a index defaults to 0).
7762     Points after \a{controlPoints}\e{[index + 3]} are ignored. Nothing
7763     happens if there aren't enough control points.
7764
7765     Use strokePath() instead.
7766
7767     \oldcode
7768              QPainter painter(this);
7769              painter.drawCubicBezier(controlPoints, index)
7770     \newcode
7771              QPainterPath path;
7772              path.moveTo(controlPoints.at(index));
7773              path.cubicTo(controlPoints.at(index+1),
7774                                  controlPoints.at(index+2),
7775                                  controlPoints.at(index+3));
7776
7777              QPainter painter(this);
7778              painter.strokePath(path, painter.pen());
7779     \endcode
7780 */
7781 void QPainter::drawCubicBezier(const QPolygon &a, int index)
7782 {
7783     Q_D(QPainter);
7784
7785     if (!d->engine)
7786         return;
7787
7788     if ((int)a.size() - index < 4) {
7789         qWarning("QPainter::drawCubicBezier: Cubic Bezier needs 4 control "
7790                   "points");
7791         return;
7792     }
7793
7794     QPainterPath path;
7795     path.moveTo(a.at(index));
7796     path.cubicTo(a.at(index+1), a.at(index+2), a.at(index+3));
7797     strokePath(path, d->state->pen);
7798 }
7799 #endif
7800
7801 struct QPaintDeviceRedirection
7802 {
7803     QPaintDeviceRedirection() : device(0), replacement(0), internalWidgetRedirectionIndex(-1) {}
7804     QPaintDeviceRedirection(const QPaintDevice *device, QPaintDevice *replacement,
7805                             const QPoint& offset, int internalWidgetRedirectionIndex)
7806         : device(device), replacement(replacement), offset(offset),
7807           internalWidgetRedirectionIndex(internalWidgetRedirectionIndex) { }
7808     const QPaintDevice *device;
7809     QPaintDevice *replacement;
7810     QPoint offset;
7811     int internalWidgetRedirectionIndex;
7812     bool operator==(const QPaintDevice *pdev) const { return device == pdev; }
7813     Q_DUMMY_COMPARISON_OPERATOR(QPaintDeviceRedirection)
7814 };
7815
7816 typedef QList<QPaintDeviceRedirection> QPaintDeviceRedirectionList;
7817 Q_GLOBAL_STATIC(QPaintDeviceRedirectionList, globalRedirections)
7818 Q_GLOBAL_STATIC(QMutex, globalRedirectionsMutex)
7819 Q_GLOBAL_STATIC(QAtomicInt, globalRedirectionAtomic)
7820
7821 /*!
7822     \threadsafe
7823
7824     \obsolete
7825
7826     Please use QWidget::render() instead.
7827
7828     Redirects all paint commands for the given paint \a device, to the
7829     \a replacement device. The optional point \a offset defines an
7830     offset within the source device.
7831
7832     The redirection will not be effective until the begin() function
7833     has been called; make sure to call end() for the given \a
7834     device's painter (if any) before redirecting. Call
7835     restoreRedirected() to restore the previous redirection.
7836
7837     \warning Making use of redirections in the QPainter API implies
7838     that QPainter::begin() and QPaintDevice destructors need to hold
7839     a mutex for a short period. This can impact performance. Use of
7840     QWidget::render is strongly encouraged.
7841
7842     \sa redirected(), restoreRedirected()
7843 */
7844 void QPainter::setRedirected(const QPaintDevice *device,
7845                              QPaintDevice *replacement,
7846                              const QPoint &offset)
7847 {
7848     Q_ASSERT(device != 0);
7849
7850     bool hadInternalWidgetRedirection = false;
7851     if (device->devType() == QInternal::Widget) {
7852         const QWidgetPrivate *widgetPrivate = static_cast<const QWidget *>(device)->d_func();
7853         // This is the case when the widget is in a paint event.
7854         if (widgetPrivate->redirectDev) {
7855             // Remove internal redirection and put it back into the global redirection list.
7856             QPoint oldOffset;
7857             QPaintDevice *oldReplacement = widgetPrivate->redirected(&oldOffset);
7858             const_cast<QWidgetPrivate *>(widgetPrivate)->restoreRedirected();
7859             setRedirected(device, oldReplacement, oldOffset);
7860             hadInternalWidgetRedirection = true;
7861         }
7862     }
7863
7864     QPoint roffset;
7865     QPaintDevice *rdev = redirected(replacement, &roffset);
7866
7867     QMutexLocker locker(globalRedirectionsMutex());
7868     QPaintDeviceRedirectionList *redirections = globalRedirections();
7869     Q_ASSERT(redirections != 0);
7870     *redirections += QPaintDeviceRedirection(device, rdev ? rdev : replacement, offset + roffset,
7871                                              hadInternalWidgetRedirection ? redirections->size() - 1 : -1);
7872     globalRedirectionAtomic()->ref();
7873 }
7874
7875 /*!
7876     \threadsafe
7877
7878     \obsolete
7879
7880     Using QWidget::render() obsoletes the use of this function.
7881
7882     Restores the previous redirection for the given \a device after a
7883     call to setRedirected().
7884
7885     \warning Making use of redirections in the QPainter API implies
7886     that QPainter::begin() and QPaintDevice destructors need to hold
7887     a mutex for a short period. This can impact performance. Use of
7888     QWidget::render is strongly encouraged.
7889
7890     \sa redirected()
7891  */
7892 void QPainter::restoreRedirected(const QPaintDevice *device)
7893 {
7894     Q_ASSERT(device != 0);
7895     QMutexLocker locker(globalRedirectionsMutex());
7896     QPaintDeviceRedirectionList *redirections = globalRedirections();
7897     Q_ASSERT(redirections != 0);
7898     for (int i = redirections->size()-1; i >= 0; --i) {
7899         if (redirections->at(i) == device) {
7900             globalRedirectionAtomic()->deref();
7901             const int internalWidgetRedirectionIndex = redirections->at(i).internalWidgetRedirectionIndex;
7902             redirections->removeAt(i);
7903             // Restore the internal widget redirection, i.e. remove it from the global
7904             // redirection list and put it back into QWidgetPrivate. The index is only set when
7905             // someone call QPainter::setRedirected in a widget's paint event and we internally
7906             // have a redirection set (typically set in QWidgetPrivate::drawWidget).
7907             if (internalWidgetRedirectionIndex >= 0) {
7908                 Q_ASSERT(internalWidgetRedirectionIndex < redirections->size());
7909                 const QPaintDeviceRedirection &redirectionDevice = redirections->at(internalWidgetRedirectionIndex);
7910                 QWidget *widget = static_cast<QWidget *>(const_cast<QPaintDevice *>(device));
7911                 widget->d_func()->setRedirected(redirectionDevice.replacement, redirectionDevice.offset);
7912                 redirections->removeAt(internalWidgetRedirectionIndex);
7913             }
7914             return;
7915         }
7916     }
7917 }
7918
7919 /*!
7920     \threadsafe
7921
7922     \obsolete
7923
7924     Using QWidget::render() obsoletes the use of this function.
7925
7926     Returns the replacement for given \a device. The optional out
7927     parameter \a offset returns the offset within the replaced device.
7928
7929     \warning Making use of redirections in the QPainter API implies
7930     that QPainter::begin() and QPaintDevice destructors need to hold
7931     a mutex for a short period. This can impact performance. Use of
7932     QWidget::render is strongly encouraged.
7933
7934     \sa setRedirected(), restoreRedirected()
7935 */
7936 QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
7937 {
7938     Q_ASSERT(device != 0);
7939
7940     if (device->devType() == QInternal::Widget) {
7941         const QWidgetPrivate *widgetPrivate = static_cast<const QWidget *>(device)->d_func();
7942         if (widgetPrivate->redirectDev)
7943             return widgetPrivate->redirected(offset);
7944     }
7945
7946     if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0)
7947         return 0;
7948
7949     QMutexLocker locker(globalRedirectionsMutex());
7950     QPaintDeviceRedirectionList *redirections = globalRedirections();
7951     Q_ASSERT(redirections != 0);
7952     for (int i = redirections->size()-1; i >= 0; --i)
7953         if (redirections->at(i) == device) {
7954             if (offset)
7955                 *offset = redirections->at(i).offset;
7956             return redirections->at(i).replacement;
7957         }
7958     if (offset)
7959         *offset = QPoint(0, 0);
7960     return 0;
7961 }
7962
7963
7964 void qt_painter_removePaintDevice(QPaintDevice *dev)
7965 {
7966     if (!globalRedirectionAtomic() || *globalRedirectionAtomic() == 0)
7967         return;
7968
7969     QMutex *mutex = 0;
7970     QT_TRY {
7971         mutex = globalRedirectionsMutex();
7972     } QT_CATCH(...) {
7973         // ignore the missing mutex, since we could be called from
7974         // a destructor, and destructors shall not throw
7975     }
7976     QMutexLocker locker(mutex);
7977     QPaintDeviceRedirectionList *redirections = 0;
7978     QT_TRY {
7979         redirections = globalRedirections();
7980     } QT_CATCH(...) {
7981         // do nothing - code below is safe with redirections being 0.
7982     }
7983     if (redirections) {
7984         for (int i = 0; i < redirections->size(); ) {
7985             if(redirections->at(i) == dev || redirections->at(i).replacement == dev)
7986                 redirections->removeAt(i);
7987             else
7988                 ++i;
7989         }
7990     }
7991 }
7992
7993 void qt_format_text(const QFont &fnt, const QRectF &_r,
7994                     int tf, const QString& str, QRectF *brect,
7995                     int tabstops, int *ta, int tabarraylen,
7996                     QPainter *painter)
7997 {
7998     qt_format_text(fnt, _r,
7999                     tf, 0, str, brect,
8000                     tabstops, ta, tabarraylen,
8001                     painter);
8002 }
8003 void qt_format_text(const QFont &fnt, const QRectF &_r,
8004                     int tf, const QTextOption *option, const QString& str, QRectF *brect,
8005                     int tabstops, int *ta, int tabarraylen,
8006                     QPainter *painter)
8007 {
8008
8009     Q_ASSERT( !((tf & ~Qt::TextDontPrint)!=0 && option!=0) ); // we either have an option or flags
8010
8011     if (option) {
8012         tf |= option->alignment();
8013         if (option->wrapMode() != QTextOption::NoWrap)
8014             tf |= Qt::TextWordWrap;
8015
8016         if (option->flags() & QTextOption::IncludeTrailingSpaces)
8017             tf |= Qt::TextIncludeTrailingSpaces;
8018
8019         if (option->tabStop() >= 0 || !option->tabArray().isEmpty())
8020             tf |= Qt::TextExpandTabs;
8021     }
8022
8023     // we need to copy r here to protect against the case (&r == brect).
8024     QRectF r(_r);
8025
8026     bool dontclip  = (tf & Qt::TextDontClip);
8027     bool wordwrap  = (tf & Qt::TextWordWrap) || (tf & Qt::TextWrapAnywhere);
8028     bool singleline = (tf & Qt::TextSingleLine);
8029     bool showmnemonic = (tf & Qt::TextShowMnemonic);
8030     bool hidemnmemonic = (tf & Qt::TextHideMnemonic);
8031
8032     Qt::LayoutDirection layout_direction;
8033     if (tf & Qt::TextForceLeftToRight)
8034         layout_direction = Qt::LeftToRight;
8035     else if (tf & Qt::TextForceRightToLeft)
8036         layout_direction = Qt::RightToLeft;
8037     else if (option)
8038         layout_direction = option->textDirection();
8039     else if (painter)
8040         layout_direction = painter->layoutDirection();
8041     else
8042         layout_direction = Qt::LeftToRight;
8043
8044     tf = QStyle::visualAlignment(layout_direction, QFlag(tf));
8045
8046     bool isRightToLeft = layout_direction == Qt::RightToLeft;
8047     bool expandtabs = ((tf & Qt::TextExpandTabs) &&
8048                         (((tf & Qt::AlignLeft) && !isRightToLeft) ||
8049                           ((tf & Qt::AlignRight) && isRightToLeft)));
8050
8051     if (!painter)
8052         tf |= Qt::TextDontPrint;
8053
8054     uint maxUnderlines = 0;
8055     int numUnderlines = 0;
8056     QVarLengthArray<int, 32> underlinePositions(1);
8057
8058     QFontMetricsF fm(fnt);
8059     QString text = str;
8060     int offset = 0;
8061 start_lengthVariant:
8062     bool hasMoreLengthVariants = false;
8063     // compatible behaviour to the old implementation. Replace
8064     // tabs by spaces
8065     int old_offset = offset;
8066     for (; offset < text.length(); offset++) {
8067         QChar chr = text.at(offset);
8068         if (chr == QLatin1Char('\r') || (singleline && chr == QLatin1Char('\n'))) {
8069             text[offset] = QLatin1Char(' ');
8070         } else if (chr == QLatin1Char('\n')) {
8071             text[offset] = QChar::LineSeparator;
8072         } else if (chr == QLatin1Char('&')) {
8073             ++maxUnderlines;
8074         } else if (chr == QLatin1Char('\t')) {
8075             if (!expandtabs) {
8076                 text[offset] = QLatin1Char(' ');
8077             } else if (!tabarraylen && !tabstops) {
8078                 tabstops = qRound(fm.width(QLatin1Char('x'))*8);
8079             }
8080         } else if (chr == QChar(ushort(0x9c))) {
8081             // string with multiple length variants
8082             hasMoreLengthVariants = true;
8083             break;
8084         }
8085     }
8086
8087     int length = offset - old_offset;
8088     if ((hidemnmemonic || showmnemonic) && maxUnderlines > 0) {
8089         underlinePositions.resize(maxUnderlines + 1);
8090
8091         QChar *cout = text.data() + old_offset;
8092         QChar *cin = cout;
8093         int l = length;
8094         while (l) {
8095             if (*cin == QLatin1Char('&')) {
8096                 ++cin;
8097                 --length;
8098                 --l;
8099                 if (!l)
8100                     break;
8101                 if (*cin != QLatin1Char('&') && !hidemnmemonic)
8102                     underlinePositions[numUnderlines++] = cout - text.data() - old_offset;
8103             }
8104             *cout = *cin;
8105             ++cout;
8106             ++cin;
8107             --l;
8108         }
8109     }
8110
8111     // no need to do extra work for underlines if we don't paint
8112     if (tf & Qt::TextDontPrint)
8113         numUnderlines = 0;
8114
8115     underlinePositions[numUnderlines] = -1;
8116     qreal height = 0;
8117     qreal width = 0;
8118
8119     QString finalText = text.mid(old_offset, length);
8120     QStackTextEngine engine(finalText, fnt);
8121     if (option) {
8122         engine.option = *option;
8123     }
8124
8125     if (engine.option.tabStop() < 0 && tabstops > 0)
8126         engine.option.setTabStop(tabstops);
8127
8128     if (engine.option.tabs().isEmpty() && ta) {
8129         QList<qreal> tabs;
8130         for (int i = 0; i < tabarraylen; i++)
8131             tabs.append(qreal(ta[i]));
8132         engine.option.setTabArray(tabs);
8133     }
8134
8135     engine.option.setTextDirection(layout_direction);
8136     if (tf & Qt::AlignJustify)
8137         engine.option.setAlignment(Qt::AlignJustify);
8138     else
8139         engine.option.setAlignment(Qt::AlignLeft); // do not do alignment twice
8140
8141     if (!option && (tf & Qt::TextWrapAnywhere))
8142         engine.option.setWrapMode(QTextOption::WrapAnywhere);
8143
8144     if (tf & Qt::TextJustificationForced)
8145         engine.forceJustification = true;
8146     QTextLayout textLayout(&engine);
8147     textLayout.setCacheEnabled(true);
8148     textLayout.engine()->underlinePositions = underlinePositions.data();
8149
8150     if (finalText.isEmpty()) {
8151         height = fm.height();
8152         width = 0;
8153         tf |= Qt::TextDontPrint;
8154     } else {
8155         qreal lineWidth = 0x01000000;
8156         if (wordwrap || (tf & Qt::TextJustificationForced))
8157             lineWidth = qMax<qreal>(0, r.width());
8158         if(!wordwrap)
8159             tf |= Qt::TextIncludeTrailingSpaces;
8160         textLayout.engine()->ignoreBidi = bool(tf & Qt::TextDontPrint);
8161         textLayout.beginLayout();
8162
8163         qreal leading = fm.leading();
8164         height = -leading;
8165
8166         while (1) {
8167             QTextLine l = textLayout.createLine();
8168             if (!l.isValid())
8169                 break;
8170
8171             l.setLineWidth(lineWidth);
8172             height += leading;
8173             l.setPosition(QPointF(0., height));
8174             height += l.height();
8175             width = qMax(width, l.naturalTextWidth());
8176             if (!dontclip && !brect && height >= r.height())
8177                 break;
8178         }
8179         textLayout.endLayout();
8180     }
8181
8182     qreal yoff = 0;
8183     qreal xoff = 0;
8184     if (tf & Qt::AlignBottom) {
8185         yoff = r.height() - height;
8186     } else if (tf & Qt::AlignVCenter) {
8187         yoff = (r.height() - height)/2;
8188         if (painter) {
8189             QTransform::TransformationType type = painter->transform().type();
8190             if (type <= QTransform::TxScale) {
8191                 // do the rounding manually to work around inconsistencies
8192                 // in the paint engines when drawing on floating point offsets
8193                 const qreal scale = painter->transform().m22();
8194                 if (scale != 0)
8195                     yoff = -qRound(-yoff * scale) / scale;
8196             }
8197         }
8198     }
8199     if (tf & Qt::AlignRight) {
8200         xoff = r.width() - width;
8201     } else if (tf & Qt::AlignHCenter) {
8202         xoff = (r.width() - width)/2;
8203         if (painter) {
8204             QTransform::TransformationType type = painter->transform().type();
8205             if (type <= QTransform::TxScale) {
8206                 // do the rounding manually to work around inconsistencies
8207                 // in the paint engines when drawing on floating point offsets
8208                 const qreal scale = painter->transform().m11();
8209                 if (scale != 0)
8210                     xoff = qRound(xoff * scale) / scale;
8211             }
8212         }
8213     }
8214     QRectF bounds = QRectF(r.x() + xoff, r.y() + yoff, width, height);
8215
8216     if (hasMoreLengthVariants && !(tf & Qt::TextLongestVariant) && !r.contains(bounds)) {
8217         offset++;
8218         goto start_lengthVariant;
8219     }
8220     if (brect)
8221         *brect = bounds;
8222
8223     if (!(tf & Qt::TextDontPrint)) {
8224         bool restore = false;
8225         if (!dontclip && !r.contains(bounds)) {
8226             restore = true;
8227             painter->save();
8228             painter->setClipRect(r, Qt::IntersectClip);
8229         }
8230
8231         for (int i = 0; i < textLayout.lineCount(); i++) {
8232             QTextLine line = textLayout.lineAt(i);
8233
8234             qreal advance = line.horizontalAdvance();
8235             xoff = 0;
8236             if (tf & Qt::AlignRight) {
8237                 QTextEngine *eng = textLayout.engine();
8238                 xoff = r.width() - advance -
8239                     eng->leadingSpaceWidth(eng->lines[line.lineNumber()]).toReal();
8240             }
8241             else if (tf & Qt::AlignHCenter)
8242                 xoff = (r.width() - advance) / 2;
8243
8244             line.draw(painter, QPointF(r.x() + xoff, r.y() + yoff));
8245         }
8246
8247         if (restore) {
8248             painter->restore();
8249         }
8250     }
8251 }
8252
8253 /*!
8254     Sets the layout direction used by the painter when drawing text,
8255     to the specified \a direction.
8256
8257     The default is Qt::LayoutDirectionAuto, which will implicitly determine the
8258     direction from the text drawn.
8259
8260     \sa QTextOption::setTextDirection(), layoutDirection(), drawText(), {QPainter#Settings}{Settings}
8261 */
8262 void QPainter::setLayoutDirection(Qt::LayoutDirection direction)
8263 {
8264     Q_D(QPainter);
8265     if (d->state)
8266         d->state->layoutDirection = direction;
8267 }
8268
8269 /*!
8270     Returns the layout direction used by the painter when drawing text.
8271
8272     \sa QTextOption::textDirection(), setLayoutDirection(), drawText(), {QPainter#Settings}{Settings}
8273 */
8274 Qt::LayoutDirection QPainter::layoutDirection() const
8275 {
8276     Q_D(const QPainter);
8277     return d->state ? d->state->layoutDirection : Qt::LayoutDirectionAuto;
8278 }
8279
8280 QPainterState::QPainterState(const QPainterState *s)
8281     : brushOrigin(s->brushOrigin), font(s->font), deviceFont(s->deviceFont),
8282       pen(s->pen), brush(s->brush), bgBrush(s->bgBrush),
8283       clipRegion(s->clipRegion), clipPath(s->clipPath),
8284       clipOperation(s->clipOperation),
8285       renderHints(s->renderHints), clipInfo(s->clipInfo),
8286       worldMatrix(s->worldMatrix), matrix(s->matrix), redirectionMatrix(s->redirectionMatrix),
8287       wx(s->wx), wy(s->wy), ww(s->ww), wh(s->wh),
8288       vx(s->vx), vy(s->vy), vw(s->vw), vh(s->vh),
8289       opacity(s->opacity), WxF(s->WxF), VxF(s->VxF),
8290       clipEnabled(s->clipEnabled), bgMode(s->bgMode), painter(s->painter),
8291       layoutDirection(s->layoutDirection),
8292       composition_mode(s->composition_mode),
8293       emulationSpecifier(s->emulationSpecifier), changeFlags(0)
8294 {
8295     dirtyFlags = s->dirtyFlags;
8296 }
8297
8298 QPainterState::QPainterState()
8299     : brushOrigin(0, 0), bgBrush(Qt::white), clipOperation(Qt::NoClip),
8300       renderHints(0),
8301       wx(0), wy(0), ww(0), wh(0), vx(0), vy(0), vw(0), vh(0),
8302       opacity(1), WxF(false), VxF(false), clipEnabled(true),
8303       bgMode(Qt::TransparentMode), painter(0),
8304       layoutDirection(QApplication::layoutDirection()),
8305       composition_mode(QPainter::CompositionMode_SourceOver),
8306       emulationSpecifier(0), changeFlags(0)
8307 {
8308     dirtyFlags = 0;
8309 }
8310
8311 QPainterState::~QPainterState()
8312 {
8313 }
8314
8315 void QPainterState::init(QPainter *p) {
8316     bgBrush = Qt::white;
8317     bgMode = Qt::TransparentMode;
8318     WxF = false;
8319     VxF = false;
8320     clipEnabled = true;
8321     wx = wy = ww = wh = 0;
8322     vx = vy = vw = vh = 0;
8323     painter = p;
8324     pen = QPen();
8325     brushOrigin = QPointF(0, 0);
8326     brush = QBrush();
8327     font = deviceFont = QFont();
8328     clipRegion = QRegion();
8329     clipPath = QPainterPath();
8330     clipOperation = Qt::NoClip;
8331     clipInfo.clear();
8332     worldMatrix.reset();
8333     matrix.reset();
8334     layoutDirection = QApplication::layoutDirection();
8335     composition_mode = QPainter::CompositionMode_SourceOver;
8336     emulationSpecifier = 0;
8337     dirtyFlags = 0;
8338     changeFlags = 0;
8339     renderHints = 0;
8340     opacity = 1;
8341 }
8342
8343 #ifdef QT3_SUPPORT
8344 static void bitBlt_helper(QPaintDevice *dst, const QPoint &dp,
8345                           const QPaintDevice *src, const QRect &sr, bool)
8346 {
8347     Q_ASSERT(dst);
8348     Q_ASSERT(src);
8349
8350     if (src->devType() == QInternal::Pixmap) {
8351         const QPixmap *pixmap = static_cast<const QPixmap *>(src);
8352         QPainter pt(dst);
8353         pt.drawPixmap(dp, *pixmap, sr);
8354
8355     } else {
8356         qWarning("QPainter: bitBlt only works when source is of type pixmap");
8357     }
8358 }
8359
8360 void bitBlt(QPaintDevice *dst, int dx, int dy,
8361              const QPaintDevice *src, int sx, int sy, int sw, int sh,
8362              bool ignoreMask )
8363 {
8364     bitBlt_helper(dst, QPoint(dx, dy), src, QRect(sx, sy, sw, sh), ignoreMask);
8365 }
8366
8367 void bitBlt(QPaintDevice *dst, const QPoint &dp, const QPaintDevice *src, const QRect &sr, bool ignoreMask)
8368 {
8369     bitBlt_helper(dst, dp, src, sr, ignoreMask);
8370 }
8371
8372 void bitBlt(QPaintDevice *dst, int dx, int dy,
8373             const QImage *src, int sx, int sy, int sw, int sh, int fl)
8374 {
8375     Qt::ImageConversionFlags flags(fl);
8376     QPixmap srcPixmap = QPixmap::fromImage(*src, flags);
8377     bitBlt_helper(dst, QPoint(dx, dy), &srcPixmap, QRect(sx, sy, sw, sh), false);
8378 }
8379
8380 #endif // QT3_SUPPORT
8381
8382 /*!
8383     \fn void QPainter::setBackgroundColor(const QColor &color)
8384
8385     Use setBackground() instead.
8386 */
8387
8388 /*!
8389     \fn const QColor &QPainter::backgroundColor() const
8390
8391     Use background() and QBrush::color() instead.
8392
8393     \oldcode
8394         QColor myColor = backgroundColor();
8395     \newcode
8396         QColor myColor = background().color();
8397     \endcode
8398
8399     Note that the background can be a complex brush such as a texture
8400     or a gradient.
8401 */
8402
8403 /*!
8404     \fn void QPainter::drawText(int x, int y, const QString &text, int pos, int length)
8405     \compat
8406
8407     Use drawText() combined with QString::mid() instead.
8408
8409     \oldcode
8410         QPainter painter(this);
8411         painter.drawText(x, y, text, pos, length);
8412     \newcode
8413         QPainter painter(this);
8414         painter.drawText(x, y, text.mid(pos, length));
8415     \endcode
8416 */
8417
8418 /*!
8419     \fn void QPainter::drawText(const QPoint &point, const QString &text, int pos, int length)
8420     \compat
8421
8422     Use drawText() combined with QString::mid() instead.
8423
8424     \oldcode
8425         QPainter painter(this);
8426         painter.drawText(point, text, pos, length);
8427     \newcode
8428         QPainter painter(this);
8429         painter.drawText(point, text.mid(pos, length));
8430     \endcode
8431 */
8432
8433 /*!
8434     \fn void QPainter::drawText(int x, int y, const QString &text, int length)
8435     \compat
8436
8437     Use drawText() combined with QString::left() instead.
8438
8439     \oldcode
8440         QPainter painter(this);
8441         painter.drawText(x, y, text, length);
8442     \newcode
8443         QPainter painter(this);
8444         painter.drawText(x, y, text.left(length));
8445     \endcode
8446 */
8447
8448 /*!
8449     \fn void QPainter::drawText(const QPoint &point, const QString &text, int length)
8450     \compat
8451
8452     Use drawText() combined with QString::left() instead.
8453
8454     \oldcode
8455         QPainter painter(this);
8456         painter.drawText(point, text, length);
8457     \newcode
8458         QPainter painter(this);
8459         painter.drawText(point, text.left(length));
8460     \endcode
8461 */
8462
8463 /*!
8464     \fn bool QPainter::begin(QPaintDevice *device, const QWidget *init)
8465     \compat
8466
8467     Use begin() instead.
8468
8469     If the paint \a device is a QWidget, QPainter is initialized after
8470     the widget's settings automatically. Otherwise, you must call the
8471     initFrom() function to initialize the painters pen, background and
8472     font to the same as any given widget.
8473
8474     \oldcode
8475         QPainter painter(this);
8476         painter.begin(device, init);
8477     \newcode
8478         QPainter painter(this);
8479         painter.begin(device);
8480         painter.initFrom(init);
8481     \endcode
8482 */
8483
8484 /*!
8485     \fn void QPainter::drawImage(const QRectF &target, const QImage &image, const QRectF &source,
8486                          Qt::ImageConversionFlags flags)
8487
8488     Draws the rectangular portion \a source of the given \a image
8489     into the \a target rectangle in the paint device.
8490
8491     \note The image is scaled to fit the rectangle, if both the image and rectangle size disagree.
8492
8493     If the image needs to be modified to fit in a lower-resolution
8494     result (e.g. converting from 32-bit to 8-bit), use the \a flags to
8495     specify how you would prefer this to happen.
8496
8497     \table 100%
8498     \row
8499     \o
8500     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 20
8501     \endtable
8502
8503     \sa drawPixmap()
8504 */
8505
8506 /*!
8507     \fn void QPainter::drawImage(const QRect &target, const QImage &image, const QRect &source,
8508                                  Qt::ImageConversionFlags flags)
8509     \overload
8510
8511     Draws the rectangular portion \a source of the given \a image
8512     into the \a target rectangle in the paint device.
8513
8514     \note The image is scaled to fit the rectangle, if both the image and rectangle size disagree.
8515 */
8516
8517 /*!
8518     \fn void QPainter::drawImage(const QPointF &point, const QImage &image)
8519
8520     \overload
8521
8522     Draws the given \a image at the given \a point.
8523 */
8524
8525 /*!
8526     \fn void QPainter::drawImage(const QPoint &point, const QImage &image)
8527
8528     \overload
8529
8530     Draws the given \a image at the given \a point.
8531 */
8532
8533 /*!
8534     \fn void QPainter::drawImage(const QPointF &point, const QImage &image, const QRectF &source,
8535                                  Qt::ImageConversionFlags flags = 0)
8536
8537     \overload
8538
8539     Draws the rectangular portion \a source of the given \a image with
8540     its origin at the given \a point.
8541 */
8542
8543 /*!
8544     \fn void QPainter::drawImage(const QPoint &point, const QImage &image, const QRect &source,
8545                                  Qt::ImageConversionFlags flags = 0)
8546     \overload
8547
8548     Draws the rectangular portion \a source of the given \a image with
8549     its origin at the given \a point.
8550 */
8551
8552 /*!
8553     \fn void QPainter::drawImage(const QRectF &rectangle, const QImage &image)
8554
8555     \overload
8556
8557     Draws the given \a image into the given \a rectangle.
8558
8559     \note The image is scaled to fit the rectangle, if both the image and rectangle size disagree.
8560 */
8561
8562 /*!
8563     \fn void QPainter::drawImage(const QRect &rectangle, const QImage &image)
8564
8565     \overload
8566
8567     Draws the given \a image into the given \a rectangle.
8568
8569    \note The image is scaled to fit the rectangle, if both the image and rectangle size disagree.
8570 */
8571
8572 /*!
8573     \fn void QPainter::drawImage(int x, int y, const QImage &image,
8574                                  int sx, int sy, int sw, int sh,
8575                                  Qt::ImageConversionFlags flags)
8576     \overload
8577
8578     Draws an image at (\a{x}, \a{y}) by copying a part of \a image into
8579     the paint device.
8580
8581     (\a{x}, \a{y}) specifies the top-left point in the paint device that is
8582     to be drawn onto. (\a{sx}, \a{sy}) specifies the top-left point in \a
8583     image that is to be drawn. The default is (0, 0).
8584
8585     (\a{sw}, \a{sh}) specifies the size of the image that is to be drawn.
8586     The default, (0, 0) (and negative) means all the way to the
8587     bottom-right of the image.
8588 */
8589
8590 /*!
8591     \fn void QPainter::redirect(QPaintDevice *pdev, QPaintDevice *replacement)
8592
8593     Use setRedirected() instead.
8594 */
8595
8596 /*!
8597     \fn QPaintDevice *QPainter::redirect(QPaintDevice *pdev)
8598
8599     Use redirected() instead.
8600 */
8601
8602 /*!
8603     \fn QRect QPainter::boundingRect(const QRect &rectangle, int flags,
8604                                      const QString &text, int length)
8605     \compat
8606
8607     Returns the bounding rectangle for the given \a length of the \a
8608     text constrained by the provided \a rectangle.
8609
8610     Use boundingRect() combined with QString::left() instead.
8611
8612     \oldcode
8613         QRect rectangle = boundingRect(rect, flags, text, length);
8614     \newcode
8615         QRect rectangle = boundingRect(rect, flags, text.left(length));
8616     \endcode
8617 */
8618
8619 /*!
8620     \fn void QPainter::drawText(const QRect &rectangle, int flags, const QString &text,
8621                                 int length, QRect *br)
8622     \compat
8623
8624     Use drawText() combined with QString::left() instead.
8625
8626     \oldcode
8627         QPainter painter(this);
8628         painter.drawText(rectangle, flags, text, length, br );
8629     \newcode
8630         QPainter painter(this);
8631         painter.drawText(rectangle, flags, text.left(length), br );
8632     \endcode
8633 */
8634
8635 /*!
8636     \fn QRect QPainter::boundingRect(int x, int y, int width, int height, int flags,
8637                                      const QString &text, int length);
8638
8639     \compat
8640
8641     Returns the bounding rectangle for the given \a length of the \a
8642     text constrained by the rectangle that begins at point (\a{x},
8643     \a{y}) with the given \a width and \a height.
8644
8645     Use boundingRect() combined with QString::left() instead.
8646
8647     \oldcode
8648         QRect rectangle = boundingRect(x, y, width, height, flags, text, length);
8649     \newcode
8650         QRect rectangle = boundingRect(x, y, width, height, flags, text.left(length));
8651     \endcode
8652 */
8653
8654 /*!
8655     \fn void QPainter::drawText(int x, int y, int width, int height, int flags,
8656                                 const QString &text, int length, QRect *br)
8657
8658     \compat
8659
8660     Use drawText() combined with QString::left() instead.
8661
8662     \oldcode
8663         QPainter painter(this);
8664         painter.drawText(x, y, width, height, flags, text, length, br );
8665     \newcode
8666         QPainter painter(this);
8667         painter.drawText(x, y, width, height, flags, text.left(length), br );
8668     \endcode
8669 */
8670
8671
8672 /*!
8673     \class QPaintEngineState
8674     \since 4.1
8675
8676     \brief The QPaintEngineState class provides information about the
8677     active paint engine's current state.
8678     \reentrant
8679
8680     QPaintEngineState records which properties that have changed since
8681     the last time the paint engine was updated, as well as their
8682     current value.
8683
8684     Which properties that have changed can at any time be retrieved
8685     using the state() function. This function returns an instance of
8686     the QPaintEngine::DirtyFlags type which stores an OR combination
8687     of QPaintEngine::DirtyFlag values. The QPaintEngine::DirtyFlag
8688     enum defines whether a property has changed since the last update
8689     or not.
8690
8691     If a property is marked with a dirty flag, its current value can
8692     be retrieved using the corresponding get function:
8693
8694     \target GetFunction
8695
8696     \table
8697     \header \o Property Flag \o Current Property Value
8698     \row \o QPaintEngine::DirtyBackground \o backgroundBrush()
8699     \row \o QPaintEngine::DirtyBackgroundMode \o backgroundMode()
8700     \row \o QPaintEngine::DirtyBrush \o brush()
8701     \row \o QPaintEngine::DirtyBrushOrigin \o brushOrigin()
8702     \row \o QPaintEngine::DirtyClipRegion \e or QPaintEngine::DirtyClipPath
8703          \o clipOperation()
8704     \row \o QPaintEngine::DirtyClipPath \o clipPath()
8705     \row \o QPaintEngine::DirtyClipRegion \o clipRegion()
8706     \row \o QPaintEngine::DirtyCompositionMode \o compositionMode()
8707     \row \o QPaintEngine::DirtyFont \o font()
8708     \row \o QPaintEngine::DirtyTransform \o transform()
8709     \row \o QPaintEngine::DirtyClipEnabled \o isClipEnabled()
8710     \row \o QPaintEngine::DirtyPen \o pen()
8711     \row \o QPaintEngine::DirtyHints \o renderHints()
8712     \endtable
8713
8714     The QPaintEngineState class also provide the painter() function
8715     which returns a pointer to the painter that is currently updating
8716     the paint engine.
8717
8718     An instance of this class, representing the current state of the
8719     active paint engine, is passed as argument to the
8720     QPaintEngine::updateState() function. The only situation in which
8721     you will have to use this class directly is when implementing your
8722     own paint engine.
8723
8724     \sa QPaintEngine
8725 */
8726
8727
8728 /*!
8729     \fn QPaintEngine::DirtyFlags QPaintEngineState::state() const
8730
8731     Returns a combination of flags identifying the set of properties
8732     that need to be updated when updating the paint engine's state
8733     (i.e. during a call to the QPaintEngine::updateState() function).
8734
8735     \sa QPaintEngine::updateState()
8736 */
8737
8738
8739 /*!
8740     Returns the pen in the current paint engine state.
8741
8742     This variable should only be used when the state() returns a
8743     combination which includes the QPaintEngine::DirtyPen flag.
8744
8745     \sa state(), QPaintEngine::updateState()
8746 */
8747
8748 QPen QPaintEngineState::pen() const
8749 {
8750     return static_cast<const QPainterState *>(this)->pen;
8751 }
8752
8753 /*!
8754     Returns the brush in the current paint engine state.
8755
8756     This variable should only be used when the state() returns a
8757     combination which includes the QPaintEngine::DirtyBrush flag.
8758
8759     \sa state(), QPaintEngine::updateState()
8760 */
8761
8762 QBrush QPaintEngineState::brush() const
8763 {
8764     return static_cast<const QPainterState *>(this)->brush;
8765 }
8766
8767 /*!
8768     Returns the brush origin in the current paint engine state.
8769
8770     This variable should only be used when the state() returns a
8771     combination which includes the QPaintEngine::DirtyBrushOrigin flag.
8772
8773     \sa state(), QPaintEngine::updateState()
8774 */
8775
8776 QPointF QPaintEngineState::brushOrigin() const
8777 {
8778     return static_cast<const QPainterState *>(this)->brushOrigin;
8779 }
8780
8781 /*!
8782     Returns the background brush in the current paint engine state.
8783
8784     This variable should only be used when the state() returns a
8785     combination which includes the QPaintEngine::DirtyBackground flag.
8786
8787     \sa state(), QPaintEngine::updateState()
8788 */
8789
8790 QBrush QPaintEngineState::backgroundBrush() const
8791 {
8792     return static_cast<const QPainterState *>(this)->bgBrush;
8793 }
8794
8795 /*!
8796     Returns the background mode in the current paint engine
8797     state.
8798
8799     This variable should only be used when the state() returns a
8800     combination which includes the QPaintEngine::DirtyBackgroundMode flag.
8801
8802     \sa state(), QPaintEngine::updateState()
8803 */
8804
8805 Qt::BGMode QPaintEngineState::backgroundMode() const
8806 {
8807     return static_cast<const QPainterState *>(this)->bgMode;
8808 }
8809
8810 /*!
8811     Returns the font in the current paint engine
8812     state.
8813
8814     This variable should only be used when the state() returns a
8815     combination which includes the QPaintEngine::DirtyFont flag.
8816
8817     \sa state(), QPaintEngine::updateState()
8818 */
8819
8820 QFont QPaintEngineState::font() const
8821 {
8822     return static_cast<const QPainterState *>(this)->font;
8823 }
8824
8825 /*!
8826     \since 4.2
8827     \obsolete
8828
8829     Returns the matrix in the current paint engine
8830     state.
8831
8832     \note It is advisable to use transform() instead of this function to
8833     preserve the properties of perspective transformations.
8834
8835     This variable should only be used when the state() returns a
8836     combination which includes the QPaintEngine::DirtyTransform flag.
8837
8838     \sa state(), QPaintEngine::updateState()
8839 */
8840
8841 QMatrix QPaintEngineState::matrix() const
8842 {
8843     const QPainterState *st = static_cast<const QPainterState *>(this);
8844
8845     return st->matrix.toAffine();
8846 }
8847
8848 /*!
8849     \since 4.3
8850
8851     Returns the matrix in the current paint engine state.
8852
8853     This variable should only be used when the state() returns a
8854     combination which includes the QPaintEngine::DirtyTransform flag.
8855
8856     \sa state(), QPaintEngine::updateState()
8857 */
8858
8859
8860 QTransform QPaintEngineState::transform() const
8861 {
8862     const QPainterState *st = static_cast<const QPainterState *>(this);
8863
8864     return st->matrix;
8865 }
8866
8867
8868 /*!
8869     Returns the clip operation in the current paint engine
8870     state.
8871
8872     This variable should only be used when the state() returns a
8873     combination which includes either the QPaintEngine::DirtyClipPath
8874     or the QPaintEngine::DirtyClipRegion flag.
8875
8876     \sa state(), QPaintEngine::updateState()
8877 */
8878
8879 Qt::ClipOperation QPaintEngineState::clipOperation() const
8880 {
8881     return static_cast<const QPainterState *>(this)->clipOperation;
8882 }
8883
8884 /*!
8885     \since 4.3
8886
8887     Returns whether the coordinate of the fill have been specified
8888     as bounded by the current rendering operation and have to be
8889     resolved (about the currently rendered primitive).
8890 */
8891 bool QPaintEngineState::brushNeedsResolving() const
8892 {
8893     const QBrush &brush = static_cast<const QPainterState *>(this)->brush;
8894     return needsResolving(brush);
8895 }
8896
8897
8898 /*!
8899     \since 4.3
8900
8901     Returns whether the coordinate of the stroke have been specified
8902     as bounded by the current rendering operation and have to be
8903     resolved (about the currently rendered primitive).
8904 */
8905 bool QPaintEngineState::penNeedsResolving() const
8906 {
8907     const QPen &pen = static_cast<const QPainterState *>(this)->pen;
8908     return needsResolving(pen.brush());
8909 }
8910
8911 /*!
8912     Returns the clip region in the current paint engine state.
8913
8914     This variable should only be used when the state() returns a
8915     combination which includes the QPaintEngine::DirtyClipRegion flag.
8916
8917     \sa state(), QPaintEngine::updateState()
8918 */
8919
8920 QRegion QPaintEngineState::clipRegion() const
8921 {
8922     return static_cast<const QPainterState *>(this)->clipRegion;
8923 }
8924
8925 /*!
8926     Returns the clip path in the current paint engine state.
8927
8928     This variable should only be used when the state() returns a
8929     combination which includes the QPaintEngine::DirtyClipPath flag.
8930
8931     \sa state(), QPaintEngine::updateState()
8932 */
8933
8934 QPainterPath QPaintEngineState::clipPath() const
8935 {
8936     return static_cast<const QPainterState *>(this)->clipPath;
8937 }
8938
8939 /*!
8940     Returns whether clipping is enabled or not in the current paint
8941     engine state.
8942
8943     This variable should only be used when the state() returns a
8944     combination which includes the QPaintEngine::DirtyClipEnabled
8945     flag.
8946
8947     \sa state(), QPaintEngine::updateState()
8948 */
8949
8950 bool QPaintEngineState::isClipEnabled() const
8951 {
8952     return static_cast<const QPainterState *>(this)->clipEnabled;
8953 }
8954
8955 /*!
8956     Returns the render hints in the current paint engine state.
8957
8958     This variable should only be used when the state() returns a
8959     combination which includes the QPaintEngine::DirtyHints
8960     flag.
8961
8962     \sa state(), QPaintEngine::updateState()
8963 */
8964
8965 QPainter::RenderHints QPaintEngineState::renderHints() const
8966 {
8967     return static_cast<const QPainterState *>(this)->renderHints;
8968 }
8969
8970 /*!
8971     Returns the composition mode in the current paint engine state.
8972
8973     This variable should only be used when the state() returns a
8974     combination which includes the QPaintEngine::DirtyCompositionMode
8975     flag.
8976
8977     \sa state(), QPaintEngine::updateState()
8978 */
8979
8980 QPainter::CompositionMode QPaintEngineState::compositionMode() const
8981 {
8982     return static_cast<const QPainterState *>(this)->composition_mode;
8983 }
8984
8985
8986 /*!
8987     Returns a pointer to the painter currently updating the paint
8988     engine.
8989 */
8990
8991 QPainter *QPaintEngineState::painter() const
8992 {
8993     return static_cast<const QPainterState *>(this)->painter;
8994 }
8995
8996
8997 /*!
8998     \since 4.2
8999
9000     Returns the opacity in the current paint engine state.
9001 */
9002
9003 qreal QPaintEngineState::opacity() const
9004 {
9005     return static_cast<const QPainterState *>(this)->opacity;
9006 }
9007
9008 /*!
9009     \since 4.3
9010
9011     Sets the world transformation matrix.
9012     If \a combine is true, the specified \a transform is combined with
9013     the current matrix; otherwise it replaces the current matrix.
9014
9015     \sa transform() setWorldTransform()
9016 */
9017
9018 void QPainter::setTransform(const QTransform &transform, bool combine )
9019 {
9020     setWorldTransform(transform, combine);
9021 }
9022
9023 /*!
9024     Returns the world transformation matrix.
9025
9026     \sa worldTransform()
9027 */
9028
9029 const QTransform & QPainter::transform() const
9030 {
9031     return worldTransform();
9032 }
9033
9034
9035 /*!
9036     Returns the matrix that transforms from logical coordinates to
9037     device coordinates of the platform dependent paint device.
9038
9039     This function is \e only needed when using platform painting
9040     commands on the platform dependent handle (Qt::HANDLE), and the
9041     platform does not do transformations nativly.
9042
9043     The QPaintEngine::PaintEngineFeature enum can be queried to
9044     determine whether the platform performs the transformations or
9045     not.
9046
9047     \sa worldTransform(), QPaintEngine::hasFeature(),
9048 */
9049
9050 const QTransform & QPainter::deviceTransform() const
9051 {
9052     Q_D(const QPainter);
9053     if (!d->engine) {
9054         qWarning("QPainter::deviceTransform: Painter not active");
9055         return d->fakeState()->transform;
9056     }
9057     return d->state->matrix;
9058 }
9059
9060
9061 /*!
9062     Resets any transformations that were made using translate(),
9063     scale(), shear(), rotate(), setWorldTransform(), setViewport()
9064     and setWindow().
9065
9066     \sa {Coordinate Transformations}
9067 */
9068
9069 void QPainter::resetTransform()
9070 {
9071      Q_D(QPainter);
9072 #ifdef QT_DEBUG_DRAW
9073     if (qt_show_painter_debug_output)
9074         printf("QPainter::resetMatrix()\n");
9075 #endif
9076     if (!d->engine) {
9077         qWarning("QPainter::resetMatrix: Painter not active");
9078         return;
9079     }
9080
9081     d->state->wx = d->state->wy = d->state->vx = d->state->vy = 0;                        // default view origins
9082     d->state->ww = d->state->vw = d->device->metric(QPaintDevice::PdmWidth);
9083     d->state->wh = d->state->vh = d->device->metric(QPaintDevice::PdmHeight);
9084     d->state->worldMatrix = QTransform();
9085     setMatrixEnabled(false);
9086     setViewTransformEnabled(false);
9087     if (d->extended)
9088         d->extended->transformChanged();
9089     else
9090         d->state->dirtyFlags |= QPaintEngine::DirtyTransform;
9091 }
9092
9093 /*!
9094     Sets the world transformation matrix.
9095     If \a combine is true, the specified \a matrix is combined with the current matrix;
9096     otherwise it replaces the current matrix.
9097
9098     \sa transform(), setTransform()
9099 */
9100
9101 void QPainter::setWorldTransform(const QTransform &matrix, bool combine )
9102 {
9103     Q_D(QPainter);
9104
9105     if (!d->engine) {
9106         qWarning("QPainter::setWorldTransform: Painter not active");
9107         return;
9108     }
9109
9110     if (combine)
9111         d->state->worldMatrix = matrix * d->state->worldMatrix;                        // combines
9112     else
9113         d->state->worldMatrix = matrix;                                // set new matrix
9114
9115     d->state->WxF = true;
9116     d->updateMatrix();
9117 }
9118
9119 /*!
9120     Returns the world transformation matrix.
9121 */
9122
9123 const QTransform & QPainter::worldTransform() const
9124 {
9125     Q_D(const QPainter);
9126     if (!d->engine) {
9127         qWarning("QPainter::worldTransform: Painter not active");
9128         return d->fakeState()->transform;
9129     }
9130     return d->state->worldMatrix;
9131 }
9132
9133 /*!
9134     Returns the transformation matrix combining the current
9135     window/viewport and world transformation.
9136
9137     \sa setWorldTransform(), setWindow(), setViewport()
9138 */
9139
9140 QTransform QPainter::combinedTransform() const
9141 {
9142     Q_D(const QPainter);
9143     if (!d->engine) {
9144         qWarning("QPainter::combinedTransform: Painter not active");
9145         return QTransform();
9146     }
9147     return d->state->worldMatrix * d->viewTransform();
9148 }
9149
9150 /*!
9151     \since 4.7
9152
9153     This function is used to draw \a pixmap, or a sub-rectangle of \a pixmap,
9154     at multiple positions with different scale, rotation and opacity. \a
9155     fragments is an array of \a fragmentCount elements specifying the
9156     parameters used to draw each pixmap fragment. The \a hints
9157     parameter can be used to pass in drawing hints.
9158
9159     This function is potentially faster than multiple calls to drawPixmap(),
9160     since the backend can optimize state changes.
9161
9162     \sa QPainter::PixmapFragment, QPainter::PixmapFragmentHint
9163 */
9164
9165 void QPainter::drawPixmapFragments(const PixmapFragment *fragments, int fragmentCount,
9166                                    const QPixmap &pixmap, PixmapFragmentHints hints)
9167 {
9168     Q_D(QPainter);
9169
9170     if (!d->engine || pixmap.isNull())
9171         return;
9172
9173 #ifndef QT_NO_DEBUG
9174     for (int i = 0; i < fragmentCount; ++i) {
9175         QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop,
9176                           fragments[i].width, fragments[i].height);
9177         if (!(QRectF(pixmap.rect()).contains(sourceRect)))
9178             qWarning("QPainter::drawPixmapFragments - the source rect is not contained by the pixmap's rectangle");
9179     }
9180 #endif
9181
9182     if (d->engine->isExtended()) {
9183         d->extended->drawPixmapFragments(fragments, fragmentCount, pixmap, hints);
9184     } else {
9185         qreal oldOpacity = opacity();
9186         QTransform oldTransform = transform();
9187
9188         for (int i = 0; i < fragmentCount; ++i) {
9189             QTransform transform = oldTransform;
9190             qreal xOffset = 0;
9191             qreal yOffset = 0;
9192             if (fragments[i].rotation == 0) {
9193                 xOffset = fragments[i].x;
9194                 yOffset = fragments[i].y;
9195             } else {
9196                 transform.translate(fragments[i].x, fragments[i].y);
9197                 transform.rotate(fragments[i].rotation);
9198             }
9199             setOpacity(oldOpacity * fragments[i].opacity);
9200             setTransform(transform);
9201
9202             qreal w = fragments[i].scaleX * fragments[i].width;
9203             qreal h = fragments[i].scaleY * fragments[i].height;
9204             QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop,
9205                               fragments[i].width, fragments[i].height);
9206             drawPixmap(QRectF(-0.5 * w + xOffset, -0.5 * h + yOffset, w, h), pixmap, sourceRect);
9207         }
9208
9209         setOpacity(oldOpacity);
9210         setTransform(oldTransform);
9211     }
9212 }
9213
9214 /*!
9215     \since 4.7
9216     \class QPainter::PixmapFragment
9217
9218     \brief This class is used in conjunction with the
9219     QPainter::drawPixmapFragments() function to specify how a pixmap, or
9220     sub-rect of a pixmap, is drawn.
9221
9222     The \a sourceLeft, \a sourceTop, \a width and \a height variables are used
9223     as a source rectangle within the pixmap passed into the
9224     QPainter::drawPixmapFragments() function. The variables \a x, \a y, \a
9225     width and \a height are used to calculate the target rectangle that is
9226     drawn. \a x and \a y denotes the center of the target rectangle. The \a
9227     width and \a height in the target rectangle is scaled by the \a scaleX and
9228     \a scaleY values. The resulting target rectangle is then rotated \a
9229     rotation degrees around the \a x, \a y center point.
9230
9231     \sa QPainter::drawPixmapFragments()
9232 */
9233
9234 /*!
9235     \since 4.7
9236
9237     This is a convenience function that returns a QPainter::PixmapFragment that is
9238     initialized with the \a pos, \a sourceRect, \a scaleX, \a scaleY, \a
9239     rotation, \a opacity parameters.
9240 */
9241
9242 QPainter::PixmapFragment QPainter::PixmapFragment::create(const QPointF &pos, const QRectF &sourceRect,
9243                                               qreal scaleX, qreal scaleY, qreal rotation,
9244                                               qreal opacity)
9245 {
9246     PixmapFragment fragment = {pos.x(), pos.y(), sourceRect.x(), sourceRect.y(), sourceRect.width(),
9247                                sourceRect.height(), scaleX, scaleY, rotation, opacity};
9248     return fragment;
9249 }
9250
9251 /*!
9252     \variable QPainter::PixmapFragment::x
9253     \brief the x coordinate of center point in the target rectangle.
9254 */
9255
9256 /*!
9257     \variable QPainter::PixmapFragment::y
9258     \brief the y coordinate of the center point in the target rectangle.
9259 */
9260
9261 /*!
9262     \variable QPainter::PixmapFragment::sourceLeft
9263     \brief the left coordinate of the source rectangle.
9264 */
9265
9266 /*!
9267     \variable QPainter::PixmapFragment::sourceTop
9268     \brief the top coordinate of the source rectangle.
9269 */
9270
9271 /*!
9272     \variable QPainter::PixmapFragment::width
9273
9274     \brief the width of the source rectangle and is used to calculate the width
9275     of the target rectangle.
9276 */
9277
9278 /*!
9279     \variable QPainter::PixmapFragment::height
9280
9281     \brief the height of the source rectangle and is used to calculate the
9282     height of the target rectangle.
9283 */
9284
9285 /*!
9286     \variable QPainter::PixmapFragment::scaleX
9287     \brief the horizontal scale of the target rectangle.
9288 */
9289
9290 /*!
9291     \variable QPainter::PixmapFragment::scaleY
9292     \brief the vertical scale of the target rectangle.
9293 */
9294
9295 /*!
9296     \variable QPainter::PixmapFragment::rotation
9297
9298     \brief the rotation of the target rectangle in degrees. The target
9299     rectangle is rotated after it has been scaled.
9300 */
9301
9302 /*!
9303     \variable QPainter::PixmapFragment::opacity
9304
9305     \brief the opacity of the target rectangle, where 0.0 is fully transparent
9306     and 1.0 is fully opaque.
9307 */
9308
9309 /*!
9310     \since 4.7
9311
9312     \enum QPainter::PixmapFragmentHint
9313
9314     \value OpaqueHint Indicates that the pixmap fragments to be drawn are
9315     opaque. Opaque fragments are potentially faster to draw.
9316
9317     \sa QPainter::drawPixmapFragments(), QPainter::PixmapFragment
9318 */
9319
9320 void qt_draw_helper(QPainterPrivate *p, const QPainterPath &path, QPainterPrivate::DrawOperation operation)
9321 {
9322     p->draw_helper(path, operation);
9323 }
9324
9325 /*! \fn Display *QPaintDevice::x11Display() const
9326     Use QX11Info::display() instead.
9327
9328     \oldcode
9329         Display *display = widget->x11Display();
9330     \newcode
9331         Display *display = QX11Info::display();
9332     \endcode
9333
9334     \sa QWidget::x11Info(), QX11Info::display()
9335 */
9336
9337 /*! \fn int QPaintDevice::x11Screen() const
9338     Use QX11Info::screen() instead.
9339
9340     \oldcode
9341         int screen = widget->x11Screen();
9342     \newcode
9343         int screen = widget->x11Info().screen();
9344     \endcode
9345
9346     \sa QWidget::x11Info(), QPixmap::x11Info()
9347 */
9348
9349 /*! \fn void *QPaintDevice::x11Visual() const
9350     Use QX11Info::visual() instead.
9351
9352     \oldcode
9353         void *visual = widget->x11Visual();
9354     \newcode
9355         void *visual = widget->x11Info().visual();
9356     \endcode
9357
9358     \sa QWidget::x11Info(), QPixmap::x11Info()
9359 */
9360
9361 /*! \fn int QPaintDevice::x11Depth() const
9362     Use QX11Info::depth() instead.
9363
9364     \oldcode
9365         int depth = widget->x11Depth();
9366     \newcode
9367         int depth = widget->x11Info().depth();
9368     \endcode
9369
9370     \sa QWidget::x11Info(), QPixmap::x11Info()
9371 */
9372
9373 /*! \fn int QPaintDevice::x11Cells() const
9374     Use QX11Info::cells() instead.
9375
9376     \oldcode
9377         int cells = widget->x11Cells();
9378     \newcode
9379         int cells = widget->x11Info().cells();
9380     \endcode
9381
9382     \sa QWidget::x11Info(), QPixmap::x11Info()
9383 */
9384
9385 /*! \fn Qt::HANDLE QPaintDevice::x11Colormap() const
9386     Use QX11Info::colormap() instead.
9387
9388     \oldcode
9389         unsigned long screen = widget->x11Colormap();
9390     \newcode
9391         unsigned long screen = widget->x11Info().colormap();
9392     \endcode
9393
9394     \sa QWidget::x11Info(), QPixmap::x11Info()
9395 */
9396
9397 /*! \fn bool QPaintDevice::x11DefaultColormap() const
9398     Use QX11Info::defaultColormap() instead.
9399
9400     \oldcode
9401         bool isDefault = widget->x11DefaultColormap();
9402     \newcode
9403         bool isDefault = widget->x11Info().defaultColormap();
9404     \endcode
9405
9406     \sa QWidget::x11Info(), QPixmap::x11Info()
9407 */
9408
9409 /*! \fn bool QPaintDevice::x11DefaultVisual() const
9410     Use QX11Info::defaultVisual() instead.
9411
9412     \oldcode
9413         bool isDefault = widget->x11DefaultVisual();
9414     \newcode
9415         bool isDefault = widget->x11Info().defaultVisual();
9416     \endcode
9417
9418     \sa QWidget::x11Info(), QPixmap::x11Info()
9419 */
9420
9421 /*! \fn void *QPaintDevice::x11AppVisual(int screen)
9422     Use QX11Info::visual() instead.
9423
9424     \oldcode
9425         void *visual = QPaintDevice::x11AppVisual(screen);
9426     \newcode
9427         void *visual = qApp->x11Info(screen).visual();
9428     \endcode
9429
9430     \sa QWidget::x11Info(), QPixmap::x11Info()
9431 */
9432
9433 /*! \fn Qt::HANDLE QPaintDevice::x11AppColormap(int screen)
9434     Use QX11Info::colormap() instead.
9435
9436     \oldcode
9437         unsigned long colormap = QPaintDevice::x11AppColormap(screen);
9438     \newcode
9439         unsigned long colormap = qApp->x11Info(screen).colormap();
9440     \endcode
9441
9442     \sa QWidget::x11Info(), QPixmap::x11Info()
9443 */
9444
9445 /*! \fn Display *QPaintDevice::x11AppDisplay()
9446     Use QX11Info::display() instead.
9447
9448     \oldcode
9449         Display *display = QPaintDevice::x11AppDisplay();
9450     \newcode
9451         Display *display = qApp->x11Info().display();
9452     \endcode
9453
9454     \sa QWidget::x11Info(), QPixmap::x11Info()
9455 */
9456
9457 /*! \fn int QPaintDevice::x11AppScreen()
9458     Use QX11Info::screen() instead.
9459
9460     \oldcode
9461         int screen = QPaintDevice::x11AppScreen();
9462     \newcode
9463         int screen = qApp->x11Info().screen();
9464     \endcode
9465
9466     \sa QWidget::x11Info(), QPixmap::x11Info()
9467 */
9468
9469 /*! \fn int QPaintDevice::x11AppDepth(int screen)
9470     Use QX11Info::depth() instead.
9471
9472     \oldcode
9473         int depth = QPaintDevice::x11AppDepth(screen);
9474     \newcode
9475         int depth = qApp->x11Info(screen).depth();
9476     \endcode
9477
9478     \sa QWidget::x11Info(), QPixmap::x11Info()
9479 */
9480
9481 /*! \fn int QPaintDevice::x11AppCells(int screen)
9482     Use QX11Info::cells() instead.
9483
9484     \oldcode
9485         int cells = QPaintDevice::x11AppCells(screen);
9486     \newcode
9487         int cells = qApp->x11Info(screen).cells();
9488     \endcode
9489
9490     \sa QWidget::x11Info(), QPixmap::x11Info()
9491 */
9492
9493 /*! \fn Qt::HANDLE QPaintDevice::x11AppRootWindow(int screen)
9494     Use QX11Info::appRootWindow() instead.
9495
9496     \oldcode
9497         unsigned long window = QPaintDevice::x11AppRootWindow(screen);
9498     \newcode
9499         unsigned long window = qApp->x11Info(screen).appRootWindow();
9500     \endcode
9501
9502     \sa QWidget::x11Info(), QPixmap::x11Info()
9503 */
9504
9505 /*! \fn bool QPaintDevice::x11AppDefaultColormap(int screen)
9506     Use QX11Info::defaultColormap() instead.
9507
9508     \oldcode
9509         bool isDefault = QPaintDevice::x11AppDefaultColormap(screen);
9510     \newcode
9511         bool isDefault = qApp->x11Info(screen).defaultColormap();
9512     \endcode
9513
9514     \sa QWidget::x11Info(), QPixmap::x11Info()
9515 */
9516
9517 /*! \fn bool QPaintDevice::x11AppDefaultVisual(int screen)
9518     Use QX11Info::defaultVisual() instead.
9519
9520     \oldcode
9521         bool isDefault = QPaintDevice::x11AppDefaultVisual(screen);
9522     \newcode
9523         bool isDefault = qApp->x11Info(screen).defaultVisual();
9524     \endcode
9525
9526     \sa QWidget::x11Info(), QPixmap::x11Info()
9527 */
9528
9529 /*! \fn void QPaintDevice::x11SetAppDpiX(int dpi, int screen)
9530     Use QX11Info::setAppDpiX() instead.
9531 */
9532
9533 /*! \fn void QPaintDevice::x11SetAppDpiY(int dpi, int screen)
9534     Use QX11Info::setAppDpiY() instead.
9535 */
9536
9537 /*! \fn int QPaintDevice::x11AppDpiX(int screen)
9538     Use QX11Info::appDpiX() instead.
9539
9540     \oldcode
9541         bool isDefault = QPaintDevice::x11AppDpiX(screen);
9542     \newcode
9543         bool isDefault = qApp->x11Info(screen).appDpiX();
9544     \endcode
9545
9546     \sa QWidget::x11Info(), QPixmap::x11Info()
9547 */
9548
9549 /*! \fn int QPaintDevice::x11AppDpiY(int screen)
9550     Use QX11Info::appDpiY() instead.
9551
9552     \oldcode
9553         bool isDefault = QPaintDevice::x11AppDpiY(screen);
9554     \newcode
9555         bool isDefault = qApp->x11Info(screen).appDpiY();
9556     \endcode
9557
9558     \sa QWidget::x11Info(), QPixmap::x11Info()
9559 */
9560
9561 /*! \fn HDC QPaintDevice::getDC() const
9562   \internal
9563 */
9564
9565 /*! \fn void QPaintDevice::releaseDC(HDC) const
9566   \internal
9567 */
9568
9569 /*! \fn QWSDisplay *QPaintDevice::qwsDisplay()
9570     \internal
9571 */
9572
9573 QT_END_NAMESPACE