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