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