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