Merge remote branch 'gerrit/master' into refactor
[profile/ivi/qtbase.git] / src / gui / painting / qpainter.cpp
1 /****************************************************************************
2 **
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
6 **
7 ** This file is part of the QtGui module of the Qt Toolkit.
8 **
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
17 **
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
21 **
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
29 **
30 ** Other Usage
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
33 **
34 **
35 **
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41
42 // QtCore
43 #include <qdebug.h>
44 #include <qmath.h>
45 #include <qmutex.h>
46
47 // QtGui
48 #include "qbitmap.h"
49 #include "qimage.h"
50 #include "qpaintdevice.h"
51 #include "qpaintengine.h"
52 #include "qpainter.h"
53 #include "qpainter_p.h"
54 #include "qpainterpath.h"
55 #include "qpicture.h"
56 #include "qpixmapcache.h"
57 #include "qpolygon.h"
58 #include "qtextlayout.h"
59 #include "qthread.h"
60 #include "qvarlengtharray.h"
61 #include "qstatictext.h"
62 #include "qglyphrun.h"
63
64 #include <private/qfontengine_p.h>
65 #include <private/qpaintengine_p.h>
66 #include <private/qemulationpaintengine_p.h>
67 #include <private/qpainterpath_p.h>
68 #include <private/qtextengine_p.h>
69 #include <private/qpaintengine_raster_p.h>
70 #include <private/qmath_p.h>
71 #include <private/qstatictext_p.h>
72 #include <private/qglyphrun_p.h>
73 #include <private/qhexstring_p.h>
74 #include <private/qguiapplication_p.h>
75 #include <private/qrawfont_p.h>
76
77 QT_BEGIN_NAMESPACE
78
79 #define QGradient_StretchToDevice 0x10000000
80 #define QPaintEngine_OpaqueBackground 0x40000000
81
82 // #define QT_DEBUG_DRAW
83 #ifdef QT_DEBUG_DRAW
84 bool qt_show_painter_debug_output = true;
85 #endif
86
87 extern QPixmap qt_pixmapForBrush(int style, bool invert);
88
89 void qt_format_text(const QFont &font,
90                     const QRectF &_r, int tf, const QTextOption *option, const QString& str, QRectF *brect,
91                     int tabstops, int* tabarray, int tabarraylen,
92                     QPainter *painter);
93 static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe,
94                                    QTextCharFormat::UnderlineStyle underlineStyle,
95                                    QTextItem::RenderFlags flags, qreal width,
96                                    const QTextCharFormat &charFormat);
97 // Helper function to calculate left most position, width and flags for decoration drawing
98 Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray,
99                                                 const QFixedPoint *positions, int glyphCount,
100                                                 QFontEngine *fontEngine, const QFont &font,
101                                                 const QTextCharFormat &charFormat);
102
103 static inline QGradient::CoordinateMode coordinateMode(const QBrush &brush)
104 {
105     switch (brush.style()) {
106     case Qt::LinearGradientPattern:
107     case Qt::RadialGradientPattern:
108     case Qt::ConicalGradientPattern:
109         return brush.gradient()->coordinateMode();
110     default:
111         ;
112     }
113     return QGradient::LogicalMode;
114 }
115
116 /* Returns true if the gradient requires stretch to device...*/
117 static inline bool check_gradient(const QBrush &brush)
118 {
119     return coordinateMode(brush) == QGradient::StretchToDeviceMode;
120 }
121
122 extern bool qHasPixmapTexture(const QBrush &);
123
124 static inline bool is_brush_transparent(const QBrush &brush) {
125     Qt::BrushStyle s = brush.style();
126     bool brushBitmap = qHasPixmapTexture(brush)
127                        ? brush.texture().isQBitmap()
128                        : (brush.textureImage().depth() == 1);
129     return ((s >= Qt::Dense1Pattern && s <= Qt::DiagCrossPattern)
130             || (s == Qt::TexturePattern && brushBitmap));
131 }
132
133 static inline bool is_pen_transparent(const QPen &pen) {
134     return pen.style() > Qt::SolidLine || is_brush_transparent(pen.brush());
135 }
136
137 /* Discards the emulation flags that are not relevant for line drawing
138    and returns the result
139 */
140 static inline uint line_emulation(uint emulation)
141 {
142     return emulation & (QPaintEngine::PrimitiveTransform
143                         | QPaintEngine::AlphaBlend
144                         | QPaintEngine::Antialiasing
145                         | QPaintEngine::BrushStroke
146                         | QPaintEngine::ConstantOpacity
147                         | QGradient_StretchToDevice
148                         | QPaintEngine::ObjectBoundingModeGradients
149                         | QPaintEngine_OpaqueBackground);
150 }
151
152 #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 {painting/deform}{Vector Deformation} example which
1096     shows how to use advanced vector techniques to draw text using a
1097     QPainterPath, the \l {painting/gradients}{Gradients} example which shows
1098     the different types of gradients that are available in Qt, and the \l
1099     {painting/pathstroke}{Path Stroking} example 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 {painting/deform}{Vector Deformation}
1106     \o \l {painting/gradients}{Gradients}
1107     \o \l {painting/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     {painting/affine}{Affine Transformations} example 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 Example}
1211
1212     The \l {painting/affine}{Affine Transformations} example shows 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 {painting/composition}{Composition Modes} example, available in
1297     Qt's examples 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::NoClip) {
2530                 lastWasNothing = true;
2531                 region = QRegion();
2532             } else
2533                 region = info.region * matrix;
2534             break;
2535         }
2536
2537         case QPainterClipInfo::PathClip: {
2538             QTransform matrix = (info.matrix * d->invMatrix);
2539             if (lastWasNothing) {
2540                 region = QRegion((info.path * matrix).toFillPolygon().toPolygon(),
2541                                  info.path.fillRule());
2542                 lastWasNothing = false;
2543                 continue;
2544             }
2545             if (info.operation == Qt::IntersectClip) {
2546                 region &= QRegion((info.path * matrix).toFillPolygon().toPolygon(),
2547                                   info.path.fillRule());
2548             } else if (info.operation == Qt::NoClip) {
2549                 lastWasNothing = true;
2550                 region = QRegion();
2551             } else {
2552                 region = QRegion((info.path * matrix).toFillPolygon().toPolygon(),
2553                                  info.path.fillRule());
2554             }
2555             break;
2556         }
2557
2558         case QPainterClipInfo::RectClip: {
2559             QTransform matrix = (info.matrix * d->invMatrix);
2560             if (lastWasNothing) {
2561                 region = QRegion(info.rect) * matrix;
2562                 lastWasNothing = false;
2563                 continue;
2564             }
2565             if (info.operation == Qt::IntersectClip) {
2566                 // Use rect intersection if possible.
2567                 if (matrix.type() <= QTransform::TxScale)
2568                     region &= matrix.mapRect(info.rect);
2569                 else
2570                     region &= matrix.map(QRegion(info.rect));
2571             } else if (info.operation == Qt::NoClip) {
2572                 lastWasNothing = true;
2573                 region = QRegion();
2574             } else {
2575                 region = QRegion(info.rect) * matrix;
2576             }
2577             break;
2578         }
2579
2580         case QPainterClipInfo::RectFClip: {
2581             QTransform matrix = (info.matrix * d->invMatrix);
2582             if (lastWasNothing) {
2583                 region = QRegion(info.rectf.toRect()) * matrix;
2584                 lastWasNothing = false;
2585                 continue;
2586             }
2587             if (info.operation == Qt::IntersectClip) {
2588                 // Use rect intersection if possible.
2589                 if (matrix.type() <= QTransform::TxScale)
2590                     region &= matrix.mapRect(info.rectf.toRect());
2591                 else
2592                     region &= matrix.map(QRegion(info.rectf.toRect()));
2593             } else if (info.operation == Qt::NoClip) {
2594                 lastWasNothing = true;
2595                 region = QRegion();
2596             } else {
2597                 region = QRegion(info.rectf.toRect()) * matrix;
2598             }
2599             break;
2600         }
2601         }
2602     }
2603
2604     return region;
2605 }
2606
2607 extern QPainterPath qt_regionToPath(const QRegion &region);
2608
2609 /*!
2610     Returns the currently clip as a path. Note that the clip path is
2611     given in logical coordinates.
2612
2613     \warning QPainter does not store the combined clip explicitly as
2614     this is handled by the underlying QPaintEngine, so the path is
2615     recreated on demand and transformed to the current logical
2616     coordinate system. This is potentially an expensive operation.
2617
2618     \sa setClipPath(), clipRegion(), setClipping()
2619 */
2620 QPainterPath QPainter::clipPath() const
2621 {
2622     Q_D(const QPainter);
2623
2624     // ### Since we do not support path intersections and path unions yet,
2625     // we just use clipRegion() here...
2626     if (!d->engine) {
2627         qWarning("QPainter::clipPath: Painter not active");
2628         return QPainterPath();
2629     }
2630
2631     // No clip, return empty
2632     if (d->state->clipInfo.size() == 0) {
2633         return QPainterPath();
2634     } else {
2635
2636         // Update inverse matrix, used below.
2637         if (!d->txinv)
2638             const_cast<QPainter *>(this)->d_ptr->updateInvMatrix();
2639
2640         // For the simple case avoid conversion.
2641         if (d->state->clipInfo.size() == 1
2642             && d->state->clipInfo.at(0).clipType == QPainterClipInfo::PathClip) {
2643             QTransform matrix = (d->state->clipInfo.at(0).matrix * d->invMatrix);
2644             return d->state->clipInfo.at(0).path * matrix;
2645
2646         } else if (d->state->clipInfo.size() == 1
2647                    && d->state->clipInfo.at(0).clipType == QPainterClipInfo::RectClip) {
2648             QTransform matrix = (d->state->clipInfo.at(0).matrix * d->invMatrix);
2649             QPainterPath path;
2650             path.addRect(d->state->clipInfo.at(0).rect);
2651             return path * matrix;
2652         } else {
2653             // Fallback to clipRegion() for now, since we don't have isect/unite for paths
2654             return qt_regionToPath(clipRegion());
2655         }
2656     }
2657 }
2658
2659 /*!
2660     Returns the bounding rectangle of the current clip if there is a clip;
2661     otherwise returns an empty rectangle. Note that the clip region is
2662     given in logical coordinates.
2663
2664     The bounding rectangle is not guaranteed to be tight.
2665
2666     \sa setClipRect(), setClipPath(), setClipRegion()
2667
2668     \since 4.8
2669  */
2670
2671 QRectF QPainter::clipBoundingRect() const
2672 {
2673     Q_D(const QPainter);
2674
2675     if (!d->engine) {
2676         qWarning("QPainter::clipBoundingRect: Painter not active");
2677         return QRectF();
2678     }
2679
2680     // Accumulate the bounding box in device space. This is not 100%
2681     // precise, but it fits within the guarantee and it is reasonably
2682     // fast.
2683     QRectF bounds;
2684     for (int i=0; i<d->state->clipInfo.size(); ++i) {
2685          QRectF r;
2686          const QPainterClipInfo &info = d->state->clipInfo.at(i);
2687
2688          if (info.clipType == QPainterClipInfo::RectClip)
2689              r = info.rect;
2690          else if (info.clipType == QPainterClipInfo::RectFClip)
2691              r = info.rectf;
2692          else if (info.clipType == QPainterClipInfo::RegionClip)
2693              r = info.region.boundingRect();
2694          else
2695              r = info.path.boundingRect();
2696
2697          r = info.matrix.mapRect(r);
2698
2699          if (i == 0)
2700              bounds = r;
2701          else if (info.operation == Qt::IntersectClip)
2702              bounds &= r;
2703     }
2704
2705
2706     // Map the rectangle back into logical space using the inverse
2707     // matrix.
2708     if (!d->txinv)
2709         const_cast<QPainter *>(this)->d_ptr->updateInvMatrix();
2710
2711     return d->invMatrix.mapRect(bounds);
2712 }
2713
2714 /*!
2715     \fn void QPainter::setClipRect(const QRectF &rectangle, Qt::ClipOperation operation)
2716
2717     Enables clipping, and sets the clip region to the given \a
2718     rectangle using the given clip \a operation. The default operation
2719     is to replace the current clip rectangle.
2720
2721     Note that the clip rectangle is specified in logical (painter)
2722     coordinates.
2723
2724     \sa clipRegion(), setClipping(), {QPainter#Clipping}{Clipping}
2725 */
2726 void QPainter::setClipRect(const QRectF &rect, Qt::ClipOperation op)
2727 {
2728     Q_D(QPainter);
2729
2730     if (d->extended) {
2731         if ((!d->state->clipEnabled && op != Qt::NoClip))
2732             op = Qt::ReplaceClip;
2733
2734         if (!d->engine) {
2735             qWarning("QPainter::setClipRect: Painter not active");
2736             return;
2737         }
2738         qreal right = rect.x() + rect.width();
2739         qreal bottom = rect.y() + rect.height();
2740         qreal pts[] = { rect.x(), rect.y(),
2741                         right, rect.y(),
2742                         right, bottom,
2743                         rect.x(), bottom };
2744         QVectorPath vp(pts, 4, 0, QVectorPath::RectangleHint);
2745         d->state->clipEnabled = true;
2746         d->extended->clip(vp, op);
2747         if (op == Qt::ReplaceClip || op == Qt::NoClip)
2748             d->state->clipInfo.clear();
2749         d->state->clipInfo << QPainterClipInfo(rect, op, d->state->matrix);
2750         d->state->clipOperation = op;
2751         return;
2752     }
2753
2754     if (qreal(int(rect.top())) == rect.top()
2755         && qreal(int(rect.bottom())) == rect.bottom()
2756         && qreal(int(rect.left())) == rect.left()
2757         && qreal(int(rect.right())) == rect.right())
2758     {
2759         setClipRect(rect.toRect(), op);
2760         return;
2761     }
2762
2763     if (rect.isEmpty()) {
2764         setClipRegion(QRegion(), op);
2765         return;
2766     }
2767
2768     QPainterPath path;
2769     path.addRect(rect);
2770     setClipPath(path, op);
2771 }
2772
2773 /*!
2774     \fn void QPainter::setClipRect(const QRect &rectangle, Qt::ClipOperation operation)
2775     \overload
2776
2777     Enables clipping, and sets the clip region to the given \a rectangle using the given
2778     clip \a operation.
2779 */
2780 void QPainter::setClipRect(const QRect &rect, Qt::ClipOperation op)
2781 {
2782     Q_D(QPainter);
2783
2784     if (!d->engine) {
2785         qWarning("QPainter::setClipRect: Painter not active");
2786         return;
2787     }
2788
2789     if ((!d->state->clipEnabled && op != Qt::NoClip))
2790         op = Qt::ReplaceClip;
2791
2792     if (d->extended) {
2793         d->state->clipEnabled = true;
2794         d->extended->clip(rect, op);
2795         if (op == Qt::ReplaceClip || op == Qt::NoClip)
2796             d->state->clipInfo.clear();
2797         d->state->clipInfo << QPainterClipInfo(rect, op, d->state->matrix);
2798         d->state->clipOperation = op;
2799         return;
2800     }
2801
2802     d->state->clipRegion = rect;
2803     d->state->clipOperation = op;
2804     if (op == Qt::NoClip || op == Qt::ReplaceClip)
2805         d->state->clipInfo.clear();
2806     d->state->clipInfo << QPainterClipInfo(rect, op, d->state->matrix);
2807     d->state->clipEnabled = true;
2808     d->state->dirtyFlags |= QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyClipEnabled;
2809     d->updateState(d->state);
2810 }
2811
2812 /*!
2813     \fn void QPainter::setClipRect(int x, int y, int width, int height, Qt::ClipOperation operation)
2814
2815     Enables clipping, and sets the clip region to the rectangle beginning at (\a x, \a y)
2816     with the given \a width and \a height.
2817 */
2818
2819 /*!
2820     \fn void QPainter::setClipRegion(const QRegion &region, Qt::ClipOperation operation)
2821
2822     Sets the clip region to the given \a region using the specified clip
2823     \a operation. The default clip operation is to replace the current
2824     clip region.
2825
2826     Note that the clip region is given in logical coordinates.
2827
2828     \sa clipRegion(), setClipRect(), {QPainter#Clipping}{Clipping}
2829 */
2830 void QPainter::setClipRegion(const QRegion &r, Qt::ClipOperation op)
2831 {
2832     Q_D(QPainter);
2833 #ifdef QT_DEBUG_DRAW
2834     QRect rect = r.boundingRect();
2835     if (qt_show_painter_debug_output)
2836         printf("QPainter::setClipRegion(), size=%d, [%d,%d,%d,%d]\n",
2837            r.rects().size(), rect.x(), rect.y(), rect.width(), rect.height());
2838 #endif
2839     if (!d->engine) {
2840         qWarning("QPainter::setClipRegion: Painter not active");
2841         return;
2842     }
2843
2844     if ((!d->state->clipEnabled && op != Qt::NoClip))
2845         op = Qt::ReplaceClip;
2846
2847     if (d->extended) {
2848         d->state->clipEnabled = true;
2849         d->extended->clip(r, op);
2850         if (op == Qt::NoClip || op == Qt::ReplaceClip)
2851             d->state->clipInfo.clear();
2852         d->state->clipInfo << QPainterClipInfo(r, op, d->state->matrix);
2853         d->state->clipOperation = op;
2854         return;
2855     }
2856
2857     d->state->clipRegion = r;
2858     d->state->clipOperation = op;
2859     if (op == Qt::NoClip || op == Qt::ReplaceClip)
2860         d->state->clipInfo.clear();
2861     d->state->clipInfo << QPainterClipInfo(r, op, d->state->matrix);
2862     d->state->clipEnabled = true;
2863     d->state->dirtyFlags |= QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyClipEnabled;
2864     d->updateState(d->state);
2865 }
2866
2867 /*!
2868     \since 4.2
2869     \obsolete
2870
2871     Sets the transformation matrix to \a matrix and enables transformations.
2872
2873     \note It is advisable to use setWorldTransform() instead of this function to
2874     preserve the properties of perspective transformations.
2875
2876     If \a combine is true, then \a matrix is combined with the current
2877     transformation matrix; otherwise \a matrix replaces the current
2878     transformation matrix.
2879
2880     If \a matrix is the identity matrix and \a combine is false, this
2881     function calls setWorldMatrixEnabled(false). (The identity matrix is the
2882     matrix where QMatrix::m11() and QMatrix::m22() are 1.0 and the
2883     rest are 0.0.)
2884
2885     The following functions can transform the coordinate system without using
2886     a QMatrix:
2887     \list
2888     \i translate()
2889     \i scale()
2890     \i shear()
2891     \i rotate()
2892     \endlist
2893
2894     They operate on the painter's worldMatrix() and are implemented like this:
2895
2896     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 4
2897
2898     Note that when using setWorldMatrix() function you should always have
2899     \a combine be true when you are drawing into a QPicture. Otherwise
2900     it may not be possible to replay the picture with additional
2901     transformations; using the translate(), scale(), etc. convenience
2902     functions is safe.
2903
2904     For more information about the coordinate system, transformations
2905     and window-viewport conversion, see \l {Coordinate System}.
2906
2907     \sa setWorldTransform(), QTransform
2908 */
2909
2910 void QPainter::setWorldMatrix(const QMatrix &matrix, bool combine)
2911 {
2912     setWorldTransform(QTransform(matrix), combine);
2913 }
2914
2915 /*!
2916     \since 4.2
2917     \obsolete
2918
2919     Returns the world transformation matrix.
2920
2921     It is advisable to use worldTransform() because worldMatrix() does not
2922     preserve the properties of perspective transformations.
2923
2924     \sa {QPainter#Coordinate Transformations}{Coordinate Transformations},
2925     {Coordinate System}
2926 */
2927
2928 const QMatrix &QPainter::worldMatrix() const
2929 {
2930     Q_D(const QPainter);
2931     if (!d->engine) {
2932         qWarning("QPainter::worldMatrix: Painter not active");
2933         return d->fakeState()->transform.toAffine();
2934     }
2935     return d->state->worldMatrix.toAffine();
2936 }
2937
2938 /*!
2939     \obsolete
2940
2941     Use setWorldTransform() instead.
2942
2943     \sa setWorldTransform()
2944 */
2945
2946 void QPainter::setMatrix(const QMatrix &matrix, bool combine)
2947 {
2948     setWorldTransform(QTransform(matrix), combine);
2949 }
2950
2951 /*!
2952     \obsolete
2953
2954     Use worldTransform() instead.
2955
2956     \sa worldTransform()
2957 */
2958
2959 const QMatrix &QPainter::matrix() const
2960 {
2961     return worldMatrix();
2962 }
2963
2964
2965 /*!
2966     \since 4.2
2967     \obsolete
2968
2969     Returns the transformation matrix combining the current
2970     window/viewport and world transformation.
2971
2972     It is advisable to use combinedTransform() instead of this
2973     function to preserve the properties of perspective transformations.
2974
2975     \sa setWorldTransform(), setWindow(), setViewport()
2976 */
2977 QMatrix QPainter::combinedMatrix() const
2978 {
2979     return combinedTransform().toAffine();
2980 }
2981
2982
2983 /*!
2984     \obsolete
2985
2986     Returns the matrix that transforms from logical coordinates to
2987     device coordinates of the platform dependent paint device.
2988
2989     \note It is advisable to use deviceTransform() instead of this
2990     function to preserve the properties of perspective transformations.
2991
2992     This function is \e only needed when using platform painting
2993     commands on the platform dependent handle (Qt::HANDLE), and the
2994     platform does not do transformations nativly.
2995
2996     The QPaintEngine::PaintEngineFeature enum can be queried to
2997     determine whether the platform performs the transformations or
2998     not.
2999
3000     \sa worldMatrix(), QPaintEngine::hasFeature(),
3001 */
3002 const QMatrix &QPainter::deviceMatrix() const
3003 {
3004     Q_D(const QPainter);
3005     if (!d->engine) {
3006         qWarning("QPainter::deviceMatrix: Painter not active");
3007         return d->fakeState()->transform.toAffine();
3008     }
3009     return d->state->matrix.toAffine();
3010 }
3011
3012 /*!
3013     \obsolete
3014
3015     Resets any transformations that were made using translate(), scale(),
3016     shear(), rotate(), setWorldMatrix(), setViewport() and
3017     setWindow().
3018
3019     It is advisable to use resetTransform() instead of this function
3020     to preserve the properties of perspective transformations.
3021
3022     \sa {QPainter#Coordinate Transformations}{Coordinate
3023     Transformations}
3024 */
3025
3026 void QPainter::resetMatrix()
3027 {
3028     resetTransform();
3029 }
3030
3031
3032 /*!
3033     \since 4.2
3034
3035     Enables transformations if \a enable is true, or disables
3036     transformations if \a enable is false. The world transformation
3037     matrix is not changed.
3038
3039     \sa worldMatrixEnabled(), worldTransform(), {QPainter#Coordinate
3040     Transformations}{Coordinate Transformations}
3041 */
3042
3043 void QPainter::setWorldMatrixEnabled(bool enable)
3044 {
3045     Q_D(QPainter);
3046 #ifdef QT_DEBUG_DRAW
3047     if (qt_show_painter_debug_output)
3048         printf("QPainter::setMatrixEnabled(), enable=%d\n", enable);
3049 #endif
3050
3051     if (!d->engine) {
3052         qWarning("QPainter::setMatrixEnabled: Painter not active");
3053         return;
3054     }
3055     if (enable == d->state->WxF)
3056         return;
3057
3058     d->state->WxF = enable;
3059     d->updateMatrix();
3060 }
3061
3062 /*!
3063     \since 4.2
3064
3065     Returns true if world transformation is enabled; otherwise returns
3066     false.
3067
3068     \sa setWorldMatrixEnabled(), worldTransform(), {Coordinate System}
3069 */
3070
3071 bool QPainter::worldMatrixEnabled() const
3072 {
3073     Q_D(const QPainter);
3074     if (!d->engine) {
3075         qWarning("QPainter::worldMatrixEnabled: Painter not active");
3076         return false;
3077     }
3078     return d->state->WxF;
3079 }
3080
3081 /*!
3082     \obsolete
3083
3084     Use setWorldMatrixEnabled() instead.
3085
3086     \sa setWorldMatrixEnabled()
3087 */
3088
3089 void QPainter::setMatrixEnabled(bool enable)
3090 {
3091     setWorldMatrixEnabled(enable);
3092 }
3093
3094 /*!
3095     \obsolete
3096
3097     Use worldMatrixEnabled() instead
3098
3099     \sa worldMatrixEnabled()
3100 */
3101
3102 bool QPainter::matrixEnabled() const
3103 {
3104     return worldMatrixEnabled();
3105 }
3106
3107 /*!
3108     Scales the coordinate system by (\a{sx}, \a{sy}).
3109
3110     \sa setWorldTransform() {QPainter#Coordinate Transformations}{Coordinate
3111     Transformations}
3112 */
3113
3114 void QPainter::scale(qreal sx, qreal sy)
3115 {
3116 #ifdef QT_DEBUG_DRAW
3117     if (qt_show_painter_debug_output)
3118         printf("QPainter::scale(), sx=%f, sy=%f\n", sx, sy);
3119 #endif
3120     Q_D(QPainter);
3121     if (!d->engine) {
3122         qWarning("QPainter::scale: Painter not active");
3123         return;
3124     }
3125
3126     d->state->worldMatrix.scale(sx,sy);
3127     d->state->WxF = true;
3128     d->updateMatrix();
3129 }
3130
3131 /*!
3132     Shears the coordinate system by (\a{sh}, \a{sv}).
3133
3134     \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate
3135     Transformations}
3136 */
3137
3138 void QPainter::shear(qreal sh, qreal sv)
3139 {
3140 #ifdef QT_DEBUG_DRAW
3141     if (qt_show_painter_debug_output)
3142         printf("QPainter::shear(), sh=%f, sv=%f\n", sh, sv);
3143 #endif
3144     Q_D(QPainter);
3145     if (!d->engine) {
3146         qWarning("QPainter::shear: Painter not active");
3147         return;
3148     }
3149
3150     d->state->worldMatrix.shear(sh, sv);
3151     d->state->WxF = true;
3152     d->updateMatrix();
3153 }
3154
3155 /*!
3156     \fn void QPainter::rotate(qreal angle)
3157
3158     Rotates the coordinate system the given \a angle clockwise.
3159
3160     \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate
3161     Transformations}
3162 */
3163
3164 void QPainter::rotate(qreal a)
3165 {
3166 #ifdef QT_DEBUG_DRAW
3167     if (qt_show_painter_debug_output)
3168         printf("QPainter::rotate(), angle=%f\n", a);
3169 #endif
3170     Q_D(QPainter);
3171     if (!d->engine) {
3172         qWarning("QPainter::rotate: Painter not active");
3173         return;
3174     }
3175
3176     d->state->worldMatrix.rotate(a);
3177     d->state->WxF = true;
3178     d->updateMatrix();
3179 }
3180
3181 /*!
3182     Translates the coordinate system by the given \a offset; i.e. the
3183     given \a offset is added to points.
3184
3185     \sa setWorldTransform(), {QPainter#Coordinate Transformations}{Coordinate
3186     Transformations}
3187 */
3188 void QPainter::translate(const QPointF &offset)
3189 {
3190     qreal dx = offset.x();
3191     qreal dy = offset.y();
3192 #ifdef QT_DEBUG_DRAW
3193     if (qt_show_painter_debug_output)
3194         printf("QPainter::translate(), dx=%f, dy=%f\n", dx, dy);
3195 #endif
3196     Q_D(QPainter);
3197     if (!d->engine) {
3198         qWarning("QPainter::translate: Painter not active");
3199         return;
3200     }
3201
3202     d->state->worldMatrix.translate(dx, dy);
3203     d->state->WxF = true;
3204     d->updateMatrix();
3205 }
3206
3207 /*!
3208     \fn void QPainter::translate(const QPoint &offset)
3209     \overload
3210
3211     Translates the coordinate system by the given \a offset.
3212 */
3213
3214 /*!
3215     \fn void QPainter::translate(qreal dx, qreal dy)
3216     \overload
3217
3218     Translates the coordinate system by the vector (\a dx, \a dy).
3219 */
3220
3221 /*!
3222     \fn void QPainter::setClipPath(const QPainterPath &path, Qt::ClipOperation operation)
3223
3224     Enables clipping, and sets the clip path for the painter to the
3225     given \a path, with the clip \a operation.
3226
3227     Note that the clip path is specified in logical (painter)
3228     coordinates.
3229
3230     \sa clipPath(), clipRegion(), {QPainter#Clipping}{Clipping}
3231
3232 */
3233 void QPainter::setClipPath(const QPainterPath &path, Qt::ClipOperation op)
3234 {
3235 #ifdef QT_DEBUG_DRAW
3236     if (qt_show_painter_debug_output) {
3237         QRectF b = path.boundingRect();
3238         printf("QPainter::setClipPath(), size=%d, op=%d, bounds=[%.2f,%.2f,%.2f,%.2f]\n",
3239                path.elementCount(), op, b.x(), b.y(), b.width(), b.height());
3240     }
3241 #endif
3242     Q_D(QPainter);
3243
3244     if (!d->engine) {
3245         qWarning("QPainter::setClipPath: Painter not active");
3246         return;
3247     }
3248
3249     if ((!d->state->clipEnabled && op != Qt::NoClip))
3250         op = Qt::ReplaceClip;
3251
3252     if (d->extended) {
3253         d->state->clipEnabled = true;
3254         d->extended->clip(path, op);
3255         if (op == Qt::NoClip || op == Qt::ReplaceClip)
3256             d->state->clipInfo.clear();
3257         d->state->clipInfo << QPainterClipInfo(path, op, d->state->matrix);
3258         d->state->clipOperation = op;
3259         return;
3260     }
3261
3262     d->state->clipPath = path;
3263     d->state->clipOperation = op;
3264     if (op == Qt::NoClip || op == Qt::ReplaceClip)
3265         d->state->clipInfo.clear();
3266     d->state->clipInfo << QPainterClipInfo(path, op, d->state->matrix);
3267     d->state->clipEnabled = true;
3268     d->state->dirtyFlags |= QPaintEngine::DirtyClipPath | QPaintEngine::DirtyClipEnabled;
3269     d->updateState(d->state);
3270 }
3271
3272 /*!
3273     Draws the outline (strokes) the path \a path with the pen specified
3274     by \a pen
3275
3276     \sa fillPath(), {QPainter#Drawing}{Drawing}
3277 */
3278 void QPainter::strokePath(const QPainterPath &path, const QPen &pen)
3279 {
3280     Q_D(QPainter);
3281
3282     if (!d->engine) {
3283         qWarning("QPainter::strokePath: Painter not active");
3284         return;
3285     }
3286
3287     if (path.isEmpty())
3288         return;
3289
3290     if (d->extended) {
3291         const QGradient *g = qpen_brush(pen).gradient();
3292         if (!g || g->coordinateMode() == QGradient::LogicalMode) {
3293             d->extended->stroke(qtVectorPathForPath(path), pen);
3294             return;
3295         }
3296     }
3297
3298     QBrush oldBrush = d->state->brush;
3299     QPen oldPen = d->state->pen;
3300
3301     setPen(pen);
3302     setBrush(Qt::NoBrush);
3303
3304     drawPath(path);
3305
3306     // Reset old state
3307     setPen(oldPen);
3308     setBrush(oldBrush);
3309 }
3310
3311 /*!
3312     Fills the given \a path using the given \a brush. The outline is
3313     not drawn.
3314
3315     Alternatively, you can specify a QColor instead of a QBrush; the
3316     QBrush constructor (taking a QColor argument) will automatically
3317     create a solid pattern brush.
3318
3319     \sa drawPath()
3320 */
3321 void QPainter::fillPath(const QPainterPath &path, const QBrush &brush)
3322 {
3323     Q_D(QPainter);
3324
3325     if (!d->engine) {
3326         qWarning("QPainter::fillPath: Painter not active");
3327         return;
3328     }
3329
3330     if (path.isEmpty())
3331         return;
3332
3333     if (d->extended) {
3334         const QGradient *g = brush.gradient();
3335         if (!g || g->coordinateMode() == QGradient::LogicalMode) {
3336             d->extended->fill(qtVectorPathForPath(path), brush);
3337             return;
3338         }
3339     }
3340
3341     QBrush oldBrush = d->state->brush;
3342     QPen oldPen = d->state->pen;
3343
3344     setPen(Qt::NoPen);
3345     setBrush(brush);
3346
3347     drawPath(path);
3348
3349     // Reset old state
3350     setPen(oldPen);
3351     setBrush(oldBrush);
3352 }
3353
3354 /*!
3355     Draws the given painter \a path using the current pen for outline
3356     and the current brush for filling.
3357
3358     \table 100%
3359     \row
3360     \o \inlineimage qpainter-path.png
3361     \o
3362     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 5
3363     \endtable
3364
3365     \sa {painting/painterpaths}{the Painter Paths
3366     example},{painting/deform}{the Vector Deformation example}
3367 */
3368 void QPainter::drawPath(const QPainterPath &path)
3369 {
3370 #ifdef QT_DEBUG_DRAW
3371     QRectF pathBounds = path.boundingRect();
3372     if (qt_show_painter_debug_output)
3373         printf("QPainter::drawPath(), size=%d, [%.2f,%.2f,%.2f,%.2f]\n",
3374                path.elementCount(),
3375                pathBounds.x(), pathBounds.y(), pathBounds.width(), pathBounds.height());
3376 #endif
3377
3378     Q_D(QPainter);
3379
3380     if (!d->engine) {
3381         qWarning("QPainter::drawPath: Painter not active");
3382         return;
3383     }
3384
3385     if (d->extended) {
3386         d->extended->drawPath(path);
3387         return;
3388     }
3389     d->updateState(d->state);
3390
3391     if (d->engine->hasFeature(QPaintEngine::PainterPaths) && d->state->emulationSpecifier == 0) {
3392         d->engine->drawPath(path);
3393     } else {
3394         d->draw_helper(path);
3395     }
3396 }
3397
3398 /*!
3399     \fn void QPainter::drawLine(const QLineF &line)
3400
3401     Draws a line defined by \a line.
3402
3403     \table 100%
3404     \row
3405     \o \inlineimage qpainter-line.png
3406     \o
3407     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 6
3408     \endtable
3409
3410     \sa drawLines(), drawPolyline(), {Coordinate System}
3411 */
3412
3413 /*!
3414     \fn void QPainter::drawLine(const QLine &line)
3415     \overload
3416
3417     Draws a line defined by \a line.
3418 */
3419
3420 /*!
3421     \fn void QPainter::drawLine(const QPoint &p1, const QPoint &p2)
3422     \overload
3423
3424     Draws a line from \a p1 to \a p2.
3425 */
3426
3427 /*!
3428     \fn void QPainter::drawLine(const QPointF &p1, const QPointF &p2)
3429     \overload
3430
3431     Draws a line from \a p1 to \a p2.
3432 */
3433
3434 /*!
3435     \fn void QPainter::drawLine(int x1, int y1, int x2, int y2)
3436     \overload
3437
3438     Draws a line from (\a x1, \a y1) to (\a x2, \a y2) and sets the
3439     current pen position to (\a x2, \a y2).
3440 */
3441
3442 /*!
3443     \fn void QPainter::drawRect(const QRectF &rectangle)
3444
3445     Draws the current \a rectangle with the current pen and brush.
3446
3447     A filled rectangle has a size of \a{rectangle}.size(). A stroked
3448     rectangle has a size of \a{rectangle}.size() plus the pen width.
3449
3450     \table 100%
3451     \row
3452     \o \inlineimage qpainter-rectangle.png
3453     \o
3454     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 7
3455     \endtable
3456
3457     \sa drawRects(), drawPolygon(), {Coordinate System}
3458 */
3459
3460 /*!
3461     \fn void QPainter::drawRect(const QRect &rectangle)
3462
3463     \overload
3464
3465     Draws the current \a rectangle with the current pen and brush.
3466 */
3467
3468 /*!
3469     \fn void QPainter::drawRect(int x, int y, int width, int height)
3470
3471     \overload
3472
3473     Draws a rectangle with upper left corner at (\a{x}, \a{y}) and
3474     with the given \a width and \a height.
3475 */
3476
3477 /*!
3478     \fn void QPainter::drawRects(const QRectF *rectangles, int rectCount)
3479
3480     Draws the first \a rectCount of the given \a rectangles using the
3481     current pen and brush.
3482
3483     \sa drawRect()
3484 */
3485 void QPainter::drawRects(const QRectF *rects, int rectCount)
3486 {
3487 #ifdef QT_DEBUG_DRAW
3488     if (qt_show_painter_debug_output)
3489         printf("QPainter::drawRects(), count=%d\n", rectCount);
3490 #endif
3491     Q_D(QPainter);
3492
3493     if (!d->engine) {
3494         qWarning("QPainter::drawRects: Painter not active");
3495         return;
3496     }
3497
3498     if (rectCount <= 0)
3499         return;
3500
3501     if (d->extended) {
3502         d->extended->drawRects(rects, rectCount);
3503         return;
3504     }
3505
3506     d->updateState(d->state);
3507
3508     if (!d->state->emulationSpecifier) {
3509         d->engine->drawRects(rects, rectCount);
3510         return;
3511     }
3512
3513     if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
3514         && d->state->matrix.type() == QTransform::TxTranslate) {
3515         for (int i=0; i<rectCount; ++i) {
3516             QRectF r(rects[i].x() + d->state->matrix.dx(),
3517                      rects[i].y() + d->state->matrix.dy(),
3518                      rects[i].width(),
3519                      rects[i].height());
3520             d->engine->drawRects(&r, 1);
3521         }
3522     } else {
3523         if (d->state->brushNeedsResolving() || d->state->penNeedsResolving()) {
3524             for (int i=0; i<rectCount; ++i) {
3525                 QPainterPath rectPath;
3526                 rectPath.addRect(rects[i]);
3527                 d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
3528             }
3529         } else {
3530             QPainterPath rectPath;
3531             for (int i=0; i<rectCount; ++i)
3532                 rectPath.addRect(rects[i]);
3533             d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
3534         }
3535     }
3536 }
3537
3538 /*!
3539     \fn void QPainter::drawRects(const QRect *rectangles, int rectCount)
3540     \overload
3541
3542     Draws the first \a rectCount of the given \a rectangles using the
3543     current pen and brush.
3544 */
3545 void QPainter::drawRects(const QRect *rects, int rectCount)
3546 {
3547 #ifdef QT_DEBUG_DRAW
3548     if (qt_show_painter_debug_output)
3549         printf("QPainter::drawRects(), count=%d\n", rectCount);
3550 #endif
3551     Q_D(QPainter);
3552
3553     if (!d->engine) {
3554         qWarning("QPainter::drawRects: Painter not active");
3555         return;
3556     }
3557
3558     if (rectCount <= 0)
3559         return;
3560
3561     if (d->extended) {
3562         d->extended->drawRects(rects, rectCount);
3563         return;
3564     }
3565
3566     d->updateState(d->state);
3567
3568     if (!d->state->emulationSpecifier) {
3569         d->engine->drawRects(rects, rectCount);
3570         return;
3571     }
3572
3573     if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
3574         && d->state->matrix.type() == QTransform::TxTranslate) {
3575         for (int i=0; i<rectCount; ++i) {
3576             QRectF r(rects[i].x() + d->state->matrix.dx(),
3577                      rects[i].y() + d->state->matrix.dy(),
3578                      rects[i].width(),
3579                      rects[i].height());
3580
3581             d->engine->drawRects(&r, 1);
3582         }
3583     } else {
3584         if (d->state->brushNeedsResolving() || d->state->penNeedsResolving()) {
3585             for (int i=0; i<rectCount; ++i) {
3586                 QPainterPath rectPath;
3587                 rectPath.addRect(rects[i]);
3588                 d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
3589             }
3590         } else {
3591             QPainterPath rectPath;
3592             for (int i=0; i<rectCount; ++i)
3593                 rectPath.addRect(rects[i]);
3594
3595             d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
3596         }
3597     }
3598 }
3599
3600 /*!
3601     \fn void QPainter::drawRects(const QVector<QRectF> &rectangles)
3602     \overload
3603
3604     Draws the given \a rectangles using the current pen and brush.
3605 */
3606
3607 /*!
3608     \fn void QPainter::drawRects(const QVector<QRect> &rectangles)
3609
3610     \overload
3611
3612     Draws the given \a rectangles using the current pen and brush.
3613 */
3614
3615 /*!
3616   \fn void QPainter::drawPoint(const QPointF &position)
3617
3618     Draws a single point at the given \a position using the current
3619     pen's color.
3620
3621     \sa {Coordinate System}
3622 */
3623
3624 /*!
3625     \fn void QPainter::drawPoint(const QPoint &position)
3626     \overload
3627
3628     Draws a single point at the given \a position using the current
3629     pen's color.
3630 */
3631
3632 /*! \fn void QPainter::drawPoint(int x, int y)
3633
3634     \overload
3635
3636     Draws a single point at position (\a x, \a y).
3637 */
3638
3639 /*!
3640     Draws the first \a pointCount points in the array \a points using
3641     the current pen's color.
3642
3643     \sa {Coordinate System}
3644 */
3645 void QPainter::drawPoints(const QPointF *points, int pointCount)
3646 {
3647 #ifdef QT_DEBUG_DRAW
3648     if (qt_show_painter_debug_output)
3649         printf("QPainter::drawPoints(), count=%d\n", pointCount);
3650 #endif
3651     Q_D(QPainter);
3652
3653     if (!d->engine) {
3654         qWarning("QPainter::drawPoints: Painter not active");
3655         return;
3656     }
3657
3658     if (pointCount <= 0)
3659         return;
3660
3661     if (d->extended) {
3662         d->extended->drawPoints(points, pointCount);
3663         return;
3664     }
3665
3666     d->updateState(d->state);
3667
3668     if (!d->state->emulationSpecifier) {
3669         d->engine->drawPoints(points, pointCount);
3670         return;
3671     }
3672
3673     if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
3674         && d->state->matrix.type() == QTransform::TxTranslate) {
3675         // ### use drawPoints function
3676         for (int i=0; i<pointCount; ++i) {
3677             QPointF pt(points[i].x() + d->state->matrix.dx(),
3678                        points[i].y() + d->state->matrix.dy());
3679             d->engine->drawPoints(&pt, 1);
3680         }
3681     } else {
3682         QPen pen = d->state->pen;
3683         bool flat_pen = pen.capStyle() == Qt::FlatCap;
3684         if (flat_pen) {
3685             save();
3686             pen.setCapStyle(Qt::SquareCap);
3687             setPen(pen);
3688         }
3689         QPainterPath path;
3690         for (int i=0; i<pointCount; ++i) {
3691             path.moveTo(points[i].x(), points[i].y());
3692             path.lineTo(points[i].x() + 0.0001, points[i].y());
3693         }
3694         d->draw_helper(path, QPainterPrivate::StrokeDraw);
3695         if (flat_pen)
3696             restore();
3697     }
3698 }
3699
3700 /*!
3701     \overload
3702
3703     Draws the first \a pointCount points in the array \a points using
3704     the current pen's color.
3705 */
3706
3707 void QPainter::drawPoints(const QPoint *points, int pointCount)
3708 {
3709 #ifdef QT_DEBUG_DRAW
3710     if (qt_show_painter_debug_output)
3711         printf("QPainter::drawPoints(), count=%d\n", pointCount);
3712 #endif
3713     Q_D(QPainter);
3714
3715     if (!d->engine) {
3716         qWarning("QPainter::drawPoints: Painter not active");
3717         return;
3718     }
3719
3720     if (pointCount <= 0)
3721         return;
3722
3723     if (d->extended) {
3724         d->extended->drawPoints(points, pointCount);
3725         return;
3726     }
3727
3728     d->updateState(d->state);
3729
3730     if (!d->state->emulationSpecifier) {
3731         d->engine->drawPoints(points, pointCount);
3732         return;
3733     }
3734
3735     if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
3736         && d->state->matrix.type() == QTransform::TxTranslate) {
3737         // ### use drawPoints function
3738         for (int i=0; i<pointCount; ++i) {
3739             QPointF pt(points[i].x() + d->state->matrix.dx(),
3740                        points[i].y() + d->state->matrix.dy());
3741             d->engine->drawPoints(&pt, 1);
3742         }
3743     } else {
3744         QPen pen = d->state->pen;
3745         bool flat_pen = (pen.capStyle() == Qt::FlatCap);
3746         if (flat_pen) {
3747             save();
3748             pen.setCapStyle(Qt::SquareCap);
3749             setPen(pen);
3750         }
3751         QPainterPath path;
3752         for (int i=0; i<pointCount; ++i) {
3753             path.moveTo(points[i].x(), points[i].y());
3754             path.lineTo(points[i].x() + 0.0001, points[i].y());
3755         }
3756         d->draw_helper(path, QPainterPrivate::StrokeDraw);
3757         if (flat_pen)
3758             restore();
3759     }
3760 }
3761
3762 /*!
3763     \fn void QPainter::drawPoints(const QPolygonF &points)
3764
3765     \overload
3766
3767     Draws the points in the vector  \a points.
3768 */
3769
3770 /*!
3771     \fn void QPainter::drawPoints(const QPolygon &points)
3772
3773     \overload
3774
3775     Draws the points in the vector  \a points.
3776 */
3777
3778 /*!
3779     \fn void QPainter::drawPoints(const QPolygon &polygon, int index,
3780     int count)
3781
3782     \overload
3783     \compat
3784
3785     Draws \a count points in the vector \a polygon starting on \a index
3786     using the current pen.
3787
3788     Use drawPoints() combined with QPolygon::constData() instead.
3789
3790     \oldcode
3791         QPainter painter(this);
3792         painter.drawPoints(polygon, index, count);
3793     \newcode
3794         int pointCount = (count == -1) ?  polygon.size() - index : count;
3795
3796         QPainter painter(this);
3797         painter.drawPoints(polygon.constData() + index, pointCount);
3798     \endcode
3799 */
3800
3801 /*!
3802     Sets the background mode of the painter to the given \a mode
3803
3804     Qt::TransparentMode (the default) draws stippled lines and text
3805     without setting the background pixels.  Qt::OpaqueMode fills these
3806     space with the current background color.
3807
3808     Note that in order to draw a bitmap or pixmap transparently, you
3809     must use QPixmap::setMask().
3810
3811     \sa backgroundMode(), setBackground(),
3812     {QPainter#Settings}{Settings}
3813 */
3814
3815 void QPainter::setBackgroundMode(Qt::BGMode mode)
3816 {
3817 #ifdef QT_DEBUG_DRAW
3818     if (qt_show_painter_debug_output)
3819         printf("QPainter::setBackgroundMode(), mode=%d\n", mode);
3820 #endif
3821
3822     Q_D(QPainter);
3823     if (!d->engine) {
3824         qWarning("QPainter::setBackgroundMode: Painter not active");
3825         return;
3826     }
3827     if (d->state->bgMode == mode)
3828         return;
3829
3830     d->state->bgMode = mode;
3831     if (d->extended) {
3832         d->checkEmulation();
3833     } else {
3834         d->state->dirtyFlags |= QPaintEngine::DirtyBackgroundMode;
3835     }
3836 }
3837
3838 /*!
3839     Returns the current background mode.
3840
3841     \sa setBackgroundMode(), {QPainter#Settings}{Settings}
3842 */
3843 Qt::BGMode QPainter::backgroundMode() const
3844 {
3845     Q_D(const QPainter);
3846     if (!d->engine) {
3847         qWarning("QPainter::backgroundMode: Painter not active");
3848         return Qt::TransparentMode;
3849     }
3850     return d->state->bgMode;
3851 }
3852
3853
3854 /*!
3855     \overload
3856
3857     Sets the painter's pen to have style Qt::SolidLine, width 0 and the
3858     specified \a color.
3859 */
3860
3861 void QPainter::setPen(const QColor &color)
3862 {
3863 #ifdef QT_DEBUG_DRAW
3864     if (qt_show_painter_debug_output)
3865         printf("QPainter::setPen(), color=%04x\n", color.rgb());
3866 #endif
3867     Q_D(QPainter);
3868     if (!d->engine) {
3869         qWarning("QPainter::setPen: Painter not active");
3870         return;
3871     }
3872
3873     if (d->state->pen.style() == Qt::SolidLine
3874         && d->state->pen.widthF() == 0
3875         && d->state->pen.isSolid()
3876         && d->state->pen.color() == color)
3877         return;
3878
3879     QPen pen(color.isValid() ? color : QColor(Qt::black), 0, Qt::SolidLine);
3880
3881     d->state->pen = pen;
3882     if (d->extended)
3883         d->extended->penChanged();
3884     else
3885         d->state->dirtyFlags |= QPaintEngine::DirtyPen;
3886 }
3887
3888 /*!
3889     Sets the painter's pen to be the given \a pen.
3890
3891     The \a pen defines how to draw lines and outlines, and it also
3892     defines the text color.
3893
3894     \sa pen(), {QPainter#Settings}{Settings}
3895 */
3896
3897 void QPainter::setPen(const QPen &pen)
3898 {
3899
3900 #ifdef QT_DEBUG_DRAW
3901     if (qt_show_painter_debug_output)
3902         printf("QPainter::setPen(), color=%04x, (brushStyle=%d) style=%d, cap=%d, join=%d\n",
3903            pen.color().rgb(), pen.brush().style(), pen.style(), pen.capStyle(), pen.joinStyle());
3904 #endif
3905     Q_D(QPainter);
3906     if (!d->engine) {
3907         qWarning("QPainter::setPen: Painter not active");
3908         return;
3909     }
3910
3911     if (d->state->pen == pen)
3912         return;
3913
3914     d->state->pen = pen;
3915
3916     if (d->extended) {
3917         d->checkEmulation();
3918         d->extended->penChanged();
3919         return;
3920     }
3921
3922     d->state->dirtyFlags |= QPaintEngine::DirtyPen;
3923 }
3924
3925 /*!
3926     \overload
3927
3928     Sets the painter's pen to have the given \a style, width 0 and
3929     black color.
3930 */
3931
3932 void QPainter::setPen(Qt::PenStyle style)
3933 {
3934     Q_D(QPainter);
3935     if (!d->engine) {
3936         qWarning("QPainter::setPen: Painter not active");
3937         return;
3938     }
3939
3940     if (d->state->pen.style() == style
3941         && (style == Qt::NoPen || (d->state->pen.widthF() == 0
3942                                    && d->state->pen.isSolid()
3943                                    && d->state->pen.color() == QColor(Qt::black))))
3944         return;
3945
3946     // QPen(Qt::NoPen) is to avoid creating QPenData, including its brush (from the color)
3947     // Note that this works well as long as QPen(Qt::NoPen) returns a black, zero-width pen
3948     d->state->pen = (style == Qt::NoPen) ? QPen(Qt::NoPen) : QPen(Qt::black, 0, style);
3949
3950     if (d->extended)
3951         d->extended->penChanged();
3952     else
3953         d->state->dirtyFlags |= QPaintEngine::DirtyPen;
3954
3955 }
3956
3957 /*!
3958     Returns the painter's current pen.
3959
3960     \sa setPen(), {QPainter#Settings}{Settings}
3961 */
3962
3963 const QPen &QPainter::pen() const
3964 {
3965     Q_D(const QPainter);
3966     if (!d->engine) {
3967         qWarning("QPainter::pen: Painter not active");
3968         return d->fakeState()->pen;
3969     }
3970     return d->state->pen;
3971 }
3972
3973
3974 /*!
3975     Sets the painter's brush to the given \a brush.
3976
3977     The painter's brush defines how shapes are filled.
3978
3979     \sa brush(), {QPainter#Settings}{Settings}
3980 */
3981
3982 void QPainter::setBrush(const QBrush &brush)
3983 {
3984 #ifdef QT_DEBUG_DRAW
3985     if (qt_show_painter_debug_output)
3986         printf("QPainter::setBrush(), color=%04x, style=%d\n", brush.color().rgb(), brush.style());
3987 #endif
3988     Q_D(QPainter);
3989     if (!d->engine) {
3990         qWarning("QPainter::setBrush: Painter not active");
3991         return;
3992     }
3993
3994     if (d->state->brush.d == brush.d)
3995         return;
3996
3997     if (d->extended) {
3998         d->state->brush = brush;
3999         d->checkEmulation();
4000         d->extended->brushChanged();
4001         return;
4002     }
4003
4004     d->state->brush = brush;
4005     d->state->dirtyFlags |= QPaintEngine::DirtyBrush;
4006 }
4007
4008
4009 /*!
4010     \overload
4011
4012     Sets the painter's brush to black color and the specified \a
4013     style.
4014 */
4015
4016 void QPainter::setBrush(Qt::BrushStyle style)
4017 {
4018     Q_D(QPainter);
4019     if (!d->engine) {
4020         qWarning("QPainter::setBrush: Painter not active");
4021         return;
4022     }
4023     if (d->state->brush.style() == style &&
4024         (style == Qt::NoBrush
4025          || (style == Qt::SolidPattern && d->state->brush.color() == QColor(0, 0, 0))))
4026         return;
4027     d->state->brush = QBrush(Qt::black, style);
4028     if (d->extended)
4029         d->extended->brushChanged();
4030     else
4031         d->state->dirtyFlags |= QPaintEngine::DirtyBrush;
4032 }
4033
4034 /*!
4035     Returns the painter's current brush.
4036
4037     \sa QPainter::setBrush(), {QPainter#Settings}{Settings}
4038 */
4039
4040 const QBrush &QPainter::brush() const
4041 {
4042     Q_D(const QPainter);
4043     if (!d->engine) {
4044         qWarning("QPainter::brush: Painter not active");
4045         return d->fakeState()->brush;
4046     }
4047     return d->state->brush;
4048 }
4049
4050 /*!
4051     \fn void QPainter::setBackground(const QBrush &brush)
4052
4053     Sets the background brush of the painter to the given \a brush.
4054
4055     The background brush is the brush that is filled in when drawing
4056     opaque text, stippled lines and bitmaps. The background brush has
4057     no effect in transparent background mode (which is the default).
4058
4059     \sa background(), setBackgroundMode(),
4060     {QPainter#Settings}{Settings}
4061 */
4062
4063 void QPainter::setBackground(const QBrush &bg)
4064 {
4065 #ifdef QT_DEBUG_DRAW
4066     if (qt_show_painter_debug_output)
4067         printf("QPainter::setBackground(), color=%04x, style=%d\n", bg.color().rgb(), bg.style());
4068 #endif
4069
4070     Q_D(QPainter);
4071     if (!d->engine) {
4072         qWarning("QPainter::setBackground: Painter not active");
4073         return;
4074     }
4075     d->state->bgBrush = bg;
4076     if (!d->extended)
4077         d->state->dirtyFlags |= QPaintEngine::DirtyBackground;
4078 }
4079
4080 /*!
4081     Sets the painter's font to the given \a font.
4082
4083     This font is used by subsequent drawText() functions. The text
4084     color is the same as the pen color.
4085
4086     If you set a font that isn't available, Qt finds a close match.
4087     font() will return what you set using setFont() and fontInfo() returns the
4088     font actually being used (which may be the same).
4089
4090     \sa font(), drawText(), {QPainter#Settings}{Settings}
4091 */
4092
4093 void QPainter::setFont(const QFont &font)
4094 {
4095     Q_D(QPainter);
4096
4097 #ifdef QT_DEBUG_DRAW
4098     if (qt_show_painter_debug_output)
4099         printf("QPainter::setFont(), family=%s, pointSize=%d\n", font.family().toLatin1().constData(), font.pointSize());
4100 #endif
4101
4102     if (!d->engine) {
4103         qWarning("QPainter::setFont: Painter not active");
4104         return;
4105     }
4106
4107     d->state->font = QFont(font.resolve(d->state->deviceFont), device());
4108     if (!d->extended)
4109         d->state->dirtyFlags |= QPaintEngine::DirtyFont;
4110 }
4111
4112 /*!
4113     Returns the currently set font used for drawing text.
4114
4115     \sa setFont(), drawText(), {QPainter#Settings}{Settings}
4116 */
4117 const QFont &QPainter::font() const
4118 {
4119     Q_D(const QPainter);
4120     if (!d->engine) {
4121         qWarning("QPainter::font: Painter not active");
4122         return d->fakeState()->font;
4123     }
4124     return d->state->font;
4125 }
4126
4127 /*!
4128     \since 4.4
4129
4130     Draws the given rectangle \a rect with rounded corners.
4131
4132     The \a xRadius and \a yRadius arguments specify the radii
4133     of the ellipses defining the corners of the rounded rectangle.
4134     When \a mode is Qt::RelativeSize, \a xRadius and
4135     \a yRadius are specified in percentage of half the rectangle's
4136     width and height respectively, and should be in the range
4137     0.0 to 100.0.
4138
4139     A filled rectangle has a size of rect.size(). A stroked rectangle
4140     has a size of rect.size() plus the pen width.
4141
4142     \table 100%
4143     \row
4144     \o \inlineimage qpainter-roundrect.png
4145     \o
4146     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 8
4147     \endtable
4148
4149     \sa drawRect(), QPen
4150 */
4151 void QPainter::drawRoundedRect(const QRectF &rect, qreal xRadius, qreal yRadius, Qt::SizeMode mode)
4152 {
4153 #ifdef QT_DEBUG_DRAW
4154     if (qt_show_painter_debug_output)
4155         printf("QPainter::drawRoundedRect(), [%.2f,%.2f,%.2f,%.2f]\n", rect.x(), rect.y(), rect.width(), rect.height());
4156 #endif
4157     Q_D(QPainter);
4158
4159     if (!d->engine)
4160         return;
4161
4162     if (xRadius <= 0 || yRadius <= 0) {             // draw normal rectangle
4163         drawRect(rect);
4164         return;
4165     }
4166
4167     if (d->extended) {
4168         d->extended->drawRoundedRect(rect, xRadius, yRadius, mode);
4169         return;
4170     }
4171
4172     QPainterPath path;
4173     path.addRoundedRect(rect, xRadius, yRadius, mode);
4174     drawPath(path);
4175 }
4176
4177 /*!
4178     \fn void QPainter::drawRoundedRect(const QRect &rect, qreal xRadius, qreal yRadius,
4179                                        Qt::SizeMode mode = Qt::AbsoluteSize);
4180     \since 4.4
4181     \overload
4182
4183     Draws the given rectangle \a rect with rounded corners.
4184 */
4185
4186 /*!
4187     \fn void QPainter::drawRoundedRect(int x, int y, int w, int h, qreal xRadius, qreal yRadius,
4188                                        Qt::SizeMode mode = Qt::AbsoluteSize);
4189     \since 4.4
4190     \overload
4191
4192     Draws the given rectangle \a x, \a y, \a w, \a h with rounded corners.
4193 */
4194
4195 /*!
4196     \obsolete
4197
4198     Draws a rectangle \a r with rounded corners.
4199
4200     The \a xRnd and \a yRnd arguments specify how rounded the corners
4201     should be. 0 is angled corners, 99 is maximum roundedness.
4202
4203     A filled rectangle has a size of r.size(). A stroked rectangle
4204     has a size of r.size() plus the pen width.
4205
4206     \sa drawRoundedRect()
4207 */
4208 void QPainter::drawRoundRect(const QRectF &r, int xRnd, int yRnd)
4209 {
4210     drawRoundedRect(r, xRnd, yRnd, Qt::RelativeSize);
4211 }
4212
4213
4214 /*!
4215     \fn void QPainter::drawRoundRect(const QRect &r, int xRnd = 25, int yRnd = 25)
4216
4217     \overload
4218     \obsolete
4219
4220     Draws the rectangle \a r with rounded corners.
4221 */
4222
4223 /*!
4224     \obsolete
4225
4226     \fn QPainter::drawRoundRect(int x, int y, int w, int h, int xRnd, int yRnd)
4227
4228     \overload
4229
4230     Draws the rectangle \a x, \a y, \a w, \a h with rounded corners.
4231 */
4232
4233 /*!
4234     \fn void QPainter::drawEllipse(const QRectF &rectangle)
4235
4236     Draws the ellipse defined by the given \a rectangle.
4237
4238     A filled ellipse has a size of \a{rectangle}.\l
4239     {QRect::size()}{size()}. A stroked ellipse has a size of
4240     \a{rectangle}.\l {QRect::size()}{size()} plus the pen width.
4241
4242     \table 100%
4243     \row
4244     \o \inlineimage qpainter-ellipse.png
4245     \o
4246     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 9
4247     \endtable
4248
4249     \sa drawPie(), {Coordinate System}
4250 */
4251 void QPainter::drawEllipse(const QRectF &r)
4252 {
4253 #ifdef QT_DEBUG_DRAW
4254     if (qt_show_painter_debug_output)
4255         printf("QPainter::drawEllipse(), [%.2f,%.2f,%.2f,%.2f]\n", r.x(), r.y(), r.width(), r.height());
4256 #endif
4257     Q_D(QPainter);
4258
4259     if (!d->engine)
4260         return;
4261
4262     QRectF rect(r.normalized());
4263
4264     if (d->extended) {
4265         d->extended->drawEllipse(rect);
4266         return;
4267     }
4268
4269     d->updateState(d->state);
4270     if (d->state->emulationSpecifier) {
4271         if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
4272             && d->state->matrix.type() == QTransform::TxTranslate) {
4273             rect.translate(QPointF(d->state->matrix.dx(), d->state->matrix.dy()));
4274         } else {
4275             QPainterPath path;
4276             path.addEllipse(rect);
4277             d->draw_helper(path, QPainterPrivate::StrokeAndFillDraw);
4278             return;
4279         }
4280     }
4281
4282     d->engine->drawEllipse(rect);
4283 }
4284
4285 /*!
4286     \fn QPainter::drawEllipse(const QRect &rectangle)
4287
4288     \overload
4289
4290     Draws the ellipse defined by the given \a rectangle.
4291 */
4292 void QPainter::drawEllipse(const QRect &r)
4293 {
4294 #ifdef QT_DEBUG_DRAW
4295     if (qt_show_painter_debug_output)
4296         printf("QPainter::drawEllipse(), [%d,%d,%d,%d]\n", r.x(), r.y(), r.width(), r.height());
4297 #endif
4298     Q_D(QPainter);
4299
4300     if (!d->engine)
4301         return;
4302
4303     QRect rect(r.normalized());
4304
4305     if (d->extended) {
4306         d->extended->drawEllipse(rect);
4307         return;
4308     }
4309
4310     d->updateState(d->state);
4311
4312     if (d->state->emulationSpecifier) {
4313         if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
4314             && d->state->matrix.type() == QTransform::TxTranslate) {
4315             rect.translate(QPoint(qRound(d->state->matrix.dx()), qRound(d->state->matrix.dy())));
4316         } else {
4317             QPainterPath path;
4318             path.addEllipse(rect);
4319             d->draw_helper(path, QPainterPrivate::StrokeAndFillDraw);
4320             return;
4321         }
4322     }
4323
4324     d->engine->drawEllipse(rect);
4325 }
4326
4327 /*!
4328     \fn QPainter::drawEllipse(int x, int y, int width, int height)
4329
4330     \overload
4331
4332     Draws the ellipse defined by the rectangle beginning at (\a{x},
4333     \a{y}) with the given \a width and \a height.
4334 */
4335
4336 /*!
4337     \since 4.4
4338
4339     \fn QPainter::drawEllipse(const QPointF &center, qreal rx, qreal ry)
4340
4341     \overload
4342
4343     Draws the ellipse positioned at \a{center} with radii \a{rx} and \a{ry}.
4344 */
4345
4346 /*!
4347     \since 4.4
4348
4349     \fn QPainter::drawEllipse(const QPoint &center, int rx, int ry)
4350
4351     \overload
4352
4353     Draws the ellipse positioned at \a{center} with radii \a{rx} and \a{ry}.
4354 */
4355
4356 /*!
4357     \fn void QPainter::drawArc(const QRectF &rectangle, int startAngle, int spanAngle)
4358
4359     Draws the arc defined by the given \a rectangle, \a startAngle and
4360     \a spanAngle.
4361
4362     The \a startAngle and \a spanAngle must be specified in 1/16th of
4363     a degree, i.e. a full circle equals 5760 (16 * 360). Positive
4364     values for the angles mean counter-clockwise while negative values
4365     mean the clockwise direction. Zero degrees is at the 3 o'clock
4366     position.
4367
4368     \table 100%
4369     \row
4370     \o \inlineimage qpainter-arc.png
4371     \o
4372     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 10
4373     \endtable
4374
4375     \sa drawPie(), drawChord(), {Coordinate System}
4376 */
4377
4378 void QPainter::drawArc(const QRectF &r, int a, int alen)
4379 {
4380 #ifdef QT_DEBUG_DRAW
4381     if (qt_show_painter_debug_output)
4382         printf("QPainter::drawArc(), [%.2f,%.2f,%.2f,%.2f], angle=%d, sweep=%d\n",
4383            r.x(), r.y(), r.width(), r.height(), a/16, alen/16);
4384 #endif
4385     Q_D(QPainter);
4386
4387     if (!d->engine)
4388         return;
4389
4390     QRectF rect = r.normalized();
4391
4392     QPainterPath path;
4393     path.arcMoveTo(rect, a/16.0);
4394     path.arcTo(rect, a/16.0, alen/16.0);
4395     strokePath(path, d->state->pen);
4396 }
4397
4398 /*! \fn void QPainter::drawArc(const QRect &rectangle, int startAngle,
4399                                int spanAngle)
4400
4401     \overload
4402
4403     Draws the arc defined by the given \a rectangle, \a startAngle and
4404     \a spanAngle.
4405 */
4406
4407 /*!
4408     \fn void QPainter::drawArc(int x, int y, int width, int height,
4409                                int startAngle, int spanAngle)
4410
4411     \overload
4412
4413     Draws the arc defined by the rectangle beginning at (\a x, \a y)
4414     with the specified \a width and \a height, and the given \a
4415     startAngle and \a spanAngle.
4416 */
4417
4418 /*!
4419     \fn void QPainter::drawPie(const QRectF &rectangle, int startAngle, int spanAngle)
4420
4421     Draws a pie defined by the given \a rectangle, \a startAngle and
4422     and \a spanAngle.
4423
4424     The pie is filled with the current brush().
4425
4426     The startAngle and spanAngle must be specified in 1/16th of a
4427     degree, i.e. a full circle equals 5760 (16 * 360). Positive values
4428     for the angles mean counter-clockwise while negative values mean
4429     the clockwise direction. Zero degrees is at the 3 o'clock
4430     position.
4431
4432     \table 100%
4433     \row
4434     \o \inlineimage qpainter-pie.png
4435     \o
4436     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 11
4437     \endtable
4438
4439     \sa drawEllipse(), drawChord(), {Coordinate System}
4440 */
4441 void QPainter::drawPie(const QRectF &r, int a, int alen)
4442 {
4443 #ifdef QT_DEBUG_DRAW
4444     if (qt_show_painter_debug_output)
4445         printf("QPainter::drawPie(), [%.2f,%.2f,%.2f,%.2f], angle=%d, sweep=%d\n",
4446            r.x(), r.y(), r.width(), r.height(), a/16, alen/16);
4447 #endif
4448     Q_D(QPainter);
4449
4450     if (!d->engine)
4451         return;
4452
4453     if (a > (360*16)) {
4454         a = a % (360*16);
4455     } else if (a < 0) {
4456         a = a % (360*16);
4457         if (a < 0) a += (360*16);
4458     }
4459
4460     QRectF rect = r.normalized();
4461
4462     QPainterPath path;
4463     path.moveTo(rect.center());
4464     path.arcTo(rect.x(), rect.y(), rect.width(), rect.height(), a/16.0, alen/16.0);
4465     path.closeSubpath();
4466     drawPath(path);
4467
4468 }
4469
4470 /*!
4471     \fn void QPainter::drawPie(const QRect &rectangle, int startAngle, int spanAngle)
4472     \overload
4473
4474     Draws a pie defined by the given \a rectangle, \a startAngle and
4475     and \a spanAngle.
4476 */
4477
4478 /*!
4479     \fn void QPainter::drawPie(int x, int y, int width, int height, int
4480     startAngle, int spanAngle)
4481
4482     \overload
4483
4484     Draws the pie defined by the rectangle beginning at (\a x, \a y) with
4485     the specified \a width and \a height, and the given \a startAngle and
4486     \a spanAngle.
4487 */
4488
4489 /*!
4490     \fn void QPainter::drawChord(const QRectF &rectangle, int startAngle, int spanAngle)
4491
4492     Draws the chord defined by the given \a rectangle, \a startAngle and
4493     \a spanAngle.  The chord is filled with the current brush().
4494
4495     The startAngle and spanAngle must be specified in 1/16th of a
4496     degree, i.e. a full circle equals 5760 (16 * 360). Positive values
4497     for the angles mean counter-clockwise while negative values mean
4498     the clockwise direction. Zero degrees is at the 3 o'clock
4499     position.
4500
4501     \table 100%
4502     \row
4503     \o \inlineimage qpainter-chord.png
4504     \o
4505     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 12
4506     \endtable
4507
4508     \sa drawArc(), drawPie(), {Coordinate System}
4509 */
4510 void QPainter::drawChord(const QRectF &r, int a, int alen)
4511 {
4512 #ifdef QT_DEBUG_DRAW
4513     if (qt_show_painter_debug_output)
4514         printf("QPainter::drawChord(), [%.2f,%.2f,%.2f,%.2f], angle=%d, sweep=%d\n",
4515            r.x(), r.y(), r.width(), r.height(), a/16, alen/16);
4516 #endif
4517     Q_D(QPainter);
4518
4519     if (!d->engine)
4520         return;
4521
4522     QRectF rect = r.normalized();
4523
4524     QPainterPath path;
4525     path.arcMoveTo(rect, a/16.0);
4526     path.arcTo(rect, a/16.0, alen/16.0);
4527     path.closeSubpath();
4528     drawPath(path);
4529 }
4530 /*!
4531     \fn void QPainter::drawChord(const QRect &rectangle, int startAngle, int spanAngle)
4532
4533     \overload
4534
4535     Draws the chord defined by the given \a rectangle, \a startAngle and
4536     \a spanAngle.
4537 */
4538
4539 /*!
4540     \fn void QPainter::drawChord(int x, int y, int width, int height, int
4541     startAngle, int spanAngle)
4542
4543     \overload
4544
4545    Draws the chord defined by the rectangle beginning at (\a x, \a y)
4546    with the specified \a width and \a height, and the given \a
4547    startAngle and \a spanAngle.
4548 */
4549
4550
4551 /*!
4552     Draws the first \a lineCount lines in the array \a lines
4553     using the current pen.
4554
4555     \sa drawLine(), drawPolyline()
4556 */
4557 void QPainter::drawLines(const QLineF *lines, int lineCount)
4558 {
4559 #ifdef QT_DEBUG_DRAW
4560     if (qt_show_painter_debug_output)
4561         printf("QPainter::drawLines(), line count=%d\n", lineCount);
4562 #endif
4563
4564     Q_D(QPainter);
4565
4566     if (!d->engine || lineCount < 1)
4567         return;
4568
4569     if (d->extended) {
4570         d->extended->drawLines(lines, lineCount);
4571         return;
4572     }
4573
4574     d->updateState(d->state);
4575
4576     uint lineEmulation = line_emulation(d->state->emulationSpecifier);
4577
4578     if (lineEmulation) {
4579         if (lineEmulation == QPaintEngine::PrimitiveTransform
4580             && d->state->matrix.type() == QTransform::TxTranslate) {
4581             for (int i = 0; i < lineCount; ++i) {
4582                 QLineF line = lines[i];
4583                 line.translate(d->state->matrix.dx(), d->state->matrix.dy());
4584                 d->engine->drawLines(&line, 1);
4585             }
4586         } else {
4587             QPainterPath linePath;
4588             for (int i = 0; i < lineCount; ++i) {
4589                 linePath.moveTo(lines[i].p1());
4590                 linePath.lineTo(lines[i].p2());
4591             }
4592             d->draw_helper(linePath, QPainterPrivate::StrokeDraw);
4593         }
4594         return;
4595     }
4596     d->engine->drawLines(lines, lineCount);
4597 }
4598
4599 /*!
4600     \fn void QPainter::drawLines(const QLine *lines, int lineCount)
4601     \overload
4602
4603     Draws the first \a lineCount lines in the array \a lines
4604     using the current pen.
4605 */
4606 void QPainter::drawLines(const QLine *lines, int lineCount)
4607 {
4608 #ifdef QT_DEBUG_DRAW
4609     if (qt_show_painter_debug_output)
4610         printf("QPainter::drawLine(), line count=%d\n", lineCount);
4611 #endif
4612
4613     Q_D(QPainter);
4614
4615     if (!d->engine || lineCount < 1)
4616         return;
4617
4618     if (d->extended) {
4619         d->extended->drawLines(lines, lineCount);
4620         return;
4621     }
4622
4623     d->updateState(d->state);
4624
4625     uint lineEmulation = line_emulation(d->state->emulationSpecifier);
4626
4627     if (lineEmulation) {
4628         if (lineEmulation == QPaintEngine::PrimitiveTransform
4629             && d->state->matrix.type() == QTransform::TxTranslate) {
4630             for (int i = 0; i < lineCount; ++i) {
4631                 QLineF line = lines[i];
4632                 line.translate(d->state->matrix.dx(), d->state->matrix.dy());
4633                 d->engine->drawLines(&line, 1);
4634             }
4635         } else {
4636             QPainterPath linePath;
4637             for (int i = 0; i < lineCount; ++i) {
4638                 linePath.moveTo(lines[i].p1());
4639                 linePath.lineTo(lines[i].p2());
4640             }
4641             d->draw_helper(linePath, QPainterPrivate::StrokeDraw);
4642         }
4643         return;
4644     }
4645     d->engine->drawLines(lines, lineCount);
4646 }
4647
4648 /*!
4649     \overload
4650
4651     Draws the first \a lineCount lines in the array \a pointPairs
4652     using the current pen.  The lines are specified as pairs of points
4653     so the number of entries in \a pointPairs must be at least \a
4654     lineCount * 2.
4655 */
4656 void QPainter::drawLines(const QPointF *pointPairs, int lineCount)
4657 {
4658     Q_ASSERT(sizeof(QLineF) == 2*sizeof(QPointF));
4659
4660     drawLines((QLineF*)pointPairs, lineCount);
4661 }
4662
4663 /*!
4664     \overload
4665
4666     Draws the first \a lineCount lines in the array \a pointPairs
4667     using the current pen.
4668 */
4669 void QPainter::drawLines(const QPoint *pointPairs, int lineCount)
4670 {
4671     Q_ASSERT(sizeof(QLine) == 2*sizeof(QPoint));
4672
4673     drawLines((QLine*)pointPairs, lineCount);
4674 }
4675
4676
4677 /*!
4678     \fn void QPainter::drawLines(const QVector<QPointF> &pointPairs)
4679     \overload
4680
4681     Draws a line for each pair of points in the vector \a pointPairs
4682     using the current pen. If there is an odd number of points in the
4683     array, the last point will be ignored.
4684 */
4685
4686 /*!
4687     \fn void QPainter::drawLines(const QVector<QPoint> &pointPairs)
4688     \overload
4689
4690     Draws a line for each pair of points in the vector \a pointPairs
4691     using the current pen.
4692 */
4693
4694 /*!
4695     \fn void QPainter::drawLines(const QVector<QLineF> &lines)
4696     \overload
4697
4698     Draws the set of lines defined by the list \a lines using the
4699     current pen and brush.
4700 */
4701
4702 /*!
4703     \fn void QPainter::drawLines(const QVector<QLine> &lines)
4704     \overload
4705
4706     Draws the set of lines defined by the list \a lines using the
4707     current pen and brush.
4708 */
4709
4710 /*!
4711     Draws the polyline defined by the first \a pointCount points in \a
4712     points using the current pen.
4713
4714     Note that unlike the drawPolygon() function the last point is \e
4715     not connected to the first, neither is the polyline filled.
4716
4717     \table 100%
4718     \row
4719     \o
4720     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 13
4721     \endtable
4722
4723     \sa drawLines(), drawPolygon(), {Coordinate System}
4724 */
4725 void QPainter::drawPolyline(const QPointF *points, int pointCount)
4726 {
4727 #ifdef QT_DEBUG_DRAW
4728     if (qt_show_painter_debug_output)
4729         printf("QPainter::drawPolyline(), count=%d\n", pointCount);
4730 #endif
4731     Q_D(QPainter);
4732
4733     if (!d->engine || pointCount < 2)
4734         return;
4735
4736     if (d->extended) {
4737         d->extended->drawPolygon(points, pointCount, QPaintEngine::PolylineMode);
4738         return;
4739     }
4740
4741     d->updateState(d->state);
4742
4743     uint lineEmulation = line_emulation(d->state->emulationSpecifier);
4744
4745     if (lineEmulation) {
4746         // ###
4747 //         if (lineEmulation == QPaintEngine::PrimitiveTransform
4748 //             && d->state->matrix.type() == QTransform::TxTranslate) {
4749 //         } else {
4750         QPainterPath polylinePath(points[0]);
4751         for (int i=1; i<pointCount; ++i)
4752             polylinePath.lineTo(points[i]);
4753         d->draw_helper(polylinePath, QPainterPrivate::StrokeDraw);
4754 //         }
4755     } else {
4756         d->engine->drawPolygon(points, pointCount, QPaintEngine::PolylineMode);
4757     }
4758 }
4759
4760 /*!
4761     \overload
4762
4763     Draws the polyline defined by the first \a pointCount points in \a
4764     points using the current pen.
4765  */
4766 void QPainter::drawPolyline(const QPoint *points, int pointCount)
4767 {
4768 #ifdef QT_DEBUG_DRAW
4769     if (qt_show_painter_debug_output)
4770         printf("QPainter::drawPolyline(), count=%d\n", pointCount);
4771 #endif
4772     Q_D(QPainter);
4773
4774     if (!d->engine || pointCount < 2)
4775         return;
4776
4777     if (d->extended) {
4778         d->extended->drawPolygon(points, pointCount, QPaintEngine::PolylineMode);
4779         return;
4780     }
4781
4782     d->updateState(d->state);
4783
4784     uint lineEmulation = line_emulation(d->state->emulationSpecifier);
4785
4786     if (lineEmulation) {
4787         // ###
4788 //         if (lineEmulation == QPaintEngine::PrimitiveTransform
4789 //             && d->state->matrix.type() == QTransform::TxTranslate) {
4790 //         } else {
4791         QPainterPath polylinePath(points[0]);
4792         for (int i=1; i<pointCount; ++i)
4793             polylinePath.lineTo(points[i]);
4794         d->draw_helper(polylinePath, QPainterPrivate::StrokeDraw);
4795 //         }
4796     } else {
4797         d->engine->drawPolygon(points, pointCount, QPaintEngine::PolylineMode);
4798     }
4799 }
4800
4801 /*!
4802     \fn void QPainter::drawPolyline(const QPolygon &polygon, int index, int
4803     count)
4804
4805     \overload
4806     \compat
4807
4808     Draws the polyline defined by the \a count lines of the given \a
4809     polygon starting at \a index (\a index defaults to 0).
4810
4811     Use drawPolyline() combined with QPolygon::constData() instead.
4812
4813     \oldcode
4814         QPainter painter(this);
4815         painter.drawPolyline(polygon, index, count);
4816     \newcode
4817         int pointCount = (count == -1) ?  polygon.size() - index : count;
4818
4819         QPainter painter(this);
4820         painter.drawPolyline(polygon.constData() + index, pointCount);
4821     \endcode
4822 */
4823
4824 /*!
4825     \fn void QPainter::drawPolyline(const QPolygonF &points)
4826
4827     \overload
4828
4829     Draws the polyline defined by the given \a points using the
4830     current pen.
4831 */
4832
4833 /*!
4834     \fn void QPainter::drawPolyline(const QPolygon &points)
4835
4836     \overload
4837
4838     Draws the polyline defined by the given \a points using the
4839     current pen.
4840 */
4841
4842 /*!
4843     Draws the polygon defined by the first \a pointCount points in the
4844     array \a points using the current pen and brush.
4845
4846     \table 100%
4847     \row
4848     \o \inlineimage qpainter-polygon.png
4849     \o
4850     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 14
4851     \endtable
4852
4853     The first point is implicitly connected to the last point, and the
4854     polygon is filled with the current brush().
4855
4856     If \a fillRule is Qt::WindingFill, the polygon is filled using the
4857     winding fill algorithm.  If \a fillRule is Qt::OddEvenFill, the
4858     polygon is filled using the odd-even fill algorithm. See
4859     \l{Qt::FillRule} for a more detailed description of these fill
4860     rules.
4861
4862     \sa  drawConvexPolygon(), drawPolyline(), {Coordinate System}
4863 */
4864 void QPainter::drawPolygon(const QPointF *points, int pointCount, Qt::FillRule fillRule)
4865 {
4866 #ifdef QT_DEBUG_DRAW
4867     if (qt_show_painter_debug_output)
4868         printf("QPainter::drawPolygon(), count=%d\n", pointCount);
4869 #endif
4870
4871     Q_D(QPainter);
4872
4873     if (!d->engine || pointCount < 2)
4874         return;
4875
4876     if (d->extended) {
4877         d->extended->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
4878         return;
4879     }
4880
4881     d->updateState(d->state);
4882
4883     uint emulationSpecifier = d->state->emulationSpecifier;
4884
4885     if (emulationSpecifier) {
4886         QPainterPath polygonPath(points[0]);
4887         for (int i=1; i<pointCount; ++i)
4888             polygonPath.lineTo(points[i]);
4889         polygonPath.closeSubpath();
4890         polygonPath.setFillRule(fillRule);
4891         d->draw_helper(polygonPath);
4892         return;
4893     }
4894
4895     d->engine->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
4896 }
4897
4898 /*! \overload
4899
4900     Draws the polygon defined by the first \a pointCount points in the
4901     array \a points.
4902 */
4903 void QPainter::drawPolygon(const QPoint *points, int pointCount, Qt::FillRule fillRule)
4904 {
4905 #ifdef QT_DEBUG_DRAW
4906     if (qt_show_painter_debug_output)
4907         printf("QPainter::drawPolygon(), count=%d\n", pointCount);
4908 #endif
4909
4910     Q_D(QPainter);
4911
4912     if (!d->engine || pointCount < 2)
4913         return;
4914
4915     if (d->extended) {
4916         d->extended->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
4917         return;
4918     }
4919
4920     d->updateState(d->state);
4921
4922     uint emulationSpecifier = d->state->emulationSpecifier;
4923
4924     if (emulationSpecifier) {
4925         QPainterPath polygonPath(points[0]);
4926         for (int i=1; i<pointCount; ++i)
4927             polygonPath.lineTo(points[i]);
4928         polygonPath.closeSubpath();
4929         polygonPath.setFillRule(fillRule);
4930         d->draw_helper(polygonPath);
4931         return;
4932     }
4933
4934     d->engine->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
4935 }
4936
4937 /*! \fn void QPainter::drawPolygon(const QPolygonF &polygon, bool winding, int index = 0,
4938                                    int count = -1)
4939     \compat
4940     \overload
4941
4942     Use drawPolygon() combined with QPolygonF::constData() instead.
4943
4944     \oldcode
4945         QPainter painter(this);
4946         painter.drawPolygon(polygon, winding, index, count);
4947     \newcode
4948         int pointCount = (count == -1) ?  polygon.size() - index : count;
4949         int fillRule = winding ? Qt::WindingFill : Qt::OddEvenFill;
4950
4951         QPainter painter(this);
4952         painter.drawPolygon( polygon.constData() + index, pointCount, fillRule);
4953     \endcode
4954 */
4955
4956 /*! \fn void QPainter::drawPolygon(const QPolygon &polygon, bool winding,
4957                                    int index = 0, int count = -1)
4958
4959     \compat
4960     \overload
4961
4962     Use drawPolygon() combined with QPolygon::constData() instead.
4963
4964     \oldcode
4965         QPainter painter(this);
4966         painter.drawPolygon(polygon, winding, index, count);
4967     \newcode
4968         int pointCount = (count == -1) ?  polygon.size() - index : count;
4969         int fillRule = winding ? Qt::WindingFill : Qt::OddEvenFill;
4970
4971         QPainter painter(this);
4972         painter.drawPolygon( polygon.constData() + index, pointCount, fillRule);
4973     \endcode
4974 */
4975
4976 /*! \fn void QPainter::drawPolygon(const QPolygonF &points, Qt::FillRule fillRule)
4977
4978     \overload
4979
4980     Draws the polygon defined by the given \a points using the fill
4981     rule \a fillRule.
4982 */
4983
4984 /*! \fn void QPainter::drawPolygon(const QPolygon &points, Qt::FillRule fillRule)
4985
4986     \overload
4987
4988     Draws the polygon defined by the given \a points using the fill
4989     rule \a fillRule.
4990 */
4991
4992 /*!
4993     \fn void QPainter::drawConvexPolygon(const QPointF *points, int pointCount)
4994
4995     Draws the convex polygon defined by the first \a pointCount points
4996     in the array \a points using the current pen.
4997
4998     \table 100%
4999     \row
5000     \o \inlineimage qpainter-polygon.png
5001     \o
5002     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 15
5003     \endtable
5004
5005     The first point is implicitly connected to the last point, and the
5006     polygon is filled with the current brush().  If the supplied
5007     polygon is not convex, i.e. it contains at least one angle larger
5008     than 180 degrees, the results are undefined.
5009
5010     On some platforms (e.g. X11), the drawConvexPolygon() function can
5011     be faster than the drawPolygon() function.
5012
5013     \sa drawPolygon(), drawPolyline(), {Coordinate System}
5014 */
5015
5016 /*!
5017     \fn void QPainter::drawConvexPolygon(const QPoint *points, int pointCount)
5018     \overload
5019
5020     Draws the convex polygon defined by the first \a pointCount points
5021     in the array \a points using the current pen.
5022 */
5023
5024 /*!
5025     \fn void QPainter::drawConvexPolygon(const QPolygonF &polygon)
5026
5027     \overload
5028
5029     Draws the convex polygon defined by \a polygon using the current
5030     pen and brush.
5031 */
5032
5033 /*!
5034     \fn void QPainter::drawConvexPolygon(const QPolygon &polygon)
5035     \overload
5036
5037     Draws the convex polygon defined by \a polygon using the current
5038     pen and brush.
5039 */
5040
5041 /*!
5042     \fn void QPainter::drawConvexPolygon(const QPolygonF &polygon, int
5043     index, int count)
5044
5045     \compat
5046     \overload
5047
5048     Use drawConvexPolygon() combined with QPolygonF::constData()
5049     instead.
5050
5051     \oldcode
5052         QPainter painter(this);
5053         painter.drawConvexPolygon(polygon, index, count);
5054     \newcode
5055         int pointCount = (count == -1) ?  polygon.size() - index : count;
5056
5057         QPainter painter(this);
5058         painter.drawConvexPolygon(polygon.constData() + index, pointCount);
5059     \endcode
5060 */
5061
5062 /*!
5063     \fn void QPainter::drawConvexPolygon(const QPolygon &polygon, int
5064     index, int count)
5065
5066     \compat
5067     \overload
5068
5069     Use drawConvexPolygon() combined with QPolygon::constData()
5070     instead.
5071
5072     \oldcode
5073         QPainter painter(this);
5074         painter.drawConvexPolygon(polygon, index, count);
5075     \newcode
5076         int pointCount = (count == -1) ?  polygon.size() - index : count;
5077
5078         QPainter painter(this);
5079         painter.drawConvexPolygon(polygon.constData() + index, pointCount);
5080     \endcode
5081 */
5082
5083 void QPainter::drawConvexPolygon(const QPoint *points, int pointCount)
5084 {
5085 #ifdef QT_DEBUG_DRAW
5086     if (qt_show_painter_debug_output)
5087         printf("QPainter::drawConvexPolygon(), count=%d\n", pointCount);
5088 #endif
5089
5090     Q_D(QPainter);
5091
5092     if (!d->engine || pointCount < 2)
5093         return;
5094
5095     if (d->extended) {
5096         d->extended->drawPolygon(points, pointCount, QPaintEngine::ConvexMode);
5097         return;
5098     }
5099
5100     d->updateState(d->state);
5101
5102     uint emulationSpecifier = d->state->emulationSpecifier;
5103
5104     if (emulationSpecifier) {
5105         QPainterPath polygonPath(points[0]);
5106         for (int i=1; i<pointCount; ++i)
5107             polygonPath.lineTo(points[i]);
5108         polygonPath.closeSubpath();
5109         polygonPath.setFillRule(Qt::WindingFill);
5110         d->draw_helper(polygonPath);
5111         return;
5112     }
5113
5114     d->engine->drawPolygon(points, pointCount, QPaintEngine::ConvexMode);
5115 }
5116
5117 void QPainter::drawConvexPolygon(const QPointF *points, int pointCount)
5118 {
5119 #ifdef QT_DEBUG_DRAW
5120     if (qt_show_painter_debug_output)
5121         printf("QPainter::drawConvexPolygon(), count=%d\n", pointCount);
5122 #endif
5123
5124     Q_D(QPainter);
5125
5126     if (!d->engine || pointCount < 2)
5127         return;
5128
5129     if (d->extended) {
5130         d->extended->drawPolygon(points, pointCount, QPaintEngine::ConvexMode);
5131         return;
5132     }
5133
5134     d->updateState(d->state);
5135
5136     uint emulationSpecifier = d->state->emulationSpecifier;
5137
5138     if (emulationSpecifier) {
5139         QPainterPath polygonPath(points[0]);
5140         for (int i=1; i<pointCount; ++i)
5141             polygonPath.lineTo(points[i]);
5142         polygonPath.closeSubpath();
5143         polygonPath.setFillRule(Qt::WindingFill);
5144         d->draw_helper(polygonPath);
5145         return;
5146     }
5147
5148     d->engine->drawPolygon(points, pointCount, QPaintEngine::ConvexMode);
5149 }
5150
5151 static inline QPointF roundInDeviceCoordinates(const QPointF &p, const QTransform &m)
5152 {
5153     return m.inverted().map(QPointF(m.map(p).toPoint()));
5154 }
5155
5156 /*!
5157     \fn void QPainter::drawPixmap(const QRectF &target, const QPixmap &pixmap, const QRectF &source)
5158
5159     Draws the rectangular portion \a source of the given \a pixmap
5160     into the given \a target in the paint device.
5161
5162     \note The pixmap is scaled to fit the rectangle, if both the pixmap and rectangle size disagree.
5163
5164     \table 100%
5165     \row
5166     \o
5167     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 16
5168     \endtable
5169
5170     If \a pixmap is a QBitmap it is drawn with the bits that are "set"
5171     using the pens color. If backgroundMode is Qt::OpaqueMode, the
5172     "unset" bits are drawn using the color of the background brush; if
5173     backgroundMode is Qt::TransparentMode, the "unset" bits are
5174     transparent. Drawing bitmaps with gradient or texture colors is
5175     not supported.
5176
5177     \sa drawImage()
5178 */
5179 void QPainter::drawPixmap(const QPointF &p, const QPixmap &pm)
5180 {
5181 #if defined QT_DEBUG_DRAW
5182     if (qt_show_painter_debug_output)
5183         printf("QPainter::drawPixmap(), p=[%.2f,%.2f], pix=[%d,%d]\n",
5184                p.x(), p.y(),
5185                pm.width(), pm.height());
5186 #endif
5187
5188     Q_D(QPainter);
5189
5190     if (!d->engine || pm.isNull())
5191         return;
5192
5193 #ifndef QT_NO_DEBUG
5194     qt_painter_thread_test(d->device->devType(), "drawPixmap()", true);
5195 #endif
5196
5197     if (d->extended) {
5198         d->extended->drawPixmap(p, pm);
5199         return;
5200     }
5201
5202     qreal x = p.x();
5203     qreal y = p.y();
5204
5205     int w = pm.width();
5206     int h = pm.height();
5207
5208     if (w <= 0)
5209         return;
5210
5211     // Emulate opaque background for bitmaps
5212     if (d->state->bgMode == Qt::OpaqueMode && pm.isQBitmap()) {
5213         fillRect(QRectF(x, y, w, h), d->state->bgBrush.color());
5214     }
5215
5216     d->updateState(d->state);
5217
5218     if ((d->state->matrix.type() > QTransform::TxTranslate
5219          && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
5220         || (!d->state->matrix.isAffine() && !d->engine->hasFeature(QPaintEngine::PerspectiveTransform))
5221         || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity)))
5222     {
5223         save();
5224         // If there is no rotation involved we have to make sure we use the
5225         // antialiased and not the aliased coordinate system by rounding the coordinates.
5226         if (d->state->matrix.type() <= QTransform::TxScale) {
5227             const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
5228             x = p.x();
5229             y = p.y();
5230         }
5231         translate(x, y);
5232         setBackgroundMode(Qt::TransparentMode);
5233         setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
5234         QBrush brush(d->state->pen.color(), pm);
5235         setBrush(brush);
5236         setPen(Qt::NoPen);
5237         setBrushOrigin(QPointF(0, 0));
5238
5239         drawRect(pm.rect());
5240         restore();
5241     } else {
5242         if (!d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
5243             x += d->state->matrix.dx();
5244             y += d->state->matrix.dy();
5245         }
5246         d->engine->drawPixmap(QRectF(x, y, w, h), pm, QRectF(0, 0, w, h));
5247     }
5248 }
5249
5250 void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
5251 {
5252 #if defined QT_DEBUG_DRAW
5253     if (qt_show_painter_debug_output)
5254         printf("QPainter::drawPixmap(), target=[%.2f,%.2f,%.2f,%.2f], pix=[%d,%d], source=[%.2f,%.2f,%.2f,%.2f]\n",
5255                r.x(), r.y(), r.width(), r.height(),
5256                pm.width(), pm.height(),
5257                sr.x(), sr.y(), sr.width(), sr.height());
5258 #endif
5259
5260     Q_D(QPainter);
5261     if (!d->engine || pm.isNull())
5262         return;
5263 #ifndef QT_NO_DEBUG
5264     qt_painter_thread_test(d->device->devType(), "drawPixmap()", true);
5265 #endif
5266
5267     qreal x = r.x();
5268     qreal y = r.y();
5269     qreal w = r.width();
5270     qreal h = r.height();
5271     qreal sx = sr.x();
5272     qreal sy = sr.y();
5273     qreal sw = sr.width();
5274     qreal sh = sr.height();
5275
5276     // Sanity-check clipping
5277     if (sw <= 0)
5278         sw = pm.width() - sx;
5279
5280     if (sh <= 0)
5281         sh = pm.height() - sy;
5282
5283     if (w < 0)
5284         w = sw;
5285     if (h < 0)
5286         h = sh;
5287
5288     if (sx < 0) {
5289         qreal w_ratio = sx * w/sw;
5290         x -= w_ratio;
5291         w += w_ratio;
5292         sw += sx;
5293         sx = 0;
5294     }
5295
5296     if (sy < 0) {
5297         qreal h_ratio = sy * h/sh;
5298         y -= h_ratio;
5299         h += h_ratio;
5300         sh += sy;
5301         sy = 0;
5302     }
5303
5304     if (sw + sx > pm.width()) {
5305         qreal delta = sw - (pm.width() - sx);
5306         qreal w_ratio = delta * w/sw;
5307         sw -= delta;
5308         w -= w_ratio;
5309     }
5310
5311     if (sh + sy > pm.height()) {
5312         qreal delta = sh - (pm.height() - sy);
5313         qreal h_ratio = delta * h/sh;
5314         sh -= delta;
5315         h -= h_ratio;
5316     }
5317
5318     if (w == 0 || h == 0 || sw <= 0 || sh <= 0)
5319         return;
5320
5321     if (d->extended) {
5322         d->extended->drawPixmap(QRectF(x, y, w, h), pm, QRectF(sx, sy, sw, sh));
5323         return;
5324     }
5325
5326     // Emulate opaque background for bitmaps
5327     if (d->state->bgMode == Qt::OpaqueMode && pm.isQBitmap())
5328         fillRect(QRectF(x, y, w, h), d->state->bgBrush.color());
5329
5330     d->updateState(d->state);
5331
5332     if ((d->state->matrix.type() > QTransform::TxTranslate
5333          && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
5334         || (!d->state->matrix.isAffine() && !d->engine->hasFeature(QPaintEngine::PerspectiveTransform))
5335         || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity))
5336         || ((sw != w || sh != h) && !d->engine->hasFeature(QPaintEngine::PixmapTransform)))
5337     {
5338         save();
5339         // If there is no rotation involved we have to make sure we use the
5340         // antialiased and not the aliased coordinate system by rounding the coordinates.
5341         if (d->state->matrix.type() <= QTransform::TxScale) {
5342             const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
5343             x = p.x();
5344             y = p.y();
5345         }
5346
5347         if (d->state->matrix.type() <= QTransform::TxTranslate && sw == w && sh == h) {
5348             sx = qRound(sx);
5349             sy = qRound(sy);
5350             sw = qRound(sw);
5351             sh = qRound(sh);
5352         }
5353
5354         translate(x, y);
5355         scale(w / sw, h / sh);
5356         setBackgroundMode(Qt::TransparentMode);
5357         setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
5358         QBrush brush;
5359
5360         if (sw == pm.width() && sh == pm.height())
5361             brush = QBrush(d->state->pen.color(), pm);
5362         else
5363             brush = QBrush(d->state->pen.color(), pm.copy(sx, sy, sw, sh));
5364
5365         setBrush(brush);
5366         setPen(Qt::NoPen);
5367
5368         drawRect(QRectF(0, 0, sw, sh));
5369         restore();
5370     } else {
5371         if (!d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
5372             x += d->state->matrix.dx();
5373             y += d->state->matrix.dy();
5374         }
5375         d->engine->drawPixmap(QRectF(x, y, w, h), pm, QRectF(sx, sy, sw, sh));
5376     }
5377 }
5378
5379
5380 /*!
5381     \fn void QPainter::drawPixmap(const QRect &target, const QPixmap &pixmap,
5382                                   const QRect &source)
5383     \overload
5384
5385     Draws the rectangular portion \a source of the given \a pixmap
5386     into the given \a target in the paint device.
5387
5388     \note The pixmap is scaled to fit the rectangle, if both the pixmap and rectangle size disagree.
5389 */
5390
5391 /*!
5392     \fn void QPainter::drawPixmap(const QPointF &point, const QPixmap &pixmap,
5393                                   const QRectF &source)
5394     \overload
5395
5396     Draws the rectangular portion \a source of the given \a pixmap
5397     with its origin at the given \a point.
5398 */
5399
5400 /*!
5401     \fn void QPainter::drawPixmap(const QPoint &point, const QPixmap &pixmap,
5402                                   const QRect &source)
5403
5404     \overload
5405
5406     Draws the rectangular portion \a source of the given \a pixmap
5407     with its origin at the given \a point.
5408 */
5409
5410 /*!
5411     \fn void QPainter::drawPixmap(const QPointF &point, const QPixmap &pixmap)
5412     \overload
5413
5414     Draws the given \a pixmap with its origin at the given \a point.
5415 */
5416
5417 /*!
5418     \fn void QPainter::drawPixmap(const QPoint &point, const QPixmap &pixmap)
5419     \overload
5420
5421     Draws the given \a pixmap with its origin at the given \a point.
5422 */
5423
5424 /*!
5425     \fn void QPainter::drawPixmap(int x, int y, const QPixmap &pixmap)
5426
5427     \overload
5428
5429     Draws the given \a pixmap at position (\a{x}, \a{y}).
5430 */
5431
5432 /*!
5433     \fn void QPainter::drawPixmap(const QRect &rectangle, const QPixmap &pixmap)
5434     \overload
5435
5436     Draws the given \a  pixmap into the given \a rectangle.
5437
5438     \note The pixmap is scaled to fit the rectangle, if both the pixmap and rectangle size disagree.
5439 */
5440
5441 /*!
5442     \fn void QPainter::drawPixmap(int x, int y, int width, int height,
5443     const QPixmap &pixmap)
5444
5445     \overload
5446
5447     Draws the \a pixmap into the rectangle at position (\a{x}, \a{y})
5448     with  the given \a width and \a height.
5449 */
5450
5451 /*!
5452     \fn void QPainter::drawPixmap(int x, int y, int w, int h, const QPixmap &pixmap,
5453                                   int sx, int sy, int sw, int sh)
5454
5455     \overload
5456
5457     Draws the rectangular portion with the origin (\a{sx}, \a{sy}),
5458     width \a sw and height \a sh, of the given \a pixmap , at the
5459     point (\a{x}, \a{y}), with a width of \a w and a height of \a h.
5460     If sw or sh are equal to zero the width/height of the pixmap
5461     is used and adjusted by the offset sx/sy;
5462 */
5463
5464 /*!
5465     \fn void QPainter::drawPixmap(int x, int y, const QPixmap &pixmap,
5466                                   int sx, int sy, int sw, int sh)
5467
5468     \overload
5469
5470     Draws a pixmap at (\a{x}, \a{y}) by copying a part of the given \a
5471     pixmap into the paint device.
5472
5473     (\a{x}, \a{y}) specifies the top-left point in the paint device that is
5474     to be drawn onto. (\a{sx}, \a{sy}) specifies the top-left point in \a
5475     pixmap that is to be drawn. The default is (0, 0).
5476
5477     (\a{sw}, \a{sh}) specifies the size of the pixmap that is to be drawn.
5478     The default, (0, 0) (and negative) means all the way to the
5479     bottom-right of the pixmap.
5480 */
5481
5482 void QPainter::drawImage(const QPointF &p, const QImage &image)
5483 {
5484     Q_D(QPainter);
5485
5486     if (!d->engine || image.isNull())
5487         return;
5488
5489     if (d->extended) {
5490         d->extended->drawImage(p, image);
5491         return;
5492     }
5493
5494     qreal x = p.x();
5495     qreal y = p.y();
5496
5497     int w = image.width();
5498     int h = image.height();
5499
5500     d->updateState(d->state);
5501
5502     if (((d->state->matrix.type() > QTransform::TxTranslate)
5503          && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
5504         || (!d->state->matrix.isAffine() && !d->engine->hasFeature(QPaintEngine::PerspectiveTransform))
5505         || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity)))
5506     {
5507         save();
5508         // If there is no rotation involved we have to make sure we use the
5509         // antialiased and not the aliased coordinate system by rounding the coordinates.
5510         if (d->state->matrix.type() <= QTransform::TxScale) {
5511             const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
5512             x = p.x();
5513             y = p.y();
5514         }
5515         translate(x, y);
5516         setBackgroundMode(Qt::TransparentMode);
5517         setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
5518         QBrush brush(image);
5519         setBrush(brush);
5520         setPen(Qt::NoPen);
5521         setBrushOrigin(QPointF(0, 0));
5522
5523         drawRect(image.rect());
5524         restore();
5525         return;
5526     }
5527
5528     if (d->state->matrix.type() == QTransform::TxTranslate
5529         && !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
5530         x += d->state->matrix.dx();
5531         y += d->state->matrix.dy();
5532     }
5533
5534     d->engine->drawImage(QRectF(x, y, w, h), image, QRectF(0, 0, w, h), Qt::AutoColor);
5535 }
5536
5537 void QPainter::drawImage(const QRectF &targetRect, const QImage &image, const QRectF &sourceRect,
5538                          Qt::ImageConversionFlags flags)
5539 {
5540     Q_D(QPainter);
5541
5542     if (!d->engine || image.isNull())
5543         return;
5544
5545     qreal x = targetRect.x();
5546     qreal y = targetRect.y();
5547     qreal w = targetRect.width();
5548     qreal h = targetRect.height();
5549     qreal sx = sourceRect.x();
5550     qreal sy = sourceRect.y();
5551     qreal sw = sourceRect.width();
5552     qreal sh = sourceRect.height();
5553
5554     // Sanity-check clipping
5555     if (sw <= 0)
5556         sw = image.width() - sx;
5557
5558     if (sh <= 0)
5559         sh = image.height() - sy;
5560
5561     if (w < 0)
5562         w = sw;
5563     if (h < 0)
5564         h = sh;
5565
5566     if (sx < 0) {
5567         qreal w_ratio = sx * w/sw;
5568         x -= w_ratio;
5569         w += w_ratio;
5570         sw += sx;
5571         sx = 0;
5572     }
5573
5574     if (sy < 0) {
5575         qreal h_ratio = sy * h/sh;
5576         y -= h_ratio;
5577         h += h_ratio;
5578         sh += sy;
5579         sy = 0;
5580     }
5581
5582     if (sw + sx > image.width()) {
5583         qreal delta = sw - (image.width() - sx);
5584         qreal w_ratio = delta * w/sw;
5585         sw -= delta;
5586         w -= w_ratio;
5587     }
5588
5589     if (sh + sy > image.height()) {
5590         qreal delta = sh - (image.height() - sy);
5591         qreal h_ratio = delta * h/sh;
5592         sh -= delta;
5593         h -= h_ratio;
5594     }
5595
5596     if (w == 0 || h == 0 || sw <= 0 || sh <= 0)
5597         return;
5598
5599     if (d->extended) {
5600         d->extended->drawImage(QRectF(x, y, w, h), image, QRectF(sx, sy, sw, sh), flags);
5601         return;
5602     }
5603
5604     d->updateState(d->state);
5605
5606     if (((d->state->matrix.type() > QTransform::TxTranslate || (sw != w || sh != h))
5607          && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
5608         || (!d->state->matrix.isAffine() && !d->engine->hasFeature(QPaintEngine::PerspectiveTransform))
5609         || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity)))
5610     {
5611         save();
5612         // If there is no rotation involved we have to make sure we use the
5613         // antialiased and not the aliased coordinate system by rounding the coordinates.
5614         if (d->state->matrix.type() <= QTransform::TxScale) {
5615             const QPointF p = roundInDeviceCoordinates(QPointF(x, y), d->state->matrix);
5616             x = p.x();
5617             y = p.y();
5618         }
5619
5620         if (d->state->matrix.type() <= QTransform::TxTranslate && sw == w && sh == h) {
5621             sx = qRound(sx);
5622             sy = qRound(sy);
5623             sw = qRound(sw);
5624             sh = qRound(sh);
5625         }
5626         translate(x, y);
5627         scale(w / sw, h / sh);
5628         setBackgroundMode(Qt::TransparentMode);
5629         setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
5630         QBrush brush(image);
5631         setBrush(brush);
5632         setPen(Qt::NoPen);
5633         setBrushOrigin(QPointF(-sx, -sy));
5634
5635         drawRect(QRectF(0, 0, sw, sh));
5636         restore();
5637         return;
5638     }
5639
5640     if (d->state->matrix.type() == QTransform::TxTranslate
5641         && !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
5642         x += d->state->matrix.dx();
5643         y += d->state->matrix.dy();
5644     }
5645
5646     d->engine->drawImage(QRectF(x, y, w, h), image, QRectF(sx, sy, sw, sh), flags);
5647 }
5648
5649 /*!
5650     \fn void QPainter::drawGlyphRun(const QPointF &position, const QGlyphRun &glyphs)
5651
5652     Draws the glyphs represented by \a glyphs at \a position. The \a position gives the
5653     edge of the baseline for the string of glyphs. The glyphs will be retrieved from the font
5654     selected on \a glyphs and at offsets given by the positions in \a glyphs.
5655
5656     \since 4.8
5657
5658     \sa QGlyphRun::setRawFont(), QGlyphRun::setPositions(), QGlyphRun::setGlyphIndexes()
5659 */
5660 #if !defined(QT_NO_RAWFONT)
5661 void QPainter::drawGlyphRun(const QPointF &position, const QGlyphRun &glyphRun)
5662 {
5663     Q_D(QPainter);
5664
5665     QRawFont font = glyphRun.rawFont();
5666     if (!font.isValid())
5667         return;
5668
5669     QGlyphRunPrivate *glyphRun_d = QGlyphRunPrivate::get(glyphRun);
5670
5671     const quint32 *glyphIndexes = glyphRun_d->glyphIndexData;
5672     const QPointF *glyphPositions = glyphRun_d->glyphPositionData;
5673
5674     int count = qMin(glyphRun_d->glyphIndexDataSize, glyphRun_d->glyphPositionDataSize);
5675     QVarLengthArray<QFixedPoint, 128> fixedPointPositions(count);
5676
5677     QRawFontPrivate *fontD = QRawFontPrivate::get(font);
5678     bool supportsTransformations;
5679     if (d->extended != 0) {
5680         supportsTransformations = d->extended->supportsTransformations(fontD->fontEngine->fontDef.pixelSize,
5681                                                                        d->state->matrix);
5682     } else {
5683         supportsTransformations = d->engine->type() == QPaintEngine::CoreGraphics
5684                                   || d->state->matrix.isAffine();
5685     }
5686
5687     for (int i=0; i<count; ++i) {
5688         QPointF processedPosition = position + glyphPositions[i];
5689         if (!supportsTransformations)
5690             processedPosition = d->state->transform().map(processedPosition);
5691         fixedPointPositions[i] = QFixedPoint::fromPointF(processedPosition);
5692     }
5693
5694     d->drawGlyphs(glyphIndexes, fixedPointPositions.data(), count, font, glyphRun.overline(),
5695                   glyphRun.underline(), glyphRun.strikeOut());
5696 }
5697
5698 void QPainterPrivate::drawGlyphs(const quint32 *glyphArray, QFixedPoint *positions,
5699                                  int glyphCount,
5700                                  const QRawFont &font, bool overline, bool underline,
5701                                  bool strikeOut)
5702 {
5703     Q_Q(QPainter);
5704
5705     updateState(state);
5706
5707     QRawFontPrivate *fontD = QRawFontPrivate::get(font);
5708     QFontEngine *fontEngine = fontD->fontEngine;
5709
5710     QFixed leftMost;
5711     QFixed rightMost;
5712     QFixed baseLine;
5713     for (int i=0; i<glyphCount; ++i) {
5714         glyph_metrics_t gm = fontEngine->boundingBox(glyphArray[i]);
5715         if (i == 0 || leftMost > positions[i].x)
5716             leftMost = positions[i].x;
5717
5718         // We don't support glyphs that do not share a common baseline. If this turns out to
5719         // be a relevant use case, then we need to find clusters of glyphs that share a baseline
5720         // and do a drawTextItemDecorations call per cluster.
5721         if (i == 0 || baseLine < positions[i].y)
5722             baseLine = positions[i].y;
5723
5724         // We use the advance rather than the actual bounds to match the algorithm in drawText()
5725         if (i == 0 || rightMost < positions[i].x + gm.xoff)
5726             rightMost = positions[i].x + gm.xoff;
5727     }
5728
5729     QFixed width = rightMost - leftMost;
5730
5731     if (extended != 0 && state->matrix.isAffine()) {
5732         QStaticTextItem staticTextItem;
5733         staticTextItem.color = state->pen.color();
5734         staticTextItem.font = state->font;
5735         staticTextItem.setFontEngine(fontEngine);
5736         staticTextItem.numGlyphs = glyphCount;
5737         staticTextItem.glyphs = reinterpret_cast<glyph_t *>(const_cast<glyph_t *>(glyphArray));
5738         staticTextItem.glyphPositions = positions;
5739
5740         extended->drawStaticTextItem(&staticTextItem);
5741     } else {
5742         QTextItemInt textItem;
5743         textItem.fontEngine = fontEngine;
5744
5745         QVarLengthArray<QFixed, 128> advances(glyphCount);
5746         QVarLengthArray<QGlyphJustification, 128> glyphJustifications(glyphCount);
5747         QVarLengthArray<HB_GlyphAttributes, 128> glyphAttributes(glyphCount);
5748         qMemSet(glyphAttributes.data(), 0, glyphAttributes.size() * sizeof(HB_GlyphAttributes));
5749         qMemSet(advances.data(), 0, advances.size() * sizeof(QFixed));
5750         qMemSet(glyphJustifications.data(), 0, glyphJustifications.size() * sizeof(QGlyphJustification));
5751
5752         textItem.glyphs.numGlyphs = glyphCount;
5753         textItem.glyphs.glyphs = reinterpret_cast<HB_Glyph *>(const_cast<quint32 *>(glyphArray));
5754         textItem.glyphs.offsets = positions;
5755         textItem.glyphs.advances_x = advances.data();
5756         textItem.glyphs.advances_y = advances.data();
5757         textItem.glyphs.justifications = glyphJustifications.data();
5758         textItem.glyphs.attributes = glyphAttributes.data();
5759
5760         engine->drawTextItem(QPointF(0, 0), textItem);
5761     }
5762
5763     QTextItemInt::RenderFlags flags;
5764     if (underline)
5765         flags |= QTextItemInt::Underline;
5766     if (overline)
5767         flags |= QTextItemInt::Overline;
5768     if (strikeOut)
5769         flags |= QTextItemInt::StrikeOut;
5770
5771     drawTextItemDecoration(q, QPointF(leftMost.toReal(), baseLine.toReal()),
5772                            fontEngine,
5773                            (underline
5774                               ? QTextCharFormat::SingleUnderline
5775                               : QTextCharFormat::NoUnderline),
5776                            flags, width.toReal(), QTextCharFormat());
5777 }
5778 #endif // QT_NO_RAWFONT
5779
5780 /*!
5781
5782     \fn void QPainter::drawStaticText(const QPoint &topLeftPosition, const QStaticText &staticText)
5783     \since 4.7
5784     \overload
5785
5786     Draws the \a staticText at the \a topLeftPosition.
5787
5788     \note The y-position is used as the top of the font.
5789
5790 */
5791
5792 /*!
5793     \fn void QPainter::drawStaticText(int left, int top, const QStaticText &staticText)
5794     \since 4.7
5795     \overload
5796
5797     Draws the \a staticText at coordinates \a left and \a top.
5798
5799     \note The y-position is used as the top of the font.
5800 */
5801
5802 /*!
5803     \fn void QPainter::drawText(const QPointF &position, const QString &text)
5804
5805     Draws the given \a text with the currently defined text direction,
5806     beginning at the given \a position.
5807
5808     This function does not handle the newline character (\n), as it cannot
5809     break text into multiple lines, and it cannot display the newline character.
5810     Use the QPainter::drawText() overload that takes a rectangle instead
5811     if you want to draw multiple lines of text with the newline character, or
5812     if you want the text to be wrapped.
5813
5814     By default, QPainter draws text anti-aliased.
5815
5816     \note The y-position is used as the baseline of the font.
5817 */
5818
5819 void QPainter::drawText(const QPointF &p, const QString &str)
5820 {
5821     drawText(p, str, 0, 0);
5822 }
5823
5824 /*!
5825     \since 4.7
5826
5827     Draws the given \a staticText at the given \a topLeftPosition.
5828
5829     The text will be drawn using the font and the transformation set on the painter. If the
5830     font and/or transformation set on the painter are different from the ones used to initialize
5831     the layout of the QStaticText, then the layout will have to be recalculated. Use
5832     QStaticText::prepare() to initialize \a staticText with the font and transformation with which
5833     it will later be drawn.
5834
5835     If \a topLeftPosition is not the same as when \a staticText was initialized, or when it was
5836     last drawn, then there will be a slight overhead when translating the text to its new position.
5837
5838     \note If the painter's transformation is not affine, then \a staticText will be drawn using
5839     regular calls to drawText(), losing any potential for performance improvement.
5840
5841     \note The y-position is used as the top of the font.
5842
5843     \sa QStaticText
5844 */
5845 void QPainter::drawStaticText(const QPointF &topLeftPosition, const QStaticText &staticText)
5846 {
5847     Q_D(QPainter);
5848     if (!d->engine || staticText.text().isEmpty() || pen().style() == Qt::NoPen)
5849         return;
5850
5851     QStaticTextPrivate *staticText_d =
5852             const_cast<QStaticTextPrivate *>(QStaticTextPrivate::get(&staticText));
5853
5854     if (font() != staticText_d->font) {
5855         staticText_d->font = font();
5856         staticText_d->needsRelayout = true;
5857     }
5858
5859     // If we don't have an extended paint engine, or if the painter is projected,
5860     // we go through standard code path
5861     if (d->extended == 0 || !d->state->matrix.isAffine()) {
5862         staticText_d->paintText(topLeftPosition, this);
5863         return;
5864     }
5865
5866     bool supportsTransformations = d->extended->supportsTransformations(staticText_d->font.pixelSize(),
5867                                                                         d->state->matrix);
5868     if (supportsTransformations && !staticText_d->untransformedCoordinates) {
5869         staticText_d->untransformedCoordinates = true;
5870         staticText_d->needsRelayout = true;
5871     } else if (!supportsTransformations && staticText_d->untransformedCoordinates) {
5872         staticText_d->untransformedCoordinates = false;
5873         staticText_d->needsRelayout = true;
5874     }
5875
5876     // Don't recalculate entire layout because of translation, rather add the dx and dy
5877     // into the position to move each text item the correct distance.
5878     QPointF transformedPosition = topLeftPosition;
5879     if (!staticText_d->untransformedCoordinates)
5880         transformedPosition = transformedPosition * d->state->matrix;
5881     QTransform oldMatrix;
5882
5883     // The translation has been applied to transformedPosition. Remove translation
5884     // component from matrix.
5885     if (d->state->matrix.isTranslating() && !staticText_d->untransformedCoordinates) {
5886         qreal m11 = d->state->matrix.m11();
5887         qreal m12 = d->state->matrix.m12();
5888         qreal m13 = d->state->matrix.m13();
5889         qreal m21 = d->state->matrix.m21();
5890         qreal m22 = d->state->matrix.m22();
5891         qreal m23 = d->state->matrix.m23();
5892         qreal m33 = d->state->matrix.m33();
5893
5894         oldMatrix = d->state->matrix;
5895         d->state->matrix.setMatrix(m11, m12, m13,
5896                                    m21, m22, m23,
5897                                    0.0, 0.0, m33);
5898     }
5899
5900     // If the transform is not identical to the text transform,
5901     // we have to relayout the text (for other transformations than plain translation)
5902     bool staticTextNeedsReinit = staticText_d->needsRelayout;
5903     if (!staticText_d->untransformedCoordinates && staticText_d->matrix != d->state->matrix) {
5904         staticText_d->matrix = d->state->matrix;
5905         staticTextNeedsReinit = true;
5906     }
5907
5908     // Recreate the layout of the static text because the matrix or font has changed
5909     if (staticTextNeedsReinit)
5910         staticText_d->init();
5911
5912     if (transformedPosition != staticText_d->position) { // Translate to actual position
5913         QFixed fx = QFixed::fromReal(transformedPosition.x());
5914         QFixed fy = QFixed::fromReal(transformedPosition.y());
5915         QFixed oldX = QFixed::fromReal(staticText_d->position.x());
5916         QFixed oldY = QFixed::fromReal(staticText_d->position.y());
5917         for (int item=0; item<staticText_d->itemCount;++item) {
5918             QStaticTextItem *textItem = staticText_d->items + item;
5919             for (int i=0; i<textItem->numGlyphs; ++i) {
5920                 textItem->glyphPositions[i].x += fx - oldX;
5921                 textItem->glyphPositions[i].y += fy - oldY;
5922             }
5923             textItem->userDataNeedsUpdate = true;
5924         }
5925
5926         staticText_d->position = transformedPosition;
5927     }
5928
5929     QPen oldPen = d->state->pen;
5930     QColor currentColor = oldPen.color();
5931     for (int i=0; i<staticText_d->itemCount; ++i) {
5932         QStaticTextItem *item = staticText_d->items + i;
5933         if (item->color.isValid() && currentColor != item->color) {
5934             setPen(item->color);
5935             currentColor = item->color;
5936         }
5937         d->extended->drawStaticTextItem(item);
5938
5939         qt_draw_decoration_for_glyphs(this, item->glyphs, item->glyphPositions,
5940                                       item->numGlyphs, item->fontEngine(), staticText_d->font,
5941                                       QTextCharFormat());
5942     }
5943     if (currentColor != oldPen.color())
5944         setPen(oldPen);
5945
5946     if (!staticText_d->untransformedCoordinates && oldMatrix.isTranslating())
5947         d->state->matrix = oldMatrix;
5948 }
5949
5950 /*!
5951    \internal
5952 */
5953 void QPainter::drawText(const QPointF &p, const QString &str, int tf, int justificationPadding)
5954 {
5955 #ifdef QT_DEBUG_DRAW
5956     if (qt_show_painter_debug_output)
5957         printf("QPainter::drawText(), pos=[%.2f,%.2f], str='%s'\n", p.x(), p.y(), str.toLatin1().constData());
5958 #endif
5959
5960     Q_D(QPainter);
5961
5962     if (!d->engine || str.isEmpty() || pen().style() == Qt::NoPen)
5963         return;
5964
5965     if (tf & Qt::TextBypassShaping) {
5966         // Skip harfbuzz complex shaping, shape using glyph advances only
5967         int len = str.length();
5968         int numGlyphs = len;
5969         QVarLengthGlyphLayoutArray glyphs(len);
5970         QFontEngine *fontEngine = d->state->font.d->engineForScript(QUnicodeTables::Common);
5971         if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0)) {
5972             glyphs.resize(numGlyphs);
5973             if (!fontEngine->stringToCMap(str.data(), len, &glyphs, &numGlyphs, 0))
5974                 Q_ASSERT_X(false, Q_FUNC_INFO, "stringToCMap shouldn't fail twice");
5975         }
5976
5977         QTextItemInt gf(glyphs, &d->state->font, str.data(), len, fontEngine);
5978         drawTextItem(p, gf);
5979         return;
5980     }
5981
5982     QStackTextEngine engine(str, d->state->font);
5983     engine.option.setTextDirection(d->state->layoutDirection);
5984     if (tf & (Qt::TextForceLeftToRight|Qt::TextForceRightToLeft)) {
5985         engine.ignoreBidi = true;
5986         engine.option.setTextDirection((tf & Qt::TextForceLeftToRight) ? Qt::LeftToRight : Qt::RightToLeft);
5987     }
5988     engine.itemize();
5989     QScriptLine line;
5990     line.length = str.length();
5991     engine.shapeLine(line);
5992
5993     int nItems = engine.layoutData->items.size();
5994     QVarLengthArray<int> visualOrder(nItems);
5995     QVarLengthArray<uchar> levels(nItems);
5996     for (int i = 0; i < nItems; ++i)
5997         levels[i] = engine.layoutData->items[i].analysis.bidiLevel;
5998     QTextEngine::bidiReorder(nItems, levels.data(), visualOrder.data());
5999
6000     if (justificationPadding > 0) {
6001         engine.option.setAlignment(Qt::AlignJustify);
6002         engine.forceJustification = true;
6003         // this works because justify() is only interested in the difference between width and textWidth
6004         line.width = justificationPadding;
6005         engine.justify(line);
6006     }
6007     QFixed x = QFixed::fromReal(p.x());
6008
6009     for (int i = 0; i < nItems; ++i) {
6010         int item = visualOrder[i];
6011         const QScriptItem &si = engine.layoutData->items.at(item);
6012         if (si.analysis.flags >= QScriptAnalysis::TabOrObject) {
6013             x += si.width;
6014             continue;
6015         }
6016         QFont f = engine.font(si);
6017         QTextItemInt gf(si, &f);
6018         gf.glyphs = engine.shapedGlyphs(&si);
6019         gf.chars = engine.layoutData->string.unicode() + si.position;
6020         gf.num_chars = engine.length(item);
6021         if (engine.forceJustification) {
6022             for (int j=0; j<gf.glyphs.numGlyphs; ++j)
6023                 gf.width += gf.glyphs.effectiveAdvance(j);
6024         } else {
6025             gf.width = si.width;
6026         }
6027         gf.logClusters = engine.logClusters(&si);
6028
6029         drawTextItem(QPointF(x.toReal(), p.y()), gf);
6030
6031         x += gf.width;
6032     }
6033 }
6034
6035 void QPainter::drawText(const QRect &r, int flags, const QString &str, QRect *br)
6036 {
6037 #ifdef QT_DEBUG_DRAW
6038     if (qt_show_painter_debug_output)
6039         printf("QPainter::drawText(), r=[%d,%d,%d,%d], flags=%d, str='%s'\n",
6040            r.x(), r.y(), r.width(), r.height(), flags, str.toLatin1().constData());
6041 #endif
6042
6043     Q_D(QPainter);
6044
6045     if (!d->engine || str.length() == 0 || pen().style() == Qt::NoPen)
6046         return;
6047
6048     if (!d->extended)
6049         d->updateState(d->state);
6050
6051     QRectF bounds;
6052     qt_format_text(d->state->font, r, flags, 0, str, br ? &bounds : 0, 0, 0, 0, this);
6053     if (br)
6054         *br = bounds.toAlignedRect();
6055 }
6056
6057 /*!
6058     \fn void QPainter::drawText(const QPoint &position, const QString &text)
6059
6060     \overload
6061
6062     Draws the given \a text with the currently defined text direction,
6063     beginning at the given \a position.
6064
6065     By default, QPainter draws text anti-aliased.
6066
6067     \note The y-position is used as the baseline of the font.
6068
6069 */
6070
6071 /*!
6072     \fn void QPainter::drawText(const QRectF &rectangle, int flags, const QString &text, QRectF *boundingRect)
6073     \overload
6074
6075     Draws the given \a text within the provided \a rectangle.
6076
6077     \table 100%
6078     \row
6079     \o \inlineimage qpainter-text.png
6080     \o
6081     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 17
6082     \endtable
6083
6084     The \a boundingRect (if not null) is set to the what the bounding rectangle
6085     should be in order to enclose the whole text. The \a flags argument is a bitwise
6086     OR of the following flags:
6087
6088     \list
6089     \o Qt::AlignLeft
6090     \o Qt::AlignRight
6091     \o Qt::AlignHCenter
6092     \o Qt::AlignJustify
6093     \o Qt::AlignTop
6094     \o Qt::AlignBottom
6095     \o Qt::AlignVCenter
6096     \o Qt::AlignCenter
6097     \o Qt::TextDontClip
6098     \o Qt::TextSingleLine
6099     \o Qt::TextExpandTabs
6100     \o Qt::TextShowMnemonic
6101     \o Qt::TextWordWrap
6102     \o Qt::TextIncludeTrailingSpaces
6103     \endlist
6104
6105     \sa Qt::AlignmentFlag, Qt::TextFlag, boundingRect(), layoutDirection()
6106
6107     By default, QPainter draws text anti-aliased.
6108
6109     \note The y-coordinate of \a rectangle is used as the top of the font.
6110 */
6111 void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF *br)
6112 {
6113 #ifdef QT_DEBUG_DRAW
6114     if (qt_show_painter_debug_output)
6115         printf("QPainter::drawText(), r=[%.2f,%.2f,%.2f,%.2f], flags=%d, str='%s'\n",
6116            r.x(), r.y(), r.width(), r.height(), flags, str.toLatin1().constData());
6117 #endif
6118
6119     Q_D(QPainter);
6120
6121     if (!d->engine || str.length() == 0 || pen().style() == Qt::NoPen)
6122         return;
6123
6124     if (!d->extended)
6125         d->updateState(d->state);
6126
6127     qt_format_text(d->state->font, r, flags, 0, str, br, 0, 0, 0, this);
6128 }
6129
6130 /*!
6131     \fn void QPainter::drawText(const QRect &rectangle, int flags, const QString &text, QRect *boundingRect)
6132     \overload
6133
6134     Draws the given \a text within the provided \a rectangle according
6135     to the specified \a flags. The \a boundingRect (if not null) is set to
6136     the what the bounding rectangle should be in order to enclose the whole text.
6137
6138     By default, QPainter draws text anti-aliased.
6139
6140     \note The y-coordinate of \a rectangle is used as the top of the font.
6141 */
6142
6143 /*!
6144     \fn void QPainter::drawText(int x, int y, const QString &text)
6145
6146     \overload
6147
6148     Draws the given \a text at position (\a{x}, \a{y}), using the painter's
6149     currently defined text direction.
6150
6151     By default, QPainter draws text anti-aliased.
6152
6153     \note The y-position is used as the baseline of the font.
6154
6155 */
6156
6157 /*!
6158     \fn void QPainter::drawText(int x, int y, int width, int height, int flags,
6159                                 const QString &text, QRect *boundingRect)
6160
6161     \overload
6162
6163     Draws the given \a text within the rectangle with origin (\a{x},
6164     \a{y}), \a width and \a height.
6165
6166     The \a boundingRect (if not null) is set to the actual bounding
6167     rectangle of the output.  The \a flags argument is a bitwise OR of
6168     the following flags:
6169
6170     \list
6171     \o Qt::AlignLeft
6172     \o Qt::AlignRight
6173     \o Qt::AlignHCenter
6174     \o Qt::AlignJustify
6175     \o Qt::AlignTop
6176     \o Qt::AlignBottom
6177     \o Qt::AlignVCenter
6178     \o Qt::AlignCenter
6179     \o Qt::TextSingleLine
6180     \o Qt::TextExpandTabs
6181     \o Qt::TextShowMnemonic
6182     \o Qt::TextWordWrap
6183     \endlist
6184
6185     By default, QPainter draws text anti-aliased.
6186
6187     \note The y-position is used as the top of the font.
6188
6189     \sa Qt::AlignmentFlag, Qt::TextFlag
6190 */
6191
6192 /*!
6193     \fn void QPainter::drawText(const QRectF &rectangle, const QString &text,
6194         const QTextOption &option)
6195     \overload
6196
6197     Draws the given \a text in the \a rectangle specified using the \a option
6198     to control its positioning and orientation.
6199
6200     By default, QPainter draws text anti-aliased.
6201
6202     \note The y-coordinate of \a rectangle is used as the top of the font.
6203 */
6204 void QPainter::drawText(const QRectF &r, const QString &text, const QTextOption &o)
6205 {
6206 #ifdef QT_DEBUG_DRAW
6207     if (qt_show_painter_debug_output)
6208         printf("QPainter::drawText(), r=[%.2f,%.2f,%.2f,%.2f], str='%s'\n",
6209            r.x(), r.y(), r.width(), r.height(), text.toLatin1().constData());
6210 #endif
6211
6212     Q_D(QPainter);
6213
6214     if (!d->engine || text.length() == 0 || pen().style() == Qt::NoPen)
6215         return;
6216
6217     if (!d->extended)
6218         d->updateState(d->state);
6219
6220     qt_format_text(d->state->font, r, 0, &o, text, 0, 0, 0, 0, this);
6221 }
6222
6223 /*!
6224     \fn void QPainter::drawTextItem(int x, int y, const QTextItem &ti)
6225
6226     \internal
6227     \overload
6228 */
6229
6230 /*!
6231     \fn void QPainter::drawTextItem(const QPoint &p, const QTextItem &ti)
6232
6233     \internal
6234     \overload
6235
6236     Draws the text item \a ti at position \a p.
6237 */
6238
6239 /*!
6240     \fn void QPainter::drawTextItem(const QPointF &p, const QTextItem &ti)
6241
6242     \internal
6243     \since 4.1
6244
6245     Draws the text item \a ti at position \a p.
6246
6247     This method ignores the painters background mode and
6248     color. drawText and qt_format_text have to do it themselves, as
6249     only they know the extents of the complete string.
6250
6251     It ignores the font set on the painter as the text item has one of its own.
6252
6253     The underline and strikeout parameters of the text items font are
6254     ignored aswell. You'll need to pass in the correct flags to get
6255     underlining and strikeout.
6256 */
6257
6258 static QPixmap generateWavyPixmap(qreal maxRadius, const QPen &pen)
6259 {
6260     const qreal radiusBase = qMax(qreal(1), maxRadius);
6261
6262     QString key = QLatin1Literal("WaveUnderline-")
6263                   % pen.color().name()
6264                   % HexString<qreal>(radiusBase);
6265
6266     QPixmap pixmap;
6267     if (QPixmapCache::find(key, pixmap))
6268         return pixmap;
6269
6270     const qreal halfPeriod = qMax(qreal(2), qreal(radiusBase * 1.61803399)); // the golden ratio
6271     const int width = qCeil(100 / (2 * halfPeriod)) * (2 * halfPeriod);
6272     const int radius = qFloor(radiusBase);
6273
6274     QPainterPath path;
6275
6276     qreal xs = 0;
6277     qreal ys = radius;
6278
6279     while (xs < width) {
6280         xs += halfPeriod;
6281         ys = -ys;
6282         path.quadTo(xs - halfPeriod / 2, ys, xs, 0);
6283     }
6284
6285     pixmap = QPixmap(width, radius * 2);
6286     pixmap.fill(Qt::transparent);
6287     {
6288         QPen wavePen = pen;
6289         wavePen.setCapStyle(Qt::SquareCap);
6290
6291         // This is to protect against making the line too fat, as happens on Mac OS X
6292         // due to it having a rather thick width for the regular underline.
6293         const qreal maxPenWidth = .8 * radius;
6294         if (wavePen.widthF() > maxPenWidth)
6295             wavePen.setWidth(maxPenWidth);
6296
6297         QPainter imgPainter(&pixmap);
6298         imgPainter.setPen(wavePen);
6299         imgPainter.setRenderHint(QPainter::Antialiasing);
6300         imgPainter.translate(0, radius);
6301         imgPainter.drawPath(path);
6302     }
6303
6304     QPixmapCache::insert(key, pixmap);
6305
6306     return pixmap;
6307 }
6308
6309 static void drawTextItemDecoration(QPainter *painter, const QPointF &pos, const QFontEngine *fe,
6310                                    QTextCharFormat::UnderlineStyle underlineStyle,
6311                                    QTextItem::RenderFlags flags, qreal width,
6312                                    const QTextCharFormat &charFormat)
6313 {
6314     if (underlineStyle == QTextCharFormat::NoUnderline
6315         && !(flags & (QTextItem::StrikeOut | QTextItem::Overline)))
6316         return;
6317
6318     const QPen oldPen = painter->pen();
6319     const QBrush oldBrush = painter->brush();
6320     painter->setBrush(Qt::NoBrush);
6321     QPen pen = oldPen;
6322     pen.setStyle(Qt::SolidLine);
6323     pen.setWidthF(fe->lineThickness().toReal());
6324     pen.setCapStyle(Qt::FlatCap);
6325
6326     QLineF line(pos.x(), pos.y(), pos.x() + qFloor(width), pos.y());
6327
6328     const qreal underlineOffset = fe->underlinePosition().toReal();
6329     // deliberately ceil the offset to avoid the underline coming too close to
6330     // the text above it.
6331     const qreal aliasedCoordinateDelta = 0.5 - 0.015625;
6332     const qreal underlinePos = pos.y() + qCeil(underlineOffset) - aliasedCoordinateDelta;
6333
6334     if (underlineStyle == QTextCharFormat::SpellCheckUnderline) {
6335         underlineStyle = QTextCharFormat::SpellCheckUnderline; // ### Qt5 QTextCharFormat::UnderlineStyle(QApplication::style()->styleHint(QStyle::SH_SpellCheckUnderlineStyle));
6336     }
6337
6338     if (underlineStyle == QTextCharFormat::WaveUnderline) {
6339         painter->save();
6340         painter->translate(0, pos.y() + 1);
6341
6342         QColor uc = charFormat.underlineColor();
6343         if (uc.isValid())
6344             pen.setColor(uc);
6345
6346         // Adapt wave to underlineOffset or pen width, whatever is larger, to make it work on all platforms
6347         const QPixmap wave = generateWavyPixmap(qMax(underlineOffset, pen.widthF()), pen);
6348         const int descent = (int) fe->descent().toReal();
6349
6350         painter->setBrushOrigin(painter->brushOrigin().x(), 0);
6351         painter->fillRect(pos.x(), 0, qCeil(width), qMin(wave.height(), descent), wave);
6352         painter->restore();
6353     } else if (underlineStyle != QTextCharFormat::NoUnderline) {
6354         QLineF underLine(line.x1(), underlinePos, line.x2(), underlinePos);
6355
6356         QColor uc = charFormat.underlineColor();
6357         if (uc.isValid())
6358             pen.setColor(uc);
6359
6360         pen.setStyle((Qt::PenStyle)(underlineStyle));
6361         painter->setPen(pen);
6362         painter->drawLine(underLine);
6363     }
6364
6365     pen.setStyle(Qt::SolidLine);
6366     pen.setColor(oldPen.color());
6367
6368     if (flags & QTextItem::StrikeOut) {
6369         QLineF strikeOutLine = line;
6370         strikeOutLine.translate(0., - fe->ascent().toReal() / 3.);
6371         painter->setPen(pen);
6372         painter->drawLine(strikeOutLine);
6373     }
6374
6375     if (flags & QTextItem::Overline) {
6376         QLineF overLine = line;
6377         overLine.translate(0., - fe->ascent().toReal());
6378         painter->setPen(pen);
6379         painter->drawLine(overLine);
6380     }
6381
6382     painter->setPen(oldPen);
6383     painter->setBrush(oldBrush);
6384 }
6385
6386 Q_GUI_EXPORT void qt_draw_decoration_for_glyphs(QPainter *painter, const glyph_t *glyphArray,
6387                                                 const QFixedPoint *positions, int glyphCount,
6388                                                 QFontEngine *fontEngine, const QFont &font,
6389                                                 const QTextCharFormat &charFormat)
6390 {
6391     if (!(font.underline() || font.strikeOut() || font.overline()))
6392         return;
6393
6394     QFixed leftMost;
6395     QFixed rightMost;
6396     QFixed baseLine;
6397     for (int i=0; i<glyphCount; ++i) {
6398         glyph_metrics_t gm = fontEngine->boundingBox(glyphArray[i]);
6399         if (i == 0 || leftMost > positions[i].x)
6400             leftMost = positions[i].x;
6401
6402         // We don't support glyphs that do not share a common baseline. If this turns out to
6403         // be a relevant use case, then we need to find clusters of glyphs that share a baseline
6404         // and do a drawTextItemDecorations call per cluster.
6405         if (i == 0 || baseLine < positions[i].y)
6406             baseLine = positions[i].y;
6407
6408         // We use the advance rather than the actual bounds to match the algorithm in drawText()
6409         if (i == 0 || rightMost < positions[i].x + gm.xoff)
6410             rightMost = positions[i].x + gm.xoff;
6411     }
6412
6413     QFixed width = rightMost - leftMost;
6414     QTextItem::RenderFlags flags = 0;
6415
6416     if (font.underline())
6417         flags |= QTextItem::Underline;
6418     if (font.overline())
6419         flags |= QTextItem::Overline;
6420     if (font.strikeOut())
6421         flags |= QTextItem::StrikeOut;
6422
6423     drawTextItemDecoration(painter, QPointF(leftMost.toReal(), baseLine.toReal()),
6424                            fontEngine,
6425                            font.underline() ? QTextCharFormat::SingleUnderline
6426                                             : QTextCharFormat::NoUnderline, flags,
6427                            width.toReal(), charFormat);
6428 }
6429
6430 void QPainter::drawTextItem(const QPointF &p, const QTextItem &_ti)
6431 {
6432 #ifdef QT_DEBUG_DRAW
6433     if (qt_show_painter_debug_output)
6434         printf("QPainter::drawTextItem(), pos=[%.f,%.f], str='%s'\n",
6435                p.x(), p.y(), qPrintable(_ti.text()));
6436 #endif
6437
6438     Q_D(QPainter);
6439
6440     if (!d->engine)
6441         return;
6442
6443 #ifndef QT_NO_DEBUG
6444     qt_painter_thread_test(d->device->devType(),
6445                            "text and fonts",
6446                            QFontDatabase::supportsThreadedFontRendering());
6447 #endif
6448
6449     QTextItemInt &ti = const_cast<QTextItemInt &>(static_cast<const QTextItemInt &>(_ti));
6450
6451     if (!d->extended && d->state->bgMode == Qt::OpaqueMode) {
6452         QRectF rect(p.x(), p.y() - ti.ascent.toReal(), ti.width.toReal(), (ti.ascent + ti.descent + 1).toReal());
6453         fillRect(rect, d->state->bgBrush);
6454     }
6455
6456     if (pen().style() == Qt::NoPen)
6457         return;
6458
6459     const RenderHints oldRenderHints = d->state->renderHints;
6460     if (!d->state->renderHints & QPainter::Antialiasing && d->state->matrix.type() >= QTransform::TxScale) {
6461         // draw antialias decoration (underline/overline/strikeout) with
6462         // transformed text
6463
6464         bool aa = true;
6465         const QTransform &m = d->state->matrix;
6466         if (d->state->matrix.type() < QTransform::TxShear) {
6467             bool isPlain90DegreeRotation =
6468                 (qFuzzyIsNull(m.m11())
6469                  && qFuzzyIsNull(m.m12() - qreal(1))
6470                  && qFuzzyIsNull(m.m21() + qreal(1))
6471                  && qFuzzyIsNull(m.m22())
6472                     )
6473                 ||
6474                 (qFuzzyIsNull(m.m11() + qreal(1))
6475                  && qFuzzyIsNull(m.m12())
6476                  && qFuzzyIsNull(m.m21())
6477                  && qFuzzyIsNull(m.m22() + qreal(1))
6478                     )
6479                 ||
6480                 (qFuzzyIsNull(m.m11())
6481                  && qFuzzyIsNull(m.m12() + qreal(1))
6482                  && qFuzzyIsNull(m.m21() - qreal(1))
6483                  && qFuzzyIsNull(m.m22())
6484                     )
6485                 ;
6486             aa = !isPlain90DegreeRotation;
6487         }
6488         if (aa)
6489             setRenderHint(QPainter::Antialiasing, true);
6490     }
6491
6492     if (!d->extended)
6493         d->updateState(d->state);
6494
6495     if (!ti.glyphs.numGlyphs) {
6496         // nothing to do
6497     } else if (ti.fontEngine->type() == QFontEngine::Multi) {
6498         QFontEngineMulti *multi = static_cast<QFontEngineMulti *>(ti.fontEngine);
6499
6500         const QGlyphLayout &glyphs = ti.glyphs;
6501         int which = glyphs.glyphs[0] >> 24;
6502
6503         qreal x = p.x();
6504         qreal y = p.y();
6505
6506         int start = 0;
6507         int end, i;
6508         for (end = 0; end < ti.glyphs.numGlyphs; ++end) {
6509             const int e = glyphs.glyphs[end] >> 24;
6510             if (e == which)
6511                 continue;
6512
6513
6514             QTextItemInt ti2 = ti.midItem(multi->engine(which), start, end - start);
6515             ti2.width = 0;
6516             // set the high byte to zero and calc the width
6517             for (i = start; i < end; ++i) {
6518                 glyphs.glyphs[i] = glyphs.glyphs[i] & 0xffffff;
6519                 ti2.width += ti.glyphs.effectiveAdvance(i);
6520             }
6521
6522             d->engine->drawTextItem(QPointF(x, y), ti2);
6523
6524             // reset the high byte for all glyphs and advance to the next sub-string
6525             const int hi = which << 24;
6526             for (i = start; i < end; ++i) {
6527                 glyphs.glyphs[i] = hi | glyphs.glyphs[i];
6528             }
6529             x += ti2.width.toReal();
6530
6531             // change engine
6532             start = end;
6533             which = e;
6534         }
6535
6536         QTextItemInt ti2 = ti.midItem(multi->engine(which), start, end - start);
6537         ti2.width = 0;
6538         // set the high byte to zero and calc the width
6539         for (i = start; i < end; ++i) {
6540             glyphs.glyphs[i] = glyphs.glyphs[i] & 0xffffff;
6541             ti2.width += ti.glyphs.effectiveAdvance(i);
6542         }
6543
6544         if (d->extended)
6545             d->extended->drawTextItem(QPointF(x, y), ti2);
6546         else
6547             d->engine->drawTextItem(QPointF(x,y), ti2);
6548
6549         // reset the high byte for all glyphs
6550         const int hi = which << 24;
6551         for (i = start; i < end; ++i)
6552             glyphs.glyphs[i] = hi | glyphs.glyphs[i];
6553
6554     } else {
6555         if (d->extended)
6556             d->extended->drawTextItem(p, ti);
6557         else
6558             d->engine->drawTextItem(p, ti);
6559     }
6560     drawTextItemDecoration(this, p, ti.fontEngine, ti.underlineStyle, ti.flags, ti.width.toReal(),
6561                            ti.charFormat);
6562
6563     if (d->state->renderHints != oldRenderHints) {
6564         d->state->renderHints = oldRenderHints;
6565         if (d->extended)
6566             d->extended->renderHintsChanged();
6567         else
6568             d->state->dirtyFlags |= QPaintEngine::DirtyHints;
6569     }
6570 }
6571
6572 /*!
6573     \fn QRectF QPainter::boundingRect(const QRectF &rectangle, int flags, const QString &text)
6574
6575     Returns the bounding rectangle of the \a text as it will appear
6576     when drawn inside the given \a rectangle with the specified \a
6577     flags using the currently set font(); i.e the function tells you
6578     where the drawText() function will draw when given the same
6579     arguments.
6580
6581     If the \a text does not fit within the given \a rectangle using
6582     the specified \a flags, the function returns the required
6583     rectangle.
6584
6585     The \a flags argument is a bitwise OR of the following flags:
6586     \list
6587          \o Qt::AlignLeft
6588          \o Qt::AlignRight
6589          \o Qt::AlignHCenter
6590          \o Qt::AlignTop
6591          \o Qt::AlignBottom
6592          \o Qt::AlignVCenter
6593          \o Qt::AlignCenter
6594          \o Qt::TextSingleLine
6595          \o Qt::TextExpandTabs
6596          \o Qt::TextShowMnemonic
6597          \o Qt::TextWordWrap
6598          \o Qt::TextIncludeTrailingSpaces
6599     \endlist
6600     If several of the horizontal or several of the vertical alignment
6601     flags are set, the resulting alignment is undefined.
6602
6603     \sa drawText(), Qt::Alignment, Qt::TextFlag
6604 */
6605
6606 /*!
6607     \fn QRect QPainter::boundingRect(const QRect &rectangle, int flags,
6608                                      const QString &text)
6609
6610     \overload
6611
6612     Returns the bounding rectangle of the \a text as it will appear
6613     when drawn inside the given \a rectangle with the specified \a
6614     flags using the currently set font().
6615 */
6616
6617 /*!
6618     \fn QRect QPainter::boundingRect(int x, int y, int w, int h, int flags,
6619                                      const QString &text);
6620
6621     \overload
6622
6623     Returns the bounding rectangle of the given \a text as it will
6624     appear when drawn inside the rectangle beginning at the point
6625     (\a{x}, \a{y}) with width \a w and height \a h.
6626 */
6627 QRect QPainter::boundingRect(const QRect &rect, int flags, const QString &str)
6628 {
6629     if (str.isEmpty())
6630         return QRect(rect.x(),rect.y(), 0,0);
6631     QRect brect;
6632     drawText(rect, flags | Qt::TextDontPrint, str, &brect);
6633     return brect;
6634 }
6635
6636
6637
6638 QRectF QPainter::boundingRect(const QRectF &rect, int flags, const QString &str)
6639 {
6640     if (str.isEmpty())
6641         return QRectF(rect.x(),rect.y(), 0,0);
6642     QRectF brect;
6643     drawText(rect, flags | Qt::TextDontPrint, str, &brect);
6644     return brect;
6645 }
6646
6647 /*!
6648     \fn QRectF QPainter::boundingRect(const QRectF &rectangle,
6649         const QString &text, const QTextOption &option)
6650
6651     \overload
6652
6653     Instead of specifying flags as a bitwise OR of the
6654     Qt::AlignmentFlag and Qt::TextFlag, this overloaded function takes
6655     an \a option argument. The QTextOption class provides a
6656     description of general rich text properties.
6657
6658     \sa QTextOption
6659 */
6660 QRectF QPainter::boundingRect(const QRectF &r, const QString &text, const QTextOption &o)
6661 {
6662     Q_D(QPainter);
6663
6664     if (!d->engine || text.length() == 0)
6665         return QRectF(r.x(),r.y(), 0,0);
6666
6667     QRectF br;
6668     qt_format_text(d->state->font, r, Qt::TextDontPrint, &o, text, &br, 0, 0, 0, this);
6669     return br;
6670 }
6671
6672 /*!
6673     \fn void QPainter::drawTiledPixmap(const QRectF &rectangle, const QPixmap &pixmap, const QPointF &position)
6674
6675     Draws a tiled \a pixmap, inside the given \a rectangle with its
6676     origin at the given \a position.
6677
6678     Calling drawTiledPixmap() is similar to calling drawPixmap()
6679     several times to fill (tile) an area with a pixmap, but is
6680     potentially much more efficient depending on the underlying window
6681     system.
6682
6683     \sa drawPixmap()
6684 */
6685 void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &sp)
6686 {
6687 #ifdef QT_DEBUG_DRAW
6688     if (qt_show_painter_debug_output)
6689         printf("QPainter::drawTiledPixmap(), target=[%.2f,%.2f,%.2f,%.2f], pix=[%d,%d], offset=[%.2f,%.2f]\n",
6690                r.x(), r.y(), r.width(), r.height(),
6691                pixmap.width(), pixmap.height(),
6692                sp.x(), sp.y());
6693 #endif
6694
6695     Q_D(QPainter);
6696     if (!d->engine || pixmap.isNull() || r.isEmpty())
6697         return;
6698
6699 #ifndef QT_NO_DEBUG
6700     qt_painter_thread_test(d->device->devType(), "drawTiledPixmap()", true);
6701 #endif
6702
6703     qreal sw = pixmap.width();
6704     qreal sh = pixmap.height();
6705     qreal sx = sp.x();
6706     qreal sy = sp.y();
6707     if (sx < 0)
6708         sx = qRound(sw) - qRound(-sx) % qRound(sw);
6709     else
6710         sx = qRound(sx) % qRound(sw);
6711     if (sy < 0)
6712         sy = qRound(sh) - -qRound(sy) % qRound(sh);
6713     else
6714         sy = qRound(sy) % qRound(sh);
6715
6716
6717     if (d->extended) {
6718         d->extended->drawTiledPixmap(r, pixmap, QPointF(sx, sy));
6719         return;
6720     }
6721
6722     if (d->state->bgMode == Qt::OpaqueMode && pixmap.isQBitmap())
6723         fillRect(r, d->state->bgBrush);
6724
6725     d->updateState(d->state);
6726     if ((d->state->matrix.type() > QTransform::TxTranslate
6727         && !d->engine->hasFeature(QPaintEngine::PixmapTransform))
6728         || (d->state->opacity != 1.0 && !d->engine->hasFeature(QPaintEngine::ConstantOpacity)))
6729     {
6730         save();
6731         setBackgroundMode(Qt::TransparentMode);
6732         setRenderHint(Antialiasing, renderHints() & SmoothPixmapTransform);
6733         setBrush(QBrush(d->state->pen.color(), pixmap));
6734         setPen(Qt::NoPen);
6735
6736         // If there is no rotation involved we have to make sure we use the
6737         // antialiased and not the aliased coordinate system by rounding the coordinates.
6738         if (d->state->matrix.type() <= QTransform::TxScale) {
6739             const QPointF p = roundInDeviceCoordinates(r.topLeft(), d->state->matrix);
6740
6741             if (d->state->matrix.type() <= QTransform::TxTranslate) {
6742                 sx = qRound(sx);
6743                 sy = qRound(sy);
6744             }
6745
6746             setBrushOrigin(QPointF(r.x()-sx, r.y()-sy));
6747             drawRect(QRectF(p, r.size()));
6748         } else {
6749             setBrushOrigin(QPointF(r.x()-sx, r.y()-sy));
6750             drawRect(r);
6751         }
6752         restore();
6753         return;
6754     }
6755
6756     qreal x = r.x();
6757     qreal y = r.y();
6758     if (d->state->matrix.type() == QTransform::TxTranslate
6759         && !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
6760         x += d->state->matrix.dx();
6761         y += d->state->matrix.dy();
6762     }
6763
6764     d->engine->drawTiledPixmap(QRectF(x, y, r.width(), r.height()), pixmap, QPointF(sx, sy));
6765 }
6766
6767 /*!
6768     \fn QPainter::drawTiledPixmap(const QRect &rectangle, const QPixmap &pixmap,
6769                                   const QPoint &position = QPoint())
6770     \overload
6771
6772     Draws a tiled \a pixmap, inside the given \a rectangle with its
6773     origin at the given \a position.
6774 */
6775
6776 /*!
6777     \fn void QPainter::drawTiledPixmap(int x, int y, int width, int height, const
6778          QPixmap &pixmap, int sx, int sy);
6779     \overload
6780
6781     Draws a tiled \a pixmap in the specified rectangle.
6782
6783     (\a{x}, \a{y}) specifies the top-left point in the paint device
6784     that is to be drawn onto; with the given \a width and \a
6785     height. (\a{sx}, \a{sy}) specifies the top-left point in the \a
6786     pixmap that is to be drawn; this defaults to (0, 0).
6787 */
6788
6789 #ifndef QT_NO_PICTURE
6790
6791 /*!
6792     \fn void QPainter::drawPicture(const QPointF &point, const QPicture &picture)
6793
6794     Replays the given \a picture at the given \a point.
6795
6796     The QPicture class is a paint device that records and replays
6797     QPainter commands. A picture serializes the painter commands to an
6798     IO device in a platform-independent format. Everything that can be
6799     painted on a widget or pixmap can also be stored in a picture.
6800
6801     This function does exactly the same as QPicture::play() when
6802     called with \a point = QPoint(0, 0).
6803
6804     \table 100%
6805     \row
6806     \o
6807     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 18
6808     \endtable
6809
6810     \sa QPicture::play()
6811 */
6812
6813 void QPainter::drawPicture(const QPointF &p, const QPicture &picture)
6814 {
6815     Q_D(QPainter);
6816
6817     if (!d->engine)
6818         return;
6819
6820     if (!d->extended)
6821         d->updateState(d->state);
6822
6823     save();
6824     translate(p);
6825     const_cast<QPicture *>(&picture)->play(this);
6826     restore();
6827 }
6828
6829 /*!
6830     \fn void QPainter::drawPicture(const QPoint &point, const QPicture &picture)
6831     \overload
6832
6833     Replays the given \a picture at the given \a point.
6834 */
6835
6836 /*!
6837     \fn void QPainter::drawPicture(int x, int y, const QPicture &picture)
6838     \overload
6839
6840     Draws the given \a picture at point (\a x, \a y).
6841 */
6842
6843 #endif // QT_NO_PICTURE
6844
6845 /*!
6846     \fn void QPainter::eraseRect(const QRectF &rectangle)
6847
6848     Erases the area inside the given \a rectangle. Equivalent to
6849     calling
6850     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 19
6851
6852     \sa fillRect()
6853 */
6854 void QPainter::eraseRect(const QRectF &r)
6855 {
6856     Q_D(QPainter);
6857
6858     fillRect(r, d->state->bgBrush);
6859 }
6860
6861 static inline bool needsResolving(const QBrush &brush)
6862 {
6863     Qt::BrushStyle s = brush.style();
6864     return ((s == Qt::LinearGradientPattern || s == Qt::RadialGradientPattern ||
6865              s == Qt::ConicalGradientPattern) &&
6866             brush.gradient()->coordinateMode() == QGradient::ObjectBoundingMode);
6867 }
6868
6869 /*!
6870     \fn void QPainter::eraseRect(const QRect &rectangle)
6871     \overload
6872
6873     Erases the area inside the given  \a rectangle.
6874 */
6875
6876 /*!
6877     \fn void QPainter::eraseRect(int x, int y, int width, int height)
6878     \overload
6879
6880     Erases the area inside the rectangle beginning at (\a x, \a y)
6881     with the given \a width and \a height.
6882 */
6883
6884
6885 /*!
6886     \fn void QPainter::fillRect(int x, int y, int width, int height, Qt::BrushStyle style)
6887     \overload
6888
6889     Fills the rectangle beginning at (\a{x}, \a{y}) with the given \a
6890     width and \a height, using the brush \a style specified.
6891
6892     \since 4.5
6893 */
6894
6895 /*!
6896     \fn void QPainter::fillRect(const QRect &rectangle, Qt::BrushStyle style)
6897     \overload
6898
6899     Fills the given \a rectangle  with the brush \a style specified.
6900
6901     \since 4.5
6902 */
6903
6904 /*!
6905     \fn void QPainter::fillRect(const QRectF &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, const QBrush &brush)
6915
6916     Fills the given \a rectangle  with the \a brush specified.
6917
6918     Alternatively, you can specify a QColor instead of a QBrush; the
6919     QBrush constructor (taking a QColor argument) will automatically
6920     create a solid pattern brush.
6921
6922     \sa drawRect()
6923 */
6924 void QPainter::fillRect(const QRectF &r, const QBrush &brush)
6925 {
6926     Q_D(QPainter);
6927
6928     if (!d->engine)
6929         return;
6930
6931     if (d->extended) {
6932         const QGradient *g = brush.gradient();
6933         if (!g || g->coordinateMode() == QGradient::LogicalMode) {
6934             d->extended->fillRect(r, brush);
6935             return;
6936         }
6937     }
6938
6939     QPen oldPen = pen();
6940     QBrush oldBrush = this->brush();
6941     setPen(Qt::NoPen);
6942     if (brush.style() == Qt::SolidPattern) {
6943         d->colorBrush.setStyle(Qt::SolidPattern);
6944         d->colorBrush.setColor(brush.color());
6945         setBrush(d->colorBrush);
6946     } else {
6947         setBrush(brush);
6948     }
6949
6950     drawRect(r);
6951     setBrush(oldBrush);
6952     setPen(oldPen);
6953 }
6954
6955 /*!
6956     \fn void QPainter::fillRect(const QRect &rectangle, const QBrush &brush)
6957     \overload
6958
6959     Fills the given \a rectangle with the specified \a brush.
6960 */
6961
6962 void QPainter::fillRect(const QRect &r, const QBrush &brush)
6963 {
6964     Q_D(QPainter);
6965
6966     if (!d->engine)
6967         return;
6968
6969     if (d->extended) {
6970         const QGradient *g = brush.gradient();
6971         if (!g || g->coordinateMode() == QGradient::LogicalMode) {
6972             d->extended->fillRect(r, brush);
6973             return;
6974         }
6975     }
6976
6977     QPen oldPen = pen();
6978     QBrush oldBrush = this->brush();
6979     setPen(Qt::NoPen);
6980     if (brush.style() == Qt::SolidPattern) {
6981         d->colorBrush.setStyle(Qt::SolidPattern);
6982         d->colorBrush.setColor(brush.color());
6983         setBrush(d->colorBrush);
6984     } else {
6985         setBrush(brush);
6986     }
6987
6988     drawRect(r);
6989     setBrush(oldBrush);
6990     setPen(oldPen);
6991 }
6992
6993
6994
6995 /*!
6996     \fn void QPainter::fillRect(const QRect &rectangle, const QColor &color)
6997     \overload
6998
6999     Fills the given \a rectangle with the \a color specified.
7000
7001     \since 4.5
7002 */
7003 void QPainter::fillRect(const QRect &r, const QColor &color)
7004 {
7005     Q_D(QPainter);
7006
7007     if (!d->engine)
7008         return;
7009
7010     if (d->extended) {
7011         d->extended->fillRect(r, color);
7012         return;
7013     }
7014
7015     fillRect(r, QBrush(color));
7016 }
7017
7018
7019 /*!
7020     \fn void QPainter::fillRect(const QRectF &rectangle, const QColor &color)
7021     \overload
7022
7023     Fills the given \a rectangle with the \a color specified.
7024
7025     \since 4.5
7026 */
7027 void QPainter::fillRect(const QRectF &r, const QColor &color)
7028 {
7029     Q_D(QPainter);
7030
7031     if (!d->engine)
7032         return;
7033
7034     if (d->extended) {
7035         d->extended->fillRect(r, color);
7036         return;
7037     }
7038
7039     fillRect(r, QBrush(color));
7040 }
7041
7042 /*!
7043     \fn void QPainter::fillRect(int x, int y, int width, int height, const QBrush &brush)
7044
7045     \overload
7046
7047     Fills the rectangle beginning at (\a{x}, \a{y}) with the given \a
7048     width and \a height, using the given \a brush.
7049 */
7050
7051 /*!
7052     \fn void QPainter::fillRect(int x, int y, int width, int height, const QColor &color)
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 color.
7058
7059     \since 4.5
7060 */
7061
7062 /*!
7063     \fn void QPainter::fillRect(int x, int y, int width, int height, Qt::GlobalColor color)
7064
7065     \overload
7066
7067     Fills the rectangle beginning at (\a{x}, \a{y}) with the given \a
7068     width and \a height, using the given \a color.
7069
7070     \since 4.5
7071 */
7072
7073 /*!
7074     \fn void QPainter::fillRect(const QRect &rectangle, Qt::GlobalColor color);
7075
7076     \overload
7077
7078     Fills the given \a rectangle with the specified \a color.
7079
7080     \since 4.5
7081 */
7082
7083 /*!
7084     \fn void QPainter::fillRect(const QRectF &rectangle, Qt::GlobalColor color);
7085
7086     \overload
7087
7088     Fills the given \a rectangle with the specified \a color.
7089
7090     \since 4.5
7091 */
7092
7093 /*!
7094     Sets the given render \a hint on the painter if \a on is true;
7095     otherwise clears the render hint.
7096
7097     \sa setRenderHints(), renderHints(), {QPainter#Rendering
7098     Quality}{Rendering Quality}
7099 */
7100 void QPainter::setRenderHint(RenderHint hint, bool on)
7101 {
7102 #ifdef QT_DEBUG_DRAW
7103     if (qt_show_painter_debug_output)
7104         printf("QPainter::setRenderHint: hint=%x, %s\n", hint, on ? "on" : "off");
7105 #endif
7106
7107 #ifndef QT_NO_DEBUG
7108     static const bool antialiasingDisabled = qgetenv("QT_NO_ANTIALIASING").toInt();
7109     if (hint == QPainter::Antialiasing && antialiasingDisabled)
7110         return;
7111 #endif
7112
7113     setRenderHints(hint, on);
7114 }
7115
7116 /*!
7117     \since 4.2
7118
7119     Sets the given render \a hints on the painter if \a on is true;
7120     otherwise clears the render hints.
7121
7122     \sa setRenderHint(), renderHints(), {QPainter#Rendering
7123     Quality}{Rendering Quality}
7124 */
7125
7126 void QPainter::setRenderHints(RenderHints hints, bool on)
7127 {
7128     Q_D(QPainter);
7129
7130     if (!d->engine) {
7131         qWarning("QPainter::setRenderHint: Painter must be active to set rendering hints");
7132         return;
7133     }
7134
7135     if (on)
7136         d->state->renderHints |= hints;
7137     else
7138         d->state->renderHints &= ~hints;
7139
7140     if (d->extended)
7141         d->extended->renderHintsChanged();
7142     else
7143         d->state->dirtyFlags |= QPaintEngine::DirtyHints;
7144 }
7145
7146 /*!
7147     Returns a flag that specifies the rendering hints that are set for
7148     this painter.
7149
7150     \sa testRenderHint(), {QPainter#Rendering Quality}{Rendering Quality}
7151 */
7152 QPainter::RenderHints QPainter::renderHints() const
7153 {
7154     Q_D(const QPainter);
7155
7156     if (!d->engine)
7157         return 0;
7158
7159     return d->state->renderHints;
7160 }
7161
7162 /*!
7163     \fn bool QPainter::testRenderHint(RenderHint hint) const
7164     \since 4.3
7165
7166     Returns true if \a hint is set; otherwise returns false.
7167
7168     \sa renderHints(), setRenderHint()
7169 */
7170
7171 /*!
7172     Returns true if view transformation is enabled; otherwise returns
7173     false.
7174
7175     \sa setViewTransformEnabled(), worldTransform()
7176 */
7177
7178 bool QPainter::viewTransformEnabled() const
7179 {
7180     Q_D(const QPainter);
7181     if (!d->engine) {
7182         qWarning("QPainter::viewTransformEnabled: Painter not active");
7183         return false;
7184     }
7185     return d->state->VxF;
7186 }
7187
7188 /*!
7189     \fn void QPainter::setWindow(const QRect &rectangle)
7190
7191     Sets the painter's window to the given \a rectangle, and enables
7192     view transformations.
7193
7194     The window rectangle is part of the view transformation. The
7195     window specifies the logical coordinate system. Its sister, the
7196     viewport(), specifies the device coordinate system.
7197
7198     The default window rectangle is the same as the device's
7199     rectangle.
7200
7201     \sa window(), viewTransformEnabled(), {Coordinate
7202     System#Window-Viewport Conversion}{Window-Viewport Conversion}
7203 */
7204
7205 /*!
7206     \fn void QPainter::setWindow(int x, int y, int width, int height)
7207     \overload
7208
7209     Sets the painter's window to the rectangle beginning at (\a x, \a
7210     y) and the given \a width and \a height.
7211 */
7212
7213 void QPainter::setWindow(const QRect &r)
7214 {
7215 #ifdef QT_DEBUG_DRAW
7216     if (qt_show_painter_debug_output)
7217         printf("QPainter::setWindow(), [%d,%d,%d,%d]\n", r.x(), r.y(), r.width(), r.height());
7218 #endif
7219
7220     Q_D(QPainter);
7221
7222     if (!d->engine) {
7223         qWarning("QPainter::setWindow: Painter not active");
7224         return;
7225     }
7226
7227     d->state->wx = r.x();
7228     d->state->wy = r.y();
7229     d->state->ww = r.width();
7230     d->state->wh = r.height();
7231
7232     d->state->VxF = true;
7233     d->updateMatrix();
7234 }
7235
7236 /*!
7237     Returns the window rectangle.
7238
7239     \sa setWindow(), setViewTransformEnabled()
7240 */
7241
7242 QRect QPainter::window() const
7243 {
7244     Q_D(const QPainter);
7245     if (!d->engine) {
7246         qWarning("QPainter::window: Painter not active");
7247         return QRect();
7248     }
7249     return QRect(d->state->wx, d->state->wy, d->state->ww, d->state->wh);
7250 }
7251
7252 /*!
7253     \fn void QPainter::setViewport(const QRect &rectangle)
7254
7255     Sets the painter's viewport rectangle to the given \a rectangle,
7256     and enables view transformations.
7257
7258     The viewport rectangle is part of the view transformation. The
7259     viewport specifies the device coordinate system. Its sister, the
7260     window(), specifies the logical coordinate system.
7261
7262     The default viewport rectangle is the same as the device's
7263     rectangle.
7264
7265     \sa viewport(), viewTransformEnabled() {Coordinate
7266     System#Window-Viewport Conversion}{Window-Viewport Conversion}
7267 */
7268
7269 /*!
7270     \fn void QPainter::setViewport(int x, int y, int width, int height)
7271     \overload
7272
7273     Sets the painter's viewport rectangle to be the rectangle
7274     beginning at (\a x, \a y) with the given \a width and \a height.
7275 */
7276
7277 void QPainter::setViewport(const QRect &r)
7278 {
7279 #ifdef QT_DEBUG_DRAW
7280     if (qt_show_painter_debug_output)
7281         printf("QPainter::setViewport(), [%d,%d,%d,%d]\n", r.x(), r.y(), r.width(), r.height());
7282 #endif
7283
7284     Q_D(QPainter);
7285
7286     if (!d->engine) {
7287         qWarning("QPainter::setViewport: Painter not active");
7288         return;
7289     }
7290
7291     d->state->vx = r.x();
7292     d->state->vy = r.y();
7293     d->state->vw = r.width();
7294     d->state->vh = r.height();
7295
7296     d->state->VxF = true;
7297     d->updateMatrix();
7298 }
7299
7300 /*!
7301     Returns the viewport rectangle.
7302
7303     \sa setViewport(), setViewTransformEnabled()
7304 */
7305
7306 QRect QPainter::viewport() const
7307 {
7308     Q_D(const QPainter);
7309     if (!d->engine) {
7310         qWarning("QPainter::viewport: Painter not active");
7311         return QRect();
7312     }
7313     return QRect(d->state->vx, d->state->vy, d->state->vw, d->state->vh);
7314 }
7315
7316 /*! \fn bool QPainter::hasViewXForm() const
7317     \compat
7318
7319     Use viewTransformEnabled() instead.
7320 */
7321
7322 /*! \fn bool QPainter::hasWorldXForm() const
7323     \compat
7324
7325     Use worldMatrixEnabled() instead.
7326 */
7327
7328 /*! \fn void QPainter::resetXForm()
7329     \compat
7330
7331     Use resetTransform() instead.
7332 */
7333
7334 /*! \fn void QPainter::setViewXForm(bool enabled)
7335     \compat
7336
7337     Use setViewTransformEnabled() instead.
7338 */
7339
7340 /*! \fn void QPainter::setWorldXForm(bool enabled)
7341     \compat
7342
7343     Use setWorldMatrixEnabled() instead.
7344 */
7345 /*!
7346     Enables view transformations if \a enable is true, or disables
7347     view transformations if \a enable is false.
7348
7349     \sa viewTransformEnabled(), {Coordinate System#Window-Viewport
7350     Conversion}{Window-Viewport Conversion}
7351 */
7352
7353 void QPainter::setViewTransformEnabled(bool enable)
7354 {
7355 #ifdef QT_DEBUG_DRAW
7356     if (qt_show_painter_debug_output)
7357         printf("QPainter::setViewTransformEnabled(), enable=%d\n", enable);
7358 #endif
7359
7360     Q_D(QPainter);
7361
7362     if (!d->engine) {
7363         qWarning("QPainter::setViewTransformEnabled: Painter not active");
7364         return;
7365     }
7366
7367     if (enable == d->state->VxF)
7368         return;
7369
7370     d->state->VxF = enable;
7371     d->updateMatrix();
7372 }
7373
7374 /*!
7375     \threadsafe
7376
7377     \obsolete
7378
7379     Please use QWidget::render() instead.
7380
7381     Redirects all paint commands for the given paint \a device, to the
7382     \a replacement device. The optional point \a offset defines an
7383     offset within the source device.
7384
7385     The redirection will not be effective until the begin() function
7386     has been called; make sure to call end() for the given \a
7387     device's painter (if any) before redirecting. Call
7388     restoreRedirected() to restore the previous redirection.
7389
7390     \warning Making use of redirections in the QPainter API implies
7391     that QPainter::begin() and QPaintDevice destructors need to hold
7392     a mutex for a short period. This can impact performance. Use of
7393     QWidget::render is strongly encouraged.
7394
7395     \sa redirected(), restoreRedirected()
7396 */
7397 void QPainter::setRedirected(const QPaintDevice *device,
7398                              QPaintDevice *replacement,
7399                              const QPoint &offset)
7400 {
7401     Q_ASSERT(device != 0);
7402
7403     qWarning() << "QPainter::setRedirected(): ignoring call to deprecated function, use QWidget::render() instead";
7404 }
7405
7406 /*!
7407     \threadsafe
7408
7409     \obsolete
7410
7411     Using QWidget::render() obsoletes the use of this function.
7412
7413     Restores the previous redirection for the given \a device after a
7414     call to setRedirected().
7415
7416     \warning Making use of redirections in the QPainter API implies
7417     that QPainter::begin() and QPaintDevice destructors need to hold
7418     a mutex for a short period. This can impact performance. Use of
7419     QWidget::render is strongly encouraged.
7420
7421     \sa redirected()
7422  */
7423 void QPainter::restoreRedirected(const QPaintDevice *device)
7424 {
7425     qWarning() << "QPainter::restoreRedirected(): ignoring call to deprecated function, use QWidget::render() instead";
7426 }
7427
7428 /*!
7429     \threadsafe
7430
7431     \obsolete
7432
7433     Using QWidget::render() obsoletes the use of this function.
7434
7435     Returns the replacement for given \a device. The optional out
7436     parameter \a offset returns the offset within the replaced device.
7437
7438     \warning Making use of redirections in the QPainter API implies
7439     that QPainter::begin() and QPaintDevice destructors need to hold
7440     a mutex for a short period. This can impact performance. Use of
7441     QWidget::render is strongly encouraged.
7442
7443     \sa setRedirected(), restoreRedirected()
7444 */
7445 QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
7446 {
7447     return 0;
7448 }
7449
7450 void qt_format_text(const QFont &fnt, const QRectF &_r,
7451                     int tf, const QString& str, QRectF *brect,
7452                     int tabstops, int *ta, int tabarraylen,
7453                     QPainter *painter)
7454 {
7455     qt_format_text(fnt, _r,
7456                     tf, 0, str, brect,
7457                     tabstops, ta, tabarraylen,
7458                     painter);
7459 }
7460 void qt_format_text(const QFont &fnt, const QRectF &_r,
7461                     int tf, const QTextOption *option, const QString& str, QRectF *brect,
7462                     int tabstops, int *ta, int tabarraylen,
7463                     QPainter *painter)
7464 {
7465
7466     Q_ASSERT( !((tf & ~Qt::TextDontPrint)!=0 && option!=0) ); // we either have an option or flags
7467
7468     if (option) {
7469         tf |= option->alignment();
7470         if (option->wrapMode() != QTextOption::NoWrap)
7471             tf |= Qt::TextWordWrap;
7472
7473         if (option->flags() & QTextOption::IncludeTrailingSpaces)
7474             tf |= Qt::TextIncludeTrailingSpaces;
7475
7476         if (option->tabStop() >= 0 || !option->tabArray().isEmpty())
7477             tf |= Qt::TextExpandTabs;
7478     }
7479
7480     // we need to copy r here to protect against the case (&r == brect).
7481     QRectF r(_r);
7482
7483     bool dontclip  = (tf & Qt::TextDontClip);
7484     bool wordwrap  = (tf & Qt::TextWordWrap) || (tf & Qt::TextWrapAnywhere);
7485     bool singleline = (tf & Qt::TextSingleLine);
7486     bool showmnemonic = (tf & Qt::TextShowMnemonic);
7487     bool hidemnmemonic = (tf & Qt::TextHideMnemonic);
7488
7489     Qt::LayoutDirection layout_direction;
7490     if (tf & Qt::TextForceLeftToRight)
7491         layout_direction = Qt::LeftToRight;
7492     else if (tf & Qt::TextForceRightToLeft)
7493         layout_direction = Qt::RightToLeft;
7494     else if (option)
7495         layout_direction = option->textDirection();
7496     else if (painter)
7497         layout_direction = painter->layoutDirection();
7498     else
7499         layout_direction = Qt::LeftToRight;
7500
7501     tf = QGuiApplicationPrivate::visualAlignment(layout_direction, QFlag(tf));
7502
7503     bool isRightToLeft = layout_direction == Qt::RightToLeft;
7504     bool expandtabs = ((tf & Qt::TextExpandTabs) &&
7505                         (((tf & Qt::AlignLeft) && !isRightToLeft) ||
7506                           ((tf & Qt::AlignRight) && isRightToLeft)));
7507
7508     if (!painter)
7509         tf |= Qt::TextDontPrint;
7510
7511     uint maxUnderlines = 0;
7512     int numUnderlines = 0;
7513     QVarLengthArray<int, 32> underlinePositions(1);
7514
7515     QFontMetricsF fm(fnt);
7516     QString text = str;
7517     int offset = 0;
7518 start_lengthVariant:
7519     bool hasMoreLengthVariants = false;
7520     // compatible behaviour to the old implementation. Replace
7521     // tabs by spaces
7522     int old_offset = offset;
7523     for (; offset < text.length(); offset++) {
7524         QChar chr = text.at(offset);
7525         if (chr == QLatin1Char('\r') || (singleline && chr == QLatin1Char('\n'))) {
7526             text[offset] = QLatin1Char(' ');
7527         } else if (chr == QLatin1Char('\n')) {
7528             text[offset] = QChar::LineSeparator;
7529         } else if (chr == QLatin1Char('&')) {
7530             ++maxUnderlines;
7531         } else if (chr == QLatin1Char('\t')) {
7532             if (!expandtabs) {
7533                 text[offset] = QLatin1Char(' ');
7534             } else if (!tabarraylen && !tabstops) {
7535                 tabstops = qRound(fm.width(QLatin1Char('x'))*8);
7536             }
7537         } else if (chr == QChar(ushort(0x9c))) {
7538             // string with multiple length variants
7539             hasMoreLengthVariants = true;
7540             break;
7541         }
7542     }
7543
7544     int length = offset - old_offset;
7545     if ((hidemnmemonic || showmnemonic) && maxUnderlines > 0) {
7546         underlinePositions.resize(maxUnderlines + 1);
7547
7548         QChar *cout = text.data() + old_offset;
7549         QChar *cin = cout;
7550         int l = length;
7551         while (l) {
7552             if (*cin == QLatin1Char('&')) {
7553                 ++cin;
7554                 --length;
7555                 --l;
7556                 if (!l)
7557                     break;
7558                 if (*cin != QLatin1Char('&') && !hidemnmemonic)
7559                     underlinePositions[numUnderlines++] = cout - text.data() - old_offset;
7560             }
7561             *cout = *cin;
7562             ++cout;
7563             ++cin;
7564             --l;
7565         }
7566     }
7567
7568     // no need to do extra work for underlines if we don't paint
7569     if (tf & Qt::TextDontPrint)
7570         numUnderlines = 0;
7571
7572     underlinePositions[numUnderlines] = -1;
7573     qreal height = 0;
7574     qreal width = 0;
7575
7576     QString finalText = text.mid(old_offset, length);
7577     QStackTextEngine engine(finalText, fnt);
7578     if (option) {
7579         engine.option = *option;
7580     }
7581
7582     if (engine.option.tabStop() < 0 && tabstops > 0)
7583         engine.option.setTabStop(tabstops);
7584
7585     if (engine.option.tabs().isEmpty() && ta) {
7586         QList<qreal> tabs;
7587         for (int i = 0; i < tabarraylen; i++)
7588             tabs.append(qreal(ta[i]));
7589         engine.option.setTabArray(tabs);
7590     }
7591
7592     engine.option.setTextDirection(layout_direction);
7593     if (tf & Qt::AlignJustify)
7594         engine.option.setAlignment(Qt::AlignJustify);
7595     else
7596         engine.option.setAlignment(Qt::AlignLeft); // do not do alignment twice
7597
7598     if (!option && (tf & Qt::TextWrapAnywhere))
7599         engine.option.setWrapMode(QTextOption::WrapAnywhere);
7600
7601     if (tf & Qt::TextJustificationForced)
7602         engine.forceJustification = true;
7603     QTextLayout textLayout(&engine);
7604     textLayout.setCacheEnabled(true);
7605     textLayout.engine()->underlinePositions = underlinePositions.data();
7606
7607     if (finalText.isEmpty()) {
7608         height = fm.height();
7609         width = 0;
7610         tf |= Qt::TextDontPrint;
7611     } else {
7612         qreal lineWidth = 0x01000000;
7613         if (wordwrap || (tf & Qt::TextJustificationForced))
7614             lineWidth = qMax<qreal>(0, r.width());
7615         if(!wordwrap)
7616             tf |= Qt::TextIncludeTrailingSpaces;
7617         textLayout.engine()->ignoreBidi = bool(tf & Qt::TextDontPrint);
7618         textLayout.beginLayout();
7619
7620         qreal leading = fm.leading();
7621         height = -leading;
7622
7623         while (1) {
7624             QTextLine l = textLayout.createLine();
7625             if (!l.isValid())
7626                 break;
7627
7628             l.setLineWidth(lineWidth);
7629             height += leading;
7630             l.setPosition(QPointF(0., height));
7631             height += l.height();
7632             width = qMax(width, l.naturalTextWidth());
7633             if (!dontclip && !brect && height >= r.height())
7634                 break;
7635         }
7636         textLayout.endLayout();
7637     }
7638
7639     qreal yoff = 0;
7640     qreal xoff = 0;
7641     if (tf & Qt::AlignBottom) {
7642         yoff = r.height() - height;
7643     } else if (tf & Qt::AlignVCenter) {
7644         yoff = (r.height() - height)/2;
7645         if (painter) {
7646             QTransform::TransformationType type = painter->transform().type();
7647             if (type <= QTransform::TxScale) {
7648                 // do the rounding manually to work around inconsistencies
7649                 // in the paint engines when drawing on floating point offsets
7650                 const qreal scale = painter->transform().m22();
7651                 if (scale != 0)
7652                     yoff = -qRound(-yoff * scale) / scale;
7653             }
7654         }
7655     }
7656     if (tf & Qt::AlignRight) {
7657         xoff = r.width() - width;
7658     } else if (tf & Qt::AlignHCenter) {
7659         xoff = (r.width() - width)/2;
7660         if (painter) {
7661             QTransform::TransformationType type = painter->transform().type();
7662             if (type <= QTransform::TxScale) {
7663                 // do the rounding manually to work around inconsistencies
7664                 // in the paint engines when drawing on floating point offsets
7665                 const qreal scale = painter->transform().m11();
7666                 if (scale != 0)
7667                     xoff = qRound(xoff * scale) / scale;
7668             }
7669         }
7670     }
7671     QRectF bounds = QRectF(r.x() + xoff, r.y() + yoff, width, height);
7672
7673     if (hasMoreLengthVariants && !(tf & Qt::TextLongestVariant) && !r.contains(bounds)) {
7674         offset++;
7675         goto start_lengthVariant;
7676     }
7677     if (brect)
7678         *brect = bounds;
7679
7680     if (!(tf & Qt::TextDontPrint)) {
7681         bool restore = false;
7682         if (!dontclip && !r.contains(bounds)) {
7683             restore = true;
7684             painter->save();
7685             painter->setClipRect(r, Qt::IntersectClip);
7686         }
7687
7688         for (int i = 0; i < textLayout.lineCount(); i++) {
7689             QTextLine line = textLayout.lineAt(i);
7690
7691             qreal advance = line.horizontalAdvance();
7692             xoff = 0;
7693             if (tf & Qt::AlignRight) {
7694                 QTextEngine *eng = textLayout.engine();
7695                 xoff = r.width() - advance -
7696                     eng->leadingSpaceWidth(eng->lines[line.lineNumber()]).toReal();
7697             }
7698             else if (tf & Qt::AlignHCenter)
7699                 xoff = (r.width() - advance) / 2;
7700
7701             line.draw(painter, QPointF(r.x() + xoff, r.y() + yoff));
7702         }
7703
7704         if (restore) {
7705             painter->restore();
7706         }
7707     }
7708 }
7709
7710 /*!
7711     Sets the layout direction used by the painter when drawing text,
7712     to the specified \a direction.
7713
7714     The default is Qt::LayoutDirectionAuto, which will implicitly determine the
7715     direction from the text drawn.
7716
7717     \sa QTextOption::setTextDirection(), layoutDirection(), drawText(), {QPainter#Settings}{Settings}
7718 */
7719 void QPainter::setLayoutDirection(Qt::LayoutDirection direction)
7720 {
7721     Q_D(QPainter);
7722     if (d->state)
7723         d->state->layoutDirection = direction;
7724 }
7725
7726 /*!
7727     Returns the layout direction used by the painter when drawing text.
7728
7729     \sa QTextOption::textDirection(), setLayoutDirection(), drawText(), {QPainter#Settings}{Settings}
7730 */
7731 Qt::LayoutDirection QPainter::layoutDirection() const
7732 {
7733     Q_D(const QPainter);
7734     return d->state ? d->state->layoutDirection : Qt::LayoutDirectionAuto;
7735 }
7736
7737 QPainterState::QPainterState(const QPainterState *s)
7738     : brushOrigin(s->brushOrigin), font(s->font), deviceFont(s->deviceFont),
7739       pen(s->pen), brush(s->brush), bgBrush(s->bgBrush),
7740       clipRegion(s->clipRegion), clipPath(s->clipPath),
7741       clipOperation(s->clipOperation),
7742       renderHints(s->renderHints), clipInfo(s->clipInfo),
7743       worldMatrix(s->worldMatrix), matrix(s->matrix), redirectionMatrix(s->redirectionMatrix),
7744       wx(s->wx), wy(s->wy), ww(s->ww), wh(s->wh),
7745       vx(s->vx), vy(s->vy), vw(s->vw), vh(s->vh),
7746       opacity(s->opacity), WxF(s->WxF), VxF(s->VxF),
7747       clipEnabled(s->clipEnabled), bgMode(s->bgMode), painter(s->painter),
7748       layoutDirection(s->layoutDirection),
7749       composition_mode(s->composition_mode),
7750       emulationSpecifier(s->emulationSpecifier), changeFlags(0)
7751 {
7752     dirtyFlags = s->dirtyFlags;
7753 }
7754
7755 QPainterState::QPainterState()
7756     : brushOrigin(0, 0), bgBrush(Qt::white), clipOperation(Qt::NoClip),
7757       renderHints(0),
7758       wx(0), wy(0), ww(0), wh(0), vx(0), vy(0), vw(0), vh(0),
7759       opacity(1), WxF(false), VxF(false), clipEnabled(true),
7760       bgMode(Qt::TransparentMode), painter(0),
7761       layoutDirection(QGuiApplication::layoutDirection()),
7762       composition_mode(QPainter::CompositionMode_SourceOver),
7763       emulationSpecifier(0), changeFlags(0)
7764 {
7765     dirtyFlags = 0;
7766 }
7767
7768 QPainterState::~QPainterState()
7769 {
7770 }
7771
7772 void QPainterState::init(QPainter *p) {
7773     bgBrush = Qt::white;
7774     bgMode = Qt::TransparentMode;
7775     WxF = false;
7776     VxF = false;
7777     clipEnabled = true;
7778     wx = wy = ww = wh = 0;
7779     vx = vy = vw = vh = 0;
7780     painter = p;
7781     pen = QPen();
7782     brushOrigin = QPointF(0, 0);
7783     brush = QBrush();
7784     font = deviceFont = QFont();
7785     clipRegion = QRegion();
7786     clipPath = QPainterPath();
7787     clipOperation = Qt::NoClip;
7788     clipInfo.clear();
7789     worldMatrix.reset();
7790     matrix.reset();
7791     layoutDirection = QGuiApplication::layoutDirection();
7792     composition_mode = QPainter::CompositionMode_SourceOver;
7793     emulationSpecifier = 0;
7794     dirtyFlags = 0;
7795     changeFlags = 0;
7796     renderHints = 0;
7797     opacity = 1;
7798 }
7799
7800 /*!
7801     \fn void QPainter::setBackgroundColor(const QColor &color)
7802
7803     Use setBackground() instead.
7804 */
7805
7806 /*!
7807     \fn const QColor &QPainter::backgroundColor() const
7808
7809     Use background() and QBrush::color() instead.
7810
7811     \oldcode
7812         QColor myColor = backgroundColor();
7813     \newcode
7814         QColor myColor = background().color();
7815     \endcode
7816
7817     Note that the background can be a complex brush such as a texture
7818     or a gradient.
7819 */
7820
7821 /*!
7822     \fn void QPainter::drawText(int x, int y, const QString &text, int pos, int length)
7823     \compat
7824
7825     Use drawText() combined with QString::mid() instead.
7826
7827     \oldcode
7828         QPainter painter(this);
7829         painter.drawText(x, y, text, pos, length);
7830     \newcode
7831         QPainter painter(this);
7832         painter.drawText(x, y, text.mid(pos, length));
7833     \endcode
7834 */
7835
7836 /*!
7837     \fn void QPainter::drawText(const QPoint &point, const QString &text, int pos, int length)
7838     \compat
7839
7840     Use drawText() combined with QString::mid() instead.
7841
7842     \oldcode
7843         QPainter painter(this);
7844         painter.drawText(point, text, pos, length);
7845     \newcode
7846         QPainter painter(this);
7847         painter.drawText(point, text.mid(pos, length));
7848     \endcode
7849 */
7850
7851 /*!
7852     \fn void QPainter::drawText(int x, int y, const QString &text, int length)
7853     \compat
7854
7855     Use drawText() combined with QString::left() instead.
7856
7857     \oldcode
7858         QPainter painter(this);
7859         painter.drawText(x, y, text, length);
7860     \newcode
7861         QPainter painter(this);
7862         painter.drawText(x, y, text.left(length));
7863     \endcode
7864 */
7865
7866 /*!
7867     \fn void QPainter::drawText(const QPoint &point, const QString &text, int length)
7868     \compat
7869
7870     Use drawText() combined with QString::left() instead.
7871
7872     \oldcode
7873         QPainter painter(this);
7874         painter.drawText(point, text, length);
7875     \newcode
7876         QPainter painter(this);
7877         painter.drawText(point, text.left(length));
7878     \endcode
7879 */
7880
7881 /*!
7882     \fn bool QPainter::begin(QPaintDevice *device, const QWidget *init)
7883     \compat
7884
7885     Use begin() instead.
7886
7887     If the paint \a device is a QWidget, QPainter is initialized after
7888     the widget's settings automatically. Otherwise, you must call the
7889     initFrom() function to initialize the painters pen, background and
7890     font to the same as any given widget.
7891
7892     \oldcode
7893         QPainter painter(this);
7894         painter.begin(device, init);
7895     \newcode
7896         QPainter painter(this);
7897         painter.begin(device);
7898         painter.initFrom(init);
7899     \endcode
7900 */
7901
7902 /*!
7903     \fn void QPainter::drawImage(const QRectF &target, const QImage &image, const QRectF &source,
7904                          Qt::ImageConversionFlags flags)
7905
7906     Draws the rectangular portion \a source of the given \a image
7907     into the \a target rectangle in the paint device.
7908
7909     \note The image is scaled to fit the rectangle, if both the image and rectangle size disagree.
7910
7911     If the image needs to be modified to fit in a lower-resolution
7912     result (e.g. converting from 32-bit to 8-bit), use the \a flags to
7913     specify how you would prefer this to happen.
7914
7915     \table 100%
7916     \row
7917     \o
7918     \snippet doc/src/snippets/code/src_gui_painting_qpainter.cpp 20
7919     \endtable
7920
7921     \sa drawPixmap()
7922 */
7923
7924 /*!
7925     \fn void QPainter::drawImage(const QRect &target, const QImage &image, const QRect &source,
7926                                  Qt::ImageConversionFlags flags)
7927     \overload
7928
7929     Draws the rectangular portion \a source of the given \a image
7930     into the \a target rectangle in the paint device.
7931
7932     \note The image is scaled to fit the rectangle, if both the image and rectangle size disagree.
7933 */
7934
7935 /*!
7936     \fn void QPainter::drawImage(const QPointF &point, const QImage &image)
7937
7938     \overload
7939
7940     Draws the given \a image at the given \a point.
7941 */
7942
7943 /*!
7944     \fn void QPainter::drawImage(const QPoint &point, const QImage &image)
7945
7946     \overload
7947
7948     Draws the given \a image at the given \a point.
7949 */
7950
7951 /*!
7952     \fn void QPainter::drawImage(const QPointF &point, const QImage &image, const QRectF &source,
7953                                  Qt::ImageConversionFlags flags = 0)
7954
7955     \overload
7956
7957     Draws the rectangular portion \a source of the given \a image with
7958     its origin at the given \a point.
7959 */
7960
7961 /*!
7962     \fn void QPainter::drawImage(const QPoint &point, const QImage &image, const QRect &source,
7963                                  Qt::ImageConversionFlags flags = 0)
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 QRectF &rectangle, const QImage &image)
7972
7973     \overload
7974
7975     Draws the given \a image into the given \a rectangle.
7976
7977     \note The image is scaled to fit the rectangle, if both the image and rectangle size disagree.
7978 */
7979
7980 /*!
7981     \fn void QPainter::drawImage(const QRect &rectangle, const QImage &image)
7982
7983     \overload
7984
7985     Draws the given \a image into the given \a rectangle.
7986
7987    \note The image is scaled to fit the rectangle, if both the image and rectangle size disagree.
7988 */
7989
7990 /*!
7991     \fn void QPainter::drawImage(int x, int y, const QImage &image,
7992                                  int sx, int sy, int sw, int sh,
7993                                  Qt::ImageConversionFlags flags)
7994     \overload
7995
7996     Draws an image at (\a{x}, \a{y}) by copying a part of \a image into
7997     the paint device.
7998
7999     (\a{x}, \a{y}) specifies the top-left point in the paint device that is
8000     to be drawn onto. (\a{sx}, \a{sy}) specifies the top-left point in \a
8001     image that is to be drawn. The default is (0, 0).
8002
8003     (\a{sw}, \a{sh}) specifies the size of the image that is to be drawn.
8004     The default, (0, 0) (and negative) means all the way to the
8005     bottom-right of the image.
8006 */
8007
8008 /*!
8009     \fn void QPainter::redirect(QPaintDevice *pdev, QPaintDevice *replacement)
8010
8011     Use setRedirected() instead.
8012 */
8013
8014 /*!
8015     \fn QPaintDevice *QPainter::redirect(QPaintDevice *pdev)
8016
8017     Use redirected() instead.
8018 */
8019
8020 /*!
8021     \fn QRect QPainter::boundingRect(const QRect &rectangle, int flags,
8022                                      const QString &text, int length)
8023     \compat
8024
8025     Returns the bounding rectangle for the given \a length of the \a
8026     text constrained by the provided \a rectangle.
8027
8028     Use boundingRect() combined with QString::left() instead.
8029
8030     \oldcode
8031         QRect rectangle = boundingRect(rect, flags, text, length);
8032     \newcode
8033         QRect rectangle = boundingRect(rect, flags, text.left(length));
8034     \endcode
8035 */
8036
8037 /*!
8038     \fn void QPainter::drawText(const QRect &rectangle, int flags, const QString &text,
8039                                 int length, QRect *br)
8040     \compat
8041
8042     Use drawText() combined with QString::left() instead.
8043
8044     \oldcode
8045         QPainter painter(this);
8046         painter.drawText(rectangle, flags, text, length, br );
8047     \newcode
8048         QPainter painter(this);
8049         painter.drawText(rectangle, flags, text.left(length), br );
8050     \endcode
8051 */
8052
8053 /*!
8054     \fn QRect QPainter::boundingRect(int x, int y, int width, int height, int flags,
8055                                      const QString &text, int length);
8056
8057     \compat
8058
8059     Returns the bounding rectangle for the given \a length of the \a
8060     text constrained by the rectangle that begins at point (\a{x},
8061     \a{y}) with the given \a width and \a height.
8062
8063     Use boundingRect() combined with QString::left() instead.
8064
8065     \oldcode
8066         QRect rectangle = boundingRect(x, y, width, height, flags, text, length);
8067     \newcode
8068         QRect rectangle = boundingRect(x, y, width, height, flags, text.left(length));
8069     \endcode
8070 */
8071
8072 /*!
8073     \fn void QPainter::drawText(int x, int y, int width, int height, int flags,
8074                                 const QString &text, int length, QRect *br)
8075
8076     \compat
8077
8078     Use drawText() combined with QString::left() instead.
8079
8080     \oldcode
8081         QPainter painter(this);
8082         painter.drawText(x, y, width, height, flags, text, length, br );
8083     \newcode
8084         QPainter painter(this);
8085         painter.drawText(x, y, width, height, flags, text.left(length), br );
8086     \endcode
8087 */
8088
8089
8090 /*!
8091     \class QPaintEngineState
8092     \since 4.1
8093
8094     \brief The QPaintEngineState class provides information about the
8095     active paint engine's current state.
8096     \reentrant
8097
8098     QPaintEngineState records which properties that have changed since
8099     the last time the paint engine was updated, as well as their
8100     current value.
8101
8102     Which properties that have changed can at any time be retrieved
8103     using the state() function. This function returns an instance of
8104     the QPaintEngine::DirtyFlags type which stores an OR combination
8105     of QPaintEngine::DirtyFlag values. The QPaintEngine::DirtyFlag
8106     enum defines whether a property has changed since the last update
8107     or not.
8108
8109     If a property is marked with a dirty flag, its current value can
8110     be retrieved using the corresponding get function:
8111
8112     \target GetFunction
8113
8114     \table
8115     \header \o Property Flag \o Current Property Value
8116     \row \o QPaintEngine::DirtyBackground \o backgroundBrush()
8117     \row \o QPaintEngine::DirtyBackgroundMode \o backgroundMode()
8118     \row \o QPaintEngine::DirtyBrush \o brush()
8119     \row \o QPaintEngine::DirtyBrushOrigin \o brushOrigin()
8120     \row \o QPaintEngine::DirtyClipRegion \e or QPaintEngine::DirtyClipPath
8121          \o clipOperation()
8122     \row \o QPaintEngine::DirtyClipPath \o clipPath()
8123     \row \o QPaintEngine::DirtyClipRegion \o clipRegion()
8124     \row \o QPaintEngine::DirtyCompositionMode \o compositionMode()
8125     \row \o QPaintEngine::DirtyFont \o font()
8126     \row \o QPaintEngine::DirtyTransform \o transform()
8127     \row \o QPaintEngine::DirtyClipEnabled \o isClipEnabled()
8128     \row \o QPaintEngine::DirtyPen \o pen()
8129     \row \o QPaintEngine::DirtyHints \o renderHints()
8130     \endtable
8131
8132     The QPaintEngineState class also provide the painter() function
8133     which returns a pointer to the painter that is currently updating
8134     the paint engine.
8135
8136     An instance of this class, representing the current state of the
8137     active paint engine, is passed as argument to the
8138     QPaintEngine::updateState() function. The only situation in which
8139     you will have to use this class directly is when implementing your
8140     own paint engine.
8141
8142     \sa QPaintEngine
8143 */
8144
8145
8146 /*!
8147     \fn QPaintEngine::DirtyFlags QPaintEngineState::state() const
8148
8149     Returns a combination of flags identifying the set of properties
8150     that need to be updated when updating the paint engine's state
8151     (i.e. during a call to the QPaintEngine::updateState() function).
8152
8153     \sa QPaintEngine::updateState()
8154 */
8155
8156
8157 /*!
8158     Returns the pen in the current paint engine state.
8159
8160     This variable should only be used when the state() returns a
8161     combination which includes the QPaintEngine::DirtyPen flag.
8162
8163     \sa state(), QPaintEngine::updateState()
8164 */
8165
8166 QPen QPaintEngineState::pen() const
8167 {
8168     return static_cast<const QPainterState *>(this)->pen;
8169 }
8170
8171 /*!
8172     Returns the brush in the current paint engine state.
8173
8174     This variable should only be used when the state() returns a
8175     combination which includes the QPaintEngine::DirtyBrush flag.
8176
8177     \sa state(), QPaintEngine::updateState()
8178 */
8179
8180 QBrush QPaintEngineState::brush() const
8181 {
8182     return static_cast<const QPainterState *>(this)->brush;
8183 }
8184
8185 /*!
8186     Returns the brush origin in the current paint engine state.
8187
8188     This variable should only be used when the state() returns a
8189     combination which includes the QPaintEngine::DirtyBrushOrigin flag.
8190
8191     \sa state(), QPaintEngine::updateState()
8192 */
8193
8194 QPointF QPaintEngineState::brushOrigin() const
8195 {
8196     return static_cast<const QPainterState *>(this)->brushOrigin;
8197 }
8198
8199 /*!
8200     Returns the background brush in the current paint engine state.
8201
8202     This variable should only be used when the state() returns a
8203     combination which includes the QPaintEngine::DirtyBackground flag.
8204
8205     \sa state(), QPaintEngine::updateState()
8206 */
8207
8208 QBrush QPaintEngineState::backgroundBrush() const
8209 {
8210     return static_cast<const QPainterState *>(this)->bgBrush;
8211 }
8212
8213 /*!
8214     Returns the background mode in the current paint engine
8215     state.
8216
8217     This variable should only be used when the state() returns a
8218     combination which includes the QPaintEngine::DirtyBackgroundMode flag.
8219
8220     \sa state(), QPaintEngine::updateState()
8221 */
8222
8223 Qt::BGMode QPaintEngineState::backgroundMode() const
8224 {
8225     return static_cast<const QPainterState *>(this)->bgMode;
8226 }
8227
8228 /*!
8229     Returns the font in the current paint engine
8230     state.
8231
8232     This variable should only be used when the state() returns a
8233     combination which includes the QPaintEngine::DirtyFont flag.
8234
8235     \sa state(), QPaintEngine::updateState()
8236 */
8237
8238 QFont QPaintEngineState::font() const
8239 {
8240     return static_cast<const QPainterState *>(this)->font;
8241 }
8242
8243 /*!
8244     \since 4.2
8245     \obsolete
8246
8247     Returns the matrix in the current paint engine
8248     state.
8249
8250     \note It is advisable to use transform() instead of this function to
8251     preserve the properties of perspective transformations.
8252
8253     This variable should only be used when the state() returns a
8254     combination which includes the QPaintEngine::DirtyTransform flag.
8255
8256     \sa state(), QPaintEngine::updateState()
8257 */
8258
8259 QMatrix QPaintEngineState::matrix() const
8260 {
8261     const QPainterState *st = static_cast<const QPainterState *>(this);
8262
8263     return st->matrix.toAffine();
8264 }
8265
8266 /*!
8267     \since 4.3
8268
8269     Returns the matrix in the current paint engine state.
8270
8271     This variable should only be used when the state() returns a
8272     combination which includes the QPaintEngine::DirtyTransform flag.
8273
8274     \sa state(), QPaintEngine::updateState()
8275 */
8276
8277
8278 QTransform QPaintEngineState::transform() const
8279 {
8280     const QPainterState *st = static_cast<const QPainterState *>(this);
8281
8282     return st->matrix;
8283 }
8284
8285
8286 /*!
8287     Returns the clip operation in the current paint engine
8288     state.
8289
8290     This variable should only be used when the state() returns a
8291     combination which includes either the QPaintEngine::DirtyClipPath
8292     or the QPaintEngine::DirtyClipRegion flag.
8293
8294     \sa state(), QPaintEngine::updateState()
8295 */
8296
8297 Qt::ClipOperation QPaintEngineState::clipOperation() const
8298 {
8299     return static_cast<const QPainterState *>(this)->clipOperation;
8300 }
8301
8302 /*!
8303     \since 4.3
8304
8305     Returns whether the coordinate of the fill have been specified
8306     as bounded by the current rendering operation and have to be
8307     resolved (about the currently rendered primitive).
8308 */
8309 bool QPaintEngineState::brushNeedsResolving() const
8310 {
8311     const QBrush &brush = static_cast<const QPainterState *>(this)->brush;
8312     return needsResolving(brush);
8313 }
8314
8315
8316 /*!
8317     \since 4.3
8318
8319     Returns whether the coordinate of the stroke have been specified
8320     as bounded by the current rendering operation and have to be
8321     resolved (about the currently rendered primitive).
8322 */
8323 bool QPaintEngineState::penNeedsResolving() const
8324 {
8325     const QPen &pen = static_cast<const QPainterState *>(this)->pen;
8326     return needsResolving(pen.brush());
8327 }
8328
8329 /*!
8330     Returns the clip region in the current paint engine state.
8331
8332     This variable should only be used when the state() returns a
8333     combination which includes the QPaintEngine::DirtyClipRegion flag.
8334
8335     \sa state(), QPaintEngine::updateState()
8336 */
8337
8338 QRegion QPaintEngineState::clipRegion() const
8339 {
8340     return static_cast<const QPainterState *>(this)->clipRegion;
8341 }
8342
8343 /*!
8344     Returns the clip path in the current paint engine state.
8345
8346     This variable should only be used when the state() returns a
8347     combination which includes the QPaintEngine::DirtyClipPath flag.
8348
8349     \sa state(), QPaintEngine::updateState()
8350 */
8351
8352 QPainterPath QPaintEngineState::clipPath() const
8353 {
8354     return static_cast<const QPainterState *>(this)->clipPath;
8355 }
8356
8357 /*!
8358     Returns whether clipping is enabled or not in the current paint
8359     engine state.
8360
8361     This variable should only be used when the state() returns a
8362     combination which includes the QPaintEngine::DirtyClipEnabled
8363     flag.
8364
8365     \sa state(), QPaintEngine::updateState()
8366 */
8367
8368 bool QPaintEngineState::isClipEnabled() const
8369 {
8370     return static_cast<const QPainterState *>(this)->clipEnabled;
8371 }
8372
8373 /*!
8374     Returns the render hints in the current paint engine state.
8375
8376     This variable should only be used when the state() returns a
8377     combination which includes the QPaintEngine::DirtyHints
8378     flag.
8379
8380     \sa state(), QPaintEngine::updateState()
8381 */
8382
8383 QPainter::RenderHints QPaintEngineState::renderHints() const
8384 {
8385     return static_cast<const QPainterState *>(this)->renderHints;
8386 }
8387
8388 /*!
8389     Returns the composition mode in the current paint engine state.
8390
8391     This variable should only be used when the state() returns a
8392     combination which includes the QPaintEngine::DirtyCompositionMode
8393     flag.
8394
8395     \sa state(), QPaintEngine::updateState()
8396 */
8397
8398 QPainter::CompositionMode QPaintEngineState::compositionMode() const
8399 {
8400     return static_cast<const QPainterState *>(this)->composition_mode;
8401 }
8402
8403
8404 /*!
8405     Returns a pointer to the painter currently updating the paint
8406     engine.
8407 */
8408
8409 QPainter *QPaintEngineState::painter() const
8410 {
8411     return static_cast<const QPainterState *>(this)->painter;
8412 }
8413
8414
8415 /*!
8416     \since 4.2
8417
8418     Returns the opacity in the current paint engine state.
8419 */
8420
8421 qreal QPaintEngineState::opacity() const
8422 {
8423     return static_cast<const QPainterState *>(this)->opacity;
8424 }
8425
8426 /*!
8427     \since 4.3
8428
8429     Sets the world transformation matrix.
8430     If \a combine is true, the specified \a transform is combined with
8431     the current matrix; otherwise it replaces the current matrix.
8432
8433     \sa transform() setWorldTransform()
8434 */
8435
8436 void QPainter::setTransform(const QTransform &transform, bool combine )
8437 {
8438     setWorldTransform(transform, combine);
8439 }
8440
8441 /*!
8442     Returns the world transformation matrix.
8443
8444     \sa worldTransform()
8445 */
8446
8447 const QTransform & QPainter::transform() const
8448 {
8449     return worldTransform();
8450 }
8451
8452
8453 /*!
8454     Returns the matrix that transforms from logical coordinates to
8455     device coordinates of the platform dependent paint device.
8456
8457     This function is \e only needed when using platform painting
8458     commands on the platform dependent handle (Qt::HANDLE), and the
8459     platform does not do transformations nativly.
8460
8461     The QPaintEngine::PaintEngineFeature enum can be queried to
8462     determine whether the platform performs the transformations or
8463     not.
8464
8465     \sa worldTransform(), QPaintEngine::hasFeature(),
8466 */
8467
8468 const QTransform & QPainter::deviceTransform() const
8469 {
8470     Q_D(const QPainter);
8471     if (!d->engine) {
8472         qWarning("QPainter::deviceTransform: Painter not active");
8473         return d->fakeState()->transform;
8474     }
8475     return d->state->matrix;
8476 }
8477
8478
8479 /*!
8480     Resets any transformations that were made using translate(),
8481     scale(), shear(), rotate(), setWorldTransform(), setViewport()
8482     and setWindow().
8483
8484     \sa {Coordinate Transformations}
8485 */
8486
8487 void QPainter::resetTransform()
8488 {
8489      Q_D(QPainter);
8490 #ifdef QT_DEBUG_DRAW
8491     if (qt_show_painter_debug_output)
8492         printf("QPainter::resetMatrix()\n");
8493 #endif
8494     if (!d->engine) {
8495         qWarning("QPainter::resetMatrix: Painter not active");
8496         return;
8497     }
8498
8499     d->state->wx = d->state->wy = d->state->vx = d->state->vy = 0;                        // default view origins
8500     d->state->ww = d->state->vw = d->device->metric(QPaintDevice::PdmWidth);
8501     d->state->wh = d->state->vh = d->device->metric(QPaintDevice::PdmHeight);
8502     d->state->worldMatrix = QTransform();
8503     setMatrixEnabled(false);
8504     setViewTransformEnabled(false);
8505     if (d->extended)
8506         d->extended->transformChanged();
8507     else
8508         d->state->dirtyFlags |= QPaintEngine::DirtyTransform;
8509 }
8510
8511 /*!
8512     Sets the world transformation matrix.
8513     If \a combine is true, the specified \a matrix is combined with the current matrix;
8514     otherwise it replaces the current matrix.
8515
8516     \sa transform(), setTransform()
8517 */
8518
8519 void QPainter::setWorldTransform(const QTransform &matrix, bool combine )
8520 {
8521     Q_D(QPainter);
8522
8523     if (!d->engine) {
8524         qWarning("QPainter::setWorldTransform: Painter not active");
8525         return;
8526     }
8527
8528     if (combine)
8529         d->state->worldMatrix = matrix * d->state->worldMatrix;                        // combines
8530     else
8531         d->state->worldMatrix = matrix;                                // set new matrix
8532
8533     d->state->WxF = true;
8534     d->updateMatrix();
8535 }
8536
8537 /*!
8538     Returns the world transformation matrix.
8539 */
8540
8541 const QTransform & QPainter::worldTransform() const
8542 {
8543     Q_D(const QPainter);
8544     if (!d->engine) {
8545         qWarning("QPainter::worldTransform: Painter not active");
8546         return d->fakeState()->transform;
8547     }
8548     return d->state->worldMatrix;
8549 }
8550
8551 /*!
8552     Returns the transformation matrix combining the current
8553     window/viewport and world transformation.
8554
8555     \sa setWorldTransform(), setWindow(), setViewport()
8556 */
8557
8558 QTransform QPainter::combinedTransform() const
8559 {
8560     Q_D(const QPainter);
8561     if (!d->engine) {
8562         qWarning("QPainter::combinedTransform: Painter not active");
8563         return QTransform();
8564     }
8565     return d->state->worldMatrix * d->viewTransform();
8566 }
8567
8568 /*!
8569     \since 4.7
8570
8571     This function is used to draw \a pixmap, or a sub-rectangle of \a pixmap,
8572     at multiple positions with different scale, rotation and opacity. \a
8573     fragments is an array of \a fragmentCount elements specifying the
8574     parameters used to draw each pixmap fragment. The \a hints
8575     parameter can be used to pass in drawing hints.
8576
8577     This function is potentially faster than multiple calls to drawPixmap(),
8578     since the backend can optimize state changes.
8579
8580     \sa QPainter::PixmapFragment, QPainter::PixmapFragmentHint
8581 */
8582
8583 void QPainter::drawPixmapFragments(const PixmapFragment *fragments, int fragmentCount,
8584                                    const QPixmap &pixmap, PixmapFragmentHints hints)
8585 {
8586     Q_D(QPainter);
8587
8588     if (!d->engine || pixmap.isNull())
8589         return;
8590
8591 #ifndef QT_NO_DEBUG
8592     for (int i = 0; i < fragmentCount; ++i) {
8593         QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop,
8594                           fragments[i].width, fragments[i].height);
8595         if (!(QRectF(pixmap.rect()).contains(sourceRect)))
8596             qWarning("QPainter::drawPixmapFragments - the source rect is not contained by the pixmap's rectangle");
8597     }
8598 #endif
8599
8600     if (d->engine->isExtended()) {
8601         d->extended->drawPixmapFragments(fragments, fragmentCount, pixmap, hints);
8602     } else {
8603         qreal oldOpacity = opacity();
8604         QTransform oldTransform = transform();
8605
8606         for (int i = 0; i < fragmentCount; ++i) {
8607             QTransform transform = oldTransform;
8608             qreal xOffset = 0;
8609             qreal yOffset = 0;
8610             if (fragments[i].rotation == 0) {
8611                 xOffset = fragments[i].x;
8612                 yOffset = fragments[i].y;
8613             } else {
8614                 transform.translate(fragments[i].x, fragments[i].y);
8615                 transform.rotate(fragments[i].rotation);
8616             }
8617             setOpacity(oldOpacity * fragments[i].opacity);
8618             setTransform(transform);
8619
8620             qreal w = fragments[i].scaleX * fragments[i].width;
8621             qreal h = fragments[i].scaleY * fragments[i].height;
8622             QRectF sourceRect(fragments[i].sourceLeft, fragments[i].sourceTop,
8623                               fragments[i].width, fragments[i].height);
8624             drawPixmap(QRectF(-0.5 * w + xOffset, -0.5 * h + yOffset, w, h), pixmap, sourceRect);
8625         }
8626
8627         setOpacity(oldOpacity);
8628         setTransform(oldTransform);
8629     }
8630 }
8631
8632 /*!
8633     \since 4.7
8634     \class QPainter::PixmapFragment
8635
8636     \brief This class is used in conjunction with the
8637     QPainter::drawPixmapFragments() function to specify how a pixmap, or
8638     sub-rect of a pixmap, is drawn.
8639
8640     The \a sourceLeft, \a sourceTop, \a width and \a height variables are used
8641     as a source rectangle within the pixmap passed into the
8642     QPainter::drawPixmapFragments() function. The variables \a x, \a y, \a
8643     width and \a height are used to calculate the target rectangle that is
8644     drawn. \a x and \a y denotes the center of the target rectangle. The \a
8645     width and \a height in the target rectangle is scaled by the \a scaleX and
8646     \a scaleY values. The resulting target rectangle is then rotated \a
8647     rotation degrees around the \a x, \a y center point.
8648
8649     \sa QPainter::drawPixmapFragments()
8650 */
8651
8652 /*!
8653     \since 4.7
8654
8655     This is a convenience function that returns a QPainter::PixmapFragment that is
8656     initialized with the \a pos, \a sourceRect, \a scaleX, \a scaleY, \a
8657     rotation, \a opacity parameters.
8658 */
8659
8660 QPainter::PixmapFragment QPainter::PixmapFragment::create(const QPointF &pos, const QRectF &sourceRect,
8661                                               qreal scaleX, qreal scaleY, qreal rotation,
8662                                               qreal opacity)
8663 {
8664     PixmapFragment fragment = {pos.x(), pos.y(), sourceRect.x(), sourceRect.y(), sourceRect.width(),
8665                                sourceRect.height(), scaleX, scaleY, rotation, opacity};
8666     return fragment;
8667 }
8668
8669 /*!
8670     \variable QPainter::PixmapFragment::x
8671     \brief the x coordinate of center point in the target rectangle.
8672 */
8673
8674 /*!
8675     \variable QPainter::PixmapFragment::y
8676     \brief the y coordinate of the center point in the target rectangle.
8677 */
8678
8679 /*!
8680     \variable QPainter::PixmapFragment::sourceLeft
8681     \brief the left coordinate of the source rectangle.
8682 */
8683
8684 /*!
8685     \variable QPainter::PixmapFragment::sourceTop
8686     \brief the top coordinate of the source rectangle.
8687 */
8688
8689 /*!
8690     \variable QPainter::PixmapFragment::width
8691
8692     \brief the width of the source rectangle and is used to calculate the width
8693     of the target rectangle.
8694 */
8695
8696 /*!
8697     \variable QPainter::PixmapFragment::height
8698
8699     \brief the height of the source rectangle and is used to calculate the
8700     height of the target rectangle.
8701 */
8702
8703 /*!
8704     \variable QPainter::PixmapFragment::scaleX
8705     \brief the horizontal scale of the target rectangle.
8706 */
8707
8708 /*!
8709     \variable QPainter::PixmapFragment::scaleY
8710     \brief the vertical scale of the target rectangle.
8711 */
8712
8713 /*!
8714     \variable QPainter::PixmapFragment::rotation
8715
8716     \brief the rotation of the target rectangle in degrees. The target
8717     rectangle is rotated after it has been scaled.
8718 */
8719
8720 /*!
8721     \variable QPainter::PixmapFragment::opacity
8722
8723     \brief the opacity of the target rectangle, where 0.0 is fully transparent
8724     and 1.0 is fully opaque.
8725 */
8726
8727 /*!
8728     \since 4.7
8729
8730     \enum QPainter::PixmapFragmentHint
8731
8732     \value OpaqueHint Indicates that the pixmap fragments to be drawn are
8733     opaque. Opaque fragments are potentially faster to draw.
8734
8735     \sa QPainter::drawPixmapFragments(), QPainter::PixmapFragment
8736 */
8737
8738 void qt_draw_helper(QPainterPrivate *p, const QPainterPath &path, QPainterPrivate::DrawOperation operation)
8739 {
8740     p->draw_helper(path, operation);
8741 }
8742
8743 /*! \fn Display *QPaintDevice::x11Display() const
8744     Use QX11Info::display() instead.
8745
8746     \oldcode
8747         Display *display = widget->x11Display();
8748     \newcode
8749         Display *display = QX11Info::display();
8750     \endcode
8751
8752     \sa QWidget::x11Info(), QX11Info::display()
8753 */
8754
8755 /*! \fn int QPaintDevice::x11Screen() const
8756     Use QX11Info::screen() instead.
8757
8758     \oldcode
8759         int screen = widget->x11Screen();
8760     \newcode
8761         int screen = widget->x11Info().screen();
8762     \endcode
8763
8764     \sa QWidget::x11Info(), QPixmap::x11Info()
8765 */
8766
8767 /*! \fn void *QPaintDevice::x11Visual() const
8768     Use QX11Info::visual() instead.
8769
8770     \oldcode
8771         void *visual = widget->x11Visual();
8772     \newcode
8773         void *visual = widget->x11Info().visual();
8774     \endcode
8775
8776     \sa QWidget::x11Info(), QPixmap::x11Info()
8777 */
8778
8779 /*! \fn int QPaintDevice::x11Depth() const
8780     Use QX11Info::depth() instead.
8781
8782     \oldcode
8783         int depth = widget->x11Depth();
8784     \newcode
8785         int depth = widget->x11Info().depth();
8786     \endcode
8787
8788     \sa QWidget::x11Info(), QPixmap::x11Info()
8789 */
8790
8791 /*! \fn int QPaintDevice::x11Cells() const
8792     Use QX11Info::cells() instead.
8793
8794     \oldcode
8795         int cells = widget->x11Cells();
8796     \newcode
8797         int cells = widget->x11Info().cells();
8798     \endcode
8799
8800     \sa QWidget::x11Info(), QPixmap::x11Info()
8801 */
8802
8803 /*! \fn Qt::HANDLE QPaintDevice::x11Colormap() const
8804     Use QX11Info::colormap() instead.
8805
8806     \oldcode
8807         unsigned long screen = widget->x11Colormap();
8808     \newcode
8809         unsigned long screen = widget->x11Info().colormap();
8810     \endcode
8811
8812     \sa QWidget::x11Info(), QPixmap::x11Info()
8813 */
8814
8815 /*! \fn bool QPaintDevice::x11DefaultColormap() const
8816     Use QX11Info::defaultColormap() instead.
8817
8818     \oldcode
8819         bool isDefault = widget->x11DefaultColormap();
8820     \newcode
8821         bool isDefault = widget->x11Info().defaultColormap();
8822     \endcode
8823
8824     \sa QWidget::x11Info(), QPixmap::x11Info()
8825 */
8826
8827 /*! \fn bool QPaintDevice::x11DefaultVisual() const
8828     Use QX11Info::defaultVisual() instead.
8829
8830     \oldcode
8831         bool isDefault = widget->x11DefaultVisual();
8832     \newcode
8833         bool isDefault = widget->x11Info().defaultVisual();
8834     \endcode
8835
8836     \sa QWidget::x11Info(), QPixmap::x11Info()
8837 */
8838
8839 /*! \fn void *QPaintDevice::x11AppVisual(int screen)
8840     Use QX11Info::visual() instead.
8841
8842     \oldcode
8843         void *visual = QPaintDevice::x11AppVisual(screen);
8844     \newcode
8845         void *visual = qApp->x11Info(screen).visual();
8846     \endcode
8847
8848     \sa QWidget::x11Info(), QPixmap::x11Info()
8849 */
8850
8851 /*! \fn Qt::HANDLE QPaintDevice::x11AppColormap(int screen)
8852     Use QX11Info::colormap() instead.
8853
8854     \oldcode
8855         unsigned long colormap = QPaintDevice::x11AppColormap(screen);
8856     \newcode
8857         unsigned long colormap = qApp->x11Info(screen).colormap();
8858     \endcode
8859
8860     \sa QWidget::x11Info(), QPixmap::x11Info()
8861 */
8862
8863 /*! \fn Display *QPaintDevice::x11AppDisplay()
8864     Use QX11Info::display() instead.
8865
8866     \oldcode
8867         Display *display = QPaintDevice::x11AppDisplay();
8868     \newcode
8869         Display *display = qApp->x11Info().display();
8870     \endcode
8871
8872     \sa QWidget::x11Info(), QPixmap::x11Info()
8873 */
8874
8875 /*! \fn int QPaintDevice::x11AppScreen()
8876     Use QX11Info::screen() instead.
8877
8878     \oldcode
8879         int screen = QPaintDevice::x11AppScreen();
8880     \newcode
8881         int screen = qApp->x11Info().screen();
8882     \endcode
8883
8884     \sa QWidget::x11Info(), QPixmap::x11Info()
8885 */
8886
8887 /*! \fn int QPaintDevice::x11AppDepth(int screen)
8888     Use QX11Info::depth() instead.
8889
8890     \oldcode
8891         int depth = QPaintDevice::x11AppDepth(screen);
8892     \newcode
8893         int depth = qApp->x11Info(screen).depth();
8894     \endcode
8895
8896     \sa QWidget::x11Info(), QPixmap::x11Info()
8897 */
8898
8899 /*! \fn int QPaintDevice::x11AppCells(int screen)
8900     Use QX11Info::cells() instead.
8901
8902     \oldcode
8903         int cells = QPaintDevice::x11AppCells(screen);
8904     \newcode
8905         int cells = qApp->x11Info(screen).cells();
8906     \endcode
8907
8908     \sa QWidget::x11Info(), QPixmap::x11Info()
8909 */
8910
8911 /*! \fn Qt::HANDLE QPaintDevice::x11AppRootWindow(int screen)
8912     Use QX11Info::appRootWindow() instead.
8913
8914     \oldcode
8915         unsigned long window = QPaintDevice::x11AppRootWindow(screen);
8916     \newcode
8917         unsigned long window = qApp->x11Info(screen).appRootWindow();
8918     \endcode
8919
8920     \sa QWidget::x11Info(), QPixmap::x11Info()
8921 */
8922
8923 /*! \fn bool QPaintDevice::x11AppDefaultColormap(int screen)
8924     Use QX11Info::defaultColormap() instead.
8925
8926     \oldcode
8927         bool isDefault = QPaintDevice::x11AppDefaultColormap(screen);
8928     \newcode
8929         bool isDefault = qApp->x11Info(screen).defaultColormap();
8930     \endcode
8931
8932     \sa QWidget::x11Info(), QPixmap::x11Info()
8933 */
8934
8935 /*! \fn bool QPaintDevice::x11AppDefaultVisual(int screen)
8936     Use QX11Info::defaultVisual() instead.
8937
8938     \oldcode
8939         bool isDefault = QPaintDevice::x11AppDefaultVisual(screen);
8940     \newcode
8941         bool isDefault = qApp->x11Info(screen).defaultVisual();
8942     \endcode
8943
8944     \sa QWidget::x11Info(), QPixmap::x11Info()
8945 */
8946
8947 /*! \fn void QPaintDevice::x11SetAppDpiX(int dpi, int screen)
8948     Use QX11Info::setAppDpiX() instead.
8949 */
8950
8951 /*! \fn void QPaintDevice::x11SetAppDpiY(int dpi, int screen)
8952     Use QX11Info::setAppDpiY() instead.
8953 */
8954
8955 /*! \fn int QPaintDevice::x11AppDpiX(int screen)
8956     Use QX11Info::appDpiX() instead.
8957
8958     \oldcode
8959         bool isDefault = QPaintDevice::x11AppDpiX(screen);
8960     \newcode
8961         bool isDefault = qApp->x11Info(screen).appDpiX();
8962     \endcode
8963
8964     \sa QWidget::x11Info(), QPixmap::x11Info()
8965 */
8966
8967 /*! \fn int QPaintDevice::x11AppDpiY(int screen)
8968     Use QX11Info::appDpiY() instead.
8969
8970     \oldcode
8971         bool isDefault = QPaintDevice::x11AppDpiY(screen);
8972     \newcode
8973         bool isDefault = qApp->x11Info(screen).appDpiY();
8974     \endcode
8975
8976     \sa QWidget::x11Info(), QPixmap::x11Info()
8977 */
8978
8979 /*! \fn HDC QPaintDevice::getDC() const
8980   \internal
8981 */
8982
8983 /*! \fn void QPaintDevice::releaseDC(HDC) const
8984   \internal
8985 */
8986
8987 /*! \fn QWSDisplay *QPaintDevice::qwsDisplay()
8988     \internal
8989 */
8990
8991 QT_END_NAMESPACE