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