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