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