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