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