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