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