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