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