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