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