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