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