~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to src/gui/painting/qpainter.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the painting module of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
// QtGui
 
30
#include "qbitmap.h"
 
31
#include "qimage.h"
 
32
#include "qpaintdevice.h"
 
33
#include "qpaintengine.h"
 
34
#include "qpainter.h"
 
35
#include "qpainter_p.h"
 
36
#include "qpainterpath.h"
 
37
#include "qpicture.h"
 
38
#include "qpixmapcache.h"
 
39
#include "qpolygon.h"
 
40
#include "qtextlayout.h"
 
41
#include "qwidget.h"
 
42
#include "qapplication.h"
 
43
#include "qstyle.h"
 
44
 
 
45
#include <private/qfontengine_p.h>
 
46
#include <private/qpaintengine_p.h>
 
47
#include <private/qpainterpath_p.h>
 
48
#include <private/qtextengine_p.h>
 
49
#include <private/qwidget_p.h>
 
50
// QtCore
 
51
#include <qdebug.h>
 
52
 
 
53
// Other
 
54
#include <math.h>
 
55
 
 
56
// #define QT_DEBUG_DRAW
 
57
#ifdef QT_DEBUG_DRAW
 
58
bool qt_show_painter_debug_output = true;
 
59
#endif
 
60
 
 
61
extern QPixmap qt_pixmapForBrush(int style, bool invert);
 
62
 
 
63
void qt_format_text(const QFont &font,
 
64
                    const QRectF &_r, int tf, const QString& str, QRectF *brect,
 
65
                    int tabstops, int* tabarray, int tabarraylen,
 
66
                    QPainter *painter);
 
67
 
 
68
template <class From, class To> QVector<To> qt_convert_points(const From *points, int pointCount, const To & /*dummy*/)
 
69
{
 
70
    QVector<To> v;
 
71
    v.reserve(pointCount);
 
72
    for (int i=0; i<pointCount; ++i)
 
73
        v << points[i];
 
74
    return v;
 
75
}
 
76
 
 
77
void QPainterPrivate::draw_helper(const QPainterPath &originalPath, DrawOperation op)
 
78
{
 
79
#ifdef QT_DEBUG_DRAW
 
80
    if (qt_show_painter_debug_output) {
 
81
        printf("QPainter::drawHelper\n");
 
82
    }
 
83
#endif
 
84
 
 
85
    if (originalPath.isEmpty())
 
86
        return;
 
87
 
 
88
    Q_Q(QPainter);
 
89
    int devMinX = 0, devMaxX = 0, devMinY = 0, devMaxY = 0;
 
90
 
 
91
    qreal strokeOffsetX = 0, strokeOffsetY = 0;
 
92
 
 
93
    QPainterPath path = originalPath * state->matrix;
 
94
    QRectF pathBounds = path.boundingRect();
 
95
    bool doStroke = (op & StrokeDraw) && (state->pen.style() != Qt::NoPen);
 
96
    if (doStroke) {
 
97
        qreal penWidth = state->pen.widthF();
 
98
        if (penWidth == 0) {
 
99
            strokeOffsetX = 1;
 
100
            strokeOffsetY = 1;
 
101
        } else {
 
102
            // In case of complex xform
 
103
            if (state->txop > TxScale) {
 
104
                QPainterPathStroker stroker;
 
105
                stroker.setWidth(penWidth);
 
106
                stroker.setJoinStyle(state->pen.joinStyle());
 
107
                stroker.setCapStyle(state->pen.capStyle());
 
108
                QPainterPath stroke = stroker.createStroke(originalPath);
 
109
                QRectF strokeBounds = (stroke * state->matrix).boundingRect();
 
110
                strokeOffsetX = pathBounds.x() - strokeBounds.x();
 
111
                strokeOffsetY = pathBounds.y() - strokeBounds.y();
 
112
            } else {
 
113
                strokeOffsetX = penWidth / 2.0 * state->matrix.m11();
 
114
                strokeOffsetY = penWidth / 2.0 * state->matrix.m22();
 
115
            }
 
116
        }
 
117
    }
 
118
 
 
119
    const qreal ROUND_UP_TRICK = 0.9999;
 
120
    devMinX = int(pathBounds.left() - strokeOffsetX);
 
121
    devMaxX = int(pathBounds.right() + strokeOffsetX + ROUND_UP_TRICK);
 
122
    devMinY = int(pathBounds.top() - strokeOffsetY);
 
123
    devMaxY = int(pathBounds.bottom() + strokeOffsetY + ROUND_UP_TRICK);
 
124
 
 
125
    QRect absPathRect(devMinX, devMinY, devMaxX - devMinX, devMaxY - devMinY);
 
126
 
 
127
    if (state->clipInfo.size() == 0) {
 
128
        absPathRect = absPathRect.intersect(QRect(0, 0, device->width(), device->height()));
 
129
    } else {
 
130
        QRegion r = q->clipRegion() * q->deviceMatrix();
 
131
        absPathRect = absPathRect.intersect(r.boundingRect());
 
132
    }
 
133
 
 
134
 
 
135
//     qDebug("\nQPainterPrivate::draw_helper(), x=%d, y=%d, w=%d, h=%d",
 
136
//            devMinX, devMinY, devWidth, devHeight);
 
137
//     qDebug() << " - matrix" << state->matrix;
 
138
//     qDebug() << " - originalPath.bounds" << originalPath.boundingRect();
 
139
//     qDebug() << " - path.bounds" << path.boundingRect();
 
140
 
 
141
    if (absPathRect.width() <= 0 || absPathRect.height() <= 0)
 
142
        return;
 
143
 
 
144
    QImage image(absPathRect.width(), absPathRect.height(), QImage::Format_ARGB32_Premultiplied);
 
145
    image.fill(0);
 
146
 
 
147
    QPainter p(&image);
 
148
 
 
149
    p.translate(-absPathRect.x(), -absPathRect.y());
 
150
    p.setMatrix(state->matrix, true);
 
151
    p.setPen(doStroke ? state->pen : QPen(Qt::NoPen));
 
152
    p.setBrush((op & FillDraw) ? state->brush : QBrush(Qt::NoBrush));
 
153
    p.setBackground(state->bgBrush);
 
154
    p.setBackgroundMode(state->bgMode);
 
155
    p.setBrushOrigin(state->bgOrigin);
 
156
 
 
157
    p.setRenderHint(QPainter::Antialiasing, state->renderHints & QPainter::Antialiasing);
 
158
    p.setRenderHint(QPainter::SmoothPixmapTransform,
 
159
                    state->renderHints & QPainter::SmoothPixmapTransform);
 
160
 
 
161
    p.drawPath(originalPath);
 
162
 
 
163
    p.end();
 
164
 
 
165
    q->save();
 
166
    q->setMatrix(QMatrix(1, 0, 0, 1, -redirection_offset.x(), -redirection_offset.y()));
 
167
    updateState(state);
 
168
 
 
169
    engine->drawImage(absPathRect,
 
170
                      image,
 
171
                      QRectF(0, 0, absPathRect.width(), absPathRect.height()),
 
172
                      Qt::OrderedDither | Qt::OrderedAlphaDither);
 
173
 
 
174
    q->restore();
 
175
}
 
176
 
 
177
 
 
178
void QPainterPrivate::init()
 
179
{
 
180
    Q_Q(QPainter);
 
181
    state->painter = q;
 
182
}
 
183
 
 
184
void QPainterPrivate::updateMatrix()
 
185
{
 
186
    QMatrix m;
 
187
    if (state->VxF) {
 
188
        qreal scaleW = qreal(state->vw)/qreal(state->ww);
 
189
        qreal scaleH = qreal(state->vh)/qreal(state->wh);
 
190
        m.setMatrix(scaleW, 0, 0, scaleH, state->vx - state->wx*scaleW, state->vy - state->wy*scaleH);
 
191
    }
 
192
    if (state->WxF) {
 
193
        if (state->VxF)
 
194
            m = state->worldMatrix * m;
 
195
        else
 
196
            m = state->worldMatrix;
 
197
    }
 
198
    state->matrix = m;
 
199
 
 
200
    txinv = false;                                // no inverted matrix
 
201
    state->txop  = TxNone;
 
202
    if (state->matrix.m12()==0.0 && state->matrix.m21()==0.0
 
203
        && state->matrix.m11() >= 0.0 && state->matrix.m22() >= 0.0) {
 
204
        if (state->matrix.m11()==1.0 && state->matrix.m22()==1.0) {
 
205
            if (state->matrix.dx()!=0.0 || state->matrix.dy()!=0.0)
 
206
                state->txop = TxTranslate;
 
207
        } else {
 
208
            state->txop = TxScale;
 
209
        }
 
210
    } else {
 
211
        state->txop = TxRotShear;
 
212
    }
 
213
    if (!redirection_offset.isNull()) {
 
214
        state->txop |= TxTranslate;
 
215
        state->WxF = true;
 
216
        // We want to translate in dev space so we do the adding of the redirection
 
217
        // offset manually.
 
218
        state->matrix = QMatrix(state->matrix.m11(), state->matrix.m12(),
 
219
                              state->matrix.m21(), state->matrix.m22(),
 
220
                              state->matrix.dx()-redirection_offset.x(),
 
221
                              state->matrix.dy()-redirection_offset.y());
 
222
    }
 
223
    state->dirtyFlags |= QPaintEngine::DirtyTransform;
 
224
 
 
225
//     printf("VxF=%d, WxF=%d\n", state->VxF, state->WxF);
 
226
//     qDebug() << " --- using matrix" << state->matrix << redirection_offset;
 
227
}
 
228
 
 
229
/*! \internal */
 
230
void QPainterPrivate::updateInvMatrix()
 
231
{
 
232
    Q_ASSERT(txinv == false);
 
233
    txinv = true;                                // creating inverted matrix
 
234
    bool invertible;
 
235
    QMatrix m;
 
236
    if (state->VxF) {
 
237
        m.translate(state->vx, state->vy);
 
238
        m.scale(1.0*state->vw/state->ww, 1.0*state->vh/state->wh);
 
239
        m.translate(-state->wx, -state->wy);
 
240
    }
 
241
    if (state->WxF) {
 
242
        if (state->VxF)
 
243
            m = state->worldMatrix * m;
 
244
        else
 
245
            m = state->worldMatrix;
 
246
    }
 
247
    invMatrix = m.inverted(&invertible);                // invert matrix
 
248
}
 
249
 
 
250
void QPainterPrivate::updateEmulationSpecifier(QPainterState *s)
 
251
{
 
252
    bool alpha = false;
 
253
    bool linearGradient = false;
 
254
    bool radialGradient = false;
 
255
    bool conicalGradient = false;
 
256
    bool patternBrush = false;
 
257
    bool xform = false;
 
258
 
 
259
    bool skip = true;
 
260
 
 
261
    // Pen and brush properties (we have to check both if one changes because the
 
262
    // one that's unchanged can still be in a state which requires emulation)
 
263
    if (s->state() & QPaintEngine::DirtyPen ||
 
264
        s->state() & QPaintEngine::DirtyBrush) {
 
265
        // Check Brush stroke emulation
 
266
        if (!s->pen.isSolid() && !engine->hasFeature(QPaintEngine::BrushStroke))
 
267
            s->emulationSpecifier |= QPaintEngine::BrushStroke;
 
268
        else
 
269
            s->emulationSpecifier &= ~QPaintEngine::BrushStroke;
 
270
 
 
271
        skip = false;
 
272
 
 
273
        QBrush penBrush = s->pen.brush();
 
274
        alpha |= (!penBrush.isOpaque() || !s->brush.isOpaque());
 
275
        linearGradient |= ((penBrush.style() == Qt::LinearGradientPattern) ||
 
276
                           (s->brush.style() == Qt::LinearGradientPattern));
 
277
        radialGradient |= ((penBrush.style() == Qt::RadialGradientPattern) ||
 
278
                           (s->brush.style() == Qt::RadialGradientPattern));
 
279
        conicalGradient |= ((penBrush.style() == Qt::ConicalGradientPattern) ||
 
280
                            (s->brush.style() == Qt::ConicalGradientPattern));
 
281
        patternBrush |= (((penBrush.style() > Qt::SolidPattern
 
282
                           && penBrush.style() < Qt::LinearGradientPattern)
 
283
                          || s->brush.style() == Qt::TexturePattern) ||
 
284
                         ((s->brush.style() > Qt::SolidPattern
 
285
                           && s->brush.style() < Qt::LinearGradientPattern)
 
286
                          || s->brush.style() == Qt::TexturePattern));
 
287
    }
 
288
 
 
289
    if (s->state() & QPaintEngine::DirtyHints) {
 
290
        skip = false;
 
291
    }
 
292
 
 
293
    if (skip)
 
294
        return;
 
295
 
 
296
#if 0
 
297
    qDebug("QPainterPrivate::updateEmulationSpecifier, state=%p\n"
 
298
           " - alpha: %d\n"
 
299
           " - linearGradient: %d\n"
 
300
           " - radialGradient: %d\n"
 
301
           " - conicalGradient: %d\n"
 
302
           " - patternBrush: %d\n"
 
303
           " - hints: %x\n"
 
304
           " - xform: %d\n",
 
305
           s,
 
306
           alpha,
 
307
           linearGradient,
 
308
           radialGradient,
 
309
           conicalGradient,
 
310
           patternBrush,
 
311
           uint(s->renderHints),
 
312
           xform);
 
313
#endif
 
314
 
 
315
    // XForm properties
 
316
    if (s->state() & QPaintEngine::DirtyTransform) {
 
317
        xform = !s->matrix.isIdentity();
 
318
    } else if (s->txop >= TxTranslate) {
 
319
        xform = true;
 
320
    }
 
321
 
 
322
    // Check alphablending
 
323
    if (alpha && !engine->hasFeature(QPaintEngine::AlphaBlend))
 
324
        s->emulationSpecifier |= QPaintEngine::AlphaBlend;
 
325
    else
 
326
        s->emulationSpecifier &= ~QPaintEngine::AlphaBlend;
 
327
 
 
328
    // Linear gradient emulation
 
329
    if (linearGradient && !engine->hasFeature(QPaintEngine::LinearGradientFill))
 
330
        s->emulationSpecifier |= QPaintEngine::LinearGradientFill;
 
331
    else
 
332
        s->emulationSpecifier &= ~QPaintEngine::LinearGradientFill;
 
333
 
 
334
    // Radial gradient emulation
 
335
    if (radialGradient && !engine->hasFeature(QPaintEngine::RadialGradientFill))
 
336
        s->emulationSpecifier |= QPaintEngine::RadialGradientFill;
 
337
    else
 
338
        s->emulationSpecifier &= ~QPaintEngine::RadialGradientFill;
 
339
 
 
340
    // Conical gradient emulation
 
341
    if (conicalGradient && !engine->hasFeature(QPaintEngine::ConicalGradientFill))
 
342
        s->emulationSpecifier |= QPaintEngine::ConicalGradientFill;
 
343
    else
 
344
        s->emulationSpecifier &= ~QPaintEngine::ConicalGradientFill;
 
345
 
 
346
    // Pattern brushes
 
347
    if (patternBrush && !engine->hasFeature(QPaintEngine::PatternBrush))
 
348
        s->emulationSpecifier |= QPaintEngine::PatternBrush;
 
349
    else
 
350
        s->emulationSpecifier &= ~QPaintEngine::PatternBrush;
 
351
 
 
352
    // Pattern XForms
 
353
    if (patternBrush && xform && !engine->hasFeature(QPaintEngine::PatternTransform))
 
354
        s->emulationSpecifier |= QPaintEngine::PatternTransform;
 
355
    else
 
356
        s->emulationSpecifier &= ~QPaintEngine::PatternTransform;
 
357
 
 
358
    // Primitive XForms
 
359
    if (xform && !engine->hasFeature(QPaintEngine::PrimitiveTransform))
 
360
        s->emulationSpecifier |= QPaintEngine::PrimitiveTransform;
 
361
    else
 
362
        s->emulationSpecifier &= ~QPaintEngine::PrimitiveTransform;
 
363
}
 
364
 
 
365
 
 
366
 
 
367
void QPainterPrivate::updateState(QPainterState *newState)
 
368
{
 
369
 
 
370
    if (!newState) {
 
371
        engine->state = newState;
 
372
 
 
373
    } else if (newState->state() || engine->state!=newState) {
 
374
 
 
375
        if (engine->state->painter() != newState->painter)
 
376
            // ### this could break with clip regions vs paths.
 
377
            engine->setDirty(QPaintEngine::AllDirty);
 
378
 
 
379
        // Upon restore, revert all changes since last save
 
380
        else if (engine->state != newState)
 
381
            newState->dirtyFlags |= QPaintEngine::DirtyFlags(static_cast<QPainterState *>(engine->state)->changeFlags);
 
382
 
 
383
        // We need to store all changes made so that restore can deal with them
 
384
        else
 
385
            newState->changeFlags |= newState->dirtyFlags;
 
386
 
 
387
        updateEmulationSpecifier(newState);
 
388
 
 
389
        engine->state = newState;
 
390
        engine->updateState(*newState);
 
391
        engine->clearDirty(QPaintEngine::AllDirty);
 
392
    }
 
393
}
 
394
 
 
395
 
 
396
/*!
 
397
    \class QPainter
 
398
    \brief The QPainter class performs low-level painting on widgets and
 
399
    other paint devices.
 
400
 
 
401
    \ingroup multimedia
 
402
    \mainclass
 
403
 
 
404
    The painter provides highly optimized functions to do most of the
 
405
    drawing GUI programs require. QPainter can draw everything from
 
406
    simple lines to complex shapes like pies and chords. It can also
 
407
    draw aligned text and pixmaps. Normally, it draws in a "natural"
 
408
    coordinate system, but it can also do view and world
 
409
    transformation.
 
410
 
 
411
    The typical use of a painter is:
 
412
 
 
413
    \list
 
414
    \i Construct a painter.
 
415
    \i Set a pen, a brush etc.
 
416
    \i Draw.
 
417
    \i Destroy the painter.
 
418
    \endlist
 
419
 
 
420
    The common use of QPainter is inside a widget's paint
 
421
    event. Here's one simple example:
 
422
 
 
423
    \code
 
424
    void SimpleExampleWidget::paintEvent()
 
425
    {
 
426
        QPainter paint(this);
 
427
        paint.setPen(Qt::blue);
 
428
        paint.drawText(rect(), Qt::AlignCenter, "The Text");
 
429
    }
 
430
    \endcode
 
431
 
 
432
    If you need to draw a complex shape, especially if you need to do
 
433
    so repeatedly, consider creating a QPainterPath and drawing it
 
434
    using drawPath().
 
435
 
 
436
    Usage is simple, and there are many settings you can use:
 
437
 
 
438
    \list
 
439
 
 
440
    \i font() is the currently set font.
 
441
    \i brush() is the currently set brush; the color or pattern that's
 
442
    used for filling e.g. circles.
 
443
 
 
444
    \i pen() is the currently set pen; the color or stipple that's
 
445
    used for drawing lines or boundaries.
 
446
 
 
447
    \i backgroundMode() is \c Opaque or \c Transparent, i.e. whether
 
448
    background() is used or not.
 
449
 
 
450
    \i backgroundColor() only applies when backgroundMode() is Opaque
 
451
    and pen() is a stipple. In that case, it describes the color of
 
452
    the background pixels in the stipple.
 
453
 
 
454
    \i brushOrigin() is the origin of the tiled brushes, normally the
 
455
    origin of widget's background.
 
456
 
 
457
    \i viewport(), window(), matrix() and many more make up the
 
458
    painter's coordinate transformation system. See \link
 
459
    coordsys.html The Coordinate System \endlink for an explanation of
 
460
    this, or see below for a very brief overview of the functions.
 
461
 
 
462
    \i hasClipping() is whether the painter clips at all. (The paint
 
463
    device clips, too.) If the painter clips, it clips to clipRegion().
 
464
 
 
465
    \endlist
 
466
 
 
467
    Note that some of these settings mirror settings in some paint
 
468
    devices, e.g. QWidget::font(). QPainter::begin() (or the QPainter
 
469
    constructor) copies these attributes from the paint device.
 
470
    Calling, for example, QWidget::setFont() doesn't take effect until
 
471
    the next time a painter begins painting on it.
 
472
 
 
473
    save() saves all of these settings on an internal stack, restore()
 
474
    pops them back.
 
475
 
 
476
    The core functionality of QPainter is drawing, and there are
 
477
    functions to draw most primitives: drawPoint(), drawPoints(),
 
478
    drawLine(), drawRect(), drawRoundRect(),
 
479
    drawEllipse(), drawArc(), drawPie(), drawChord(),
 
480
    drawLineSegments(), drawPolyline(), drawPolygon(),
 
481
    drawConvexPolygon() and drawCubicBezier(). All of these functions
 
482
    have integer and floating point versions.
 
483
 
 
484
    There are functions to draw pixmaps/images, namely drawPixmap(),
 
485
    drawImage() and drawTiledPixmap(). Both drawPixmap() and drawImage()
 
486
    produce the same result, except that drawPixmap() is faster
 
487
    on-screen while drawImage() may be faster on a QPrinter or other
 
488
    devices.
 
489
 
 
490
    Text drawing is done using drawText(). When you need
 
491
    fine-grained positioning, boundingRect() tells you where a given
 
492
    drawText() command would draw.
 
493
 
 
494
    There is a drawPicture() function that draws the contents of an
 
495
    entire QPicture using this painter. drawPicture() is the only
 
496
    function that disregards all the painter's settings as QPicture
 
497
    has its own settings.
 
498
 
 
499
    Normally, the QPainter operates on the device's own coordinate
 
500
    system (usually pixels), but QPainter has good support for
 
501
    coordinate transformations. See \link coordsys.html The Coordinate
 
502
    System \endlink for a more general overview and a simple example.
 
503
 
 
504
    The most common functions used are scale(), rotate(), translate()
 
505
    and shear(), all of which operate on the matrix().
 
506
    setMatrix() can replace or add to the currently set
 
507
    matrix().
 
508
 
 
509
    setViewport() sets the rectangle on which QPainter operates. The
 
510
    default is the entire device, which is usually fine. setWindow()
 
511
    sets the coordinate system, that is, the rectangle that maps to
 
512
    viewport(). What's drawn inside the window() ends up being inside
 
513
    the viewport(). The window's default is the same as the viewport.
 
514
 
 
515
    QPainter can clip any drawing operation to a rectangle, a region,
 
516
    or a vector path. The current clip is available using the
 
517
    functions clipRegion() and clipPath(). Wether paths or regions are
 
518
    preferred (faster) depends on the underlying paintEngine(). For
 
519
    example, the QImage paint engine prefers paths while the X11 paint
 
520
    engine prefers regions. Setting a clip is done in the painters
 
521
    logical coordinates.
 
522
 
 
523
    After QPainter's clipping, the paint device may also clip. For
 
524
    example, most widgets clip away the pixels used by child widgets,
 
525
    and most printers clip away an area near the edges of the paper.
 
526
    This additional clipping is not reflected by the return value of
 
527
    clipRegion() or hasClipping().
 
528
 
 
529
    isActive() indicates whether the painter is active. begin() (and
 
530
    the most usual constructor) makes it active. end() (and the
 
531
    destructor) deactivates it. If the painter is active, device()
 
532
    returns the paint device on which the painter paints.
 
533
 
 
534
    Sometimes it is desirable to make someone else paint on an unusual
 
535
    QPaintDevice. QPainter supports a static function to do this,
 
536
    setRedirected().
 
537
 
 
538
    setTabStops() and setTabArray() can change where the tab stops
 
539
    are, but these are very seldomly used.
 
540
 
 
541
    \warning Unless a widget has the Qt::WA_PaintOutsidePaintEvent attribute
 
542
    set. A QPainter can only be used on a widget inside a paintEvent() or a
 
543
    function called by a paintEvent(). On Mac OS X, you can only paint on a
 
544
    widget in a paintEvent() regardless of this attribute's setting.
 
545
 
 
546
    \sa QPaintDevice QWidget QPixmap QPrinter QPicture QPaintEngine,
 
547
        {The Coordinate System}
 
548
*/
 
549
 
 
550
/*!
 
551
    \enum QPainter::RenderHint
 
552
 
 
553
    Renderhints are used to specify flags to QPainter that may or
 
554
    may not be respected by any given engine.
 
555
 
 
556
    \value Antialiasing Indicates that the engine should antialias
 
557
    edges of primitives if possible.
 
558
 
 
559
    \value TextAntialiasing Indicates that the engine should antialias
 
560
    text if possible.
 
561
 
 
562
    \value SmoothPixmapTransform Indicates that the engine should use
 
563
    a smooth pixmap transformation algorithm (such as bilinear) rather
 
564
    than nearest neighbor.
 
565
 
 
566
*/
 
567
 
 
568
/*!
 
569
    Constructs a painter.
 
570
 
 
571
    Notice that all painter settings (setPen, setBrush etc.) are reset
 
572
    to default values when begin() is called.
 
573
 
 
574
    \sa begin(), end()
 
575
*/
 
576
 
 
577
QPainter::QPainter()
 
578
{
 
579
    d_ptr = new QPainterPrivate(this);
 
580
    d_ptr->init();
 
581
}
 
582
 
 
583
/*!
 
584
    Constructs a painter that begins painting the paint device \a pd
 
585
    immediately.
 
586
 
 
587
    This constructor is convenient for short-lived painters, e.g. in a
 
588
    \link QWidget::paintEvent() paint event\endlink and should be used
 
589
    only once. The constructor calls begin() for you and the QPainter
 
590
    destructor automatically calls end().
 
591
 
 
592
    Here's an example using begin() and end():
 
593
    \code
 
594
        void MyWidget::paintEvent(QPaintEvent *)
 
595
        {
 
596
            QPainter p;
 
597
            p.begin(this);
 
598
            p.drawLine(...);        // drawing code
 
599
            p.end();
 
600
        }
 
601
    \endcode
 
602
 
 
603
    The same example using this constructor:
 
604
    \code
 
605
        void MyWidget::paintEvent(QPaintEvent *)
 
606
        {
 
607
            QPainter p(this);
 
608
            p.drawLine(...);        // drawing code
 
609
        }
 
610
    \endcode
 
611
 
 
612
    Since the constructor cannot provide feedback when the initialization
 
613
    of the painter failed you should rather use begin() and end() to paint
 
614
    on external devices, e.g. printers.
 
615
 
 
616
    \sa begin(), end()
 
617
*/
 
618
 
 
619
QPainter::QPainter(QPaintDevice *pd)
 
620
{
 
621
    d_ptr = new QPainterPrivate(this);
 
622
    d_ptr->init();
 
623
    Q_ASSERT(pd != 0);
 
624
    begin(pd);
 
625
}
 
626
 
 
627
/*!
 
628
    Destroys the painter.
 
629
*/
 
630
 
 
631
QPainter::~QPainter()
 
632
{
 
633
    if (isActive())
 
634
        end();
 
635
    delete d_ptr;
 
636
}
 
637
 
 
638
/*!
 
639
    Returns the paint device on which this painter is currently
 
640
    painting, or 0 if the painter is not active.
 
641
 
 
642
    \sa QPaintDevice::paintingActive()
 
643
*/
 
644
 
 
645
QPaintDevice *QPainter::device() const
 
646
{
 
647
    Q_D(const QPainter);
 
648
    return d->device;
 
649
}
 
650
 
 
651
/*!
 
652
    Returns true if the painter is active painting, i.e. begin() has
 
653
    been called and end() has not yet been called; otherwise returns
 
654
    false.
 
655
 
 
656
    \sa QPaintDevice::paintingActive()
 
657
*/
 
658
 
 
659
bool QPainter::isActive() const
 
660
{
 
661
    Q_D(const QPainter);
 
662
    if (d->engine) {
 
663
        return d->engine->isActive();
 
664
    }
 
665
    return false;
 
666
}
 
667
 
 
668
/*!  Initializes the painters pen, background and font to the same as
 
669
  \a widget. To be called after begin() while the painter is active.
 
670
*/
 
671
void QPainter::initFrom(const QWidget *widget)
 
672
{
 
673
    Q_ASSERT_X(widget, "QPainter::initFrom(const QWidget *widget)", "Widget cannot be 0");
 
674
    if (!isActive()) {
 
675
        qWarning("QPainter::initFrom: Painter is not active, aborted");
 
676
        return;
 
677
    }
 
678
    QPalette pal = widget->palette();
 
679
    Q_D(QPainter);
 
680
    d->state->pen = pal.color(widget->foregroundRole());
 
681
    d->state->bgBrush = pal.brush(widget->backgroundRole());
 
682
    d->state->font = widget->font();
 
683
    const QWidget *w = widget;
 
684
    d->state->bgOrigin = QPointF();
 
685
    while (w->d_func()->isBackgroundInherited()) {
 
686
        d->state->bgOrigin -= w->pos();
 
687
        w = w->parentWidget();
 
688
    }
 
689
    if (d->engine) {
 
690
        d->engine->setDirty(QPaintEngine::DirtyPen);
 
691
        d->engine->setDirty(QPaintEngine::DirtyBrush);
 
692
        d->engine->setDirty(QPaintEngine::DirtyFont);
 
693
    }
 
694
    d->state->layoutDirection = widget->layoutDirection();
 
695
}
 
696
 
 
697
 
 
698
/*!
 
699
    Saves the current painter state (pushes the state onto a stack). A
 
700
    save() must be followed by a corresponding restore(). end()
 
701
    unwinds the stack.
 
702
 
 
703
    \sa restore()
 
704
*/
 
705
 
 
706
void QPainter::save()
 
707
{
 
708
#ifdef QT_DEBUG_DRAW
 
709
    if (qt_show_painter_debug_output)
 
710
        printf("QPainter::save()\n");
 
711
#endif
 
712
    if (!isActive()) {
 
713
        qWarning("QPainter::save(), painter not active");
 
714
        return;
 
715
    }
 
716
 
 
717
    Q_D(QPainter);
 
718
    d->updateState(d->state);
 
719
 
 
720
    d->state = new QPainterState(d->states.back());
 
721
    d->states.push_back(d->state);
 
722
    d->engine->state = d->state;
 
723
}
 
724
 
 
725
/*!
 
726
    Restores the current painter state (pops a saved state off the
 
727
    stack).
 
728
 
 
729
    \sa save()
 
730
*/
 
731
 
 
732
void QPainter::restore()
 
733
{
 
734
#ifdef QT_DEBUG_DRAW
 
735
    if (qt_show_painter_debug_output)
 
736
        printf("QPainter::restore()\n");
 
737
#endif
 
738
    Q_D(QPainter);
 
739
    if (d->states.size()<=1) {
 
740
        qWarning("QPainter::restore(), unbalanced save/restore");
 
741
        return;
 
742
    } else if (!isActive()) {
 
743
        qWarning("QPainter::restore(), painter not active");
 
744
        return;
 
745
    }
 
746
 
 
747
    QPainterState *tmp = d->state;
 
748
    d->states.pop_back();
 
749
    d->state = d->states.back();
 
750
    d->txinv = false;
 
751
 
 
752
    // trigger clip update if the clip path/region has changed since
 
753
    // last save
 
754
    if (!d->state->clipInfo.isEmpty()
 
755
        && (tmp->changeFlags & (QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyClipPath))) {
 
756
        d->state->clipRegion = clipRegion();
 
757
        d->state->clipOperation = Qt::ReplaceClip;
 
758
        //Since we're updating the clip region anyway, pretend that the clip path hasn't changed:
 
759
        d->state->dirtyFlags &= ~QPaintEngine::DirtyClipPath;
 
760
        d->state->dirtyFlags |= QPaintEngine::DirtyClipRegion;
 
761
    }
 
762
 
 
763
    d->updateState(d->state);
 
764
    delete tmp;
 
765
}
 
766
 
 
767
 
 
768
/*!
 
769
    Begins painting the paint device \a pd and returns true if
 
770
    successful; otherwise returns false.
 
771
 
 
772
    The errors that can occur are serious problems, such as these:
 
773
 
 
774
    \code
 
775
        p->begin(0); // impossible - paint device cannot be 0
 
776
 
 
777
        QPixmap pm(0, 0);
 
778
        p->begin(&pm); // impossible - pm.isNull();
 
779
 
 
780
        p->begin(myWidget);
 
781
        p2->begin(myWidget); // impossible - only one painter at a time
 
782
    \endcode
 
783
 
 
784
    Note that most of the time, you can use one of the constructors
 
785
    instead of begin(), and that end() is automatically done at
 
786
    destruction.
 
787
 
 
788
    \warning A paint device can only be painted by one painter at a
 
789
    time.
 
790
 
 
791
    \sa end()
 
792
*/
 
793
 
 
794
bool QPainter::begin(QPaintDevice *pd)
 
795
{
 
796
    Q_ASSERT(pd);
 
797
 
 
798
    Q_D(QPainter);
 
799
    if (d->engine) {
 
800
        qWarning("QPainter::begin(): Painter is already active."
 
801
                 "\n\tYou must end() the painter before a second begin()");
 
802
        return false;
 
803
    }
 
804
 
 
805
    // Ensure fresh painter state
 
806
    d->state->init(d->state->painter);
 
807
 
 
808
    QPaintDevice *originalDevice = pd;
 
809
    QPaintDevice *rpd = redirected(pd, &d->redirection_offset);
 
810
 
 
811
    if (rpd) {
 
812
        pd = rpd;
 
813
    }
 
814
 
 
815
#ifdef QT_DEBUG_DRAW
 
816
    if (qt_show_painter_debug_output)
 
817
        printf("QPainter::begin(), device=%p, type=%d\n", pd, pd->devType());
 
818
#endif
 
819
 
 
820
 
 
821
    d->state->bgOrigin = QPointF();
 
822
 
 
823
    d->device = pd;
 
824
    d->engine = pd->paintEngine();
 
825
 
 
826
    if (!d->engine) {
 
827
        qWarning("QPainter::begin(), paintdevice returned engine == 0, type: %d\n", pd->devType());
 
828
        return true;
 
829
    }
 
830
 
 
831
    switch (pd->devType()) {
 
832
        case QInternal::Widget:
 
833
        {
 
834
            const QWidget *widget = static_cast<const QWidget *>(pd);
 
835
            Q_ASSERT(widget);
 
836
 
 
837
            if(!d->engine->hasFeature(QPaintEngine::PaintOutsidePaintEvent)
 
838
               && !widget->testAttribute(Qt::WA_PaintOutsidePaintEvent)
 
839
               && !widget->testAttribute(Qt::WA_WState_InPaintEvent)) {
 
840
                qWarning("QPainter::begin: Widget painting can only begin as a "
 
841
                         "result of a paintEvent");
 
842
                return false;
 
843
            }
 
844
            d->state->ww = d->state->vw = widget->width();
 
845
            d->state->wh = d->state->vh = widget->height();
 
846
            break;
 
847
        }
 
848
        case QInternal::Pixmap:
 
849
        {
 
850
            const QPixmap *pm = static_cast<const QPixmap *>(pd);
 
851
            Q_ASSERT(pm);
 
852
            const_cast<QPixmap *>(pm)->detach();
 
853
            d->state->ww = d->state->vw = pm->width();
 
854
            d->state->wh = d->state->vh = pm->height();
 
855
            if (pm->depth() == 1) {
 
856
                d->state->pen = QPen(Qt::color1);
 
857
                d->state->brush = QBrush(Qt::color0);
 
858
            }
 
859
            break;
 
860
        }
 
861
        default:
 
862
        {
 
863
            d->state->ww = d->state->vw = pd->metric(QPaintDevice::PdmWidth);
 
864
            d->state->wh = d->state->vh = pd->metric(QPaintDevice::PdmHeight);
 
865
        }
 
866
    }
 
867
 
 
868
    // Copy painter properties from original paint device,
 
869
    // required for QPixmap::grabWidget()
 
870
    if (originalDevice->devType() == QInternal::Widget) {
 
871
        QWidget *widget = static_cast<QWidget *>(originalDevice);
 
872
        d->state->deviceFont = widget->font();
 
873
        d->state->pen = widget->palette().color(widget->foregroundRole());
 
874
        d->state->bgBrush = widget->palette().brush(widget->backgroundRole());
 
875
        const QWidget *w = static_cast<const QWidget *>(originalDevice);;
 
876
        while (w->d_func()->isBackgroundInherited()) {
 
877
            d->state->bgOrigin -= w->pos();
 
878
            w = w->parentWidget();
 
879
        }
 
880
    }
 
881
 
 
882
    // make sure we have a font compatible with the paintdevice
 
883
    d->state->deviceFont = d->state->font = QFont(d->state->deviceFont, d->device);
 
884
 
 
885
    if (d->state->ww == 0) // For compat with 3.x painter defaults
 
886
        d->state->ww = d->state->wh = d->state->vw = d->state->vh = 1024;
 
887
 
 
888
    // Slip a painter state into the engine before we do any other operations
 
889
    d->engine->state = d->state;
 
890
 
 
891
    d->engine->setPaintDevice(pd);
 
892
 
 
893
    bool begun = d->engine->begin(pd);
 
894
    if (!begun) {
 
895
        qWarning("QPainter::begin(), QPaintEngine::begin() returned false\n");
 
896
        return false;
 
897
    } else {
 
898
        d->engine->setActive(begun);
 
899
    }
 
900
 
 
901
    d->redirection_offset += d->engine->coordinateOffset();
 
902
 
 
903
    Q_ASSERT(d->engine->isActive());
 
904
 
 
905
    if (!d->redirection_offset.isNull())
 
906
        d->updateMatrix();
 
907
 
 
908
    Q_ASSERT(d->engine->isActive());
 
909
    d->state->renderHints = QPainter::TextAntialiasing;
 
910
    ++d->device->painters;
 
911
 
 
912
    d->state->emulationSpecifier = 0;
 
913
 
 
914
    return true;
 
915
}
 
916
 
 
917
/*!
 
918
    Ends painting. Any resources used while painting are released. You
 
919
    don't normally need to call this since it is called by the
 
920
    destructor.
 
921
 
 
922
    \sa begin(), isActive()
 
923
*/
 
924
 
 
925
bool QPainter::end()
 
926
{
 
927
#ifdef QT_DEBUG_DRAW
 
928
    if (qt_show_painter_debug_output)
 
929
        printf("QPainter::end()\n");
 
930
#endif
 
931
 
 
932
    if (!isActive()) {
 
933
        qWarning("QPainter::end: Painter is not active, aborted");
 
934
        return false;
 
935
    }
 
936
 
 
937
    Q_D(QPainter);
 
938
    if (d->states.size()>1) {
 
939
        qWarning("QPainter::end(), painter ended with %d saved states",
 
940
                 d->states.size());
 
941
    }
 
942
 
 
943
    bool ended = d->engine->end();
 
944
    d->updateState(0);
 
945
    d->engine->setPaintDevice(0);
 
946
 
 
947
    if (d->engine->autoDestruct()) {
 
948
        delete d->engine;
 
949
    }
 
950
 
 
951
    d->engine = 0;
 
952
 
 
953
    --d->device->painters;
 
954
    return ended;
 
955
}
 
956
 
 
957
 
 
958
/*!
 
959
    If the painter is active, returns the paint engine that the painter is
 
960
    currently operating on;  otherwise 0.
 
961
 
 
962
*/
 
963
QPaintEngine *QPainter::paintEngine() const
 
964
{
 
965
    Q_D(const QPainter);
 
966
    return d->engine;
 
967
}
 
968
 
 
969
 
 
970
/*!
 
971
    If the painter is active, returns the font metrics for the painter. If the
 
972
    painter is not active, the return value is undefined.
 
973
 
 
974
    \sa fontInfo(), isActive()
 
975
*/
 
976
 
 
977
QFontMetrics QPainter::fontMetrics() const
 
978
{
 
979
    Q_D(const QPainter);
 
980
    return QFontMetrics(d->state->font);
 
981
}
 
982
 
 
983
 
 
984
/*!
 
985
    If the painter is active, returns the font info for the painter. If the
 
986
    painter is not active, the return value is undefined.
 
987
 
 
988
    \sa fontMetrics(), isActive()
 
989
*/
 
990
 
 
991
QFontInfo QPainter::fontInfo() const
 
992
{
 
993
    Q_D(const QPainter);
 
994
    return QFontInfo(d->state->font);
 
995
}
 
996
 
 
997
/*!
 
998
    Returns the brush origin currently set.
 
999
 
 
1000
    \sa setBrushOrigin()
 
1001
*/
 
1002
 
 
1003
QPoint QPainter::brushOrigin() const
 
1004
{
 
1005
    Q_D(const QPainter);
 
1006
    return QPointF(d->state->bgOrigin).toPoint();
 
1007
}
 
1008
 
 
1009
/*!
 
1010
    \fn void QPainter::setBrushOrigin(const QPoint &p)
 
1011
 
 
1012
    \overload
 
1013
 
 
1014
    Sets the brush's origin to \a p.
 
1015
*/
 
1016
 
 
1017
/*!
 
1018
    \fn void QPainter::setBrushOrigin(int x, int y)
 
1019
 
 
1020
    \overload
 
1021
 
 
1022
    Sets the brush's origin to point (\a x, \a y).
 
1023
*/
 
1024
 
 
1025
/*!
 
1026
    Sets the brush origin to \a p.
 
1027
 
 
1028
    The brush origin specifies the (0, 0) coordinate of the painter's
 
1029
    brush. This setting only applies to pattern brushes and pixmap
 
1030
    brushes.
 
1031
 
 
1032
    \sa brushOrigin()
 
1033
*/
 
1034
 
 
1035
void QPainter::setBrushOrigin(const QPointF &p)
 
1036
{
 
1037
    Q_D(QPainter);
 
1038
#ifdef QT_DEBUG_DRAW
 
1039
    if (qt_show_painter_debug_output)
 
1040
        printf("QPainter::setBrushOrigin(), (%.2f,%.2f)\n", p.x(), p.y());
 
1041
#endif
 
1042
    d->state->bgOrigin = p;
 
1043
    d->state->dirtyFlags |= QPaintEngine::DirtyBrushOrigin;
 
1044
}
 
1045
 
 
1046
/*!
 
1047
  \enum QPainter::CompositionMode
 
1048
 
 
1049
  Defines one of the Porter-Duff composition operations. Composition
 
1050
  modes are used to specify how a source and destination pixel are
 
1051
  merged together.
 
1052
 
 
1053
  The most common type is SourceOver (often referred to as just alpha
 
1054
  blending) where the source pixel is blended on top of the
 
1055
  destination pixel in such a way that the alpha component of the
 
1056
  source defines the translucensy of the pixel.
 
1057
 
 
1058
  Porter Duff operator will only work when the paint device is a
 
1059
  QImage in Format::ARGB32_Premultiplied or Format::ARGB32, where
 
1060
  the premultiplied version is the preferred format.
 
1061
 
 
1062
  When a composition mode is set it applies to all painting
 
1063
  operator, pens, brushes, gradients and pixmap/image drawing.
 
1064
 
 
1065
  \value CompositionMode_SourceOver This is the default mode. The
 
1066
  alpha of the source is used to blend the pixel on top of the
 
1067
  destination.
 
1068
 
 
1069
  \value CompositionMode_DestinationOver The alpha of the destination
 
1070
  is used to blend it on top of the source pixels. This mode is
 
1071
  the inverse of CompositionMode_SourceOver.
 
1072
 
 
1073
  \value CompositionMode_Clear The pixels in the destination are
 
1074
  cleared (set to fully transparent) independent of the source.
 
1075
 
 
1076
  \value CompositionMode_Source The output is the source pixel. (This
 
1077
  means a basic copy operation and is identical to SourceOver when the
 
1078
  source pixel is opaque).
 
1079
 
 
1080
  \value CompositionMode_Destination The output is the destination
 
1081
  pixel. This means that the blending has no effect. This mode is
 
1082
  the inverse of CompositionMode_Source.
 
1083
 
 
1084
  \value CompositionMode_SourceIn The output is the source, where the
 
1085
  alpha is reduced by that of the destination.
 
1086
 
 
1087
  \value CompositionMode_DestinationIn The output is the destination,
 
1088
  where the alpha is reduced by that of the source. This mode is the
 
1089
  inverse of CompositionMode_SourceIn.
 
1090
 
 
1091
  \value CompositionMode_SourceOut The output is the source, where the
 
1092
  alpha is reduced by the inverse of destination.
 
1093
 
 
1094
  \value CompositionMode_DestinationOut The output is the
 
1095
  destionation, where the alpha is reduced byt eh inverse of the
 
1096
  source. This mode is the inverse of Compositionmode_SourceOut.
 
1097
 
 
1098
  \value CompositionMode_SourceAtop The source pixel is blended on top
 
1099
  of the destination, with the alpha of the source pixel reduced by
 
1100
  the alpha of the destination pixel.
 
1101
 
 
1102
  \value CompositionMode_DestinationAtop The destination pixel is
 
1103
  blended on top of the source, with the alpha of the destination
 
1104
  pixel is reduced by the alpha of the destination pixel. This mode is
 
1105
  the inverse of CompositionMode_SourceAtop.
 
1106
 
 
1107
  \value CompositionMode_Xor The source which alpha reduced with the
 
1108
  inverse of the destination is merged with the destination which
 
1109
  alpha is reduced by the inverse of the source.
 
1110
 
 
1111
*/
 
1112
 
 
1113
/*!
 
1114
  Sets the composition mode to \a mode.
 
1115
 
 
1116
  \warning Not all paintdevices support non default composition modes.
 
1117
 
 
1118
  \sa QPainter::CompositionMode QPaintEngine::PaintEngineFeature
 
1119
*/
 
1120
void QPainter::setCompositionMode(CompositionMode mode)
 
1121
{
 
1122
    Q_D(QPainter);
 
1123
    if (!isActive()) {
 
1124
        qWarning("QPainter::setCompositionMode(), painter not active");
 
1125
        return;
 
1126
    } else if (!d->engine->hasFeature(QPaintEngine::PorterDuff)) {
 
1127
        qWarning("QPainter::setCompositionMode(), composition modes not supported on device");
 
1128
        return;
 
1129
    }
 
1130
 
 
1131
    d->state->composition_mode = mode;
 
1132
    d->state->dirtyFlags |= QPaintEngine::DirtyCompositionMode;
 
1133
}
 
1134
 
 
1135
/*!
 
1136
  Resturns the current composition mode.
 
1137
 
 
1138
  \sa QPainter::CompositionMode setCompositionMode()
 
1139
*/
 
1140
QPainter::CompositionMode QPainter::compositionMode() const
 
1141
{
 
1142
    Q_D(const QPainter);
 
1143
    return d->state->composition_mode;
 
1144
}
 
1145
 
 
1146
/*!
 
1147
    Returns the current background brush.
 
1148
 
 
1149
    \sa setBackground() QBrush
 
1150
*/
 
1151
 
 
1152
const QBrush &QPainter::background() const
 
1153
{
 
1154
    Q_D(const QPainter);
 
1155
    return d->state->bgBrush;
 
1156
}
 
1157
 
 
1158
 
 
1159
/*!
 
1160
    Returns true if clipping has been set; otherwise returns false.
 
1161
 
 
1162
    \sa setClipping()
 
1163
*/
 
1164
 
 
1165
bool QPainter::hasClipping() const
 
1166
{
 
1167
    Q_D(const QPainter);
 
1168
    return d->state->clipOperation != Qt::NoClip;
 
1169
}
 
1170
 
 
1171
 
 
1172
/*!
 
1173
    Enables clipping if \a enable is true, or disables clipping if \a
 
1174
    enable is false.
 
1175
 
 
1176
    \sa hasClipping(), setClipRect(), setClipRegion()
 
1177
*/
 
1178
 
 
1179
void QPainter::setClipping(bool enable)
 
1180
{
 
1181
    Q_D(QPainter);
 
1182
#ifdef QT_DEBUG_DRAW
 
1183
    if (qt_show_painter_debug_output)
 
1184
        printf("QPainter::setClipping(), enable=%s, was=%s\n",
 
1185
               enable ? "on" : "off",
 
1186
               hasClipping() ? "on" : "off");
 
1187
#endif
 
1188
    if (!isActive()) {
 
1189
        qWarning("QPainter::setClipping(), painter not active, state will be reset by begin");
 
1190
        return;
 
1191
    }
 
1192
 
 
1193
    if (hasClipping() == enable)
 
1194
        return;
 
1195
 
 
1196
    if (enable) {
 
1197
        d->state->clipRegion = clipRegion();
 
1198
        d->state->clipOperation = Qt::ReplaceClip;
 
1199
    } else {
 
1200
        d->state->clipRegion = QRegion();
 
1201
        d->state->clipOperation = Qt::NoClip;
 
1202
    }
 
1203
    d->state->dirtyFlags |= QPaintEngine::DirtyClipRegion;
 
1204
    d->updateState(d->state);
 
1205
}
 
1206
 
 
1207
 
 
1208
/*!
 
1209
    Returns the currently set clip region. Note that the clip region
 
1210
    is given in logical coordinates and \e subject to
 
1211
    \link coordsys.html coordinate transformation \endlink.
 
1212
 
 
1213
    \sa setClipRegion(), setClipRect(), setClipping()
 
1214
*/
 
1215
 
 
1216
QRegion QPainter::clipRegion() const
 
1217
{
 
1218
    if (!isActive()) {
 
1219
        qWarning("QPainter::clipRegion(), painter not active");
 
1220
        return QRegion();
 
1221
    }
 
1222
 
 
1223
    Q_D(const QPainter);
 
1224
    QRegion region;
 
1225
    bool lastWasNothing = true;
 
1226
 
 
1227
    if (!d->txinv)
 
1228
        const_cast<QPainter *>(this)->d_ptr->updateInvMatrix();
 
1229
 
 
1230
    for (int i=0; i<d->state->clipInfo.size(); ++i) {
 
1231
        const QPainterClipInfo &info = d->state->clipInfo.at(i);
 
1232
        QRegion other;
 
1233
        switch (info.clipType) {
 
1234
 
 
1235
        case QPainterClipInfo::RegionClip: {
 
1236
            QMatrix matrix = (info.matrix * d->invMatrix);
 
1237
            if (lastWasNothing) {
 
1238
                region = info.region * matrix;
 
1239
                lastWasNothing = false;
 
1240
                continue;
 
1241
            }
 
1242
            if (info.operation == Qt::IntersectClip)
 
1243
                region &= info.region * matrix;
 
1244
            else if (info.operation == Qt::UniteClip)
 
1245
                region |= info.region * matrix;
 
1246
            else if (info.operation == Qt::NoClip) {
 
1247
                lastWasNothing = true;
 
1248
                region = QRegion();
 
1249
            } else
 
1250
                region = info.region * matrix;
 
1251
            break;
 
1252
        }
 
1253
 
 
1254
        case QPainterClipInfo::PathClip: {
 
1255
            QMatrix matrix = (info.matrix * d->invMatrix);
 
1256
            if (lastWasNothing) {
 
1257
                region = QRegion((info.path * matrix).toFillPolygon().toPolygon(),
 
1258
                                 info.path.fillRule());
 
1259
                lastWasNothing = false;
 
1260
                continue;
 
1261
            }
 
1262
            if (info.operation == Qt::IntersectClip) {
 
1263
                region &= QRegion((info.path * matrix).toFillPolygon().toPolygon(),
 
1264
                                  info.path.fillRule());
 
1265
            } else if (info.operation == Qt::UniteClip) {
 
1266
                region |= QRegion((info.path * matrix).toFillPolygon().toPolygon(),
 
1267
                                  info.path.fillRule());
 
1268
            } else if (info.operation == Qt::NoClip) {
 
1269
                lastWasNothing = true;
 
1270
                region = QRegion();
 
1271
            } else {
 
1272
                region = QRegion((info.path * matrix).toFillPolygon().toPolygon(),
 
1273
                                 info.path.fillRule());
 
1274
            }
 
1275
            break;
 
1276
        }
 
1277
        }
 
1278
    }
 
1279
 
 
1280
    return region;
 
1281
}
 
1282
 
 
1283
/*!
 
1284
    Returns the currently clip as a path. Note that the clip path is
 
1285
    given in logical coordinates and \e subject to \link coordsys.html
 
1286
    coordinate transformation \endlink
 
1287
*/
 
1288
QPainterPath QPainter::clipPath() const
 
1289
{
 
1290
    // ### Since we do not support path intersections and path unions yet,
 
1291
    // we just use clipRegion() here...
 
1292
    if (!isActive()) {
 
1293
        qWarning("QPainter::clipPath(), painter not active");
 
1294
        return QPainterPath();
 
1295
    }
 
1296
 
 
1297
    Q_D(const QPainter);
 
1298
    // No clip, return empty
 
1299
    if (d->state->clipInfo.size() == 0) {
 
1300
        return QPainterPath();
 
1301
    } else {
 
1302
 
 
1303
        // Update inverse matrix, used below.
 
1304
        if (!d->txinv)
 
1305
            const_cast<QPainter *>(this)->d_ptr->updateInvMatrix();
 
1306
 
 
1307
        // For the simple case avoid conversion.
 
1308
        if (d->state->clipInfo.size() == 1
 
1309
            && d->state->clipInfo.at(0).clipType == QPainterClipInfo::PathClip) {
 
1310
            QMatrix matrix = (d->state->clipInfo.at(0).matrix * d->invMatrix);
 
1311
            return d->state->clipInfo.at(0).path * matrix;
 
1312
 
 
1313
        // Fallback to clipRegion() for now, since we don't have isect/unite for paths
 
1314
        } else {
 
1315
            QPainterPath path;
 
1316
            path.addRegion(clipRegion());
 
1317
            return path;
 
1318
        }
 
1319
    }
 
1320
}
 
1321
 
 
1322
/*!
 
1323
    \fn void QPainter::setClipRect(const QRect &rect, Qt::ClipOperation op)
 
1324
 
 
1325
    Sets the clip region to the rectangle \a rect using the clip
 
1326
    operation \a op. The default operation is to replace the current
 
1327
    clip rectangle.
 
1328
 
 
1329
    \sa setClipRegion(), clipRegion(), setClipping()
 
1330
*/
 
1331
 
 
1332
/*!
 
1333
    \fn void QPainter::setClipRect(int x, int y, int w, int h, Qt::ClipOperation op)
 
1334
 
 
1335
    Sets the clip region to the rectangle \a x, \a y, \a w, \a h and
 
1336
    enables clipping.
 
1337
 
 
1338
    \sa setClipRegion(), clipRegion(), setClipping()
 
1339
*/
 
1340
 
 
1341
/*!
 
1342
    \overload
 
1343
 
 
1344
    Sets the clip region of the rectange \a rect.
 
1345
*/
 
1346
void QPainter::setClipRect(const QRectF &rect, Qt::ClipOperation op)
 
1347
{
 
1348
    QPainterPath path;
 
1349
    path.addRect(rect);
 
1350
    setClipPath(path, op);
 
1351
}
 
1352
 
 
1353
/*!
 
1354
    Sets the clip region to \a r using the clip operation \a op. The
 
1355
    default clip operation is to replace the current clip region.
 
1356
 
 
1357
    Note that the clip region is given in logical coordinates
 
1358
    and \e subject to \link coordsys.html coordinate
 
1359
    transformation.\endlink
 
1360
 
 
1361
    \sa setClipRect(), clipRegion(), setClipping()
 
1362
*/
 
1363
 
 
1364
void QPainter::setClipRegion(const QRegion &r, Qt::ClipOperation op)
 
1365
{
 
1366
    Q_D(QPainter);
 
1367
#ifdef QT_DEBUG_DRAW
 
1368
    QRect rect = r.boundingRect();
 
1369
    if (qt_show_painter_debug_output)
 
1370
        printf("QPainter::setClipRegion(), size=%d, [%d,%d,%d,%d]\n",
 
1371
           r.rects().size(), rect.x(), rect.y(), rect.width(), rect.height());
 
1372
#endif
 
1373
    Q_ASSERT(op != Qt::NoClip);
 
1374
    if (!isActive()) {
 
1375
        qWarning("QPainter::setClipRegion(); painter not active");
 
1376
        return;
 
1377
    }
 
1378
 
 
1379
    d->state->clipRegion = r;
 
1380
    d->state->clipOperation = op;
 
1381
    if (op == Qt::NoClip || op == Qt::ReplaceClip)
 
1382
        d->state->clipInfo.clear();
 
1383
    d->state->clipInfo << QPainterClipInfo(r, op, d->state->worldMatrix);
 
1384
    d->state->dirtyFlags |= QPaintEngine::DirtyClipRegion;
 
1385
    d->updateState(d->state);
 
1386
}
 
1387
 
 
1388
/*!
 
1389
    Sets the transformation matrix to \a matrix and enables transformations.
 
1390
 
 
1391
    If \a combine is true, then \a matrix is combined with the current
 
1392
    transformation matrix; otherwise \a matrix replaces the current
 
1393
    transformation matrix.
 
1394
 
 
1395
    If \a matrix is the identity matrix and \a combine is false, this
 
1396
    function calls setMatrixEnabled(false). (The identity matrix is the
 
1397
    matrix where QMatrix::m11() and QMatrix::m22() are 1.0 and the
 
1398
    rest are 0.0.)
 
1399
 
 
1400
    World transformations are applied after the view transformations
 
1401
    (i.e. \link setWindow() window\endlink and \link setViewport()
 
1402
    viewport\endlink).
 
1403
 
 
1404
    The following functions can transform the coordinate system without using
 
1405
    a QMatrix:
 
1406
    \list
 
1407
    \i translate()
 
1408
    \i scale()
 
1409
    \i shear()
 
1410
    \i rotate()
 
1411
    \endlist
 
1412
 
 
1413
    They operate on the painter's worldMatrix() and are implemented like this:
 
1414
 
 
1415
    \code
 
1416
        void QPainter::rotate(qreal a)
 
1417
        {
 
1418
            QMatrix m;
 
1419
            m.rotate(a);
 
1420
            setMatrix(m, true);
 
1421
        }
 
1422
    \endcode
 
1423
 
 
1424
    Note that you should always have \a combine be true when you are drawing
 
1425
    into a QPicture. Otherwise it may not be possible to replay the
 
1426
    picture with additional transformations. Using translate(),
 
1427
    scale(), etc., is safe.
 
1428
 
 
1429
    For a brief overview of coordinate transformation, see the \link
 
1430
    coordsys.html Coordinate System Overview. \endlink
 
1431
 
 
1432
    \sa matrix(), setMatrixEnabled(), QMatrix
 
1433
*/
 
1434
 
 
1435
void QPainter::setMatrix(const QMatrix &matrix, bool combine)
 
1436
{
 
1437
    Q_D(QPainter);
 
1438
#ifdef QT_DEBUG_DRAW
 
1439
    if (qt_show_painter_debug_output)
 
1440
        printf("QPainter::setMatrix(), combine=%d\n", combine);
 
1441
#endif
 
1442
 
 
1443
   if (!isActive()) {
 
1444
        qWarning("QPainter::setMatrix(), painter not active ");
 
1445
        return;
 
1446
    }
 
1447
 
 
1448
    if (combine)
 
1449
        d->state->worldMatrix = matrix * d->state->worldMatrix;                        // combines
 
1450
    else
 
1451
        d->state->worldMatrix = matrix;                                // set new matrix
 
1452
 
 
1453
    if (!d->state->WxF)
 
1454
        setMatrixEnabled(true);
 
1455
    else
 
1456
        d->updateMatrix();
 
1457
}
 
1458
 
 
1459
/*!
 
1460
    Returns the world transformation matrix.
 
1461
 
 
1462
    \sa setMatrix()
 
1463
*/
 
1464
 
 
1465
const QMatrix &QPainter::matrix() const
 
1466
{
 
1467
    Q_D(const QPainter);
 
1468
    return d->state->worldMatrix;
 
1469
}
 
1470
 
 
1471
 
 
1472
/*!
 
1473
    Returns the matrix that transforms from logical coordinates to
 
1474
    device coordinates of the platform dependent paintdevice.
 
1475
 
 
1476
    This function is ONLY needed when using platform painting commands
 
1477
    on the platform dependent handle, and the platform does not do
 
1478
    transformations nativly.
 
1479
 
 
1480
    \sa matrix(), QPaintEngine::hasFeature()
 
1481
*/
 
1482
const QMatrix &QPainter::deviceMatrix() const
 
1483
{
 
1484
    Q_D(const QPainter);
 
1485
    return d->state->matrix;
 
1486
}
 
1487
 
 
1488
/*!
 
1489
    Resets any transformations that were made using translate(), scale(),
 
1490
    shear(), rotate(), setMatrix(), setViewport() and
 
1491
    setWindow().
 
1492
 
 
1493
    \sa matrix(), setMatrix()
 
1494
*/
 
1495
void QPainter::resetMatrix()
 
1496
{
 
1497
    Q_D(QPainter);
 
1498
#ifdef QT_DEBUG_DRAW
 
1499
    if (qt_show_painter_debug_output)
 
1500
        printf("QPainter::resetMatrix()\n");
 
1501
#endif
 
1502
    if (!isActive()) {
 
1503
        qWarning("QPainter::resetMatrix(), painter not active");
 
1504
        return;
 
1505
    }
 
1506
 
 
1507
    d->state->wx = d->state->wy = d->state->vx = d->state->vy = 0;                        // default view origins
 
1508
    d->state->ww = d->state->vw = d->device->metric(QPaintDevice::PdmWidth);
 
1509
    d->state->wh = d->state->vh = d->device->metric(QPaintDevice::PdmHeight);
 
1510
    d->state->worldMatrix = QMatrix();
 
1511
    setMatrixEnabled(false);
 
1512
    setViewTransformEnabled(false);
 
1513
    if (d->engine)
 
1514
        d->engine->setDirty(QPaintEngine::DirtyTransform);
 
1515
}
 
1516
 
 
1517
 
 
1518
/*!
 
1519
    Enables transformations if \a enable is true, or disables
 
1520
    world transformations if \a enable is false. The world
 
1521
    transformation matrix is not changed.
 
1522
 
 
1523
    \sa setMatrix(), matrix()
 
1524
*/
 
1525
 
 
1526
void QPainter::setMatrixEnabled(bool enable)
 
1527
{
 
1528
    Q_D(QPainter);
 
1529
#ifdef QT_DEBUG_DRAW
 
1530
    if (qt_show_painter_debug_output)
 
1531
        printf("QPainter::setMatrixEnabled(), enable=%d\n", enable);
 
1532
#endif
 
1533
 
 
1534
    if (!isActive()) {
 
1535
        qWarning("QPainter::setMatrixEnabled(), painter not active");
 
1536
        return;
 
1537
    }
 
1538
    if (enable == d->state->WxF)
 
1539
        return;
 
1540
 
 
1541
    d->state->WxF = enable;
 
1542
    d->updateMatrix();
 
1543
}
 
1544
 
 
1545
/*!
 
1546
    Returns true if world transformation is enabled; otherwise returns
 
1547
    false.
 
1548
 
 
1549
    \sa setMatrixEnabled(), setMatrix()
 
1550
*/
 
1551
 
 
1552
bool QPainter::matrixEnabled() const
 
1553
{
 
1554
    Q_D(const QPainter);
 
1555
#ifndef QT_NO_TRANSFORMATIONS
 
1556
    return d->state->WxF;
 
1557
#else
 
1558
    return d->state->xlatex || d->state->xlatey;
 
1559
#endif
 
1560
}
 
1561
 
 
1562
#ifndef QT_NO_TRANSFORMATIONS
 
1563
/*!
 
1564
    Scales the coordinate system by (\a{sx}, \a{sy}).
 
1565
 
 
1566
    \sa translate(), shear(), rotate(), resetXForm(), setMatrix(),
 
1567
    xForm()
 
1568
*/
 
1569
 
 
1570
void QPainter::scale(qreal sx, qreal sy)
 
1571
{
 
1572
#ifdef QT_DEBUG_DRAW
 
1573
    if (qt_show_painter_debug_output)
 
1574
        printf("QPainter::scale(), sx=%f, sy=%f\n", sx, sy);
 
1575
#endif
 
1576
 
 
1577
    QMatrix m;
 
1578
    m.scale(sx, sy);
 
1579
    setMatrix(m, true);
 
1580
}
 
1581
 
 
1582
/*!
 
1583
    Shears the coordinate system by (\a{sh}, \a{sv}).
 
1584
 
 
1585
    \sa translate(), scale(), rotate(), resetXForm(), setMatrix(),
 
1586
    xForm()
 
1587
*/
 
1588
 
 
1589
void QPainter::shear(qreal sh, qreal sv)
 
1590
{
 
1591
#ifdef QT_DEBUG_DRAW
 
1592
    if (qt_show_painter_debug_output)
 
1593
        printf("QPainter::shear(), sh=%f, sv=%f\n", sh, sv);
 
1594
#endif
 
1595
    QMatrix m;
 
1596
    m.shear(sv, sh);
 
1597
    setMatrix(m, true);
 
1598
}
 
1599
 
 
1600
/*!
 
1601
    Rotates the coordinate system \a a degrees clockwise.
 
1602
 
 
1603
    \sa translate(), scale(), shear(), resetXForm(), setMatrix(),
 
1604
    xForm()
 
1605
*/
 
1606
 
 
1607
void QPainter::rotate(qreal a)
 
1608
{
 
1609
#ifdef QT_DEBUG_DRAW
 
1610
    if (qt_show_painter_debug_output)
 
1611
        printf("QPainter::rotate(), angle=%f\n", a);
 
1612
#endif
 
1613
    QMatrix m;
 
1614
    m.rotate(a);
 
1615
    setMatrix(m, true);
 
1616
}
 
1617
#endif
 
1618
 
 
1619
 
 
1620
/*!
 
1621
    \fn void QPainter::translate(qreal dx, qreal dy)
 
1622
 
 
1623
    \overload
 
1624
 
 
1625
    Translates the coordinate system by the vector (\a dx, \a dy).
 
1626
*/
 
1627
 
 
1628
/*!
 
1629
    \fn void QPainter::translate(const QPoint &offset)
 
1630
 
 
1631
    \overload
 
1632
 
 
1633
    Translates the coordinate system by the given \a offset.
 
1634
*/
 
1635
 
 
1636
/*!
 
1637
    Translates the coordinate system by \a offset. After this call,
 
1638
    \a offset is added to points.
 
1639
 
 
1640
    For example, the following code draws the same point twice:
 
1641
    \code
 
1642
        void MyWidget::paintEvent()
 
1643
        {
 
1644
            QPainter paint(this);
 
1645
 
 
1646
            paint.drawPoint(0, 0);
 
1647
 
 
1648
            paint.translate(100.0, 40.0);
 
1649
            paint.drawPoint(-100, -40);
 
1650
        }
 
1651
    \endcode
 
1652
 
 
1653
    \sa scale(), shear(), rotate(), resetXForm(), setMatrix(), xForm()
 
1654
*/
 
1655
 
 
1656
void QPainter::translate(const QPointF &offset)
 
1657
{
 
1658
    qreal dx = offset.x();
 
1659
    qreal dy = offset.y();
 
1660
#ifdef QT_DEBUG_DRAW
 
1661
    if (qt_show_painter_debug_output)
 
1662
        printf("QPainter::translate(), dx=%f, dy=%f\n", dx, dy);
 
1663
#endif
 
1664
 
 
1665
#ifndef QT_NO_TRANSFORMATIONS
 
1666
    QMatrix m;
 
1667
    m.translate(dx, dy);
 
1668
    setMatrix(m, true);
 
1669
#else
 
1670
    xlatex += (int)dx;
 
1671
    xlatey += (int)dy;
 
1672
    d->state->VxF = (bool)xlatex || xlatey;
 
1673
#endif
 
1674
}
 
1675
 
 
1676
/*!
 
1677
    Sets the clip path for the painter to \a path, with the clip
 
1678
    operation \a op.
 
1679
 
 
1680
    The clip path is specified in logical (painter) coordinates.
 
1681
 
 
1682
*/
 
1683
void QPainter::setClipPath(const QPainterPath &path, Qt::ClipOperation op)
 
1684
{
 
1685
#ifdef QT_DEBUG_DRAW
 
1686
    if (qt_show_painter_debug_output) {
 
1687
        QRectF b = path.boundingRect();
 
1688
        printf("QPainter::setClipPath(), size=%d, op=%d, bounds=[%.2f,%.2f,%.2f,%.2f]\n",
 
1689
               path.elementCount(), op, b.x(), b.y(), b.width(), b.height());
 
1690
    }
 
1691
#endif
 
1692
    if (!isActive())
 
1693
        return;
 
1694
 
 
1695
    Q_D(QPainter);
 
1696
 
 
1697
    d->state->clipPath = path;
 
1698
    d->state->clipOperation = op;
 
1699
    if (op == Qt::NoClip || op == Qt::ReplaceClip)
 
1700
        d->state->clipInfo.clear();
 
1701
    d->state->clipInfo << QPainterClipInfo(path, op, d->state->worldMatrix);
 
1702
    d->state->dirtyFlags |= QPaintEngine::DirtyClipPath;
 
1703
    d->updateState(d->state);
 
1704
}
 
1705
 
 
1706
/*!
 
1707
    Draws the outline (strokes) the path \a path with the pen specified
 
1708
    by \a pen
 
1709
*/
 
1710
void QPainter::strokePath(const QPainterPath &path, const QPen &pen)
 
1711
{
 
1712
    Q_D(QPainter);
 
1713
    QBrush oldBrush = d->state->brush;
 
1714
    QPen oldPen = d->state->pen;
 
1715
 
 
1716
    d->state->pen = pen;
 
1717
    d->state->brush = Qt::NoBrush;
 
1718
    d->engine->setDirty(QPaintEngine::DirtyFlags(QPaintEngine::DirtyPen | QPaintEngine::DirtyBrush));
 
1719
 
 
1720
    drawPath(path);
 
1721
 
 
1722
    // Reset old state
 
1723
    d->state->pen = oldPen;
 
1724
    d->state->brush = oldBrush;
 
1725
    d->engine->setDirty(QPaintEngine::DirtyFlags(QPaintEngine::DirtyPen | QPaintEngine::DirtyBrush));
 
1726
}
 
1727
 
 
1728
/*!
 
1729
    Fills the path \a path using the given \a brush. The outline
 
1730
    is not drawn.
 
1731
*/
 
1732
void QPainter::fillPath(const QPainterPath &path, const QBrush &brush)
 
1733
{
 
1734
    Q_D(QPainter);
 
1735
    QBrush oldBrush = d->state->brush;
 
1736
    QPen oldPen = d->state->pen;
 
1737
 
 
1738
    d->state->pen = Qt::NoPen;
 
1739
    d->state->brush = brush;
 
1740
    d->engine->setDirty(QPaintEngine::DirtyFlags(QPaintEngine::DirtyPen | QPaintEngine::DirtyBrush));
 
1741
 
 
1742
    drawPath(path);
 
1743
 
 
1744
    // Reset old state
 
1745
    d->state->pen = oldPen;
 
1746
    d->state->brush = oldBrush;
 
1747
    d->engine->setDirty(QPaintEngine::DirtyFlags(QPaintEngine::DirtyPen | QPaintEngine::DirtyBrush));
 
1748
}
 
1749
 
 
1750
/*!
 
1751
    Draws the painter path specified by \a path using the current pen
 
1752
    for outline and the current brush for filling.
 
1753
*/
 
1754
void QPainter::drawPath(const QPainterPath &path)
 
1755
{
 
1756
#ifdef QT_DEBUG_DRAW
 
1757
    QRectF pathBounds = path.boundingRect();
 
1758
    if (qt_show_painter_debug_output)
 
1759
        printf("QPainter::drawPath(), size=%d, [%.2f,%.2f,%.2f,%.2f]\n",
 
1760
               path.elementCount(),
 
1761
               pathBounds.x(), pathBounds.y(), pathBounds.width(), pathBounds.height());
 
1762
#endif
 
1763
 
 
1764
    if (!isActive())
 
1765
        return;
 
1766
 
 
1767
    Q_D(QPainter);
 
1768
    d->updateState(d->state);
 
1769
 
 
1770
    if (d->engine->hasFeature(QPaintEngine::PainterPaths) && d->state->emulationSpecifier == 0) {
 
1771
        d->engine->drawPath(path);
 
1772
    } else {
 
1773
        d->draw_helper(path);
 
1774
    }
 
1775
}
 
1776
 
 
1777
 
 
1778
/*!
 
1779
    \fn void QPainter::drawLines(const QVector<QLineF> &lines)
 
1780
 
 
1781
    Draws the set of lines defined by the list \a lines using the
 
1782
    current pen and brush.
 
1783
*/
 
1784
 
 
1785
/*!
 
1786
    \fn void QPainter::drawLines(const QVector<QLine> &lines)
 
1787
 
 
1788
    Draws the set of lines defined by the list \a lines using the
 
1789
    current pen and brush.
 
1790
*/
 
1791
 
 
1792
/*!
 
1793
    \fn void QPainter::drawLines(const QVector<QPoint> &pointPairs)
 
1794
 
 
1795
    Draws the set of lines defined by the vector of points specified by
 
1796
    \a pointPairs using the current pen and brush.
 
1797
*/
 
1798
 
 
1799
/*!
 
1800
    \fn void QPainter::drawLine(int x1, int y1, int x2, int y2)
 
1801
    \overload
 
1802
 
 
1803
    Draws a line from (\a x1, \a y1) to (\a x2, \a y2) and sets the
 
1804
    current pen position to (\a x2, \a y2).
 
1805
*/
 
1806
 
 
1807
/*!
 
1808
    \fn void QPainter::drawLine(const QPoint &p1, const QPoint &p2)
 
1809
    \overload
 
1810
 
 
1811
    Draws a line from \a p1 to \a p2.
 
1812
*/
 
1813
 
 
1814
/*!
 
1815
    \fn void QPainter::drawLine(const QPointF &p1, const QPointF &p2)
 
1816
    \overload
 
1817
 
 
1818
    Draws a line from \a p1 to \a p2.
 
1819
*/
 
1820
 
 
1821
/*!
 
1822
  \fn void QPainter::drawLine(const QLineF &line)
 
1823
 
 
1824
  Draws a line defined by \a line.
 
1825
 
 
1826
  \sa pen()
 
1827
*/
 
1828
 
 
1829
/*!
 
1830
  \fn void QPainter::drawLine(const QLine &line)
 
1831
 
 
1832
  \overload
 
1833
 
 
1834
  \sa pen()
 
1835
*/
 
1836
 
 
1837
/*!
 
1838
    \fn void QPainter::drawRect(int x, int y, int w, int h)
 
1839
 
 
1840
    \overload
 
1841
 
 
1842
    Draws a rectangle with upper left corner at (\a{x}, \a{y}) and with
 
1843
    width \a w and height \a h.
 
1844
*/
 
1845
 
 
1846
/*!
 
1847
    \fn void QPainter::drawRect(const QRect &rect)
 
1848
 
 
1849
    \overload
 
1850
 
 
1851
    Draws the rectangle \a rect with the current pen and brush.
 
1852
*/
 
1853
 
 
1854
/*!
 
1855
  \fn void QPainter::drawRect(const QRectF &r)
 
1856
 
 
1857
  Draws the rectangle \a r with the current pen and brush.
 
1858
 
 
1859
  A filled rectangle has a size of r.size(). A stroked rectangle
 
1860
  has a size of r.size() plus the pen width.
 
1861
*/
 
1862
 
 
1863
/*!
 
1864
    \fn void QPainter::drawRects(const QVector<QRectF> &rectangles)
 
1865
 
 
1866
    Draws the rectangles specified in \a rectangles using the
 
1867
    current pen and brush.
 
1868
*/
 
1869
 
 
1870
/*!
 
1871
    \fn void QPainter::drawRects(const QVector<QRect> &rectangles)
 
1872
 
 
1873
    Draws the rectangles specified in \a rectangles using the
 
1874
    current pen and brush.
 
1875
*/
 
1876
 
 
1877
/*!
 
1878
    Draws the first \a rectCount rectangles in the array \a rects
 
1879
    using the current pen and brush.
 
1880
 
 
1881
    \sa drawRect()
 
1882
*/
 
1883
void QPainter::drawRects(const QRectF *rects, int rectCount)
 
1884
{
 
1885
#ifdef QT_DEBUG_DRAW
 
1886
    if (qt_show_painter_debug_output)
 
1887
        printf("QPainter::drawRects(), count=%d\n", rectCount);
 
1888
#endif
 
1889
    if (!isActive() || rectCount <= 0)
 
1890
        return;
 
1891
 
 
1892
    Q_D(QPainter);
 
1893
    d->updateState(d->state);
 
1894
 
 
1895
    if (!d->state->emulationSpecifier) {
 
1896
        d->engine->drawRects(rects, rectCount);
 
1897
        return;
 
1898
    }
 
1899
 
 
1900
    if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
 
1901
        && d->state->txop == QPainterPrivate::TxTranslate) {
 
1902
        for (int i=0; i<rectCount; ++i) {
 
1903
            QRectF r(rects[i].x() + d->state->matrix.dx(),
 
1904
                     rects[i].y() + d->state->matrix.dy(),
 
1905
                     rects[i].width(),
 
1906
                     rects[i].height());
 
1907
            d->engine->drawRects(&r, 1);
 
1908
        }
 
1909
    } else {
 
1910
        QPainterPath rectPath;
 
1911
        for (int i=0; i<rectCount; ++i)
 
1912
            rectPath.addRect(rects[i]);
 
1913
        d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
 
1914
    }
 
1915
}
 
1916
 
 
1917
/*!
 
1918
    Draws the first \a rectCount rectangles in the array \a rects
 
1919
    using the current pen and brush.
 
1920
 
 
1921
    \sa drawRect()
 
1922
*/
 
1923
void QPainter::drawRects(const QRect *rects, int rectCount)
 
1924
{
 
1925
#ifdef QT_DEBUG_DRAW
 
1926
    if (qt_show_painter_debug_output)
 
1927
        printf("QPainter::drawRects(), count=%d\n", rectCount);
 
1928
#endif
 
1929
    if (!isActive() || rectCount <= 0)
 
1930
        return;
 
1931
 
 
1932
    Q_D(QPainter);
 
1933
    d->updateState(d->state);
 
1934
 
 
1935
    if (!d->state->emulationSpecifier) {
 
1936
        d->engine->drawRects(rects, rectCount);
 
1937
        return;
 
1938
    }
 
1939
 
 
1940
    if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
 
1941
        && d->state->txop == QPainterPrivate::TxTranslate) {
 
1942
        for (int i=0; i<rectCount; ++i) {
 
1943
            QRectF r(rects[i].x() + d->state->matrix.dx(),
 
1944
                     rects[i].y() + d->state->matrix.dy(),
 
1945
                     rects[i].width(),
 
1946
                     rects[i].height());
 
1947
            d->engine->drawRects(&r, 1);
 
1948
        }
 
1949
    } else {
 
1950
        QPainterPath rectPath;
 
1951
        for (int i=0; i<rectCount; ++i)
 
1952
            rectPath.addRect(rects[i]);
 
1953
        d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
 
1954
    }
 
1955
}
 
1956
 
 
1957
 
 
1958
/*! \fn void QPainter::drawPoint(const QPoint &p)
 
1959
    Draws a single point at position \a p using the current pen's color.
 
1960
 
 
1961
    \sa QPen
 
1962
*/
 
1963
 
 
1964
/*!
 
1965
  \fn void QPainter::drawPoint(const QPointF &p)
 
1966
 
 
1967
    Draws a single point at position \a p using the current pen's color.
 
1968
 
 
1969
    \sa QPen
 
1970
*/
 
1971
 
 
1972
/*! \fn void QPainter::drawPoint(int x, int y)
 
1973
 
 
1974
    \overload
 
1975
 
 
1976
    Draws a single point at position (\a x, \a y).
 
1977
*/
 
1978
 
 
1979
/*!
 
1980
    \fn void QPainter::drawPoints(const QPolygon &points, int index,
 
1981
    int npoints)
 
1982
 
 
1983
    \overload
 
1984
 
 
1985
    \compat
 
1986
 
 
1987
    Draws \a npoints points in the polygon \a points starting on \a index
 
1988
    using the current pen.
 
1989
 
 
1990
*/
 
1991
 
 
1992
/*! \fn void QPainter::drawPoints(const QPolygonF &points)
 
1993
 
 
1994
    \overload
 
1995
 
 
1996
    Draws the points in the list \a points.
 
1997
*/
 
1998
 
 
1999
/*!
 
2000
    Draws the first \a pointCount points in the array \a points using
 
2001
    the current pen's color.
 
2002
 
 
2003
    \sa QPen
 
2004
*/
 
2005
void QPainter::drawPoints(const QPointF *points, int pointCount)
 
2006
{
 
2007
#ifdef QT_DEBUG_DRAW
 
2008
    if (qt_show_painter_debug_output)
 
2009
        printf("QPainter::drawPoints(), count=%d\n", pointCount);
 
2010
#endif
 
2011
    if (!isActive() || pointCount <= 0)
 
2012
        return;
 
2013
    Q_D(QPainter);
 
2014
    d->updateState(d->state);
 
2015
 
 
2016
    if (!d->state->emulationSpecifier) {
 
2017
        d->engine->drawPoints(points, pointCount);
 
2018
        return;
 
2019
    }
 
2020
 
 
2021
    if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
 
2022
        && d->state->txop == QPainterPrivate::TxTranslate) {
 
2023
        // ### use drawPoints function
 
2024
        for (int i=0; i<pointCount; ++i) {
 
2025
            QPointF pt(points[i].x() + d->state->matrix.dx(),
 
2026
                       points[i].y() + d->state->matrix.dy());
 
2027
            d->engine->drawPoints(&pt, 1);
 
2028
        }
 
2029
    } else {
 
2030
        save();
 
2031
        setBrush(d->state->pen.color());
 
2032
        QPainterPath path;
 
2033
        for (int i=0; i<pointCount; ++i)
 
2034
            path.addRect(points[i].x(), points[i].y(), 1, 1);
 
2035
        d->draw_helper(path, QPainterPrivate::FillDraw);
 
2036
        restore();
 
2037
    }
 
2038
}
 
2039
 
 
2040
/*!
 
2041
    \overload
 
2042
 
 
2043
    Draws the first \a pointCount points in the array \a points using
 
2044
    the current pen's color.
 
2045
 
 
2046
    \sa QPen
 
2047
*/
 
2048
 
 
2049
void QPainter::drawPoints(const QPoint *points, int pointCount)
 
2050
{
 
2051
#ifdef QT_DEBUG_DRAW
 
2052
    if (qt_show_painter_debug_output)
 
2053
        printf("QPainter::drawPoints(), count=%d\n", pointCount);
 
2054
#endif
 
2055
    if (!isActive() || pointCount <= 0)
 
2056
        return;
 
2057
    Q_D(QPainter);
 
2058
    d->updateState(d->state);
 
2059
 
 
2060
    if (!d->state->emulationSpecifier) {
 
2061
        d->engine->drawPoints(points, pointCount);
 
2062
        return;
 
2063
    }
 
2064
 
 
2065
    if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
 
2066
        && d->state->txop == QPainterPrivate::TxTranslate) {
 
2067
        // ### use drawPoints function
 
2068
        for (int i=0; i<pointCount; ++i) {
 
2069
            QPointF pt(points[i].x() + d->state->matrix.dx(),
 
2070
                       points[i].y() + d->state->matrix.dy());
 
2071
            d->engine->drawPoints(&pt, 1);
 
2072
        }
 
2073
    } else {
 
2074
        save();
 
2075
        setBrush(d->state->pen.color());
 
2076
        QPainterPath path;
 
2077
        for (int i=0; i<pointCount; ++i)
 
2078
            path.addRect(points[i].x(), points[i].y(), 1, 1);
 
2079
        d->draw_helper(path, QPainterPrivate::FillDraw);
 
2080
        restore();
 
2081
    }
 
2082
}
 
2083
 
 
2084
/*!
 
2085
    Sets the background mode of the painter to \a mode, which must be
 
2086
    either \c Qt::TransparentMode (the default) or \c Qt::OpaqueMode.
 
2087
 
 
2088
    Transparent mode draws stippled lines and text without setting the
 
2089
    background pixels. Opaque mode fills these space with the current
 
2090
    background color.
 
2091
 
 
2092
    Note that in order to draw a bitmap or pixmap transparently, you
 
2093
    must use QPixmap::setMask().
 
2094
 
 
2095
    \sa backgroundMode(), setBackground()
 
2096
*/
 
2097
 
 
2098
void QPainter::setBackgroundMode(Qt::BGMode mode)
 
2099
{
 
2100
#ifdef QT_DEBUG_DRAW
 
2101
    if (qt_show_painter_debug_output)
 
2102
        printf("QPainter::setBackgroundMode(), mode=%d\n", mode);
 
2103
#endif
 
2104
 
 
2105
    if (mode != Qt::TransparentMode && mode != Qt::OpaqueMode) {
 
2106
        qWarning("QPainter::setBackgroundMode: Invalid mode");
 
2107
        return;
 
2108
    }
 
2109
    Q_D(QPainter);
 
2110
    d->state->bgMode = mode;
 
2111
    d->state->dirtyFlags |= QPaintEngine::DirtyBackgroundMode;
 
2112
}
 
2113
 
 
2114
/*!
 
2115
    Returns the current background mode.
 
2116
 
 
2117
    \sa setBackgroundMode() Qt::BGMode
 
2118
*/
 
2119
Qt::BGMode QPainter::backgroundMode() const
 
2120
{
 
2121
    Q_D(const QPainter);
 
2122
    return d->state->bgMode;
 
2123
}
 
2124
 
 
2125
 
 
2126
/*!
 
2127
    \overload
 
2128
 
 
2129
    Sets the painter's pen to have style \c Qt::SolidLine, width 0 and the
 
2130
    specified \a color.
 
2131
 
 
2132
    \sa pen(), QPen
 
2133
*/
 
2134
 
 
2135
void QPainter::setPen(const QColor &color)
 
2136
{
 
2137
#ifdef QT_DEBUG_DRAW
 
2138
    if (qt_show_painter_debug_output)
 
2139
        printf("QPainter::setPen(), color=%04x\n", color.rgb());
 
2140
#endif
 
2141
    setPen(QPen(color.isValid() ? color : QColor(Qt::black), 0, Qt::SolidLine));
 
2142
}
 
2143
 
 
2144
/*!
 
2145
    Sets a new painter pen.
 
2146
 
 
2147
    The \a pen defines how to draw lines and outlines, and it also
 
2148
    defines the text color.
 
2149
 
 
2150
    \sa pen()
 
2151
*/
 
2152
 
 
2153
void QPainter::setPen(const QPen &pen)
 
2154
{
 
2155
 
 
2156
#ifdef QT_DEBUG_DRAW
 
2157
    if (qt_show_painter_debug_output)
 
2158
        printf("QPainter::setPen(), color=%04x, (brushStyle=%d) style=%d, cap=%d, join=%d\n",
 
2159
           pen.color().rgb(), pen.brush().style(), pen.style(), pen.capStyle(), pen.joinStyle());
 
2160
#endif
 
2161
    Q_D(QPainter);
 
2162
    d->state->pen = pen;
 
2163
    d->state->dirtyFlags |= QPaintEngine::DirtyPen;
 
2164
}
 
2165
 
 
2166
/*!
 
2167
    \overload
 
2168
 
 
2169
    Sets the painter's pen to have style \a style, width 0 and black
 
2170
    color.
 
2171
 
 
2172
    \sa pen(), QPen
 
2173
*/
 
2174
 
 
2175
void QPainter::setPen(Qt::PenStyle style)
 
2176
{
 
2177
    setPen(QPen(Qt::black, 0, style));
 
2178
}
 
2179
 
 
2180
/*!
 
2181
    Returns the painter's current pen.
 
2182
 
 
2183
    \sa setPen()
 
2184
*/
 
2185
 
 
2186
const QPen &QPainter::pen() const
 
2187
{
 
2188
    Q_D(const QPainter);
 
2189
    return d->state->pen;
 
2190
}
 
2191
 
 
2192
 
 
2193
/*!
 
2194
    \overload
 
2195
 
 
2196
    Sets the painter's brush to \a brush.
 
2197
 
 
2198
    The \a brush defines how shapes are filled.
 
2199
 
 
2200
    \sa brush()
 
2201
*/
 
2202
 
 
2203
void QPainter::setBrush(const QBrush &brush)
 
2204
{
 
2205
#ifdef QT_DEBUG_DRAW
 
2206
    if (qt_show_painter_debug_output)
 
2207
        printf("QPainter::setBrush(), color=%04x, style=%d\n", brush.color().rgb(), brush.style());
 
2208
#endif
 
2209
    Q_D(QPainter);
 
2210
    d->state->brush = brush;
 
2211
    d->state->dirtyFlags |= QPaintEngine::DirtyBrush;
 
2212
}
 
2213
 
 
2214
 
 
2215
/*!
 
2216
    Sets the painter's brush to black color and the specified \a
 
2217
    style.
 
2218
 
 
2219
    \sa brush(), QBrush
 
2220
*/
 
2221
 
 
2222
void QPainter::setBrush(Qt::BrushStyle style)
 
2223
{
 
2224
    setBrush(QBrush(Qt::black, style));
 
2225
}
 
2226
 
 
2227
/*!
 
2228
    Returns the painter's current brush.
 
2229
 
 
2230
    \sa QPainter::setBrush()
 
2231
*/
 
2232
 
 
2233
const QBrush &QPainter::brush() const
 
2234
{
 
2235
    Q_D(const QPainter);
 
2236
    return d->state->brush;
 
2237
}
 
2238
 
 
2239
/*!
 
2240
    Sets the background brush of the painter to \a bg.
 
2241
 
 
2242
    The background brush is the brush that is filled in when drawing
 
2243
    opaque text, stippled lines and bitmaps. The background brush has
 
2244
    no effect in transparent background mode (which is the default).
 
2245
 
 
2246
    \sa background() setBackgroundMode() Qt::BGMode
 
2247
*/
 
2248
 
 
2249
void QPainter::setBackground(const QBrush &bg)
 
2250
{
 
2251
#ifdef QT_DEBUG_DRAW
 
2252
    if (qt_show_painter_debug_output)
 
2253
        printf("QPainter::setBackground(), color=%04x, style=%d\n", bg.color().rgb(), bg.style());
 
2254
#endif
 
2255
 
 
2256
    Q_D(QPainter);
 
2257
    d->state->bgBrush = bg;
 
2258
    d->state->dirtyFlags |= QPaintEngine::DirtyBackground;
 
2259
}
 
2260
 
 
2261
/*!
 
2262
    Sets the painter's font to \a font.
 
2263
 
 
2264
    This font is used by subsequent drawText() functions. The text
 
2265
    color is the same as the pen color.
 
2266
 
 
2267
    If you set a font that isn't available, Qt finds a close match.
 
2268
    font() will return what you set using setFont() and fontInfo() returns the
 
2269
    font actually being used (which may be the same).
 
2270
 
 
2271
 
 
2272
    \sa font(), drawText()
 
2273
*/
 
2274
 
 
2275
void QPainter::setFont(const QFont &font)
 
2276
{
 
2277
#ifdef QT_DEBUG_DRAW
 
2278
    if (qt_show_painter_debug_output)
 
2279
        printf("QPainter::setFont(), family=%s, pointSize=%d\n", font.family().toLatin1().constData(), font.pointSize());
 
2280
#endif
 
2281
 
 
2282
    Q_D(QPainter);
 
2283
    d->state->font = QFont(font.resolve(d->state->deviceFont), d->device);
 
2284
    d->state->dirtyFlags |= QPaintEngine::DirtyFont;
 
2285
}
 
2286
 
 
2287
/*!
 
2288
    Returns the currently set painter font.
 
2289
 
 
2290
    \sa setFont(), QFont
 
2291
*/
 
2292
 
 
2293
const QFont &QPainter::font() const
 
2294
{
 
2295
    Q_D(const QPainter);
 
2296
    return d->state->font;
 
2297
}
 
2298
 
 
2299
/*!
 
2300
    \fn QPainter::drawRoundRect(int x, int y, int w, int h, int xRnd, int yRnd)
 
2301
 
 
2302
    \overload
 
2303
 
 
2304
    Draws the rectangle \a x, \a y, \a w, \a h with rounded corners.
 
2305
*/
 
2306
 
 
2307
/*!
 
2308
    \fn void QPainter::drawRoundRect(const QRect &r, int xRnd = 25, int yRnd = 25)
 
2309
 
 
2310
    \overload
 
2311
 
 
2312
    Draws the rectangle \a r with rounded corners.
 
2313
*/
 
2314
 
 
2315
 
 
2316
/*!
 
2317
    Draws a rectangle \a r with rounded corners.
 
2318
 
 
2319
    The \a xRnd and \a yRnd arguments specify how rounded the corners
 
2320
    should be. 0 is angled corners, 99 is maximum roundedness.
 
2321
 
 
2322
    A filled rectangle has a size of r.size(). A stroked rectangle
 
2323
    has a size of r.size() plus the pen width.
 
2324
 
 
2325
    \sa drawRect(), QPen
 
2326
*/
 
2327
void QPainter::drawRoundRect(const QRectF &r, int xRnd, int yRnd)
 
2328
{
 
2329
#ifdef QT_DEBUG_DRAW
 
2330
    if (qt_show_painter_debug_output)
 
2331
        printf("QPainter::drawRoundRectangle(), [%.2f,%.2f,%.2f,%.2f]\n", r.x(), r.y(), r.width(), r.height());
 
2332
#endif
 
2333
 
 
2334
    if (!isActive())
 
2335
        return;
 
2336
 
 
2337
    if(xRnd >= 100)                          // fix ranges
 
2338
        xRnd = 99;
 
2339
    if(yRnd >= 100)
 
2340
        yRnd = 99;
 
2341
    if(xRnd <= 0 || yRnd <= 0) {             // draw normal rectangle
 
2342
        drawRect(r);
 
2343
        return;
 
2344
    }
 
2345
 
 
2346
    QRectF rect = r.normalized();
 
2347
 
 
2348
    QPainterPath path;
 
2349
 
 
2350
    qreal x = rect.x();
 
2351
    qreal y = rect.y();
 
2352
    qreal w = rect.width();
 
2353
    qreal h = rect.height();
 
2354
    qreal rxx = w*xRnd/200;
 
2355
    qreal ryy = h*yRnd/200;
 
2356
    // were there overflows?
 
2357
    if (rxx < 0)
 
2358
        rxx = w/200*xRnd;
 
2359
    if (ryy < 0)
 
2360
        ryy = h/200*yRnd;
 
2361
    qreal rxx2 = 2*rxx;
 
2362
    qreal ryy2 = 2*ryy;
 
2363
 
 
2364
    QPointF startPoint;
 
2365
    qt_find_ellipse_coords(QRectF(x, y, rxx2, ryy2), 90, 90, &startPoint, 0);
 
2366
    path.moveTo(startPoint);
 
2367
    path.arcTo(x, y, rxx2, ryy2, 90, 90);
 
2368
    path.arcTo(x, y+h-ryy2, rxx2, ryy2, 2*90, 90);
 
2369
    path.arcTo(x+w-rxx2, y+h-ryy2, rxx2, ryy2, 3*90, 90);
 
2370
    path.arcTo(x+w-rxx2, y, rxx2, ryy2, 0, 90);
 
2371
    path.closeSubpath();
 
2372
 
 
2373
    drawPath(path);
 
2374
}
 
2375
 
 
2376
/*!
 
2377
    \fn QPainter::drawEllipse(const QRect &r)
 
2378
 
 
2379
    \overload
 
2380
 
 
2381
    Draws an ellipse that fits inside the rectangle \a r.
 
2382
*/
 
2383
 
 
2384
/*!
 
2385
    \fn QPainter::drawEllipse(int x, int y, int w, int h)
 
2386
 
 
2387
    \overload
 
2388
 
 
2389
    Draws an ellipse that fits inside the rectangle (\a{x}, \a{y}, \a{w},
 
2390
    \a{h}).
 
2391
*/
 
2392
 
 
2393
/*!
 
2394
    Draws the ellipse that fits inside the rectangle \a r.
 
2395
 
 
2396
    A filled ellipse has a size of r.size(). An stroked ellipse
 
2397
    has a size of r.size() plus the pen width.
 
2398
*/
 
2399
void QPainter::drawEllipse(const QRectF &r)
 
2400
{
 
2401
#ifdef QT_DEBUG_DRAW
 
2402
    if (qt_show_painter_debug_output)
 
2403
        printf("QPainter::drawEllipse(), [%.2f,%.2f,%.2f,%.2f]\n", r.x(), r.y(), r.width(), r.height());
 
2404
#endif
 
2405
 
 
2406
    if (!isActive())
 
2407
        return;
 
2408
    Q_D(QPainter);
 
2409
    d->updateState(d->state);
 
2410
 
 
2411
    QRectF rect(r.normalized());
 
2412
 
 
2413
    if (rect.isEmpty())
 
2414
        return;
 
2415
 
 
2416
    if (d->state->emulationSpecifier) {
 
2417
        if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
 
2418
            && d->state->txop == QPainterPrivate::TxTranslate) {
 
2419
            rect.translate(QPointF(d->state->matrix.dx(), d->state->matrix.dy()));
 
2420
        } else {
 
2421
            QPainterPath path;
 
2422
            path.addEllipse(rect);
 
2423
            d->draw_helper(path, QPainterPrivate::StrokeAndFillDraw);
 
2424
            return;
 
2425
        }
 
2426
    }
 
2427
 
 
2428
    d->engine->drawEllipse(rect);
 
2429
}
 
2430
 
 
2431
void QPainter::drawEllipse(const QRect &r)
 
2432
{
 
2433
#ifdef QT_DEBUG_DRAW
 
2434
    if (qt_show_painter_debug_output)
 
2435
        printf("QPainter::drawEllipse(), [%d,%d,%d,%d]\n", r.x(), r.y(), r.width(), r.height());
 
2436
#endif
 
2437
 
 
2438
    if (!isActive())
 
2439
        return;
 
2440
    Q_D(QPainter);
 
2441
    d->updateState(d->state);
 
2442
 
 
2443
    QRect rect(r.normalized());
 
2444
 
 
2445
    if (rect.isEmpty())
 
2446
        return;
 
2447
 
 
2448
    if (d->state->emulationSpecifier) {
 
2449
        if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
 
2450
            && d->state->txop == QPainterPrivate::TxTranslate) {
 
2451
            rect.translate(QPoint(qRound(d->state->matrix.dx()), qRound(d->state->matrix.dy())));
 
2452
        } else {
 
2453
            QPainterPath path;
 
2454
            path.addEllipse(rect);
 
2455
            d->draw_helper(path, QPainterPrivate::StrokeAndFillDraw);
 
2456
            return;
 
2457
        }
 
2458
    }
 
2459
 
 
2460
    d->engine->drawEllipse(rect);
 
2461
}
 
2462
 
 
2463
 
 
2464
/*! \fn void QPainter::drawArc(const QRect &r, int startAngle,
 
2465
                               int spanAngle)
 
2466
 
 
2467
    \overload
 
2468
 
 
2469
    Draws the arc that fits inside the rectangle \a r, with the given
 
2470
    \a startAngle and \a spanAngle.
 
2471
*/
 
2472
 
 
2473
/*!
 
2474
    \fn void QPainter::drawArc(int x, int y, int w, int h,
 
2475
                               int startAngle, int spanAngle)
 
2476
 
 
2477
    \overload
 
2478
 
 
2479
    Draws the arc that fits inside the rectangle (\a{x}, \a{y}, \a{w},
 
2480
    \a{h}), with the given \a startAngle and \a spanAngle.
 
2481
*/
 
2482
 
 
2483
/*!
 
2484
    Draws an arc defined by the rectangle \a r, the start angle \a a
 
2485
    and the arc length \a alen.
 
2486
 
 
2487
    The angles \a a and \a alen are 1/16th of a degree, i.e. a full
 
2488
    circle equals 5760 (16*360). Positive values of \a a and \a alen
 
2489
    mean counter-clockwise while negative values mean the clockwise
 
2490
    direction. Zero degrees is at the 3 o'clock position.
 
2491
 
 
2492
    Example:
 
2493
    \code
 
2494
        QPainter p(myWidget);
 
2495
        p.drawArc(QRect(10,10, 70,100), 100*16, 160*16); // draws a "(" arc
 
2496
    \endcode
 
2497
 
 
2498
    \sa drawPie(), drawChord()
 
2499
*/
 
2500
 
 
2501
void QPainter::drawArc(const QRectF &r, int a, int alen)
 
2502
{
 
2503
#ifdef QT_DEBUG_DRAW
 
2504
    if (qt_show_painter_debug_output)
 
2505
        printf("QPainter::drawArc(), [%.2f,%.2f,%.2f,%.2f], angle=%d, sweep=%d\n",
 
2506
           r.x(), r.y(), r.width(), r.height(), a/16, alen/16);
 
2507
#endif
 
2508
 
 
2509
    if (!isActive())
 
2510
        return;
 
2511
    Q_D(QPainter);
 
2512
    d->updateState(d->state);
 
2513
 
 
2514
    QRectF rect = r.normalized();
 
2515
 
 
2516
    QPointF startPoint;
 
2517
    qt_find_ellipse_coords(r, a/16.0, alen/16.0, &startPoint, 0);
 
2518
 
 
2519
    QPainterPath path;
 
2520
    path.moveTo(startPoint);
 
2521
    path.arcTo(rect, a/16.0, alen/16.0);
 
2522
    strokePath(path, d->state->pen);
 
2523
}
 
2524
 
 
2525
 
 
2526
/*!
 
2527
    \fn void QPainter::drawPie(const QRect &rect, int startAngle, int spanAngle)
 
2528
 
 
2529
    \overload
 
2530
 
 
2531
    Draws a pie segment that fits inside the rectangle \a rect with
 
2532
    the given \a startAngle and \a spanAngle.
 
2533
*/
 
2534
 
 
2535
/*!
 
2536
    \fn void QPainter::drawPie(int x, int y, int w, int h, int
 
2537
    startAngle, int spanAngle)
 
2538
 
 
2539
    \overload
 
2540
 
 
2541
    Draws a pie segment that fits inside the rectangle (\a{x}, \a{y},
 
2542
    \a{w}, \a{h}) with the given \a startAngle and \a spanAngle.
 
2543
*/
 
2544
 
 
2545
/*!
 
2546
    Draws a pie defined by the rectangle \a r, the start angle \a a
 
2547
    and the arc length \a alen.
 
2548
 
 
2549
    The pie is filled with the current brush().
 
2550
 
 
2551
    The angles \a a and \a alen are 1/16th of a degree, i.e. a full
 
2552
    circle equals 5760 (16*360). Positive values of \a a and \a alen
 
2553
    mean counter-clockwise while negative values mean the clockwise
 
2554
    direction. Zero degrees is at the 3 o'clock position.
 
2555
 
 
2556
    \sa drawArc(), drawChord()
 
2557
*/
 
2558
void QPainter::drawPie(const QRectF &r, int a, int alen)
 
2559
{
 
2560
#ifdef QT_DEBUG_DRAW
 
2561
    if (qt_show_painter_debug_output)
 
2562
        printf("QPainter::drawPie(), [%.2f,%.2f,%.2f,%.2f], angle=%d, sweep=%d\n",
 
2563
           r.x(), r.y(), r.width(), r.height(), a/16, alen/16);
 
2564
#endif
 
2565
 
 
2566
    if (!isActive())
 
2567
        return;
 
2568
    Q_D(QPainter);
 
2569
    d->updateState(d->state);
 
2570
 
 
2571
    if (a > (360*16)) {
 
2572
        a = a % (360*16);
 
2573
    } else if (a < 0) {
 
2574
        a = a % (360*16);
 
2575
        if (a < 0) a += (360*16);
 
2576
    }
 
2577
 
 
2578
    QRectF rect = r.normalized();
 
2579
 
 
2580
    QPainterPath path;
 
2581
    path.moveTo(rect.center());
 
2582
    path.arcTo(rect.x(), rect.y(), rect.width(), rect.height(), a/16.0, alen/16.0);
 
2583
    path.closeSubpath();
 
2584
    drawPath(path);
 
2585
 
 
2586
}
 
2587
 
 
2588
/*!
 
2589
    \fn void QPainter::drawChord(const QRect &r, int startAngle, int spanAngle)
 
2590
 
 
2591
    \overload
 
2592
 
 
2593
    Draws a chord that fits inside the rectangle \a r with the given
 
2594
    \a startAngle and \a spanAngle.
 
2595
*/
 
2596
 
 
2597
/*!
 
2598
    \fn void QPainter::drawChord(int x, int y, int w, int h, int
 
2599
    startAngle, int spanAngle)
 
2600
 
 
2601
    \overload
 
2602
 
 
2603
    Draws a chord that fits inside the rectangle (\a{x}, \a{y}, \a{w},
 
2604
    \a{h}) with the given \a startAngle and \a spanAngle.
 
2605
*/
 
2606
 
 
2607
 
 
2608
/*!
 
2609
    Draws a chord defined by the rectangle \a r, the start angle \a a
 
2610
    and the arc length \a alen.
 
2611
 
 
2612
    The chord is filled with the current brush().
 
2613
 
 
2614
    The angles \a a and \a alen are 1/16th of a degree, i.e. a full
 
2615
    circle equals 5760 (16*360). Positive values of \a a and \a alen
 
2616
    mean counter-clockwise while negative values mean the clockwise
 
2617
    direction. Zero degrees is at the 3 o'clock position.
 
2618
 
 
2619
    \sa drawArc(), drawPie()
 
2620
*/
 
2621
 
 
2622
void QPainter::drawChord(const QRectF &r, int a, int alen)
 
2623
{
 
2624
#ifdef QT_DEBUG_DRAW
 
2625
    if (qt_show_painter_debug_output)
 
2626
        printf("QPainter::drawChord(), [%.2f,%.2f,%.2f,%.2f], angle=%d, sweep=%d\n",
 
2627
           r.x(), r.y(), r.width(), r.height(), a/16, alen/16);
 
2628
#endif
 
2629
 
 
2630
    if (!isActive())
 
2631
        return;
 
2632
    Q_D(QPainter);
 
2633
    d->updateState(d->state);
 
2634
 
 
2635
    QRectF rect = r.normalized();
 
2636
 
 
2637
    QPointF startPoint;
 
2638
    qt_find_ellipse_coords(r, a/16.0, alen/16.0, &startPoint, 0);
 
2639
 
 
2640
    QPainterPath path;
 
2641
    path.moveTo(startPoint);
 
2642
    path.arcTo(rect.x(), rect.y(), rect.width(), rect.height(), a/16.0, alen/16.0);
 
2643
    path.closeSubpath();
 
2644
    drawPath(path);
 
2645
}
 
2646
 
 
2647
#ifdef QT3_SUPPORT
 
2648
/*!
 
2649
    Draws \a nlines separate lines from points defined in \a a,
 
2650
    starting at \a{a}\e{[index]} (\a index defaults to 0). If \a nlines is
 
2651
    -1 (the default) all points until the end of the array are used
 
2652
    (i.e. (a.size()-index)/2 lines are drawn).
 
2653
 
 
2654
    Draws the 1st line from \a{a}\e{[index]} to \a{a}\e{[index + 1]}. Draws the
 
2655
    2nd line from \a{a}\e{[index + 2]} to \a{a}\e{[index + 3]} etc.
 
2656
 
 
2657
    \sa drawPolyline(), drawPolygon(), QPen
 
2658
*/
 
2659
 
 
2660
void QPainter::drawLineSegments(const QPolygon &a, int index, int nlines)
 
2661
{
 
2662
#ifdef QT_DEBUG_DRAW
 
2663
    if (qt_show_painter_debug_output)
 
2664
        printf("QPainter::drawLineSegments(), count=%d\n", a.size()/2);
 
2665
#endif
 
2666
 
 
2667
    if (!isActive())
 
2668
        return;
 
2669
 
 
2670
    if (nlines < 0)
 
2671
        nlines = a.size()/2 - index/2;
 
2672
    if (index + nlines*2 > (int)a.size())
 
2673
        nlines = (a.size() - index)/2;
 
2674
    if (nlines < 1 || index < 0)
 
2675
        return;
 
2676
 
 
2677
    Q_D(QPainter);
 
2678
    d->updateState(d->state);
 
2679
 
 
2680
    QVector<QLineF> lines;
 
2681
    if (d->state->emulationSpecifier) {
 
2682
        if (d->state->emulationSpecifier == QPaintEngine::PrimitiveTransform
 
2683
            && d->state->txop == QPainterPrivate::TxTranslate) {
 
2684
            QPointF offset(d->state->matrix.dx(), d->state->matrix.dy());
 
2685
            for (int i=index; i<index + nlines*2; i+=2)
 
2686
                lines << QLineF(a.at(i) + offset, a.at(i+1) + offset);
 
2687
        } else {
 
2688
            QPainterPath linesPath;
 
2689
            for (int i=index; i<index + nlines*2; i+=2) {
 
2690
                linesPath.moveTo(a.at(i));
 
2691
                linesPath.lineTo(a.at(i+1));
 
2692
            }
 
2693
            d->draw_helper(linesPath, QPainterPrivate::StrokeDraw);
 
2694
            return;
 
2695
        }
 
2696
    } else {
 
2697
        for (int i=index; i<index + nlines*2; i+=2)
 
2698
            lines << QLineF(a.at(i), a.at(i+1));
 
2699
    }
 
2700
 
 
2701
    d->engine->drawLines(lines.data(), lines.size());
 
2702
}
 
2703
#endif // QT3_SUPPORT
 
2704
/*!
 
2705
    Draws the first \a lineCount lines in the array \a lines
 
2706
    using the current pen.
 
2707
*/
 
2708
void QPainter::drawLines(const QLineF *lines, int lineCount)
 
2709
{
 
2710
#ifdef QT_DEBUG_DRAW
 
2711
    if (qt_show_painter_debug_output)
 
2712
        printf("QPainter::drawLine(), p1=(%.2f,%.2f), p2=(%.2f,%.2f)\n",
 
2713
               l.x1(), l.y1(), l.x2(), l.y2());
 
2714
#endif
 
2715
 
 
2716
    if (!isActive())
 
2717
        return;
 
2718
 
 
2719
    Q_D(QPainter);
 
2720
    d->updateState(d->state);
 
2721
 
 
2722
    uint lineEmulation = d->state->emulationSpecifier
 
2723
                         & (QPaintEngine::PrimitiveTransform
 
2724
                            | QPaintEngine::AlphaBlend
 
2725
                            | QPaintEngine::Antialiasing
 
2726
                            | QPaintEngine::BrushStroke);
 
2727
    if (lineEmulation) {
 
2728
        if (lineEmulation == QPaintEngine::PrimitiveTransform
 
2729
            && d->state->txop == QPainterPrivate::TxTranslate) {
 
2730
            for (int i = 0; i < lineCount; ++i) {
 
2731
                QLineF line = lines[i];
 
2732
                line.translate(d->state->matrix.dx(), d->state->matrix.dy());
 
2733
                d->engine->drawLines(&line, 1);
 
2734
            }
 
2735
        } else {
 
2736
            QPainterPath linePath;
 
2737
            for (int i = 0; i < lineCount; ++i) {
 
2738
                linePath.moveTo(lines[i].p1());
 
2739
                linePath.lineTo(lines[i].p2());
 
2740
            }
 
2741
            d->draw_helper(linePath, QPainterPrivate::StrokeDraw);
 
2742
        }
 
2743
        return;
 
2744
    }
 
2745
    d->engine->drawLines(lines, lineCount);
 
2746
}
 
2747
 
 
2748
/*!
 
2749
    Draws the first \a lineCount lines in the array \a lines
 
2750
    using the current pen.
 
2751
*/
 
2752
void QPainter::drawLines(const QLine *lines, int lineCount)
 
2753
{
 
2754
#ifdef QT_DEBUG_DRAW
 
2755
    if (qt_show_painter_debug_output)
 
2756
        printf("QPainter::drawLine(), p1=(%.2f,%.2f), p2=(%.2f,%.2f)\n",
 
2757
               l.x1(), l.y1(), l.x2(), l.y2());
 
2758
#endif
 
2759
 
 
2760
    if (!isActive())
 
2761
        return;
 
2762
 
 
2763
    Q_D(QPainter);
 
2764
    d->updateState(d->state);
 
2765
 
 
2766
    uint lineEmulation = d->state->emulationSpecifier
 
2767
                         & (QPaintEngine::PrimitiveTransform
 
2768
                            | QPaintEngine::AlphaBlend
 
2769
                            | QPaintEngine::Antialiasing
 
2770
                            | QPaintEngine::BrushStroke);
 
2771
    if (lineEmulation) {
 
2772
        if (lineEmulation == QPaintEngine::PrimitiveTransform
 
2773
            && d->state->txop == QPainterPrivate::TxTranslate) {
 
2774
            for (int i = 0; i < lineCount; ++i) {
 
2775
                QLineF line = lines[i];
 
2776
                line.translate(d->state->matrix.dx(), d->state->matrix.dy());
 
2777
                d->engine->drawLines(&line, 1);
 
2778
            }
 
2779
        } else {
 
2780
            QPainterPath linePath;
 
2781
            for (int i = 0; i < lineCount; ++i) {
 
2782
                linePath.moveTo(lines[i].p1());
 
2783
                linePath.lineTo(lines[i].p2());
 
2784
            }
 
2785
            d->draw_helper(linePath, QPainterPrivate::StrokeDraw);
 
2786
        }
 
2787
        return;
 
2788
    }
 
2789
    d->engine->drawLines(lines, lineCount);
 
2790
}
 
2791
 
 
2792
 
 
2793
/*!
 
2794
    \fn void QPainter::drawLines(const QVector<QPointF> &pointPairs)
 
2795
 
 
2796
    \overload
 
2797
 
 
2798
    Draws a line for each pair of points in the vector \a pointPairs using
 
2799
    the current pen.
 
2800
 
 
2801
    If there is an odd number of points in the array, the last point
 
2802
    will be ignored.
 
2803
*/
 
2804
 
 
2805
/*!
 
2806
    \overload
 
2807
 
 
2808
    Draws the first \a lineCount lines in the array \a pointPairs using
 
2809
    the current pen.
 
2810
 
 
2811
    The lines are specified as pairs of points so the number of entries
 
2812
    in \a pointPairs must be at least \a lineCount * 2
 
2813
 
 
2814
    \sa drawLines()
 
2815
*/
 
2816
void QPainter::drawLines(const QPointF *pointPairs, int lineCount)
 
2817
{
 
2818
    Q_ASSERT_X(pointPairs, "QPainter::drawLines", "pointPairs array cannot be 0");
 
2819
    // This will go horribly wrong if the layout of QLineF changes!
 
2820
    drawLines((QLineF*)pointPairs, lineCount);
 
2821
}
 
2822
 
 
2823
/*!
 
2824
    \overload
 
2825
 
 
2826
    Draws the first \a lineCount lines in the array \a pointPairs using
 
2827
    the current pen.
 
2828
 
 
2829
    The lines are specified as pairs of points so the number of entries
 
2830
    in \a pointPairs must be at least \a lineCount * 2
 
2831
 
 
2832
    \sa drawLines()
 
2833
*/
 
2834
void QPainter::drawLines(const QPoint *pointPairs, int lineCount)
 
2835
{
 
2836
    Q_ASSERT_X(pointPairs, "QPainter::drawLines", "pointPairs array cannot be 0");
 
2837
    QVector<QPointF> pts = qt_convert_points(pointPairs, lineCount * 2, QPointF());
 
2838
    // This will go horribly wrong if the layout of QLineF changes!
 
2839
    drawLines((QLineF*)pts.constData(), pts.size() / 2);
 
2840
}
 
2841
 
 
2842
 
 
2843
/*!
 
2844
    \fn void QPainter::drawPolyline(const QPolygon &pa, int index, int
 
2845
    npoints)
 
2846
 
 
2847
    \overload
 
2848
 
 
2849
    \compat
 
2850
 
 
2851
    Draws the polyline defined by the \a npoints points in \a pa
 
2852
    starting at \a index. (\a index defaults to 0.)
 
2853
 
 
2854
*/
 
2855
 
 
2856
/*!
 
2857
    \fn void QPainter::drawPolyline(const QPolygon &pa)
 
2858
 
 
2859
    \overload
 
2860
 
 
2861
    Draws the polyline defined by \a pa using the current pen.
 
2862
*/
 
2863
 
 
2864
/*!
 
2865
    \fn void QPainter::drawPolyline(const QPolygonF &pa)
 
2866
 
 
2867
    \overload
 
2868
 
 
2869
    Draws the polyline defined by \a pa using the current pen.
 
2870
*/
 
2871
 
 
2872
/*!
 
2873
    Draws the polyline defined by the first \a pointCount points in \a
 
2874
    points using the current pen.
 
2875
 
 
2876
    \sa drawLines(), drawPolygon(), QPen
 
2877
*/
 
2878
 
 
2879
void QPainter::drawPolyline(const QPointF *points, int pointCount)
 
2880
{
 
2881
#ifdef QT_DEBUG_DRAW
 
2882
    if (qt_show_painter_debug_output)
 
2883
        printf("QPainter::drawPolyline(), count=%d\n", pointCount);
 
2884
#endif
 
2885
 
 
2886
    if (!isActive() || pointCount <= 0)
 
2887
        return;
 
2888
 
 
2889
    Q_D(QPainter);
 
2890
    d->updateState(d->state);
 
2891
 
 
2892
    uint lineEmulation = d->state->emulationSpecifier
 
2893
                         & (QPaintEngine::PrimitiveTransform
 
2894
                            | QPaintEngine::AlphaBlend
 
2895
                            | QPaintEngine::Antialiasing
 
2896
                            | QPaintEngine::BrushStroke);
 
2897
 
 
2898
    if (lineEmulation) {
 
2899
        // ###
 
2900
//         if (lineEmulation == QPaintEngine::PrimitiveTransform
 
2901
//             && d->state->txop == QPainterPrivate::TxTranslate) {
 
2902
//         } else {
 
2903
        QPainterPath polylinePath(points[0]);
 
2904
        for (int i=1; i<pointCount; ++i)
 
2905
            polylinePath.lineTo(points[i]);
 
2906
        d->draw_helper(polylinePath, QPainterPrivate::StrokeDraw);
 
2907
//         }
 
2908
    } else {
 
2909
        d->engine->drawPolygon(points, pointCount, QPaintEngine::PolylineMode);
 
2910
    }
 
2911
}
 
2912
 
 
2913
/*! \overload
 
2914
 
 
2915
    Draws the polyline defined by the first \a pointCount points in
 
2916
    the array \a points using the current pen.
 
2917
 */
 
2918
void QPainter::drawPolyline(const QPoint *points, int pointCount)
 
2919
{
 
2920
    // ### don't realloc
 
2921
    QVector<QPointF> pts = qt_convert_points(points, pointCount, QPointF());
 
2922
    drawPolyline(pts.data(), pts.size());
 
2923
}
 
2924
 
 
2925
 
 
2926
/*! \fn void QPainter::drawPolygon(const QPolygon &pa, bool winding,
 
2927
                                   int index = 0, int npoints = -1)
 
2928
 
 
2929
    \compat
 
2930
    \overload
 
2931
 
 
2932
    Draws the polygon defined by the points in the point array \a pa.
 
2933
*/
 
2934
 
 
2935
/*! \fn void QPainter::drawPolygon(const QPolygon &pa, Qt::FillRule fillRule)
 
2936
 
 
2937
    \overload
 
2938
 
 
2939
    Draws the polygon defined by the points in \a pa using the fill
 
2940
    rule \a fillRule.
 
2941
*/
 
2942
 
 
2943
/*! \fn void QPainter::drawPolygon(const QPolygonF &pa, Qt::FillRule fillRule)
 
2944
 
 
2945
    \overload
 
2946
 
 
2947
    Draws the polygon defined by the points in \a pa using the fill
 
2948
    rule \a fillRule.
 
2949
*/
 
2950
 
 
2951
/*! \fn void QPainter::drawPolygon(const QPolygonF &polygon, bool winding, int index = 0,
 
2952
                                   int npoints = -1)
 
2953
    \compat
 
2954
    \overload
 
2955
*/
 
2956
 
 
2957
/*!
 
2958
    Draws the polygon defined by the first \a pointCount points in the
 
2959
    array \a points using the current pen and brush.
 
2960
 
 
2961
    The first point is implicitly connected to the last point.
 
2962
 
 
2963
    The polygon is filled with the current brush(). If \a fillRule is
 
2964
    \c Qt::WindingFill, the polygon is filled using the winding fill algorithm.
 
2965
    If \a fillRule is \c Qt::OddEvenFill, the polygon is filled using the
 
2966
    odd-even fill algorithm. See \l{Qt::FillRule} for a more detailed
 
2967
    description of these fill rules.
 
2968
 
 
2969
    \sa drawLines() drawPolyline() QPen
 
2970
*/
 
2971
 
 
2972
void QPainter::drawPolygon(const QPointF *points, int pointCount, Qt::FillRule fillRule)
 
2973
{
 
2974
#ifdef QT_DEBUG_DRAW
 
2975
    if (qt_show_painter_debug_output)
 
2976
        printf("QPainter::drawPolygon(), count=%d\n", pointCount);
 
2977
#endif
 
2978
 
 
2979
    if (!isActive() || pointCount <= 0)
 
2980
        return;
 
2981
 
 
2982
    Q_D(QPainter);
 
2983
    d->updateState(d->state);
 
2984
 
 
2985
    uint emulationSpecifier = d->state->emulationSpecifier;
 
2986
 
 
2987
    if (emulationSpecifier) {
 
2988
        QPainterPath polygonPath(points[0]);
 
2989
        for (int i=1; i<pointCount; ++i)
 
2990
            polygonPath.lineTo(points[i]);
 
2991
        polygonPath.closeSubpath();
 
2992
        polygonPath.setFillRule(fillRule);
 
2993
        d->draw_helper(polygonPath);
 
2994
        return;
 
2995
    }
 
2996
 
 
2997
    d->engine->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
 
2998
}
 
2999
 
 
3000
/*! \overload
 
3001
 
 
3002
    Draws the polygon defined by the first \a pointCount points in the
 
3003
    array \a points.
 
3004
*/
 
3005
void QPainter::drawPolygon(const QPoint *points, int pointCount, Qt::FillRule fillRule)
 
3006
{
 
3007
#ifdef QT_DEBUG_DRAW
 
3008
    if (qt_show_painter_debug_output)
 
3009
        printf("QPainter::drawPolygon(), count=%d\n", pointCount);
 
3010
#endif
 
3011
 
 
3012
    if (!isActive() || pointCount <= 0)
 
3013
        return;
 
3014
 
 
3015
    Q_D(QPainter);
 
3016
    d->updateState(d->state);
 
3017
 
 
3018
    uint emulationSpecifier = d->state->emulationSpecifier;
 
3019
 
 
3020
    if (emulationSpecifier) {
 
3021
        QPainterPath polygonPath(points[0]);
 
3022
        for (int i=1; i<pointCount; ++i)
 
3023
            polygonPath.lineTo(points[i]);
 
3024
        polygonPath.closeSubpath();
 
3025
        polygonPath.setFillRule(fillRule);
 
3026
        d->draw_helper(polygonPath);
 
3027
        return;
 
3028
    }
 
3029
 
 
3030
    d->engine->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
 
3031
}
 
3032
 
 
3033
 
 
3034
/*!
 
3035
    \fn void QPainter::drawConvexPolygon(const QPolygonF &polygon)
 
3036
 
 
3037
    \overload
 
3038
 
 
3039
    Draws the convex polygon defined by \a polygon using the current
 
3040
    pen and brush.
 
3041
*/
 
3042
 
 
3043
/*!
 
3044
    \fn void QPainter::drawConvexPolygon(const QPolygon &polygon)
 
3045
 
 
3046
    \overload
 
3047
 
 
3048
    Draws the convex polygon defined by \a polygon using the current
 
3049
    pen and brush.
 
3050
*/
 
3051
 
 
3052
/*!
 
3053
    \fn void QPainter::drawConvexPolygon(const QPolygonF &polygon, int
 
3054
    index, int npoints)
 
3055
 
 
3056
    \compat
 
3057
 
 
3058
    \overload
 
3059
 
 
3060
    Draws the convex polygon defined by \a polygon using the current
 
3061
    pen and brush.
 
3062
*/
 
3063
 
 
3064
/*!
 
3065
    \fn void QPainter::drawConvexPolygon(const QPolygon &polygon, int
 
3066
    index, int npoints)
 
3067
 
 
3068
    \compat
 
3069
 
 
3070
    \overload
 
3071
 
 
3072
    Draws the convex polygon defined by \a polygon using the current
 
3073
    pen and brush.
 
3074
*/
 
3075
 
 
3076
/*!
 
3077
    Draws the convex polygon defined by the first \a pointCount points
 
3078
    in the array \a points using the current pen and brush.
 
3079
 
 
3080
    If the supplied polygon is not convex, the results are undefined.
 
3081
 
 
3082
    On some platforms (e.g. X11), drawing convex polygons can be
 
3083
    faster than drawPolygon().
 
3084
 
 
3085
    \sa drawPolygon()
 
3086
*/
 
3087
 
 
3088
void QPainter::drawConvexPolygon(const QPoint *points, int pointCount)
 
3089
{
 
3090
    // ### Fix when QPainter::drawPolygon(QPolygon, PolyDrawMode) is in place
 
3091
    drawPolygon(points, pointCount, Qt::WindingFill);
 
3092
}
 
3093
 
 
3094
/*!
 
3095
    Draws the convex polygon defined by the first \a pointCount points
 
3096
    in the array \a points using the current pen and brush.
 
3097
 
 
3098
    If the supplied polygon is not convex, the results are undefined.
 
3099
 
 
3100
    On some platforms (e.g. X11), drawing convex polygons can be
 
3101
    faster than drawPolygon().
 
3102
 
 
3103
    \sa drawPolygon()
 
3104
*/
 
3105
void QPainter::drawConvexPolygon(const QPointF *points, int pointCount)
 
3106
{
 
3107
    // ### Fix when QPainter::drawPolygon(QPolygon, PolyDrawMode) is in place
 
3108
    drawPolygon(points, pointCount, Qt::WindingFill);
 
3109
}
 
3110
 
 
3111
 
 
3112
/*!
 
3113
    \fn void QPainter::drawPixmap(const QRect &targetRect, const QPixmap &pixmap,
 
3114
                                  const QRect &sourceRect)
 
3115
    \overload
 
3116
 
 
3117
    Draws the rectangular portion \a sourceRect of the pixmap \a pixmap
 
3118
    in the rectangle \a targetRect.
 
3119
 
 
3120
    \sa drawImage()
 
3121
*/
 
3122
 
 
3123
/*!
 
3124
    \fn void QPainter::drawPixmap(const QPointF &p, const QPixmap &pixmap,
 
3125
                                  const QRectF &sourceRect)
 
3126
    \overload
 
3127
 
 
3128
    Draws the rectangular portion \a sourceRect of the pixmap \a
 
3129
    pixmap at the point \a p.
 
3130
 
 
3131
    \sa drawImage()
 
3132
*/
 
3133
 
 
3134
/*!
 
3135
    \fn void QPainter::drawPixmap(const QPointF &p, const QPixmap &pixmap)
 
3136
    \overload
 
3137
 
 
3138
    Draws the \a pixmap at the point \a p.
 
3139
 
 
3140
    \sa drawImage()
 
3141
*/
 
3142
 
 
3143
/*!
 
3144
    \fn void QPainter::drawPixmap(int x, int y, const QPixmap &pixmap)
 
3145
 
 
3146
    \overload
 
3147
 
 
3148
    Draws the given \a pixmap at position (\a{x}, \a{y}).
 
3149
 
 
3150
    \sa drawImage()
 
3151
*/
 
3152
 
 
3153
/*!
 
3154
    \fn void QPainter::drawPixmap(int x, int y, int width, int height,
 
3155
    const QPixmap &pixmap)
 
3156
 
 
3157
    \overload
 
3158
 
 
3159
    Draws the \a pixmap in the rectangle at position (\a{x}, \a{y})
 
3160
    and of the given \a width and \a height.
 
3161
 
 
3162
    \sa drawImage()
 
3163
 
 
3164
*/
 
3165
 
 
3166
/*!
 
3167
    \fn void QPainter::drawPixmap(int x, int y, int w, int h, const QPixmap &pm,
 
3168
                                  int sx, int sy, int sw, int sh)
 
3169
 
 
3170
    \overload
 
3171
 
 
3172
    Draws the rectangular portion with the origin (\a{sx}, \a{sy}),
 
3173
    width \a sw and height \a sh, of the pixmap \a pm, at the point
 
3174
    (\a{x}, \a{y}), with a width of \a w and a height of \a h.
 
3175
 
 
3176
    \sa drawImage()
 
3177
*/
 
3178
 
 
3179
/*!
 
3180
    \fn void QPainter::drawPixmap(int x, int y, const QPixmap &pixmap,
 
3181
                                  int sx, int sy, int sw, int sh)
 
3182
 
 
3183
    \overload
 
3184
 
 
3185
    Draws a pixmap at (\a{x}, \a{y}) by copying a part of \a pixmap into
 
3186
    the paint device.
 
3187
 
 
3188
    (\a{x}, \a{y}) specifies the top-left point in the paint device that is
 
3189
    to be drawn onto. (\a{sx}, \a{sy}) specifies the top-left point in \a
 
3190
    pixmap that is to be drawn. The default is (0, 0).
 
3191
 
 
3192
    (\a{sw}, \a{sh}) specifies the size of the pixmap that is to be drawn.
 
3193
    The default, (-1, -1), means all the way to the bottom-right of
 
3194
    the pixmap.
 
3195
 
 
3196
    \sa QPixmap::setMask() drawImage()
 
3197
*/
 
3198
 
 
3199
/*!
 
3200
    \fn void QPainter::drawPixmap(const QPoint &p, const QPixmap &pm, const QRect &sr)
 
3201
    \overload
 
3202
 
 
3203
    Draws the rectangle \a sr of pixmap \a pm with its origin at point
 
3204
    \a p.
 
3205
 
 
3206
    \sa drawImage()
 
3207
*/
 
3208
 
 
3209
/*!
 
3210
    \fn void QPainter::drawPixmap(const QPoint &p, const QPixmap &pm)
 
3211
    \overload
 
3212
 
 
3213
    Draws the pixmap \a pm with its origin at point \a p.
 
3214
 
 
3215
    \sa drawImage()
 
3216
*/
 
3217
 
 
3218
/*!
 
3219
    \fn void QPainter::drawPixmap(const QRect &r, const QPixmap &pm)
 
3220
    \overload
 
3221
 
 
3222
    Draws the pixmap \a pm into the rectangle \a r.
 
3223
 
 
3224
    \sa drawImage()
 
3225
*/
 
3226
 
 
3227
/*!
 
3228
    Draws the rectanglular portion \a sr, of pixmap \a pm, into rectangle
 
3229
    \a r in the paint device.
 
3230
 
 
3231
    \sa drawImage()
 
3232
*/
 
3233
void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
 
3234
{
 
3235
#if defined QT_DEBUG_DRAW
 
3236
    if (qt_show_painter_debug_output)
 
3237
        printf("QPainter::drawPixmap(), target=[%.2f,%.2f,%.2f,%.2f], pix=[%d,%d], source=[%.2f,%.2f,%.2f,%.2f]\n",
 
3238
           r.x(), r.y(), r.width(), r.height(),
 
3239
           pm.width(), pm.height(),
 
3240
           sr.x(), sr.y(), sr.width(), sr.height());
 
3241
#endif
 
3242
 
 
3243
    Q_D(QPainter);
 
3244
    if (!isActive() || pm.isNull())
 
3245
        return;
 
3246
    d->updateState(d->state);
 
3247
 
 
3248
    qreal x = r.x();
 
3249
    qreal y = r.y();
 
3250
    qreal w = r.width();
 
3251
    qreal h = r.height();
 
3252
    qreal sx = sr.x();
 
3253
    qreal sy = sr.y();
 
3254
    qreal sw = sr.width();
 
3255
    qreal sh = sr.height();
 
3256
 
 
3257
    // Sanity-check clipping
 
3258
    if (sw <= 0 || sw + sx > pm.width())
 
3259
        sw = pm.width() - sx;
 
3260
 
 
3261
    if (sh <= 0 || sh + sy > pm.height())
 
3262
        sh = pm.height() - sy;
 
3263
 
 
3264
    if (sx < 0) {
 
3265
        x -= sx;
 
3266
        sw += sx;
 
3267
        sx = 0;
 
3268
    }
 
3269
 
 
3270
    if (sy < 0) {
 
3271
        y -= sy;
 
3272
        sh += sy;
 
3273
        sy = 0;
 
3274
    }
 
3275
 
 
3276
    if (w < 0)
 
3277
        w = sw;
 
3278
    if (h < 0)
 
3279
        h = sh;
 
3280
 
 
3281
    if (w == 0 || h == 0 || sw <= 0 || sh <= 0)
 
3282
        return;
 
3283
 
 
3284
    if (d->state->txop > QPainterPrivate::TxTranslate
 
3285
        && !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
 
3286
        QPixmap source;
 
3287
        if(sx != 0 || sy != 0 || sw != pm.width() || sh != pm.height()) {
 
3288
            source = pm.copy(qRound(sx), qRound(sy), qRound(sw), qRound(sh));
 
3289
        } else {
 
3290
            source = pm;
 
3291
        }
 
3292
 
 
3293
        QMatrix mat(d->state->matrix);
 
3294
        qreal scalex = w / sw;
 
3295
        qreal scaley = h / sh;
 
3296
        mat = QMatrix(scalex, 0, 0, scaley, 0, 0) * mat;
 
3297
        mat = QPixmap::trueMatrix(mat, qRound(sw), qRound(sh));
 
3298
        QPixmap pmx = source.transformed(mat,
 
3299
                                         (d->state->renderHints & SmoothPixmapTransform)
 
3300
                                         ? Qt::SmoothTransformation
 
3301
                                         : Qt::FastTransformation);
 
3302
        if (pmx.isNull())                        // xformed into nothing
 
3303
            return;
 
3304
        d->state->matrix.map(x, y, &x, &y);        // compute position of pixmap
 
3305
        qreal dx, dy;
 
3306
        mat.map(0, 0, &dx, &dy);
 
3307
        if (pmx.depth() == 1) {
 
3308
            save();
 
3309
            setClipRect(QRectF(r.x(), r.y(), w, h), Qt::IntersectClip);
 
3310
        }
 
3311
        d->engine->drawPixmap(QRectF(x-dx, y-dy, pmx.width(), pmx.height()), pmx,
 
3312
                              QRectF(0, 0, pmx.width(), pmx.height()));
 
3313
        if (pmx.depth() == 1)
 
3314
            restore();
 
3315
    } else {
 
3316
        if (!d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
 
3317
            x += qRound(d->state->matrix.dx());
 
3318
            y += qRound(d->state->matrix.dy());
 
3319
        }
 
3320
        d->engine->drawPixmap(QRectF(x, y, w, h), pm, QRectF(sx, sy, sw, sh));
 
3321
    }
 
3322
}
 
3323
 
 
3324
/*!
 
3325
    Draws the rectanglular portion \a sourceRect, of image \a image, into rectangle
 
3326
    \a targetRect in the paint device.
 
3327
 
 
3328
    If the image needs to be modified to fit in a lower-resolution
 
3329
    result (e.g. converting from 32-bit to 8-bit), use the \a flags to
 
3330
    specify how you would prefer this to happen.
 
3331
 
 
3332
    \sa drawPixmap()
 
3333
*/
 
3334
void QPainter::drawImage(const QRectF &targetRect, const QImage &image, const QRectF &sourceRect,
 
3335
                         Qt::ImageConversionFlags flags)
 
3336
{
 
3337
    if (!isActive() || image.isNull())
 
3338
        return;
 
3339
 
 
3340
    Q_D(QPainter);
 
3341
    d->updateState(d->state);
 
3342
 
 
3343
    qreal x = targetRect.x();
 
3344
    qreal y = targetRect.y();
 
3345
    qreal w = targetRect.width();
 
3346
    qreal h = targetRect.height();
 
3347
    qreal sx = sourceRect.x();
 
3348
    qreal sy = sourceRect.y();
 
3349
    qreal sw = sourceRect.width();
 
3350
    qreal sh = sourceRect.height();
 
3351
 
 
3352
    // Sanity-check clipping
 
3353
    if (sw <= 0 || sw + sx > image.width())
 
3354
        sw = image.width() - sx;
 
3355
 
 
3356
    if (sh <= 0 || sh + sy > image.height())
 
3357
        sh = image.height() - sy;
 
3358
 
 
3359
    if (sx < 0) {
 
3360
        x -= sx;
 
3361
        sw += sx;
 
3362
        sx = 0;
 
3363
    }
 
3364
 
 
3365
    if (sy < 0) {
 
3366
        y -= sy;
 
3367
        sh += sy;
 
3368
        sy = 0;
 
3369
    }
 
3370
 
 
3371
    if (w < 0)
 
3372
        w = sw;
 
3373
    if (h < 0)
 
3374
        h = sh;
 
3375
 
 
3376
    if (sw <= 0 || sh <= 0)
 
3377
        return;
 
3378
 
 
3379
    if (d->state->txop > QPainterPrivate::TxTranslate
 
3380
         && !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
 
3381
        QPixmap pm = QPixmap::fromImage(image, flags);
 
3382
        drawPixmap(targetRect, pm, sourceRect);
 
3383
        return;
 
3384
    }
 
3385
 
 
3386
    if (d->state->txop == QPainterPrivate::TxTranslate
 
3387
        && !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
 
3388
        x += qRound(d->state->matrix.dx());
 
3389
        y += qRound(d->state->matrix.dy());
 
3390
    }
 
3391
 
 
3392
    d->engine->drawImage(QRectF(x, y, w, h), image, QRectF(sx, sy, sw, sh), flags);
 
3393
}
 
3394
 
 
3395
/*!
 
3396
    \fn void QPainter::drawText(int x, int y, const QString &text)
 
3397
 
 
3398
    \overload
 
3399
 
 
3400
    Draws the given \a text at position (\a{x}, \a{y}), using the painter's
 
3401
    text layout direction.
 
3402
 
 
3403
    \sa layoutDirection(), setLayoutDirection()
 
3404
*/
 
3405
 
 
3406
/*!
 
3407
    \fn void QPainter::drawText(int x, int y, int w, int h, int flags,
 
3408
                                const QString &text, QRect *br)
 
3409
 
 
3410
    \overload
 
3411
 
 
3412
    Draws the given \a text within the rectangle with origin (\a{x},
 
3413
    \a{y}), width \a w and height \a h. The flags that are given in the
 
3414
    \a flags parameter are a selection of flags from \l{Qt::AlignmentFlag}s
 
3415
    and \l{Qt::TextFlag}s combined using the bitwise OR operator. \a br
 
3416
    (if not null) is set to the actual bounding rectangle of the
 
3417
    output.
 
3418
*/
 
3419
 
 
3420
/*!
 
3421
    Draws the string \a str with the currently defined text direction,
 
3422
    beginning at position \a p.
 
3423
 
 
3424
    \sa Qt::LayoutDirection
 
3425
*/
 
3426
 
 
3427
void QPainter::drawText(const QPointF &p, const QString &str)
 
3428
{
 
3429
#ifdef QT_DEBUG_DRAW
 
3430
    if (qt_show_painter_debug_output)
 
3431
        printf("QPainter::drawText(), pos=[%.2f,%.2f], str='%s'\n", p.x(), p.y(), str.toLatin1().constData());
 
3432
#endif
 
3433
 
 
3434
    if (!isActive() || str.isEmpty())
 
3435
        return;
 
3436
 
 
3437
    Q_D(QPainter);
 
3438
    d->updateState(d->state);
 
3439
 
 
3440
    QTextLayout layout(str, d->state->font);
 
3441
    QTextEngine *engine = layout.d;
 
3442
    QTextOption option(Qt::AlignLeft|Qt::AlignAbsolute);
 
3443
    option.setTextDirection(d->state->layoutDirection);
 
3444
    layout.setTextOption(option);
 
3445
 
 
3446
    layout.beginLayout();
 
3447
    QTextLine line = layout.createLine();
 
3448
    layout.endLayout();
 
3449
    const QScriptLine &sl = engine->lines[0];
 
3450
    line.draw(this, QPointF(p.x(), p.y() - sl.ascent));
 
3451
}
 
3452
 
 
3453
/*!
 
3454
    \overload
 
3455
 
 
3456
    Draws the string \a str within the rectangle \a r. The flags that
 
3457
    are given in the \a flags parameter are a selection of flags from
 
3458
    \l{Qt::AlignmentFlag}s and \l{Qt::TextFlag}s combined using the
 
3459
    bitwise OR operator. \a br (if not null) is set to the actual
 
3460
    bounding rectangle of the output.
 
3461
*/
 
3462
void QPainter::drawText(const QRect &r, int flags, const QString &str, QRect *br)
 
3463
{
 
3464
#ifdef QT_DEBUG_DRAW
 
3465
    if (qt_show_painter_debug_output)
 
3466
        printf("QPainter::drawText(), r=[%d,%d,%d,%d], flags=%d, str='%s'\n",
 
3467
           r.x(), r.y(), r.width(), r.height(), flags, str.toLatin1().constData());
 
3468
#endif
 
3469
 
 
3470
    if (!isActive() || str.length() == 0)
 
3471
        return;
 
3472
 
 
3473
    Q_D(QPainter);
 
3474
    d->updateState(d->state);
 
3475
 
 
3476
    QRectF bounds;
 
3477
    qt_format_text(font(), r, flags, str, &bounds, 0, 0, 0, this);
 
3478
    if (br)
 
3479
        *br = bounds.toRect();
 
3480
}
 
3481
 
 
3482
/*! \fn void QPainter::drawText(const QPoint &p, const QString &s)
 
3483
 
 
3484
    \overload
 
3485
 
 
3486
    Draws the string \a s at position \a p, using the painter's layout
 
3487
    direction.
 
3488
 
 
3489
    \sa layoutDirection(), setLayoutDirection()
 
3490
*/
 
3491
 
 
3492
/*! \overload
 
3493
 
 
3494
    Draws the string \a str within the rectangle \a r. The specified \a flags
 
3495
    are constructed from \l{Qt::AlignmentFlag}s and \l{Qt::TextFlag}s,
 
3496
    combined using the bitwise OR operator. If \a br is not null, it is set
 
3497
    to the actual bounding rectangle of the output.
 
3498
*/
 
3499
void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF *br)
 
3500
{
 
3501
#ifdef QT_DEBUG_DRAW
 
3502
    if (qt_show_painter_debug_output)
 
3503
        printf("QPainter::drawText(), r=[%.2f,%.2f,%.2f,%.2f], flags=%d, str='%s'\n",
 
3504
           r.x(), r.y(), r.width(), r.height(), flags, str.toLatin1().constData());
 
3505
#endif
 
3506
 
 
3507
    if (!isActive() || str.length() == 0)
 
3508
        return;
 
3509
 
 
3510
    Q_D(QPainter);
 
3511
    d->updateState(d->state);
 
3512
 
 
3513
    qt_format_text(font(), r, flags, str, br, 0, 0, 0, this);
 
3514
}
 
3515
 
 
3516
/*!
 
3517
    \fn void QPainter::drawText(const QRectF &rectangle, const QString &text,
 
3518
        const QTextOption &option)
 
3519
 
 
3520
    Draws the given \a text in the \a rectangle specified using the \a option
 
3521
    to control its positioning and orientation.
 
3522
*/
 
3523
void QPainter::drawText(const QRectF &r, const QString &text, const QTextOption &o)
 
3524
{
 
3525
#ifdef QT_DEBUG_DRAW
 
3526
    if (qt_show_painter_debug_output)
 
3527
        printf("QPainter::drawText(), r=[%.2f,%.2f,%.2f,%.2f], str='%s'\n",
 
3528
           r.x(), r.y(), r.width(), r.height(), text.toLatin1().constData());
 
3529
#endif
 
3530
 
 
3531
    if (!isActive() || text.length() == 0)
 
3532
        return;
 
3533
 
 
3534
    Q_D(QPainter);
 
3535
    d->updateState(d->state);
 
3536
 
 
3537
    int flags = o.alignment();
 
3538
 
 
3539
    if (o.wrapMode() == QTextOption::WordWrap)
 
3540
        flags |= Qt::TextWordWrap;
 
3541
    else if (o.wrapMode() == QTextOption::WrapAnywhere)
 
3542
        flags |= Qt::TextWrapAnywhere;
 
3543
 
 
3544
    if (o.flags() & QTextOption::IncludeTrailingSpaces)
 
3545
        flags |= Qt::TextIncludeTrailingSpaces;
 
3546
 
 
3547
    qt_format_text(font(), r, flags, text, 0, 0, 0, 0, this);
 
3548
}
 
3549
 
 
3550
/*!
 
3551
    \fn void QPainter::drawTextItem(int x, int y, const QTextItem &ti)
 
3552
 
 
3553
    \internal
 
3554
    \overload
 
3555
*/
 
3556
 
 
3557
/*!
 
3558
    \fn void QPainter::drawTextItem(const QPoint &p, const QTextItem &ti)
 
3559
 
 
3560
    \internal
 
3561
    \overload
 
3562
 
 
3563
    Draws the text item \a ti at position \a p.
 
3564
*/
 
3565
 
 
3566
/*! \internal
 
3567
    Draws the text item \a ti at position \a p.
 
3568
 
 
3569
    This method ignores the painters background mode and
 
3570
    color. drawText and qt_format_text have to do it themselves, as
 
3571
    only they know the extents of the complete string.
 
3572
 
 
3573
    It ignores the font set on the painter as the text item has one of its own.
 
3574
 
 
3575
    The underline and strikeout parameters of the text items font are
 
3576
    ignored aswell. You'll need to pass in the correct flags to get
 
3577
    underlining and strikeout.
 
3578
*/
 
3579
 
 
3580
void QPainter::drawTextItem(const QPointF &p, const QTextItem &ti)
 
3581
{
 
3582
#ifdef QT_DEBUG_DRAW
 
3583
    if (qt_show_painter_debug_output)
 
3584
        printf("QPainter::drawTextItem(), pos=[%.f,%.f], str='%s'\n",
 
3585
               p.x(), p.y(), qPrintable(ti.text()));
 
3586
#endif
 
3587
    if (!isActive())
 
3588
        return;
 
3589
    Q_D(QPainter);
 
3590
    d->updateState(d->state);
 
3591
    d->engine->drawTextItem(p, ti);
 
3592
}
 
3593
 
 
3594
/*!
 
3595
    \fn QRect QPainter::boundingRect(int x, int y, int w, int h, int flags,
 
3596
                                     const QString &text);
 
3597
 
 
3598
    \overload
 
3599
 
 
3600
    Returns the bounding rectangle of the characters in the given \a text,
 
3601
    constrained by the rectangle beginning at the point (\a{x}, \a{y})
 
3602
    with width \a w and height \a h.
 
3603
*/
 
3604
 
 
3605
/*!
 
3606
    \fn QRect QPainter::boundingRect(const QRect &rect, int flags,
 
3607
                                     const QString &str)
 
3608
 
 
3609
    \overload
 
3610
 
 
3611
    Returns the bounding rectangle constrained by rectangle \a rect.
 
3612
*/
 
3613
 
 
3614
 
 
3615
QRect QPainter::boundingRect(const QRect &rect, int flags, const QString &str)
 
3616
{
 
3617
    if (str.isEmpty())
 
3618
        return QRect(rect.x(),rect.y(), 0,0);
 
3619
    QRect brect;
 
3620
    drawText(rect, flags | Qt::TextDontPrint, str, &brect);
 
3621
    return brect;
 
3622
}
 
3623
 
 
3624
/*!
 
3625
    Returns the bounding rectangle of the aligned text that would be
 
3626
    printed with the corresponding drawText() function of the string
 
3627
    \a str. The drawing, and hence the bounding rectangle, is constrained
 
3628
    to the rectangle \a rect, or to the rectangle required to draw the
 
3629
    text, whichever is the larger.
 
3630
 
 
3631
    The \a flags argument is
 
3632
    the bitwise OR of the following flags:
 
3633
    \table
 
3634
    \header \i Flag \i Meaning
 
3635
    \row \i \c Qt::AlignLeft \i aligns to the left border, or to the right border for right-to-left languages.
 
3636
    \row \i \c Qt::AlignRight \i aligns to the right border, or to the left border for right-to-left languages.
 
3637
    \row \i \c Qt::AlignHCenter \i aligns horizontally centered.
 
3638
    \row \i \c Qt::AlignTop \i aligns to the top border.
 
3639
    \row \i \c Qt::AlignBottom \i aligns to the bottom border.
 
3640
    \row \i \c Qt::AlignVCenter \i aligns vertically centered.
 
3641
    \row \i \c Qt::AlignCenter \i (== \c Qt::AlignHCenter | \c Qt::AlignVCenter).
 
3642
    \row \i \c Qt::TextSingleLine \i ignores newline characters in the text.
 
3643
    \row \i \c Qt::TextExpandTabs \i expands tabs.
 
3644
    \row \i \c Qt::TextShowMnemonic \i interprets "&x" as \underline{x}.
 
3645
    \row \i \c Qt::TextWordBreak \i breaks the text to fit the rectangle.
 
3646
    \endtable
 
3647
 
 
3648
    Qt::Horizontal alignment defaults to \c Qt::AlignLeft and vertical
 
3649
    alignment defaults to \c Qt::AlignTop.
 
3650
 
 
3651
    If several of the horizontal or several of the vertical alignment flags
 
3652
    are set, the resulting alignment is undefined.
 
3653
 
 
3654
    \sa Qt::TextFlag
 
3655
*/
 
3656
 
 
3657
QRectF QPainter::boundingRect(const QRectF &rect, int flags, const QString &str)
 
3658
{
 
3659
    if (str.isEmpty())
 
3660
        return QRectF(rect.x(),rect.y(), 0,0);
 
3661
    QRectF brect;
 
3662
    drawText(rect, flags | Qt::TextDontPrint, str, &brect);
 
3663
    return brect;
 
3664
}
 
3665
 
 
3666
/*!
 
3667
    \fn QRectF QPainter::boundingRect(const QRectF &rectangle,
 
3668
        const QString &text, const QTextOption &option)
 
3669
 
 
3670
    Returns the bounding rectangle for the given \a text when placed within
 
3671
    the specified \a rectangle. The \a option can be used to control the
 
3672
    way the text is positioned and orientated.
 
3673
*/
 
3674
QRectF QPainter::boundingRect(const QRectF &r, const QString &text, const QTextOption &o)
 
3675
{
 
3676
    if (!isActive() || text.length() == 0)
 
3677
        return QRectF(r.x(),r.y(), 0,0);
 
3678
 
 
3679
    Q_D(QPainter);
 
3680
    d->updateState(d->state);
 
3681
 
 
3682
    int flags = o.alignment() | Qt::TextDontPrint;
 
3683
    if (o.wrapMode() == QTextOption::WordWrap)
 
3684
        flags |= Qt::TextWordWrap;
 
3685
    else if (o.wrapMode() == QTextOption::WrapAnywhere)
 
3686
        flags |= Qt::TextWrapAnywhere;
 
3687
    if (o.flags() & QTextOption::IncludeTrailingSpaces)
 
3688
        flags |= Qt::TextIncludeTrailingSpaces;
 
3689
 
 
3690
    QRectF br;
 
3691
    qt_format_text(font(), r, flags, text, &br, 0, 0, 0, this);
 
3692
    return br;
 
3693
}
 
3694
 
 
3695
/*!
 
3696
  \fn void QPainter::drawTiledPixmap(int x, int y, int w, int h, const
 
3697
  QPixmap &pixmap, int sx, int sy);
 
3698
 
 
3699
    Draws a tiled \a pixmap in the specified rectangle.
 
3700
 
 
3701
    (\a{x}, \a{y}) specifies the top-left point in the paint device
 
3702
    that is to be drawn onto; with the width and height given by \a w
 
3703
    and \a h. (\a{sx}, \a{sy}) specifies the top-left point in the \a
 
3704
    pixmap that is to be drawn; this defaults to (0, 0).
 
3705
 
 
3706
    Calling drawTiledPixmap() is similar to calling drawPixmap()
 
3707
    several times to fill (tile) an area with a pixmap, but is
 
3708
    potentially much more efficient depending on the underlying window
 
3709
    system.
 
3710
 
 
3711
    \sa drawPixmap()
 
3712
*/
 
3713
 
 
3714
/*! \fn QPainter::drawTiledPixmap(const QRect &rect, const QPixmap &pixmap,
 
3715
                                  const QPoint &sp = QPoint())
 
3716
    \overload
 
3717
 
 
3718
    Draws a tiled \a pixmap, inside rectangle \a rect with its origin
 
3719
    at point \a sp.
 
3720
*/
 
3721
 
 
3722
/*!
 
3723
    \overload
 
3724
 
 
3725
    Draws a tiled \a pixmap, inside rectangle \a r with its origin
 
3726
    at point \a sp.
 
3727
*/
 
3728
void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &sp)
 
3729
{
 
3730
#ifdef QT_DEBUG_DRAW
 
3731
    if (qt_show_painter_debug_output)
 
3732
        printf("QPainter::drawTiledPixmap(), target=[%.2f,%.2f,%.2f,%.2f], pix=[%d,%d], offset=[%.2f,%.2f]\n",
 
3733
           r.x(), r.y(), r.width(), r.height(),
 
3734
           pixmap.width(), pixmap.height(),
 
3735
           sp.x(), sp.y());
 
3736
#endif
 
3737
 
 
3738
    if (!isActive() || pixmap.isNull() || r.isEmpty())
 
3739
        return;
 
3740
    Q_D(QPainter);
 
3741
    d->updateState(d->state);
 
3742
 
 
3743
    qreal sw = pixmap.width();
 
3744
    qreal sh = pixmap.height();
 
3745
    qreal sx = sp.x();
 
3746
    qreal sy = sp.y();
 
3747
    if (sx < 0)
 
3748
        sx = qRound(sw) - qRound(-sx) % qRound(sw);
 
3749
    else
 
3750
        sx = qRound(sx) % qRound(sw);
 
3751
    if (sy < 0)
 
3752
        sy = qRound(sh) - -qRound(sy) % qRound(sh);
 
3753
    else
 
3754
        sy = qRound(sy) % qRound(sh);
 
3755
 
 
3756
    if (d->state->txop > QPainterPrivate::TxTranslate
 
3757
        && !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
 
3758
        QPixmap pm;
 
3759
        if (pixmap.hasAlphaChannel()) {
 
3760
            QImage img(qRound(r.width()), qRound(r.height()), QImage::Format_ARGB32_Premultiplied);
 
3761
            img.fill(0);
 
3762
            pm = QPixmap::fromImage(img);
 
3763
        } else {
 
3764
            pm = QPixmap(qRound(r.width()), qRound(r.height()));
 
3765
        }
 
3766
        QPainter p(&pm);
 
3767
        // Recursive call ok, since the pixmap is not transformed...
 
3768
        p.setPen(pen());
 
3769
        p.setBackground(background());
 
3770
        p.setBackgroundMode(backgroundMode());
 
3771
        p.drawTiledPixmap(QRectF(0, 0, r.width(), r.height()), pixmap, QPointF(sx, sy));
 
3772
        p.end();
 
3773
        if (backgroundMode() == Qt::TransparentMode && pixmap.depth() == 1) {
 
3774
            QBitmap mask(pm.width(), pm.height());
 
3775
            mask.clear();
 
3776
            p.begin(&mask);
 
3777
            p.drawTiledPixmap(QRectF(0, 0, r.width(), r.height()), pixmap, QPointF(sx, sy));
 
3778
            p.end();
 
3779
            pm.setMask(mask);
 
3780
        }
 
3781
        drawPixmap(qRound(r.x()), qRound(r.y()), pm);
 
3782
        return;
 
3783
    }
 
3784
 
 
3785
    qreal x = r.x();
 
3786
    qreal y = r.y();
 
3787
    if (d->state->txop == QPainterPrivate::TxTranslate
 
3788
        && !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
 
3789
        x += qRound(d->state->matrix.dx());
 
3790
        y += qRound(d->state->matrix.dy());
 
3791
    }
 
3792
 
 
3793
    d->engine->drawTiledPixmap(QRectF(x, y, r.width(), r.height()), pixmap, QPointF(sx, sy));
 
3794
}
 
3795
 
 
3796
 
 
3797
/*!
 
3798
    \fn void QPainter::drawPicture(int x, int y, const QPicture &picture)
 
3799
    \overload
 
3800
 
 
3801
    Draws picture \a picture at point (\a x, \a y).
 
3802
*/
 
3803
 
 
3804
/*!
 
3805
    \fn void QPainter::drawPicture(const QPoint &p, const QPicture &picture)
 
3806
    \overload
 
3807
 
 
3808
    Draws picture \a picture at point \a p.
 
3809
*/
 
3810
 
 
3811
/*!
 
3812
    Replays the picture \a picture at point \a p.
 
3813
 
 
3814
    This function does exactly the same as QPicture::play() when
 
3815
    called with \a p = QPoint(0, 0).
 
3816
*/
 
3817
 
 
3818
void QPainter::drawPicture(const QPointF &p, const QPicture &picture)
 
3819
{
 
3820
    if (!isActive())
 
3821
        return;
 
3822
    Q_D(QPainter);
 
3823
    d->updateState(d->state);
 
3824
    save();
 
3825
    translate(p);
 
3826
    const_cast<QPicture *>(&picture)->play(this);
 
3827
    restore();
 
3828
}
 
3829
 
 
3830
/*! \fn void QPainter::eraseRect(const QRect &rect)
 
3831
 
 
3832
    \overload
 
3833
 
 
3834
    Erases the area inside the rectangle \a rect. Equivalent to
 
3835
    \c{fillRect(rect, backgroundColor())}.
 
3836
*/
 
3837
 
 
3838
/*!
 
3839
    Erases the area inside the rectangle \a r. Equivalent to
 
3840
    \c{fillRect(r, backgroundColor())}.
 
3841
*/
 
3842
void QPainter::eraseRect(const QRectF &r)
 
3843
{
 
3844
    if (!isActive())
 
3845
        return;
 
3846
    Q_D(QPainter);
 
3847
    d->updateState(d->state);
 
3848
 
 
3849
    if (d->state->bgBrush.texture().isNull())
 
3850
        fillRect(r, d->state->bgBrush);
 
3851
    else
 
3852
        drawTiledPixmap(r, d->state->bgBrush.texture(), -d->state->bgOrigin);
 
3853
}
 
3854
 
 
3855
/*!
 
3856
  \fn void QPainter::eraseRect(int x, int y, int w, int h)
 
3857
  \overload
 
3858
 
 
3859
    Erases the area inside \a x, \a y, \a w, \a h. Equivalent to
 
3860
    \c{fillRect(x, y, w, h, backgroundColor())}.
 
3861
*/
 
3862
 
 
3863
 
 
3864
/*!
 
3865
    Fills the rectangle \a r with the \a brush.
 
3866
 
 
3867
    You can specify a QColor as \a brush, since there is a QBrush
 
3868
    constructor that takes a QColor argument and creates a solid
 
3869
    pattern brush.
 
3870
 
 
3871
    \sa drawRect()
 
3872
*/
 
3873
void QPainter::fillRect(const QRectF &r, const QBrush &brush)
 
3874
{
 
3875
    QPen oldPen   = pen();
 
3876
    bool swap = oldPen.style() != Qt::NoPen;
 
3877
    if (swap)
 
3878
        setPen(Qt::NoPen);
 
3879
    QBrush oldBrush = this->brush();
 
3880
    setBrush(brush);
 
3881
    drawRect(r);
 
3882
    setBrush(oldBrush);
 
3883
    if (swap)
 
3884
        setPen(oldPen);
 
3885
}
 
3886
 
 
3887
void QPainter::fillRect(const QRect &r, const QBrush &brush)
 
3888
{
 
3889
    QPen oldPen   = pen();
 
3890
    bool swap = oldPen.style() != Qt::NoPen;
 
3891
    if (swap)
 
3892
        setPen(Qt::NoPen);
 
3893
    QBrush oldBrush = this->brush();
 
3894
    setBrush(brush);
 
3895
    drawRect(r);
 
3896
    setBrush(oldBrush);
 
3897
    if (swap)
 
3898
        setPen(oldPen);
 
3899
}
 
3900
 
 
3901
/*!
 
3902
  \fn void QPainter::fillRect(const QRect &rect, const QBrush &brush)
 
3903
 
 
3904
    \overload
 
3905
 
 
3906
    Fills the rectangle \a rect with the \a brush.
 
3907
 
 
3908
    You can specify a QColor as \a brush, since there is a QBrush
 
3909
    constructor that takes a QColor argument and creates a solid
 
3910
    pattern brush.
 
3911
 
 
3912
    \sa drawRect()
 
3913
*/
 
3914
 
 
3915
/*!
 
3916
  \fn void QPainter::fillRect(int x, int y, int w, int h, const QBrush &brush)
 
3917
 
 
3918
    \overload
 
3919
 
 
3920
    Fills the rectangle (\a{x}, \a{y}, \a{w}, \a{h}) with the \a brush.
 
3921
 
 
3922
    You can specify a QColor as \a brush, since there is a QBrush
 
3923
    constructor that takes a QColor argument and creates a solid
 
3924
    pattern brush.
 
3925
 
 
3926
    \sa drawRect()
 
3927
*/
 
3928
 
 
3929
 
 
3930
/*!
 
3931
  Sets the render hint \a hint on this painter if \a on is true;
 
3932
  otherwise clears the render hint.
 
3933
*/
 
3934
void QPainter::setRenderHint(RenderHint hint, bool on)
 
3935
{
 
3936
#ifdef QT_DEBUG_DRAW
 
3937
    if (qt_show_painter_debug_output)
 
3938
        printf("QPainter::setRenderHint(), hint=%x, %s\n", hint, on ? "on" : "off");
 
3939
#endif
 
3940
 
 
3941
    if (!isActive()) {
 
3942
        qWarning("Painter must be active to set rendering hints");
 
3943
        return;
 
3944
    }
 
3945
 
 
3946
    Q_D(QPainter);
 
3947
 
 
3948
    if (on)
 
3949
        d->state->renderHints |= hint;
 
3950
    else
 
3951
        d->state->renderHints &= ~hint;
 
3952
 
 
3953
    d->state->dirtyFlags |= QPaintEngine::DirtyHints;
 
3954
}
 
3955
 
 
3956
/*!
 
3957
    Returns a flag that specifies the rendering hints that are set for
 
3958
    this painter.
 
3959
*/
 
3960
QPainter::RenderHints QPainter::renderHints() const
 
3961
{
 
3962
    if (!isActive()) {
 
3963
        qWarning("Painter must be active to set rendering hints");
 
3964
        return 0;
 
3965
    }
 
3966
    Q_D(const QPainter);
 
3967
    return d->state->renderHints;
 
3968
}
 
3969
 
 
3970
/*!
 
3971
    Returns true if view transformation is enabled; otherwise returns
 
3972
    false.
 
3973
 
 
3974
    \sa setViewTransformEnabled(), matrix()
 
3975
*/
 
3976
 
 
3977
bool QPainter::viewTransformEnabled() const
 
3978
{
 
3979
    Q_D(const QPainter);
 
3980
#ifndef QT_NO_TRANSFORMATIONS
 
3981
    return d->state->VxF;
 
3982
#else
 
3983
    return d->state->xlatex || d->state->xlatey;
 
3984
#endif
 
3985
}
 
3986
 
 
3987
/*!
 
3988
    \fn void QPainter::setWindow(const QRect &r)
 
3989
 
 
3990
    \overload
 
3991
 
 
3992
    Sets the painter's window to the rectangle \a r.
 
3993
*/
 
3994
 
 
3995
/*!
 
3996
  \fn void QPainter::setWindow(int x, int y, int w, int h)
 
3997
 
 
3998
    Sets the window rectangle view transformation for the painter and
 
3999
    enables view transformation.
 
4000
 
 
4001
    The window rectangle is part of the view transformation. The
 
4002
    window specifies the logical coordinate system and is specified by
 
4003
    the \a x, \a y, \a w width and \a h height parameters. Its sister,
 
4004
    the viewport(), specifies the device coordinate system.
 
4005
 
 
4006
    The default window rectangle is the same as the device's
 
4007
    rectangle. See the \link coordsys.html Coordinate System Overview
 
4008
    \endlink for an overview of coordinate transformation.
 
4009
 
 
4010
    \sa window(), setViewport(), setViewTransformEnabled(), setMatrix(),
 
4011
    setMatrixEnabled()
 
4012
*/
 
4013
 
 
4014
void QPainter::setWindow(const QRect &r)
 
4015
{
 
4016
#ifdef QT_DEBUG_DRAW
 
4017
    if (qt_show_painter_debug_output)
 
4018
        printf("QPainter::setWindow(), [%d,%d,%d,%d]\n", r.x(), r.y(), r.width(), r.height());
 
4019
#endif
 
4020
 
 
4021
    if (!isActive()) {
 
4022
        qWarning("QPainter::setWindow(), painter not active");
 
4023
        return;
 
4024
    }
 
4025
 
 
4026
    Q_D(QPainter);
 
4027
 
 
4028
    d->state->wx = r.x();
 
4029
    d->state->wy = r.y();
 
4030
    d->state->ww = r.width();
 
4031
    d->state->wh = r.height();
 
4032
    if (d->state->VxF)
 
4033
        d->updateMatrix();
 
4034
    else
 
4035
        setViewTransformEnabled(true);
 
4036
}
 
4037
 
 
4038
/*!
 
4039
    Returns the window rectangle.
 
4040
 
 
4041
    \sa setWindow(), setViewTransformEnabled()
 
4042
*/
 
4043
 
 
4044
QRect QPainter::window() const
 
4045
{
 
4046
    Q_D(const QPainter);
 
4047
    return QRect(d->state->wx, d->state->wy, d->state->ww, d->state->wh);
 
4048
}
 
4049
 
 
4050
/*!
 
4051
    \fn void QPainter::setViewport(const QRect &r)
 
4052
 
 
4053
    \overload
 
4054
 
 
4055
    Sets the painter's viewport rectangle to \a r.
 
4056
*/
 
4057
 
 
4058
/*!
 
4059
  \fn void QPainter::setViewport(int x, int y, int w, int h)
 
4060
 
 
4061
    Sets the viewport rectangle view transformation for the painter
 
4062
    and enables view transformation.
 
4063
 
 
4064
    The viewport rectangle is part of the view transformation. The
 
4065
    viewport specifies the device coordinate system and is specified
 
4066
    by the \a x, \a y, \a w width and \a h height parameters. Its
 
4067
    sister, the window(), specifies the logical coordinate system.
 
4068
 
 
4069
    The default viewport rectangle is the same as the device's
 
4070
    rectangle. See the \link coordsys.html Coordinate System Overview
 
4071
    \endlink for an overview of coordinate transformation.
 
4072
 
 
4073
    \sa viewport(), setWindow(), setViewTransformEnabled(), setMatrix(),
 
4074
    setMatrixEnabled()
 
4075
*/
 
4076
 
 
4077
void QPainter::setViewport(const QRect &r)
 
4078
{
 
4079
#ifdef QT_DEBUG_DRAW
 
4080
    if (qt_show_painter_debug_output)
 
4081
        printf("QPainter::setViewport(), [%d,%d,%d,%d]\n", r.x(), r.y(), r.width(), r.height());
 
4082
#endif
 
4083
 
 
4084
    if (!isActive()) {
 
4085
        qWarning("QPainter::setViewport(), painter not active");
 
4086
        return;
 
4087
    }
 
4088
 
 
4089
    Q_D(QPainter);
 
4090
 
 
4091
    d->state->vx = r.x();
 
4092
    d->state->vy = r.y();
 
4093
    d->state->vw = r.width();
 
4094
    d->state->vh = r.height();
 
4095
    if (d->state->VxF)
 
4096
        d->updateMatrix();
 
4097
    else
 
4098
        setViewTransformEnabled(true);
 
4099
}
 
4100
 
 
4101
/*!
 
4102
    Returns the viewport rectangle.
 
4103
 
 
4104
    \sa setViewport(), setViewTransformEnabled()
 
4105
*/
 
4106
 
 
4107
QRect QPainter::viewport() const
 
4108
{
 
4109
    Q_D(const QPainter);
 
4110
    return QRect(d->state->vx, d->state->vy, d->state->vw, d->state->vh);
 
4111
}
 
4112
 
 
4113
/*! \fn bool QPainter::hasViewXForm() const
 
4114
    \compat
 
4115
 
 
4116
    Use viewTransformEnabled() instead.
 
4117
*/
 
4118
 
 
4119
/*! \fn bool QPainter::hasWorldXForm() const
 
4120
    \compat
 
4121
 
 
4122
    Use matrixEnabled() instead.
 
4123
*/
 
4124
 
 
4125
/*! \fn void QPainter::resetXForm()
 
4126
    \compat
 
4127
 
 
4128
    Use resetMatrix() instead.
 
4129
*/
 
4130
 
 
4131
/*! \fn void QPainter::setViewXForm(bool enabled)
 
4132
    \compat
 
4133
 
 
4134
    Use setViewTransformEnabled() instead.
 
4135
*/
 
4136
 
 
4137
/*! \fn void QPainter::setWorldMatrix(const QMatrix &wm, bool combine=false)
 
4138
    \compat
 
4139
 
 
4140
    Use setMatrix() instead.
 
4141
*/
 
4142
 
 
4143
/*! \fn void QPainter::setWorldXForm(bool enabled)
 
4144
    \compat
 
4145
 
 
4146
    Use setMatrixEnabled() instead.
 
4147
*/
 
4148
 
 
4149
/*! \fn const QMatrix &QPainter::worldMatrix() const
 
4150
    \compat
 
4151
 
 
4152
    Use matrix() instead.
 
4153
*/
 
4154
 
 
4155
/*!
 
4156
    Enables view transformations if \a enable is true, or disables
 
4157
    view transformations if \a enable is false.
 
4158
 
 
4159
    \sa viewTransformEnabled(), setWindow(), setViewport(), setMatrix(),
 
4160
    setMatrixEnabled()
 
4161
*/
 
4162
 
 
4163
void QPainter::setViewTransformEnabled(bool enable)
 
4164
{
 
4165
#ifdef QT_DEBUG_DRAW
 
4166
    if (qt_show_painter_debug_output)
 
4167
        printf("QPainter::setViewTransformEnabled(), enable=%d\n", enable);
 
4168
#endif
 
4169
 
 
4170
    if (!isActive()) {
 
4171
        qWarning("QPainter::setViewTransformEnabled(), painter not active");
 
4172
        return;
 
4173
    }
 
4174
    Q_D(QPainter);
 
4175
    if (enable == d->state->VxF)
 
4176
        return;
 
4177
 
 
4178
    d->state->VxF = enable;
 
4179
    d->updateMatrix();
 
4180
}
 
4181
 
 
4182
#ifdef QT3_SUPPORT
 
4183
 
 
4184
qreal QPainter::translationX() const
 
4185
{
 
4186
    Q_D(const QPainter);
 
4187
#ifndef QT_NO_TRANSFORMATIONS
 
4188
    return d->state->worldMatrix.dx();
 
4189
#else
 
4190
    return d->state->xlatex;
 
4191
#endif
 
4192
}
 
4193
 
 
4194
qreal QPainter::translationY() const
 
4195
{
 
4196
    Q_D(const QPainter);
 
4197
#ifndef QT_NO_TRANSFORMATIONS
 
4198
    return d->state->worldMatrix.dy();
 
4199
#else
 
4200
    return d->state->xlatey;
 
4201
#endif
 
4202
}
 
4203
 
 
4204
/*!
 
4205
    \fn void QPainter::map(int x, int y, int *rx, int *ry) const
 
4206
 
 
4207
    \internal
 
4208
 
 
4209
    Sets (\a{rx}, \a{ry}) to the point that results from applying the
 
4210
    painter's current transformation on the point (\a{x}, \a{y}).
 
4211
*/
 
4212
void QPainter::map(int x, int y, int *rx, int *ry) const
 
4213
{
 
4214
    Q_D(const QPainter);
 
4215
    QPoint p(x, y);
 
4216
    p = p * d->state->matrix;
 
4217
    *rx = p.x();
 
4218
    *ry = p.y();
 
4219
}
 
4220
 
 
4221
/*!
 
4222
    Returns the point \a p transformed from model coordinates to
 
4223
    device coordinates.
 
4224
 
 
4225
    \sa xFormDev(), QMatrix::map()
 
4226
*/
 
4227
 
 
4228
QPoint QPainter::xForm(const QPoint &p) const
 
4229
{
 
4230
    Q_D(const QPainter);
 
4231
#ifndef QT_NO_TRANSFORMATIONS
 
4232
    if (d->state->txop == QPainterPrivate::TxNone)
 
4233
        return p;
 
4234
    return p * d->state->matrix;
 
4235
#else
 
4236
    return QPoint(p.x() + d->state->xlatex, p.y() + d->state->xlatey);
 
4237
#endif
 
4238
}
 
4239
 
 
4240
 
 
4241
/*!
 
4242
    \overload
 
4243
 
 
4244
    Returns the rectangle \a r transformed from model coordinates to
 
4245
    device coordinates.
 
4246
 
 
4247
    If world transformation is enabled and rotation or shearing has
 
4248
    been specified, then the bounding rectangle is returned.
 
4249
 
 
4250
    \sa xFormDev(), QMatrix::map()
 
4251
*/
 
4252
 
 
4253
QRect QPainter::xForm(const QRect &r) const
 
4254
{
 
4255
    Q_D(const QPainter);
 
4256
#ifndef QT_NO_TRANSFORMATIONS
 
4257
    if (d->state->txop == QPainterPrivate::TxNone)
 
4258
        return r;
 
4259
    return d->state->matrix.mapRect(r);
 
4260
#else
 
4261
    return QRect(r.x()+d->state->xlatex, r.y()+d->state->xlatey, r.width(), r.height());
 
4262
#endif
 
4263
}
 
4264
 
 
4265
/*!
 
4266
    \overload
 
4267
 
 
4268
    Returns the point array \a a transformed from model coordinates
 
4269
    to device coordinates.
 
4270
 
 
4271
    \sa xFormDev(), QMatrix::map()
 
4272
*/
 
4273
 
 
4274
QPolygon QPainter::xForm(const QPolygon &a) const
 
4275
{
 
4276
    Q_D(const QPainter);
 
4277
#ifndef QT_NO_TRANSFORMATIONS
 
4278
    if (d->state->txop == QPainterPrivate::TxNone)
 
4279
        return a;
 
4280
    return a * d->state->matrix;
 
4281
#else
 
4282
    QPolygon p(a);
 
4283
    p.translate(d->state->xlatex, d->state->xlatey);
 
4284
    return p;
 
4285
#endif
 
4286
}
 
4287
 
 
4288
/*!
 
4289
    \overload
 
4290
 
 
4291
    Returns the point array \a av transformed from model coordinates
 
4292
    to device coordinates. The \a index is the first point in the
 
4293
    array and \a npoints denotes the number of points to be
 
4294
    transformed. If \a npoints is negative, all points from
 
4295
    \a{av}\e{[index]} until the last point in the array are transformed.
 
4296
 
 
4297
    The returned point array consists of the number of points that
 
4298
    were transformed.
 
4299
 
 
4300
    Example:
 
4301
    \code
 
4302
        QPolygon a(10);
 
4303
        QPolygon b;
 
4304
        b = painter.xForm(a, 2, 4);  // b.size() == 4
 
4305
        b = painter.xForm(a, 2, -1); // b.size() == 8
 
4306
    \endcode
 
4307
 
 
4308
    \sa xFormDev(), QMatrix::map()
 
4309
*/
 
4310
 
 
4311
QPolygon QPainter::xForm(const QPolygon &av, int index, int npoints) const
 
4312
{
 
4313
    Q_D(const QPainter);
 
4314
    int lastPoint = npoints < 0 ? av.size() : index+npoints;
 
4315
    QPolygon a(lastPoint-index);
 
4316
    memcpy(a.data(), av.data()+index, (lastPoint-index)*sizeof(QPoint));
 
4317
#ifndef QT_NO_TRANSFORMATIONS
 
4318
    return a * d->state->matrix;
 
4319
#else
 
4320
    a.translate(d->state->xlatex, d->state->xlatey);
 
4321
    return a;
 
4322
#endif
 
4323
}
 
4324
 
 
4325
/*!
 
4326
    \overload
 
4327
 
 
4328
    Returns the point \a p transformed from device coordinates to
 
4329
    model coordinates.
 
4330
 
 
4331
    \sa xForm(), QMatrix::map()
 
4332
*/
 
4333
 
 
4334
QPoint QPainter::xFormDev(const QPoint &p) const
 
4335
{
 
4336
    Q_D(const QPainter);
 
4337
#ifndef QT_NO_TRANSFORMATIONS
 
4338
    if(d->state->txop == QPainterPrivate::TxNone)
 
4339
        return p;
 
4340
    if (!d->txinv) {
 
4341
        QPainter *that = (QPainter*)this;        // mutable
 
4342
        that->d_ptr->updateInvMatrix();
 
4343
    }
 
4344
    return p * d->invMatrix;
 
4345
#else
 
4346
    return QPoint(p.x() - xlatex, p.y() - xlatey);
 
4347
#endif
 
4348
}
 
4349
 
 
4350
/*!
 
4351
    Returns the rectangle \a r transformed from device coordinates to
 
4352
    model coordinates.
 
4353
 
 
4354
    If world transformation is enabled and rotation or shearing is
 
4355
    used, then the bounding rectangle is returned.
 
4356
 
 
4357
    \sa xForm(), QMatrix::map()
 
4358
*/
 
4359
 
 
4360
QRect QPainter::xFormDev(const QRect &r)  const
 
4361
{
 
4362
    Q_D(const QPainter);
 
4363
#ifndef QT_NO_TRANSFORMATIONS
 
4364
    if (d->state->txop == QPainterPrivate::TxNone)
 
4365
        return r;
 
4366
    if (!d->txinv) {
 
4367
        QPainter *that = (QPainter*)this;        // mutable
 
4368
        that->d_ptr->updateInvMatrix();
 
4369
    }
 
4370
    return d->invMatrix.mapRect(r);
 
4371
#else
 
4372
    return QRect(r.x()-d->state->xlatex, r.y()-d->state->xlatey, r.width(), r.height());
 
4373
#endif
 
4374
}
 
4375
 
 
4376
/*!
 
4377
    \overload
 
4378
 
 
4379
    Returns the point array \a a transformed from device coordinates
 
4380
    to model coordinates.
 
4381
 
 
4382
    \sa xForm(), QMatrix::map()
 
4383
*/
 
4384
 
 
4385
QPolygon QPainter::xFormDev(const QPolygon &a) const
 
4386
{
 
4387
    Q_D(const QPainter);
 
4388
#ifndef QT_NO_TRANSFORMATIONS
 
4389
    if (d->state->txop == QPainterPrivate::TxNone)
 
4390
        return a;
 
4391
    if (!d->txinv) {
 
4392
        QPainter *that = (QPainter*)this;        // mutable
 
4393
        that->d_ptr->updateInvMatrix();
 
4394
    }
 
4395
    return a * d->invMatrix;
 
4396
#else
 
4397
    QPolygon p(a);
 
4398
    p.translate(-d->state->xlatex, -d->state->xlatey);
 
4399
    return p;
 
4400
#endif
 
4401
 
 
4402
}
 
4403
 
 
4404
/*!
 
4405
    \overload
 
4406
 
 
4407
    Returns the point array \a ad transformed from device coordinates
 
4408
    to model coordinates. The \a index is the first point in the array
 
4409
    and \a npoints denotes the number of points to be transformed. If
 
4410
    \a npoints is negative, all points from \a{ad}\e{[index]} until the
 
4411
    last point in the array are transformed.
 
4412
 
 
4413
    The returned point array consists of the number of points that
 
4414
    were transformed.
 
4415
 
 
4416
    Example:
 
4417
    \code
 
4418
        QPolygon a(10);
 
4419
        QPolygon b;
 
4420
        b = painter.xFormDev(a, 1, 3);  // b.size() == 3
 
4421
        b = painter.xFormDev(a, 1, -1); // b.size() == 9
 
4422
    \endcode
 
4423
 
 
4424
    \sa xForm(), QMatrix::map()
 
4425
*/
 
4426
 
 
4427
QPolygon QPainter::xFormDev(const QPolygon &ad, int index, int npoints) const
 
4428
{
 
4429
    Q_D(const QPainter);
 
4430
    int lastPoint = npoints < 0 ? ad.size() : index+npoints;
 
4431
    QPolygon a(lastPoint-index);
 
4432
    memcpy(a.data(), ad.data()+index, (lastPoint-index)*sizeof(QPoint));
 
4433
#ifndef QT_NO_TRANSFORMATIONS
 
4434
    if (d->state->txop == QPainterPrivate::TxNone)
 
4435
        return a;
 
4436
    if (!d->txinv) {
 
4437
        QPainter *that = (QPainter*)this;        // mutable
 
4438
        that->d_ptr->updateInvMatrix();
 
4439
    }
 
4440
    return a * d->invMatrix;
 
4441
#else
 
4442
    a.translate(-d->state->xlatex, -d->state->xlatey);
 
4443
    return a;
 
4444
#endif
 
4445
}
 
4446
 
 
4447
/*!
 
4448
    \fn void QPainter::drawPoints(const QPolygon &points)
 
4449
 
 
4450
    \overload
 
4451
 
 
4452
    Draws the points in the polygon \a points using the current pen's color.
 
4453
 
 
4454
*/
 
4455
 
 
4456
/*!
 
4457
    Draws a cubic Bezier curve defined by the control points in \a a,
 
4458
    starting at \a{a}\e{[index]} (\a index defaults to 0).
 
4459
 
 
4460
    Control points after \a{a}\e{[index + 3]} are ignored. Nothing happens
 
4461
    if there aren't enough control points.
 
4462
*/
 
4463
void QPainter::drawCubicBezier(const QPolygon &a, int index)
 
4464
{
 
4465
    if (!isActive())
 
4466
        return;
 
4467
    Q_D(QPainter);
 
4468
    d->updateState(d->state);
 
4469
 
 
4470
    if ((int)a.size() - index < 4) {
 
4471
        qWarning("QPainter::drawCubicBezier: Cubic Bezier needs 4 control "
 
4472
                  "points");
 
4473
        return;
 
4474
    }
 
4475
 
 
4476
    QPainterPath path;
 
4477
    path.moveTo(a.at(index));
 
4478
    path.cubicTo(a.at(index+1), a.at(index+2), a.at(index+3));
 
4479
    strokePath(path, d->state->pen);
 
4480
}
 
4481
#endif
 
4482
 
 
4483
struct QPaintDeviceRedirection
 
4484
{
 
4485
    QPaintDeviceRedirection() : device(0), replacement(0) {}
 
4486
    QPaintDeviceRedirection(const QPaintDevice *device, QPaintDevice *replacement,
 
4487
                            const QPoint& offset)
 
4488
        : device(device), replacement(replacement), offset(offset) { }
 
4489
    const QPaintDevice *device;
 
4490
    QPaintDevice *replacement;
 
4491
    QPoint offset;
 
4492
    bool operator==(const QPaintDevice *pdev) const { return device == pdev; }
 
4493
    Q_DUMMY_COMPARISON_OPERATOR(QPaintDeviceRedirection)
 
4494
};
 
4495
 
 
4496
typedef QList<QPaintDeviceRedirection> QPaintDeviceRedirectionList;
 
4497
Q_GLOBAL_STATIC(QPaintDeviceRedirectionList, globalRedirections)
 
4498
 
 
4499
/*!
 
4500
  \internal
 
4501
 
 
4502
    Redirects all paint commands for a paint device, \a device, to
 
4503
    another paint device, \a replacement. The optional point \a offset
 
4504
    defines an offset within the replaced device. After painting you
 
4505
    must call restoreRedirected().
 
4506
 
 
4507
    In general, you'll probably find calling QPixmap::grabWidget() or
 
4508
    QPixmap::grabWindow() is an easier solution.
 
4509
 
 
4510
    \sa redirected()
 
4511
*/
 
4512
void QPainter::setRedirected(const QPaintDevice *device,
 
4513
                             QPaintDevice *replacement,
 
4514
                             const QPoint &offset)
 
4515
{
 
4516
    Q_ASSERT(device != 0);
 
4517
    QPaintDeviceRedirectionList *redirections = globalRedirections();
 
4518
    Q_ASSERT(redirections != 0);
 
4519
 
 
4520
    QPoint roffset;
 
4521
    QPaintDevice *rdev = redirected(replacement, &roffset);
 
4522
    *redirections += QPaintDeviceRedirection(device, rdev ? rdev : replacement, offset + roffset);
 
4523
}
 
4524
 
 
4525
 
 
4526
/*!\internal
 
4527
 
 
4528
  Restores the previous redirection for \a device after a call to
 
4529
  setRedirected().
 
4530
 
 
4531
  \sa redirected()
 
4532
 */
 
4533
void QPainter::restoreRedirected(const QPaintDevice *device)
 
4534
{
 
4535
    Q_ASSERT(device != 0);
 
4536
    QPaintDeviceRedirectionList *redirections = globalRedirections();
 
4537
    Q_ASSERT(redirections != 0);
 
4538
    for (int i = redirections->size()-1; i >= 0; --i)
 
4539
        if (redirections->at(i) == device) {
 
4540
            redirections->removeAt(i);
 
4541
            return;
 
4542
        }
 
4543
}
 
4544
 
 
4545
 
 
4546
/*!
 
4547
    \internal
 
4548
 
 
4549
    Returns the replacement for \a device. The optional out parameter
 
4550
    \a offset returns return the offset within the replaced device.
 
4551
*/
 
4552
QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
 
4553
{
 
4554
    Q_ASSERT(device != 0);
 
4555
    QPaintDeviceRedirectionList *redirections = globalRedirections();
 
4556
    Q_ASSERT(redirections != 0);
 
4557
    for (int i = redirections->size()-1; i >= 0; --i)
 
4558
        if (redirections->at(i) == device) {
 
4559
            if (offset)
 
4560
                *offset = redirections->at(i).offset;
 
4561
            return redirections->at(i).replacement;
 
4562
        }
 
4563
    if (offset)
 
4564
        *offset = QPoint(0, 0);
 
4565
    return 0;
 
4566
}
 
4567
 
 
4568
 
 
4569
void qt_format_text(const QFont &font, const QRectF &_r,
 
4570
                    int tf, const QString& str, QRectF *brect,
 
4571
                    int tabstops, int *, int tabarraylen,
 
4572
                    QPainter *painter)
 
4573
{
 
4574
    // we need to copy r here to protect against the case (&r == brect).
 
4575
    QRectF r(_r);
 
4576
 
 
4577
    bool dontclip  = (tf & Qt::TextDontClip);
 
4578
    bool wordwrap  = (tf & Qt::TextWordWrap);
 
4579
    bool singleline = (tf & Qt::TextSingleLine);
 
4580
    bool showmnemonic = (tf & Qt::TextShowMnemonic);
 
4581
    bool hidemnmemonic = (tf & Qt::TextHideMnemonic);
 
4582
 
 
4583
    tf = QStyle::visualAlignment(painter ? painter->layoutDirection() : QApplication::layoutDirection(), QFlag(tf));
 
4584
 
 
4585
    bool isRightToLeft = (painter ? painter->layoutDirection() : qApp->layoutDirection()) == Qt::RightToLeft;
 
4586
    bool expandtabs = ((tf & Qt::TextExpandTabs) &&
 
4587
                        (((tf & Qt::AlignLeft) && !isRightToLeft) ||
 
4588
                          ((tf & Qt::AlignRight) && isRightToLeft)));
 
4589
 
 
4590
    if (!painter)
 
4591
        tf |= Qt::TextDontPrint;
 
4592
 
 
4593
    int maxUnderlines = 0;
 
4594
    int numUnderlines = 0;
 
4595
    int underlinePositionStack[32];
 
4596
    int *underlinePositions = underlinePositionStack;
 
4597
 
 
4598
    QFont fnt(painter ? painter->d_ptr->state->font : font);
 
4599
    QFontMetricsF fm(fnt);
 
4600
 
 
4601
    QString text = str;
 
4602
    // compatible behaviour to the old implementation. Replace
 
4603
    // tabs by spaces
 
4604
    QChar *chr = text.data();
 
4605
    const QChar *end = chr + str.length();
 
4606
    while (chr != end) {
 
4607
        if (*chr == QLatin1Char('\r') || (singleline && *chr == QLatin1Char('\n'))) {
 
4608
            *chr = ' ';
 
4609
        } else if (*chr == QLatin1Char('\n')) {
 
4610
            *chr = QChar::LineSeparator;
 
4611
        } else if (*chr == QLatin1Char('&')) {
 
4612
            ++maxUnderlines;
 
4613
        }
 
4614
        ++chr;
 
4615
    }
 
4616
    if (!expandtabs) {
 
4617
        chr = text.data();
 
4618
        while (chr != end) {
 
4619
            if (*chr == QLatin1Char('\t'))
 
4620
                *chr = QLatin1Char(' ');
 
4621
            ++chr;
 
4622
        }
 
4623
    } else if (!tabarraylen && !tabstops) {
 
4624
        tabstops = qRound(fm.width(QLatin1Char('x'))*8);
 
4625
    }
 
4626
 
 
4627
    if (hidemnmemonic || showmnemonic) {
 
4628
        if (maxUnderlines > 32)
 
4629
            underlinePositions = new int[maxUnderlines];
 
4630
        QChar *cout = text.data();
 
4631
        QChar *cin = cout;
 
4632
        int l = str.length();
 
4633
        while (l) {
 
4634
            if (*cin == QLatin1Char('&')) {
 
4635
                ++cin;
 
4636
                --l;
 
4637
                if (!l)
 
4638
                    break;
 
4639
                if (*cin != QLatin1Char('&') && !hidemnmemonic)
 
4640
                    underlinePositions[numUnderlines++] = cout - text.unicode();
 
4641
            }
 
4642
            *cout = *cin;
 
4643
            ++cout;
 
4644
            ++cin;
 
4645
            --l;
 
4646
        }
 
4647
        int newlen = cout - text.unicode();
 
4648
        if (newlen != text.length())
 
4649
            text.resize(newlen);
 
4650
    }
 
4651
 
 
4652
    // no need to do extra work for underlines if we don't paint
 
4653
    if (tf & Qt::TextDontPrint)
 
4654
        numUnderlines = 0;
 
4655
 
 
4656
    underlinePositions[numUnderlines] = -1;
 
4657
    qreal height = 0;
 
4658
    qreal width = 0;
 
4659
 
 
4660
    QTextLayout textLayout(text, fnt);
 
4661
    textLayout.engine()->underlinePositions = underlinePositions;
 
4662
 
 
4663
    if (text.isEmpty()) {
 
4664
        height = fm.height();
 
4665
        width = 0;
 
4666
        tf |= Qt::TextDontPrint;
 
4667
    } else {
 
4668
        qreal lineWidth = wordwrap ? qMax<qreal>(0, r.width()) : 0x01000000;
 
4669
        if(!wordwrap)
 
4670
            tf |= Qt::TextIncludeTrailingSpaces;
 
4671
        textLayout.engine()->ignoreBidi = (tf & Qt::TextDontPrint);
 
4672
        textLayout.beginLayout();
 
4673
 
 
4674
        qreal leading = fm.leading();
 
4675
        height = -leading;
 
4676
 
 
4677
        while (1) {
 
4678
            QTextLine l = textLayout.createLine();
 
4679
            if (!l.isValid())
 
4680
                break;
 
4681
 
 
4682
            l.setLineWidth(lineWidth);
 
4683
            height += leading;
 
4684
            l.setPosition(QPointF(0., height));
 
4685
            height += l.ascent() + l.descent();
 
4686
            width = qMax(width, l.naturalTextWidth());
 
4687
        }
 
4688
        textLayout.endLayout();
 
4689
    }
 
4690
 
 
4691
    qreal yoff = 0;
 
4692
    qreal xoff = 0;
 
4693
    if (tf & Qt::AlignBottom)
 
4694
        yoff = r.height() - height;
 
4695
    else if (tf & Qt::AlignVCenter)
 
4696
        yoff = (r.height() - height)/2;
 
4697
    if (tf & Qt::AlignRight)
 
4698
        xoff = r.width() - width;
 
4699
    else if (tf & Qt::AlignHCenter)
 
4700
        xoff = (r.width() - width)/2;
 
4701
    if (brect)
 
4702
        *brect = QRectF(r.x() + xoff, r.y() + yoff, width, height);
 
4703
 
 
4704
    if (!(tf & Qt::TextDontPrint)) {
 
4705
        bool restore = false;
 
4706
        if (!dontclip) {
 
4707
            restore = true;
 
4708
            painter->save();
 
4709
            painter->setClipRect(r, Qt::IntersectClip);
 
4710
        }
 
4711
 
 
4712
        for (int i = 0; i < textLayout.lineCount(); i++) {
 
4713
            QTextLine line = textLayout.lineAt(i);
 
4714
 
 
4715
            line.draw(painter, QPointF(r.x() + xoff + line.x(), r.y() + yoff));
 
4716
        }
 
4717
 
 
4718
        if (restore) {
 
4719
            painter->restore();
 
4720
        }
 
4721
    }
 
4722
 
 
4723
    if (underlinePositions != underlinePositionStack)
 
4724
        delete [] underlinePositions;
 
4725
}
 
4726
 
 
4727
/*!
 
4728
    Sets the layout direction used by the painter when drawing text to the
 
4729
    \a direction specified.
 
4730
 
 
4731
    \sa layoutDirection()
 
4732
*/
 
4733
void QPainter::setLayoutDirection(Qt::LayoutDirection direction)
 
4734
{
 
4735
    Q_D(QPainter);
 
4736
    d->state->layoutDirection = direction;
 
4737
}
 
4738
 
 
4739
/*!
 
4740
    Returns the layout direction used by the painter when drawing text.
 
4741
 
 
4742
    \sa setLayoutDirection()
 
4743
*/
 
4744
Qt::LayoutDirection QPainter::layoutDirection() const
 
4745
{
 
4746
    Q_D(const QPainter);
 
4747
    return d->state->layoutDirection;
 
4748
}
 
4749
 
 
4750
QPainterState::QPainterState(const QPainterState *s)
 
4751
{
 
4752
    font = s->font;
 
4753
    deviceFont = s->deviceFont;
 
4754
    pen = QPen(s->pen);
 
4755
    brush = QBrush(s->brush);
 
4756
    bgOrigin = s->bgOrigin;
 
4757
    bgBrush = QBrush(s->bgBrush);
 
4758
    clipRegion = QRegion(s->clipRegion);
 
4759
    clipPath = s->clipPath;
 
4760
    clipOperation = s->clipOperation;
 
4761
    bgMode = s->bgMode;
 
4762
    VxF = s->VxF;
 
4763
    WxF = s->WxF;
 
4764
#ifndef QT_NO_TRANSFORMATIONS
 
4765
    worldMatrix = s->worldMatrix;
 
4766
    matrix = s->matrix;
 
4767
    txop = s->txop;
 
4768
#else
 
4769
    xlatex = s->xlatex;
 
4770
    xlatey = s->xlatey;
 
4771
#endif
 
4772
    wx = s->wx;
 
4773
    wy = s->wy;
 
4774
    ww = s->ww;
 
4775
    wh = s->wh;
 
4776
    vx = s->vx;
 
4777
    vy = s->vy;
 
4778
    vw = s->vw;
 
4779
    vh = s->vh;
 
4780
    painter = s->painter;
 
4781
    clipInfo = s->clipInfo;
 
4782
    layoutDirection = s->layoutDirection;
 
4783
    composition_mode = s->composition_mode;
 
4784
    emulationSpecifier = s->emulationSpecifier;
 
4785
    dirtyFlags = s->dirtyFlags;
 
4786
    changeFlags = 0;
 
4787
    renderHints = s->renderHints;
 
4788
}
 
4789
 
 
4790
QPainterState::QPainterState()
 
4791
{
 
4792
    init(0);
 
4793
}
 
4794
 
 
4795
QPainterState::~QPainterState()
 
4796
{
 
4797
}
 
4798
 
 
4799
void QPainterState::init(QPainter *p) {
 
4800
    bgBrush = Qt::white;
 
4801
    bgMode = Qt::TransparentMode;
 
4802
    WxF = false;
 
4803
    VxF = false;
 
4804
    wx = wy = ww = wh = 0;
 
4805
    vx = vy = vw = vh = 0;
 
4806
    painter = p;
 
4807
    pen = QPen();
 
4808
    bgOrigin = QPointF(0, 0);
 
4809
    brush = QBrush();
 
4810
    font = deviceFont = QFont();
 
4811
    clipRegion = QRegion();
 
4812
    clipPath = QPainterPath();
 
4813
    clipOperation = Qt::NoClip;
 
4814
#ifndef QT_NO_TRANSFORMATIONS
 
4815
    worldMatrix.reset();
 
4816
    matrix.reset();
 
4817
    txop = 0;
 
4818
#else
 
4819
    xlatex = xlatey = 0;
 
4820
#endif
 
4821
    layoutDirection = QApplication::layoutDirection();
 
4822
    composition_mode = QPainter::CompositionMode_SourceOver;
 
4823
    emulationSpecifier = 0;
 
4824
    dirtyFlags = 0;
 
4825
    changeFlags = 0;
 
4826
    renderHints = 0;
 
4827
}
 
4828
 
 
4829
#ifdef QT3_SUPPORT
 
4830
static void bitBlt_helper(QPaintDevice *dst, const QPoint &dp,
 
4831
                          const QPaintDevice *src, const QRect &sr, bool)
 
4832
{
 
4833
    Q_ASSERT(dst);
 
4834
    Q_ASSERT(src);
 
4835
 
 
4836
    if (src->devType() == QInternal::Pixmap) {
 
4837
        const QPixmap *pixmap = static_cast<const QPixmap *>(src);
 
4838
        QPainter pt(dst);
 
4839
        // quieten the warning for engines that don't support it.
 
4840
        if (pt.paintEngine()->hasFeature(QPaintEngine::PorterDuff))
 
4841
            pt.setCompositionMode(QPainter::CompositionMode_Source);
 
4842
        pt.drawPixmap(dp, *pixmap, sr);
 
4843
 
 
4844
    } else {
 
4845
        qWarning("::bitBlt only works when source is of type pixmap");
 
4846
    }
 
4847
}
 
4848
 
 
4849
void bitBlt(QPaintDevice *dst, int dx, int dy,
 
4850
             const QPaintDevice *src, int sx, int sy, int sw, int sh,
 
4851
             bool ignoreMask )
 
4852
{
 
4853
    bitBlt_helper(dst, QPoint(dx, dy), src, QRect(sx, sy, sw, sh), ignoreMask);
 
4854
}
 
4855
 
 
4856
void bitBlt(QPaintDevice *dst, const QPoint &dp, const QPaintDevice *src, const QRect &sr, bool ignoreMask)
 
4857
{
 
4858
    bitBlt_helper(dst, dp, src, sr, ignoreMask);
 
4859
}
 
4860
 
 
4861
void bitBlt(QPaintDevice *dst, int dx, int dy,
 
4862
            const QImage *src, int sx, int sy, int sw, int sh, Qt::ImageConversionFlags flags)
 
4863
{
 
4864
    QPixmap srcPixmap = QPixmap::fromImage(*src, flags);
 
4865
    bitBlt_helper(dst, QPoint(dx, dy), &srcPixmap, QRect(sx, sy, sw, sh), false);
 
4866
}
 
4867
 
 
4868
#endif // QT3_SUPPORT
 
4869
 
 
4870
/*!
 
4871
    \fn void QPainter::setBackgroundColor(const QColor &color)
 
4872
 
 
4873
    Use setBackground() instead.
 
4874
*/
 
4875
 
 
4876
/*!
 
4877
    \fn const QColor &QPainter::backgroundColor() const
 
4878
 
 
4879
    Use background().color() instead.
 
4880
*/
 
4881
 
 
4882
/*!
 
4883
    \fn void QPainter::drawText(int x, int y, const QString &text, int pos, int len)
 
4884
    \compat
 
4885
 
 
4886
    Use drawText(x, y, text.mid(pos, len)) instead.
 
4887
*/
 
4888
 
 
4889
/*!
 
4890
    \fn void QPainter::drawText(const QPoint &p, const QString &text, int pos, int len)
 
4891
    \compat
 
4892
 
 
4893
    Use drawText(p, text.mid(pos, len)) instead.
 
4894
*/
 
4895
 
 
4896
/*!
 
4897
    \fn void QPainter::drawText(int x, int y, const QString &text, int len)
 
4898
    \compat
 
4899
 
 
4900
    Use drawText(x, y, text.left(len)) instead.
 
4901
*/
 
4902
 
 
4903
/*!
 
4904
    \fn void QPainter::drawText(const QPoint &p, const QString &s, int len)
 
4905
    \compat
 
4906
 
 
4907
    Use drawText(p, text.left(len)) instead.
 
4908
*/
 
4909
 
 
4910
/*!
 
4911
    \fn bool QPainter::begin(QPaintDevice *pdev, const QWidget *init)
 
4912
    \compat
 
4913
*/
 
4914
 
 
4915
 
 
4916
/*!
 
4917
    \fn void QPainter::drawImage(const QPoint &p, const QImage &image)
 
4918
 
 
4919
    Draws the image \a image at point \a p.
 
4920
 
 
4921
    \sa drawPixmap()
 
4922
*/
 
4923
 
 
4924
/*!
 
4925
    \fn void QPainter::drawImage(const QPointF &p, const QImage &image)
 
4926
 
 
4927
    \overload
 
4928
 
 
4929
    Draws the image \a image at point \a p.
 
4930
 
 
4931
    \sa drawPixmap()
 
4932
*/
 
4933
 
 
4934
/*!
 
4935
    \fn void QPainter::drawImage(const QPointF &p, const QImage &image, const QRectF &sr,
 
4936
                                 Qt::ImageConversionFlags flags = 0)
 
4937
 
 
4938
    Draws the rectangle \a sr of image \a image with its origin at point \a p.
 
4939
 
 
4940
    If the image needs to be modified to fit in a lower-resolution
 
4941
    result (e.g. converting from 32-bit to 8-bit), use the \a flags to
 
4942
    specify how you would prefer this to happen.
 
4943
 
 
4944
    \sa drawPixmap()
 
4945
*/
 
4946
 
 
4947
/*!
 
4948
    \fn void QPainter::drawImage(const QPoint &p, const QImage &image, const QRect &sr,
 
4949
                                 Qt::ImageConversionFlags flags = 0)
 
4950
    \overload
 
4951
 
 
4952
    Draws the rectangle \a sr of image \a image with its origin at point \a p.
 
4953
 
 
4954
    \sa drawPixmap()
 
4955
*/
 
4956
 
 
4957
/*!
 
4958
    \fn void QPainter::drawImage(const QRectF &rectangle, const QImage &image)
 
4959
 
 
4960
    Draws \a image into \a rectangle.
 
4961
 
 
4962
    \sa drawPixmap()
 
4963
*/
 
4964
 
 
4965
/*!
 
4966
    \fn void QPainter::drawImage(const QRect &rectangle, const QImage &image)
 
4967
 
 
4968
    \overload
 
4969
 
 
4970
    Draws \a image into \a rectangle.
 
4971
 
 
4972
    \sa drawPixmap()
 
4973
*/
 
4974
 
 
4975
/*!
 
4976
    \fn void QPainter::drawImage(int x, int y, const QImage &image,
 
4977
                                 int sx, int sy, int sw, int sh,
 
4978
                                 Qt::ImageConversionFlags flags)
 
4979
    \overload
 
4980
 
 
4981
    Draws an image at (\a{x}, \a{y}) by copying a part of \a image into
 
4982
    the paint device.
 
4983
 
 
4984
    (\a{x}, \a{y}) specifies the top-left point in the paint device that is
 
4985
    to be drawn onto. (\a{sx}, \a{sy}) specifies the top-left point in \a
 
4986
    image that is to be drawn. The default is (0, 0).
 
4987
 
 
4988
    (\a{sw}, \a{sh}) specifies the size of the image that is to be drawn.
 
4989
    The default, (-1, -1), means all the way to the bottom-right of
 
4990
    the image.
 
4991
 
 
4992
    \sa drawPixmap()
 
4993
*/
 
4994
 
 
4995
/*!
 
4996
    \fn void QPainter::drawImage(const QRect &targetRect, const QImage &image, const QRect &sourceRect,
 
4997
                                 Qt::ImageConversionFlags flags)
 
4998
    \overload
 
4999
*/
 
5000
 
 
5001
/*!
 
5002
    \fn void QPainter::redirect(QPaintDevice *pdev, QPaintDevice *replacement)
 
5003
 
 
5004
    Use setRedirected() instead.
 
5005
*/
 
5006
 
 
5007
/*!
 
5008
    \fn QPaintDevice *QPainter::redirect(QPaintDevice *pdev)
 
5009
 
 
5010
    Use redirected() instead.
 
5011
*/
 
5012
 
 
5013
/*!
 
5014
    \fn QRect QPainter::boundingRect(const QRect &rect, int flags,
 
5015
                                     const QString &text, int len)
 
5016
    \compat
 
5017
*/
 
5018
 
 
5019
/*!
 
5020
    \fn void QPainter::drawText(const QRect &r, int flags, const QString &str,
 
5021
                                int len, QRect *br)
 
5022
    \compat
 
5023
*/
 
5024
 
 
5025
/*!
 
5026
    \fn QRect QPainter::boundingRect(int x, int y, int w, int h, int flags,
 
5027
                                     const QString &text, int len);
 
5028
 
 
5029
    \compat
 
5030
 
 
5031
    Returns the bounding rectangle of the first \a len characters of
 
5032
    the given \a text constrained by the rectangle that begins at
 
5033
    point (\a{x}, \a{y}) with width \a w and height \a h.
 
5034
*/
 
5035
 
 
5036
/*!
 
5037
    \fn void QPainter::drawText(int x, int y, int w, int h, int flags,
 
5038
                                const QString &str, int len, QRect *br)
 
5039
 
 
5040
    \compat
 
5041
 
 
5042
    Draws the string \a str within the rectangle with origin (\a{x},
 
5043
    \a{y}), width \a w and height \a h. If \a len is -1 (the default)
 
5044
    all the text is drawn, otherwise only the first \a len characters
 
5045
    are drawn. The flags that are given in the \a flags parameter are
 
5046
    \l{Qt::AlignmentFlag}s and \l{Qt::TextFlag}s OR'd together. \a br
 
5047
    (if not null) is set to the actual bounding rectangle of the
 
5048
    output.
 
5049
*/
 
5050
 
 
5051
 
 
5052
QPen QPaintEngineState::pen() const
 
5053
{
 
5054
    return static_cast<const QPainterState *>(this)->pen;
 
5055
}
 
5056
 
 
5057
QBrush QPaintEngineState::brush() const
 
5058
{
 
5059
    return static_cast<const QPainterState *>(this)->brush;
 
5060
}
 
5061
 
 
5062
QPointF QPaintEngineState::brushOrigin() const
 
5063
{
 
5064
    return static_cast<const QPainterState *>(this)->bgOrigin;
 
5065
}
 
5066
 
 
5067
QBrush QPaintEngineState::backgroundBrush() const
 
5068
{
 
5069
    return static_cast<const QPainterState *>(this)->bgBrush;
 
5070
}
 
5071
 
 
5072
Qt::BGMode QPaintEngineState::backgroundMode() const
 
5073
{
 
5074
    return static_cast<const QPainterState *>(this)->bgMode;
 
5075
}
 
5076
 
 
5077
QFont QPaintEngineState::font() const
 
5078
{
 
5079
    return static_cast<const QPainterState *>(this)->font;
 
5080
}
 
5081
 
 
5082
QMatrix QPaintEngineState::matrix() const
 
5083
{
 
5084
    return static_cast<const QPainterState *>(this)->matrix;
 
5085
}
 
5086
 
 
5087
Qt::ClipOperation QPaintEngineState::clipOperation() const
 
5088
{
 
5089
    return static_cast<const QPainterState *>(this)->clipOperation;
 
5090
}
 
5091
 
 
5092
QRegion QPaintEngineState::clipRegion() const
 
5093
{
 
5094
    return static_cast<const QPainterState *>(this)->clipRegion;
 
5095
}
 
5096
 
 
5097
QPainterPath QPaintEngineState::clipPath() const
 
5098
{
 
5099
    return static_cast<const QPainterState *>(this)->clipPath;
 
5100
}
 
5101
 
 
5102
QPainter::RenderHints QPaintEngineState::renderHints() const
 
5103
{
 
5104
    return static_cast<const QPainterState *>(this)->renderHints;
 
5105
}
 
5106
 
 
5107
QPainter::CompositionMode QPaintEngineState::compositionMode() const
 
5108
{
 
5109
    return static_cast<const QPainterState *>(this)->composition_mode;
 
5110
}
 
5111
 
 
5112
QPainter *QPaintEngineState::painter() const
 
5113
{
 
5114
    return static_cast<const QPainterState *>(this)->painter;
 
5115
}
 
5116
 
 
5117