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