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