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