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