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