1
/****************************************************************************
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
5
** This file is part of the painting module of the Qt Toolkit.
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.
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.
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.
21
** Contact info@trolltech.com if any conditions of this licensing are
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.
27
****************************************************************************/
32
#include "qpaintdevice.h"
33
#include "qpaintengine.h"
35
#include "qpainter_p.h"
36
#include "qpainterpath.h"
38
#include "qpixmapcache.h"
40
#include "qtextlayout.h"
42
#include "qapplication.h"
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>
56
// #define QT_DEBUG_DRAW
58
bool qt_show_painter_debug_output = true;
61
extern QPixmap qt_pixmapForBrush(int style, bool invert);
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,
68
template <class From, class To> QVector<To> qt_convert_points(const From *points, int pointCount, const To & /*dummy*/)
71
v.reserve(pointCount);
72
for (int i=0; i<pointCount; ++i)
77
void QPainterPrivate::draw_helper(const QPainterPath &originalPath, DrawOperation op)
80
if (qt_show_painter_debug_output) {
81
printf("QPainter::drawHelper\n");
85
if (originalPath.isEmpty())
89
int devMinX = 0, devMaxX = 0, devMinY = 0, devMaxY = 0;
91
qreal strokeOffsetX = 0, strokeOffsetY = 0;
93
QPainterPath path = originalPath * state->matrix;
94
QRectF pathBounds = path.boundingRect();
95
bool doStroke = (op & StrokeDraw) && (state->pen.style() != Qt::NoPen);
97
qreal penWidth = state->pen.widthF();
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();
113
strokeOffsetX = penWidth / 2.0 * state->matrix.m11();
114
strokeOffsetY = penWidth / 2.0 * state->matrix.m22();
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);
125
QRect absPathRect(devMinX, devMinY, devMaxX - devMinX, devMaxY - devMinY);
127
if (state->clipInfo.size() == 0) {
128
absPathRect = absPathRect.intersect(QRect(0, 0, device->width(), device->height()));
130
QRegion r = q->clipRegion() * q->deviceMatrix();
131
absPathRect = absPathRect.intersect(r.boundingRect());
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();
141
if (absPathRect.width() <= 0 || absPathRect.height() <= 0)
144
QImage image(absPathRect.width(), absPathRect.height(), QImage::Format_ARGB32_Premultiplied);
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);
157
p.setRenderHint(QPainter::Antialiasing, state->renderHints & QPainter::Antialiasing);
158
p.setRenderHint(QPainter::SmoothPixmapTransform,
159
state->renderHints & QPainter::SmoothPixmapTransform);
161
p.drawPath(originalPath);
166
q->setMatrix(QMatrix(1, 0, 0, 1, -redirection_offset.x(), -redirection_offset.y()));
169
engine->drawImage(absPathRect,
171
QRectF(0, 0, absPathRect.width(), absPathRect.height()),
172
Qt::OrderedDither | Qt::OrderedAlphaDither);
178
void QPainterPrivate::init()
184
void QPainterPrivate::updateMatrix()
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);
194
m = state->worldMatrix * m;
196
m = state->worldMatrix;
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;
208
state->txop = TxScale;
211
state->txop = TxRotShear;
213
if (!redirection_offset.isNull()) {
214
state->txop |= TxTranslate;
216
// We want to translate in dev space so we do the adding of the redirection
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());
223
state->dirtyFlags |= QPaintEngine::DirtyTransform;
225
// printf("VxF=%d, WxF=%d\n", state->VxF, state->WxF);
226
// qDebug() << " --- using matrix" << state->matrix << redirection_offset;
230
void QPainterPrivate::updateInvMatrix()
232
Q_ASSERT(txinv == false);
233
txinv = true; // creating inverted matrix
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);
243
m = state->worldMatrix * m;
245
m = state->worldMatrix;
247
invMatrix = m.inverted(&invertible); // invert matrix
250
void QPainterPrivate::updateEmulationSpecifier(QPainterState *s)
253
bool linearGradient = false;
254
bool radialGradient = false;
255
bool conicalGradient = false;
256
bool patternBrush = false;
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;
269
s->emulationSpecifier &= ~QPaintEngine::BrushStroke;
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));
289
if (s->state() & QPaintEngine::DirtyHints) {
297
qDebug("QPainterPrivate::updateEmulationSpecifier, state=%p\n"
299
" - linearGradient: %d\n"
300
" - radialGradient: %d\n"
301
" - conicalGradient: %d\n"
302
" - patternBrush: %d\n"
311
uint(s->renderHints),
316
if (s->state() & QPaintEngine::DirtyTransform) {
317
xform = !s->matrix.isIdentity();
318
} else if (s->txop >= TxTranslate) {
322
// Check alphablending
323
if (alpha && !engine->hasFeature(QPaintEngine::AlphaBlend))
324
s->emulationSpecifier |= QPaintEngine::AlphaBlend;
326
s->emulationSpecifier &= ~QPaintEngine::AlphaBlend;
328
// Linear gradient emulation
329
if (linearGradient && !engine->hasFeature(QPaintEngine::LinearGradientFill))
330
s->emulationSpecifier |= QPaintEngine::LinearGradientFill;
332
s->emulationSpecifier &= ~QPaintEngine::LinearGradientFill;
334
// Radial gradient emulation
335
if (radialGradient && !engine->hasFeature(QPaintEngine::RadialGradientFill))
336
s->emulationSpecifier |= QPaintEngine::RadialGradientFill;
338
s->emulationSpecifier &= ~QPaintEngine::RadialGradientFill;
340
// Conical gradient emulation
341
if (conicalGradient && !engine->hasFeature(QPaintEngine::ConicalGradientFill))
342
s->emulationSpecifier |= QPaintEngine::ConicalGradientFill;
344
s->emulationSpecifier &= ~QPaintEngine::ConicalGradientFill;
347
if (patternBrush && !engine->hasFeature(QPaintEngine::PatternBrush))
348
s->emulationSpecifier |= QPaintEngine::PatternBrush;
350
s->emulationSpecifier &= ~QPaintEngine::PatternBrush;
353
if (patternBrush && xform && !engine->hasFeature(QPaintEngine::PatternTransform))
354
s->emulationSpecifier |= QPaintEngine::PatternTransform;
356
s->emulationSpecifier &= ~QPaintEngine::PatternTransform;
359
if (xform && !engine->hasFeature(QPaintEngine::PrimitiveTransform))
360
s->emulationSpecifier |= QPaintEngine::PrimitiveTransform;
362
s->emulationSpecifier &= ~QPaintEngine::PrimitiveTransform;
367
void QPainterPrivate::updateState(QPainterState *newState)
371
engine->state = newState;
373
} else if (newState->state() || engine->state!=newState) {
375
if (engine->state->painter() != newState->painter)
376
// ### this could break with clip regions vs paths.
377
engine->setDirty(QPaintEngine::AllDirty);
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);
383
// We need to store all changes made so that restore can deal with them
385
newState->changeFlags |= newState->dirtyFlags;
387
updateEmulationSpecifier(newState);
389
engine->state = newState;
390
engine->updateState(*newState);
391
engine->clearDirty(QPaintEngine::AllDirty);
398
\brief The QPainter class performs low-level painting on widgets and
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
411
The typical use of a painter is:
414
\i Construct a painter.
415
\i Set a pen, a brush etc.
417
\i Destroy the painter.
420
The common use of QPainter is inside a widget's paint
421
event. Here's one simple example:
424
void SimpleExampleWidget::paintEvent()
426
QPainter paint(this);
427
paint.setPen(Qt::blue);
428
paint.drawText(rect(), Qt::AlignCenter, "The Text");
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
436
Usage is simple, and there are many settings you can use:
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.
444
\i pen() is the currently set pen; the color or stipple that's
445
used for drawing lines or boundaries.
447
\i backgroundMode() is \c Opaque or \c Transparent, i.e. whether
448
background() is used or not.
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.
454
\i brushOrigin() is the origin of the tiled brushes, normally the
455
origin of widget's background.
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.
462
\i hasClipping() is whether the painter clips at all. (The paint
463
device clips, too.) If the painter clips, it clips to clipRegion().
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.
473
save() saves all of these settings on an internal stack, restore()
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.
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
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.
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.
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.
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
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.
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
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().
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.
534
Sometimes it is desirable to make someone else paint on an unusual
535
QPaintDevice. QPainter supports a static function to do this,
538
setTabStops() and setTabArray() can change where the tab stops
539
are, but these are very seldomly used.
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.
546
\sa QPaintDevice QWidget QPixmap QPrinter QPicture QPaintEngine,
547
{The Coordinate System}
551
\enum QPainter::RenderHint
553
Renderhints are used to specify flags to QPainter that may or
554
may not be respected by any given engine.
556
\value Antialiasing Indicates that the engine should antialias
557
edges of primitives if possible.
559
\value TextAntialiasing Indicates that the engine should antialias
562
\value SmoothPixmapTransform Indicates that the engine should use
563
a smooth pixmap transformation algorithm (such as bilinear) rather
564
than nearest neighbor.
569
Constructs a painter.
571
Notice that all painter settings (setPen, setBrush etc.) are reset
572
to default values when begin() is called.
579
d_ptr = new QPainterPrivate(this);
584
Constructs a painter that begins painting the paint device \a pd
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().
592
Here's an example using begin() and end():
594
void MyWidget::paintEvent(QPaintEvent *)
598
p.drawLine(...); // drawing code
603
The same example using this constructor:
605
void MyWidget::paintEvent(QPaintEvent *)
608
p.drawLine(...); // drawing code
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.
619
QPainter::QPainter(QPaintDevice *pd)
621
d_ptr = new QPainterPrivate(this);
628
Destroys the painter.
631
QPainter::~QPainter()
639
Returns the paint device on which this painter is currently
640
painting, or 0 if the painter is not active.
642
\sa QPaintDevice::paintingActive()
645
QPaintDevice *QPainter::device() const
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
656
\sa QPaintDevice::paintingActive()
659
bool QPainter::isActive() const
663
return d->engine->isActive();
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.
671
void QPainter::initFrom(const QWidget *widget)
673
Q_ASSERT_X(widget, "QPainter::initFrom(const QWidget *widget)", "Widget cannot be 0");
675
qWarning("QPainter::initFrom: Painter is not active, aborted");
678
QPalette pal = widget->palette();
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();
690
d->engine->setDirty(QPaintEngine::DirtyPen);
691
d->engine->setDirty(QPaintEngine::DirtyBrush);
692
d->engine->setDirty(QPaintEngine::DirtyFont);
694
d->state->layoutDirection = widget->layoutDirection();
699
Saves the current painter state (pushes the state onto a stack). A
700
save() must be followed by a corresponding restore(). end()
706
void QPainter::save()
709
if (qt_show_painter_debug_output)
710
printf("QPainter::save()\n");
713
qWarning("QPainter::save(), painter not active");
718
d->updateState(d->state);
720
d->state = new QPainterState(d->states.back());
721
d->states.push_back(d->state);
722
d->engine->state = d->state;
726
Restores the current painter state (pops a saved state off the
732
void QPainter::restore()
735
if (qt_show_painter_debug_output)
736
printf("QPainter::restore()\n");
739
if (d->states.size()<=1) {
740
qWarning("QPainter::restore(), unbalanced save/restore");
742
} else if (!isActive()) {
743
qWarning("QPainter::restore(), painter not active");
747
QPainterState *tmp = d->state;
748
d->states.pop_back();
749
d->state = d->states.back();
752
// trigger clip update if the clip path/region has changed since
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;
763
d->updateState(d->state);
769
Begins painting the paint device \a pd and returns true if
770
successful; otherwise returns false.
772
The errors that can occur are serious problems, such as these:
775
p->begin(0); // impossible - paint device cannot be 0
778
p->begin(&pm); // impossible - pm.isNull();
781
p2->begin(myWidget); // impossible - only one painter at a time
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
788
\warning A paint device can only be painted by one painter at a
794
bool QPainter::begin(QPaintDevice *pd)
800
qWarning("QPainter::begin(): Painter is already active."
801
"\n\tYou must end() the painter before a second begin()");
805
// Ensure fresh painter state
806
d->state->init(d->state->painter);
808
QPaintDevice *originalDevice = pd;
809
QPaintDevice *rpd = redirected(pd, &d->redirection_offset);
816
if (qt_show_painter_debug_output)
817
printf("QPainter::begin(), device=%p, type=%d\n", pd, pd->devType());
821
d->state->bgOrigin = QPointF();
824
d->engine = pd->paintEngine();
827
qWarning("QPainter::begin(), paintdevice returned engine == 0, type: %d\n", pd->devType());
831
switch (pd->devType()) {
832
case QInternal::Widget:
834
const QWidget *widget = static_cast<const QWidget *>(pd);
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");
844
d->state->ww = d->state->vw = widget->width();
845
d->state->wh = d->state->vh = widget->height();
848
case QInternal::Pixmap:
850
const QPixmap *pm = static_cast<const QPixmap *>(pd);
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);
863
d->state->ww = d->state->vw = pd->metric(QPaintDevice::PdmWidth);
864
d->state->wh = d->state->vh = pd->metric(QPaintDevice::PdmHeight);
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();
882
// make sure we have a font compatible with the paintdevice
883
d->state->deviceFont = d->state->font = QFont(d->state->deviceFont, d->device);
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;
888
// Slip a painter state into the engine before we do any other operations
889
d->engine->state = d->state;
891
d->engine->setPaintDevice(pd);
893
bool begun = d->engine->begin(pd);
895
qWarning("QPainter::begin(), QPaintEngine::begin() returned false\n");
898
d->engine->setActive(begun);
901
d->redirection_offset += d->engine->coordinateOffset();
903
Q_ASSERT(d->engine->isActive());
905
if (!d->redirection_offset.isNull())
908
Q_ASSERT(d->engine->isActive());
909
d->state->renderHints = QPainter::TextAntialiasing;
910
++d->device->painters;
912
d->state->emulationSpecifier = 0;
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
922
\sa begin(), isActive()
928
if (qt_show_painter_debug_output)
929
printf("QPainter::end()\n");
933
qWarning("QPainter::end: Painter is not active, aborted");
938
if (d->states.size()>1) {
939
qWarning("QPainter::end(), painter ended with %d saved states",
943
bool ended = d->engine->end();
945
d->engine->setPaintDevice(0);
947
if (d->engine->autoDestruct()) {
953
--d->device->painters;
959
If the painter is active, returns the paint engine that the painter is
960
currently operating on; otherwise 0.
963
QPaintEngine *QPainter::paintEngine() const
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.
974
\sa fontInfo(), isActive()
977
QFontMetrics QPainter::fontMetrics() const
980
return QFontMetrics(d->state->font);
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.
988
\sa fontMetrics(), isActive()
991
QFontInfo QPainter::fontInfo() const
994
return QFontInfo(d->state->font);
998
Returns the brush origin currently set.
1000
\sa setBrushOrigin()
1003
QPoint QPainter::brushOrigin() const
1005
Q_D(const QPainter);
1006
return QPointF(d->state->bgOrigin).toPoint();
1010
\fn void QPainter::setBrushOrigin(const QPoint &p)
1014
Sets the brush's origin to \a p.
1018
\fn void QPainter::setBrushOrigin(int x, int y)
1022
Sets the brush's origin to point (\a x, \a y).
1026
Sets the brush origin to \a p.
1028
The brush origin specifies the (0, 0) coordinate of the painter's
1029
brush. This setting only applies to pattern brushes and pixmap
1035
void QPainter::setBrushOrigin(const QPointF &p)
1038
#ifdef QT_DEBUG_DRAW
1039
if (qt_show_painter_debug_output)
1040
printf("QPainter::setBrushOrigin(), (%.2f,%.2f)\n", p.x(), p.y());
1042
d->state->bgOrigin = p;
1043
d->state->dirtyFlags |= QPaintEngine::DirtyBrushOrigin;
1047
\enum QPainter::CompositionMode
1049
Defines one of the Porter-Duff composition operations. Composition
1050
modes are used to specify how a source and destination pixel are
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.
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.
1062
When a composition mode is set it applies to all painting
1063
operator, pens, brushes, gradients and pixmap/image drawing.
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
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.
1073
\value CompositionMode_Clear The pixels in the destination are
1074
cleared (set to fully transparent) independent of the source.
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).
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.
1084
\value CompositionMode_SourceIn The output is the source, where the
1085
alpha is reduced by that of the destination.
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.
1091
\value CompositionMode_SourceOut The output is the source, where the
1092
alpha is reduced by the inverse of destination.
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.
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.
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.
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.
1114
Sets the composition mode to \a mode.
1116
\warning Not all paintdevices support non default composition modes.
1118
\sa QPainter::CompositionMode QPaintEngine::PaintEngineFeature
1120
void QPainter::setCompositionMode(CompositionMode mode)
1124
qWarning("QPainter::setCompositionMode(), painter not active");
1126
} else if (!d->engine->hasFeature(QPaintEngine::PorterDuff)) {
1127
qWarning("QPainter::setCompositionMode(), composition modes not supported on device");
1131
d->state->composition_mode = mode;
1132
d->state->dirtyFlags |= QPaintEngine::DirtyCompositionMode;
1136
Resturns the current composition mode.
1138
\sa QPainter::CompositionMode setCompositionMode()
1140
QPainter::CompositionMode QPainter::compositionMode() const
1142
Q_D(const QPainter);
1143
return d->state->composition_mode;
1147
Returns the current background brush.
1149
\sa setBackground() QBrush
1152
const QBrush &QPainter::background() const
1154
Q_D(const QPainter);
1155
return d->state->bgBrush;
1160
Returns true if clipping has been set; otherwise returns false.
1165
bool QPainter::hasClipping() const
1167
Q_D(const QPainter);
1168
return d->state->clipOperation != Qt::NoClip;
1173
Enables clipping if \a enable is true, or disables clipping if \a
1176
\sa hasClipping(), setClipRect(), setClipRegion()
1179
void QPainter::setClipping(bool enable)
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");
1189
qWarning("QPainter::setClipping(), painter not active, state will be reset by begin");
1193
if (hasClipping() == enable)
1197
d->state->clipRegion = clipRegion();
1198
d->state->clipOperation = Qt::ReplaceClip;
1200
d->state->clipRegion = QRegion();
1201
d->state->clipOperation = Qt::NoClip;
1203
d->state->dirtyFlags |= QPaintEngine::DirtyClipRegion;
1204
d->updateState(d->state);
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.
1213
\sa setClipRegion(), setClipRect(), setClipping()
1216
QRegion QPainter::clipRegion() const
1219
qWarning("QPainter::clipRegion(), painter not active");
1223
Q_D(const QPainter);
1225
bool lastWasNothing = true;
1228
const_cast<QPainter *>(this)->d_ptr->updateInvMatrix();
1230
for (int i=0; i<d->state->clipInfo.size(); ++i) {
1231
const QPainterClipInfo &info = d->state->clipInfo.at(i);
1233
switch (info.clipType) {
1235
case QPainterClipInfo::RegionClip: {
1236
QMatrix matrix = (info.matrix * d->invMatrix);
1237
if (lastWasNothing) {
1238
region = info.region * matrix;
1239
lastWasNothing = false;
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;
1250
region = info.region * matrix;
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;
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;
1272
region = QRegion((info.path * matrix).toFillPolygon().toPolygon(),
1273
info.path.fillRule());
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
1288
QPainterPath QPainter::clipPath() const
1290
// ### Since we do not support path intersections and path unions yet,
1291
// we just use clipRegion() here...
1293
qWarning("QPainter::clipPath(), painter not active");
1294
return QPainterPath();
1297
Q_D(const QPainter);
1298
// No clip, return empty
1299
if (d->state->clipInfo.size() == 0) {
1300
return QPainterPath();
1303
// Update inverse matrix, used below.
1305
const_cast<QPainter *>(this)->d_ptr->updateInvMatrix();
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;
1313
// Fallback to clipRegion() for now, since we don't have isect/unite for paths
1316
path.addRegion(clipRegion());
1323
\fn void QPainter::setClipRect(const QRect &rect, Qt::ClipOperation op)
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
1329
\sa setClipRegion(), clipRegion(), setClipping()
1333
\fn void QPainter::setClipRect(int x, int y, int w, int h, Qt::ClipOperation op)
1335
Sets the clip region to the rectangle \a x, \a y, \a w, \a h and
1338
\sa setClipRegion(), clipRegion(), setClipping()
1344
Sets the clip region of the rectange \a rect.
1346
void QPainter::setClipRect(const QRectF &rect, Qt::ClipOperation op)
1350
setClipPath(path, op);
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.
1357
Note that the clip region is given in logical coordinates
1358
and \e subject to \link coordsys.html coordinate
1359
transformation.\endlink
1361
\sa setClipRect(), clipRegion(), setClipping()
1364
void QPainter::setClipRegion(const QRegion &r, Qt::ClipOperation op)
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());
1373
Q_ASSERT(op != Qt::NoClip);
1375
qWarning("QPainter::setClipRegion(); painter not active");
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);
1389
Sets the transformation matrix to \a matrix and enables transformations.
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.
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
1400
World transformations are applied after the view transformations
1401
(i.e. \link setWindow() window\endlink and \link setViewport()
1404
The following functions can transform the coordinate system without using
1413
They operate on the painter's worldMatrix() and are implemented like this:
1416
void QPainter::rotate(qreal a)
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.
1429
For a brief overview of coordinate transformation, see the \link
1430
coordsys.html Coordinate System Overview. \endlink
1432
\sa matrix(), setMatrixEnabled(), QMatrix
1435
void QPainter::setMatrix(const QMatrix &matrix, bool combine)
1438
#ifdef QT_DEBUG_DRAW
1439
if (qt_show_painter_debug_output)
1440
printf("QPainter::setMatrix(), combine=%d\n", combine);
1444
qWarning("QPainter::setMatrix(), painter not active ");
1449
d->state->worldMatrix = matrix * d->state->worldMatrix; // combines
1451
d->state->worldMatrix = matrix; // set new matrix
1454
setMatrixEnabled(true);
1460
Returns the world transformation matrix.
1465
const QMatrix &QPainter::matrix() const
1467
Q_D(const QPainter);
1468
return d->state->worldMatrix;
1473
Returns the matrix that transforms from logical coordinates to
1474
device coordinates of the platform dependent paintdevice.
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.
1480
\sa matrix(), QPaintEngine::hasFeature()
1482
const QMatrix &QPainter::deviceMatrix() const
1484
Q_D(const QPainter);
1485
return d->state->matrix;
1489
Resets any transformations that were made using translate(), scale(),
1490
shear(), rotate(), setMatrix(), setViewport() and
1493
\sa matrix(), setMatrix()
1495
void QPainter::resetMatrix()
1498
#ifdef QT_DEBUG_DRAW
1499
if (qt_show_painter_debug_output)
1500
printf("QPainter::resetMatrix()\n");
1503
qWarning("QPainter::resetMatrix(), painter not active");
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);
1514
d->engine->setDirty(QPaintEngine::DirtyTransform);
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.
1523
\sa setMatrix(), matrix()
1526
void QPainter::setMatrixEnabled(bool enable)
1529
#ifdef QT_DEBUG_DRAW
1530
if (qt_show_painter_debug_output)
1531
printf("QPainter::setMatrixEnabled(), enable=%d\n", enable);
1535
qWarning("QPainter::setMatrixEnabled(), painter not active");
1538
if (enable == d->state->WxF)
1541
d->state->WxF = enable;
1546
Returns true if world transformation is enabled; otherwise returns
1549
\sa setMatrixEnabled(), setMatrix()
1552
bool QPainter::matrixEnabled() const
1554
Q_D(const QPainter);
1555
#ifndef QT_NO_TRANSFORMATIONS
1556
return d->state->WxF;
1558
return d->state->xlatex || d->state->xlatey;
1562
#ifndef QT_NO_TRANSFORMATIONS
1564
Scales the coordinate system by (\a{sx}, \a{sy}).
1566
\sa translate(), shear(), rotate(), resetXForm(), setMatrix(),
1570
void QPainter::scale(qreal sx, qreal sy)
1572
#ifdef QT_DEBUG_DRAW
1573
if (qt_show_painter_debug_output)
1574
printf("QPainter::scale(), sx=%f, sy=%f\n", sx, sy);
1583
Shears the coordinate system by (\a{sh}, \a{sv}).
1585
\sa translate(), scale(), rotate(), resetXForm(), setMatrix(),
1589
void QPainter::shear(qreal sh, qreal sv)
1591
#ifdef QT_DEBUG_DRAW
1592
if (qt_show_painter_debug_output)
1593
printf("QPainter::shear(), sh=%f, sv=%f\n", sh, sv);
1601
Rotates the coordinate system \a a degrees clockwise.
1603
\sa translate(), scale(), shear(), resetXForm(), setMatrix(),
1607
void QPainter::rotate(qreal a)
1609
#ifdef QT_DEBUG_DRAW
1610
if (qt_show_painter_debug_output)
1611
printf("QPainter::rotate(), angle=%f\n", a);
1621
\fn void QPainter::translate(qreal dx, qreal dy)
1625
Translates the coordinate system by the vector (\a dx, \a dy).
1629
\fn void QPainter::translate(const QPoint &offset)
1633
Translates the coordinate system by the given \a offset.
1637
Translates the coordinate system by \a offset. After this call,
1638
\a offset is added to points.
1640
For example, the following code draws the same point twice:
1642
void MyWidget::paintEvent()
1644
QPainter paint(this);
1646
paint.drawPoint(0, 0);
1648
paint.translate(100.0, 40.0);
1649
paint.drawPoint(-100, -40);
1653
\sa scale(), shear(), rotate(), resetXForm(), setMatrix(), xForm()
1656
void QPainter::translate(const QPointF &offset)
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);
1665
#ifndef QT_NO_TRANSFORMATIONS
1667
m.translate(dx, dy);
1672
d->state->VxF = (bool)xlatex || xlatey;
1677
Sets the clip path for the painter to \a path, with the clip
1680
The clip path is specified in logical (painter) coordinates.
1683
void QPainter::setClipPath(const QPainterPath &path, Qt::ClipOperation op)
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());
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);
1707
Draws the outline (strokes) the path \a path with the pen specified
1710
void QPainter::strokePath(const QPainterPath &path, const QPen &pen)
1713
QBrush oldBrush = d->state->brush;
1714
QPen oldPen = d->state->pen;
1716
d->state->pen = pen;
1717
d->state->brush = Qt::NoBrush;
1718
d->engine->setDirty(QPaintEngine::DirtyFlags(QPaintEngine::DirtyPen | QPaintEngine::DirtyBrush));
1723
d->state->pen = oldPen;
1724
d->state->brush = oldBrush;
1725
d->engine->setDirty(QPaintEngine::DirtyFlags(QPaintEngine::DirtyPen | QPaintEngine::DirtyBrush));
1729
Fills the path \a path using the given \a brush. The outline
1732
void QPainter::fillPath(const QPainterPath &path, const QBrush &brush)
1735
QBrush oldBrush = d->state->brush;
1736
QPen oldPen = d->state->pen;
1738
d->state->pen = Qt::NoPen;
1739
d->state->brush = brush;
1740
d->engine->setDirty(QPaintEngine::DirtyFlags(QPaintEngine::DirtyPen | QPaintEngine::DirtyBrush));
1745
d->state->pen = oldPen;
1746
d->state->brush = oldBrush;
1747
d->engine->setDirty(QPaintEngine::DirtyFlags(QPaintEngine::DirtyPen | QPaintEngine::DirtyBrush));
1751
Draws the painter path specified by \a path using the current pen
1752
for outline and the current brush for filling.
1754
void QPainter::drawPath(const QPainterPath &path)
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());
1768
d->updateState(d->state);
1770
if (d->engine->hasFeature(QPaintEngine::PainterPaths) && d->state->emulationSpecifier == 0) {
1771
d->engine->drawPath(path);
1773
d->draw_helper(path);
1779
\fn void QPainter::drawLines(const QVector<QLineF> &lines)
1781
Draws the set of lines defined by the list \a lines using the
1782
current pen and brush.
1786
\fn void QPainter::drawLines(const QVector<QLine> &lines)
1788
Draws the set of lines defined by the list \a lines using the
1789
current pen and brush.
1793
\fn void QPainter::drawLines(const QVector<QPoint> &pointPairs)
1795
Draws the set of lines defined by the vector of points specified by
1796
\a pointPairs using the current pen and brush.
1800
\fn void QPainter::drawLine(int x1, int y1, int x2, int y2)
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).
1808
\fn void QPainter::drawLine(const QPoint &p1, const QPoint &p2)
1811
Draws a line from \a p1 to \a p2.
1815
\fn void QPainter::drawLine(const QPointF &p1, const QPointF &p2)
1818
Draws a line from \a p1 to \a p2.
1822
\fn void QPainter::drawLine(const QLineF &line)
1824
Draws a line defined by \a line.
1830
\fn void QPainter::drawLine(const QLine &line)
1838
\fn void QPainter::drawRect(int x, int y, int w, int h)
1842
Draws a rectangle with upper left corner at (\a{x}, \a{y}) and with
1843
width \a w and height \a h.
1847
\fn void QPainter::drawRect(const QRect &rect)
1851
Draws the rectangle \a rect with the current pen and brush.
1855
\fn void QPainter::drawRect(const QRectF &r)
1857
Draws the rectangle \a r with the current pen and brush.
1859
A filled rectangle has a size of r.size(). A stroked rectangle
1860
has a size of r.size() plus the pen width.
1864
\fn void QPainter::drawRects(const QVector<QRectF> &rectangles)
1866
Draws the rectangles specified in \a rectangles using the
1867
current pen and brush.
1871
\fn void QPainter::drawRects(const QVector<QRect> &rectangles)
1873
Draws the rectangles specified in \a rectangles using the
1874
current pen and brush.
1878
Draws the first \a rectCount rectangles in the array \a rects
1879
using the current pen and brush.
1883
void QPainter::drawRects(const QRectF *rects, int rectCount)
1885
#ifdef QT_DEBUG_DRAW
1886
if (qt_show_painter_debug_output)
1887
printf("QPainter::drawRects(), count=%d\n", rectCount);
1889
if (!isActive() || rectCount <= 0)
1893
d->updateState(d->state);
1895
if (!d->state->emulationSpecifier) {
1896
d->engine->drawRects(rects, rectCount);
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(),
1907
d->engine->drawRects(&r, 1);
1910
QPainterPath rectPath;
1911
for (int i=0; i<rectCount; ++i)
1912
rectPath.addRect(rects[i]);
1913
d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
1918
Draws the first \a rectCount rectangles in the array \a rects
1919
using the current pen and brush.
1923
void QPainter::drawRects(const QRect *rects, int rectCount)
1925
#ifdef QT_DEBUG_DRAW
1926
if (qt_show_painter_debug_output)
1927
printf("QPainter::drawRects(), count=%d\n", rectCount);
1929
if (!isActive() || rectCount <= 0)
1933
d->updateState(d->state);
1935
if (!d->state->emulationSpecifier) {
1936
d->engine->drawRects(rects, rectCount);
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(),
1947
d->engine->drawRects(&r, 1);
1950
QPainterPath rectPath;
1951
for (int i=0; i<rectCount; ++i)
1952
rectPath.addRect(rects[i]);
1953
d->draw_helper(rectPath, QPainterPrivate::StrokeAndFillDraw);
1958
/*! \fn void QPainter::drawPoint(const QPoint &p)
1959
Draws a single point at position \a p using the current pen's color.
1965
\fn void QPainter::drawPoint(const QPointF &p)
1967
Draws a single point at position \a p using the current pen's color.
1972
/*! \fn void QPainter::drawPoint(int x, int y)
1976
Draws a single point at position (\a x, \a y).
1980
\fn void QPainter::drawPoints(const QPolygon &points, int index,
1987
Draws \a npoints points in the polygon \a points starting on \a index
1988
using the current pen.
1992
/*! \fn void QPainter::drawPoints(const QPolygonF &points)
1996
Draws the points in the list \a points.
2000
Draws the first \a pointCount points in the array \a points using
2001
the current pen's color.
2005
void QPainter::drawPoints(const QPointF *points, int pointCount)
2007
#ifdef QT_DEBUG_DRAW
2008
if (qt_show_painter_debug_output)
2009
printf("QPainter::drawPoints(), count=%d\n", pointCount);
2011
if (!isActive() || pointCount <= 0)
2014
d->updateState(d->state);
2016
if (!d->state->emulationSpecifier) {
2017
d->engine->drawPoints(points, pointCount);
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);
2031
setBrush(d->state->pen.color());
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);
2043
Draws the first \a pointCount points in the array \a points using
2044
the current pen's color.
2049
void QPainter::drawPoints(const QPoint *points, int pointCount)
2051
#ifdef QT_DEBUG_DRAW
2052
if (qt_show_painter_debug_output)
2053
printf("QPainter::drawPoints(), count=%d\n", pointCount);
2055
if (!isActive() || pointCount <= 0)
2058
d->updateState(d->state);
2060
if (!d->state->emulationSpecifier) {
2061
d->engine->drawPoints(points, pointCount);
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);
2075
setBrush(d->state->pen.color());
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);
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.
2088
Transparent mode draws stippled lines and text without setting the
2089
background pixels. Opaque mode fills these space with the current
2092
Note that in order to draw a bitmap or pixmap transparently, you
2093
must use QPixmap::setMask().
2095
\sa backgroundMode(), setBackground()
2098
void QPainter::setBackgroundMode(Qt::BGMode mode)
2100
#ifdef QT_DEBUG_DRAW
2101
if (qt_show_painter_debug_output)
2102
printf("QPainter::setBackgroundMode(), mode=%d\n", mode);
2105
if (mode != Qt::TransparentMode && mode != Qt::OpaqueMode) {
2106
qWarning("QPainter::setBackgroundMode: Invalid mode");
2110
d->state->bgMode = mode;
2111
d->state->dirtyFlags |= QPaintEngine::DirtyBackgroundMode;
2115
Returns the current background mode.
2117
\sa setBackgroundMode() Qt::BGMode
2119
Qt::BGMode QPainter::backgroundMode() const
2121
Q_D(const QPainter);
2122
return d->state->bgMode;
2129
Sets the painter's pen to have style \c Qt::SolidLine, width 0 and the
2135
void QPainter::setPen(const QColor &color)
2137
#ifdef QT_DEBUG_DRAW
2138
if (qt_show_painter_debug_output)
2139
printf("QPainter::setPen(), color=%04x\n", color.rgb());
2141
setPen(QPen(color.isValid() ? color : QColor(Qt::black), 0, Qt::SolidLine));
2145
Sets a new painter pen.
2147
The \a pen defines how to draw lines and outlines, and it also
2148
defines the text color.
2153
void QPainter::setPen(const QPen &pen)
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());
2162
d->state->pen = pen;
2163
d->state->dirtyFlags |= QPaintEngine::DirtyPen;
2169
Sets the painter's pen to have style \a style, width 0 and black
2175
void QPainter::setPen(Qt::PenStyle style)
2177
setPen(QPen(Qt::black, 0, style));
2181
Returns the painter's current pen.
2186
const QPen &QPainter::pen() const
2188
Q_D(const QPainter);
2189
return d->state->pen;
2196
Sets the painter's brush to \a brush.
2198
The \a brush defines how shapes are filled.
2203
void QPainter::setBrush(const QBrush &brush)
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());
2210
d->state->brush = brush;
2211
d->state->dirtyFlags |= QPaintEngine::DirtyBrush;
2216
Sets the painter's brush to black color and the specified \a
2222
void QPainter::setBrush(Qt::BrushStyle style)
2224
setBrush(QBrush(Qt::black, style));
2228
Returns the painter's current brush.
2230
\sa QPainter::setBrush()
2233
const QBrush &QPainter::brush() const
2235
Q_D(const QPainter);
2236
return d->state->brush;
2240
Sets the background brush of the painter to \a bg.
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).
2246
\sa background() setBackgroundMode() Qt::BGMode
2249
void QPainter::setBackground(const QBrush &bg)
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());
2257
d->state->bgBrush = bg;
2258
d->state->dirtyFlags |= QPaintEngine::DirtyBackground;
2262
Sets the painter's font to \a font.
2264
This font is used by subsequent drawText() functions. The text
2265
color is the same as the pen color.
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).
2272
\sa font(), drawText()
2275
void QPainter::setFont(const QFont &font)
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());
2283
d->state->font = QFont(font.resolve(d->state->deviceFont), d->device);
2284
d->state->dirtyFlags |= QPaintEngine::DirtyFont;
2288
Returns the currently set painter font.
2290
\sa setFont(), QFont
2293
const QFont &QPainter::font() const
2295
Q_D(const QPainter);
2296
return d->state->font;
2300
\fn QPainter::drawRoundRect(int x, int y, int w, int h, int xRnd, int yRnd)
2304
Draws the rectangle \a x, \a y, \a w, \a h with rounded corners.
2308
\fn void QPainter::drawRoundRect(const QRect &r, int xRnd = 25, int yRnd = 25)
2312
Draws the rectangle \a r with rounded corners.
2317
Draws a rectangle \a r with rounded corners.
2319
The \a xRnd and \a yRnd arguments specify how rounded the corners
2320
should be. 0 is angled corners, 99 is maximum roundedness.
2322
A filled rectangle has a size of r.size(). A stroked rectangle
2323
has a size of r.size() plus the pen width.
2325
\sa drawRect(), QPen
2327
void QPainter::drawRoundRect(const QRectF &r, int xRnd, int yRnd)
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());
2337
if(xRnd >= 100) // fix ranges
2341
if(xRnd <= 0 || yRnd <= 0) { // draw normal rectangle
2346
QRectF rect = r.normalized();
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?
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();
2377
\fn QPainter::drawEllipse(const QRect &r)
2381
Draws an ellipse that fits inside the rectangle \a r.
2385
\fn QPainter::drawEllipse(int x, int y, int w, int h)
2389
Draws an ellipse that fits inside the rectangle (\a{x}, \a{y}, \a{w},
2394
Draws the ellipse that fits inside the rectangle \a r.
2396
A filled ellipse has a size of r.size(). An stroked ellipse
2397
has a size of r.size() plus the pen width.
2399
void QPainter::drawEllipse(const QRectF &r)
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());
2409
d->updateState(d->state);
2411
QRectF rect(r.normalized());
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()));
2422
path.addEllipse(rect);
2423
d->draw_helper(path, QPainterPrivate::StrokeAndFillDraw);
2428
d->engine->drawEllipse(rect);
2431
void QPainter::drawEllipse(const QRect &r)
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());
2441
d->updateState(d->state);
2443
QRect rect(r.normalized());
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())));
2454
path.addEllipse(rect);
2455
d->draw_helper(path, QPainterPrivate::StrokeAndFillDraw);
2460
d->engine->drawEllipse(rect);
2464
/*! \fn void QPainter::drawArc(const QRect &r, int startAngle,
2469
Draws the arc that fits inside the rectangle \a r, with the given
2470
\a startAngle and \a spanAngle.
2474
\fn void QPainter::drawArc(int x, int y, int w, int h,
2475
int startAngle, int spanAngle)
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.
2484
Draws an arc defined by the rectangle \a r, the start angle \a a
2485
and the arc length \a alen.
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.
2494
QPainter p(myWidget);
2495
p.drawArc(QRect(10,10, 70,100), 100*16, 160*16); // draws a "(" arc
2498
\sa drawPie(), drawChord()
2501
void QPainter::drawArc(const QRectF &r, int a, int alen)
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);
2512
d->updateState(d->state);
2514
QRectF rect = r.normalized();
2517
qt_find_ellipse_coords(r, a/16.0, alen/16.0, &startPoint, 0);
2520
path.moveTo(startPoint);
2521
path.arcTo(rect, a/16.0, alen/16.0);
2522
strokePath(path, d->state->pen);
2527
\fn void QPainter::drawPie(const QRect &rect, int startAngle, int spanAngle)
2531
Draws a pie segment that fits inside the rectangle \a rect with
2532
the given \a startAngle and \a spanAngle.
2536
\fn void QPainter::drawPie(int x, int y, int w, int h, int
2537
startAngle, int spanAngle)
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.
2546
Draws a pie defined by the rectangle \a r, the start angle \a a
2547
and the arc length \a alen.
2549
The pie is filled with the current brush().
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.
2556
\sa drawArc(), drawChord()
2558
void QPainter::drawPie(const QRectF &r, int a, int alen)
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);
2569
d->updateState(d->state);
2575
if (a < 0) a += (360*16);
2578
QRectF rect = r.normalized();
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();
2589
\fn void QPainter::drawChord(const QRect &r, int startAngle, int spanAngle)
2593
Draws a chord that fits inside the rectangle \a r with the given
2594
\a startAngle and \a spanAngle.
2598
\fn void QPainter::drawChord(int x, int y, int w, int h, int
2599
startAngle, int spanAngle)
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.
2609
Draws a chord defined by the rectangle \a r, the start angle \a a
2610
and the arc length \a alen.
2612
The chord is filled with the current brush().
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.
2619
\sa drawArc(), drawPie()
2622
void QPainter::drawChord(const QRectF &r, int a, int alen)
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);
2633
d->updateState(d->state);
2635
QRectF rect = r.normalized();
2638
qt_find_ellipse_coords(r, a/16.0, alen/16.0, &startPoint, 0);
2641
path.moveTo(startPoint);
2642
path.arcTo(rect.x(), rect.y(), rect.width(), rect.height(), a/16.0, alen/16.0);
2643
path.closeSubpath();
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).
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.
2657
\sa drawPolyline(), drawPolygon(), QPen
2660
void QPainter::drawLineSegments(const QPolygon &a, int index, int nlines)
2662
#ifdef QT_DEBUG_DRAW
2663
if (qt_show_painter_debug_output)
2664
printf("QPainter::drawLineSegments(), count=%d\n", a.size()/2);
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)
2678
d->updateState(d->state);
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);
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));
2693
d->draw_helper(linesPath, QPainterPrivate::StrokeDraw);
2697
for (int i=index; i<index + nlines*2; i+=2)
2698
lines << QLineF(a.at(i), a.at(i+1));
2701
d->engine->drawLines(lines.data(), lines.size());
2703
#endif // QT3_SUPPORT
2705
Draws the first \a lineCount lines in the array \a lines
2706
using the current pen.
2708
void QPainter::drawLines(const QLineF *lines, int lineCount)
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());
2720
d->updateState(d->state);
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);
2736
QPainterPath linePath;
2737
for (int i = 0; i < lineCount; ++i) {
2738
linePath.moveTo(lines[i].p1());
2739
linePath.lineTo(lines[i].p2());
2741
d->draw_helper(linePath, QPainterPrivate::StrokeDraw);
2745
d->engine->drawLines(lines, lineCount);
2749
Draws the first \a lineCount lines in the array \a lines
2750
using the current pen.
2752
void QPainter::drawLines(const QLine *lines, int lineCount)
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());
2764
d->updateState(d->state);
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);
2780
QPainterPath linePath;
2781
for (int i = 0; i < lineCount; ++i) {
2782
linePath.moveTo(lines[i].p1());
2783
linePath.lineTo(lines[i].p2());
2785
d->draw_helper(linePath, QPainterPrivate::StrokeDraw);
2789
d->engine->drawLines(lines, lineCount);
2794
\fn void QPainter::drawLines(const QVector<QPointF> &pointPairs)
2798
Draws a line for each pair of points in the vector \a pointPairs using
2801
If there is an odd number of points in the array, the last point
2808
Draws the first \a lineCount lines in the array \a pointPairs using
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
2816
void QPainter::drawLines(const QPointF *pointPairs, int lineCount)
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);
2826
Draws the first \a lineCount lines in the array \a pointPairs using
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
2834
void QPainter::drawLines(const QPoint *pointPairs, int lineCount)
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);
2844
\fn void QPainter::drawPolyline(const QPolygon &pa, int index, int
2851
Draws the polyline defined by the \a npoints points in \a pa
2852
starting at \a index. (\a index defaults to 0.)
2857
\fn void QPainter::drawPolyline(const QPolygon &pa)
2861
Draws the polyline defined by \a pa using the current pen.
2865
\fn void QPainter::drawPolyline(const QPolygonF &pa)
2869
Draws the polyline defined by \a pa using the current pen.
2873
Draws the polyline defined by the first \a pointCount points in \a
2874
points using the current pen.
2876
\sa drawLines(), drawPolygon(), QPen
2879
void QPainter::drawPolyline(const QPointF *points, int pointCount)
2881
#ifdef QT_DEBUG_DRAW
2882
if (qt_show_painter_debug_output)
2883
printf("QPainter::drawPolyline(), count=%d\n", pointCount);
2886
if (!isActive() || pointCount <= 0)
2890
d->updateState(d->state);
2892
uint lineEmulation = d->state->emulationSpecifier
2893
& (QPaintEngine::PrimitiveTransform
2894
| QPaintEngine::AlphaBlend
2895
| QPaintEngine::Antialiasing
2896
| QPaintEngine::BrushStroke);
2898
if (lineEmulation) {
2900
// if (lineEmulation == QPaintEngine::PrimitiveTransform
2901
// && d->state->txop == QPainterPrivate::TxTranslate) {
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);
2909
d->engine->drawPolygon(points, pointCount, QPaintEngine::PolylineMode);
2915
Draws the polyline defined by the first \a pointCount points in
2916
the array \a points using the current pen.
2918
void QPainter::drawPolyline(const QPoint *points, int pointCount)
2920
// ### don't realloc
2921
QVector<QPointF> pts = qt_convert_points(points, pointCount, QPointF());
2922
drawPolyline(pts.data(), pts.size());
2926
/*! \fn void QPainter::drawPolygon(const QPolygon &pa, bool winding,
2927
int index = 0, int npoints = -1)
2932
Draws the polygon defined by the points in the point array \a pa.
2935
/*! \fn void QPainter::drawPolygon(const QPolygon &pa, Qt::FillRule fillRule)
2939
Draws the polygon defined by the points in \a pa using the fill
2943
/*! \fn void QPainter::drawPolygon(const QPolygonF &pa, Qt::FillRule fillRule)
2947
Draws the polygon defined by the points in \a pa using the fill
2951
/*! \fn void QPainter::drawPolygon(const QPolygonF &polygon, bool winding, int index = 0,
2958
Draws the polygon defined by the first \a pointCount points in the
2959
array \a points using the current pen and brush.
2961
The first point is implicitly connected to the last point.
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.
2969
\sa drawLines() drawPolyline() QPen
2972
void QPainter::drawPolygon(const QPointF *points, int pointCount, Qt::FillRule fillRule)
2974
#ifdef QT_DEBUG_DRAW
2975
if (qt_show_painter_debug_output)
2976
printf("QPainter::drawPolygon(), count=%d\n", pointCount);
2979
if (!isActive() || pointCount <= 0)
2983
d->updateState(d->state);
2985
uint emulationSpecifier = d->state->emulationSpecifier;
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);
2997
d->engine->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
3002
Draws the polygon defined by the first \a pointCount points in the
3005
void QPainter::drawPolygon(const QPoint *points, int pointCount, Qt::FillRule fillRule)
3007
#ifdef QT_DEBUG_DRAW
3008
if (qt_show_painter_debug_output)
3009
printf("QPainter::drawPolygon(), count=%d\n", pointCount);
3012
if (!isActive() || pointCount <= 0)
3016
d->updateState(d->state);
3018
uint emulationSpecifier = d->state->emulationSpecifier;
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);
3030
d->engine->drawPolygon(points, pointCount, QPaintEngine::PolygonDrawMode(fillRule));
3035
\fn void QPainter::drawConvexPolygon(const QPolygonF &polygon)
3039
Draws the convex polygon defined by \a polygon using the current
3044
\fn void QPainter::drawConvexPolygon(const QPolygon &polygon)
3048
Draws the convex polygon defined by \a polygon using the current
3053
\fn void QPainter::drawConvexPolygon(const QPolygonF &polygon, int
3060
Draws the convex polygon defined by \a polygon using the current
3065
\fn void QPainter::drawConvexPolygon(const QPolygon &polygon, int
3072
Draws the convex polygon defined by \a polygon using the current
3077
Draws the convex polygon defined by the first \a pointCount points
3078
in the array \a points using the current pen and brush.
3080
If the supplied polygon is not convex, the results are undefined.
3082
On some platforms (e.g. X11), drawing convex polygons can be
3083
faster than drawPolygon().
3088
void QPainter::drawConvexPolygon(const QPoint *points, int pointCount)
3090
// ### Fix when QPainter::drawPolygon(QPolygon, PolyDrawMode) is in place
3091
drawPolygon(points, pointCount, Qt::WindingFill);
3095
Draws the convex polygon defined by the first \a pointCount points
3096
in the array \a points using the current pen and brush.
3098
If the supplied polygon is not convex, the results are undefined.
3100
On some platforms (e.g. X11), drawing convex polygons can be
3101
faster than drawPolygon().
3105
void QPainter::drawConvexPolygon(const QPointF *points, int pointCount)
3107
// ### Fix when QPainter::drawPolygon(QPolygon, PolyDrawMode) is in place
3108
drawPolygon(points, pointCount, Qt::WindingFill);
3113
\fn void QPainter::drawPixmap(const QRect &targetRect, const QPixmap &pixmap,
3114
const QRect &sourceRect)
3117
Draws the rectangular portion \a sourceRect of the pixmap \a pixmap
3118
in the rectangle \a targetRect.
3124
\fn void QPainter::drawPixmap(const QPointF &p, const QPixmap &pixmap,
3125
const QRectF &sourceRect)
3128
Draws the rectangular portion \a sourceRect of the pixmap \a
3129
pixmap at the point \a p.
3135
\fn void QPainter::drawPixmap(const QPointF &p, const QPixmap &pixmap)
3138
Draws the \a pixmap at the point \a p.
3144
\fn void QPainter::drawPixmap(int x, int y, const QPixmap &pixmap)
3148
Draws the given \a pixmap at position (\a{x}, \a{y}).
3154
\fn void QPainter::drawPixmap(int x, int y, int width, int height,
3155
const QPixmap &pixmap)
3159
Draws the \a pixmap in the rectangle at position (\a{x}, \a{y})
3160
and of the given \a width and \a height.
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)
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.
3180
\fn void QPainter::drawPixmap(int x, int y, const QPixmap &pixmap,
3181
int sx, int sy, int sw, int sh)
3185
Draws a pixmap at (\a{x}, \a{y}) by copying a part of \a pixmap into
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).
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
3196
\sa QPixmap::setMask() drawImage()
3200
\fn void QPainter::drawPixmap(const QPoint &p, const QPixmap &pm, const QRect &sr)
3203
Draws the rectangle \a sr of pixmap \a pm with its origin at point
3210
\fn void QPainter::drawPixmap(const QPoint &p, const QPixmap &pm)
3213
Draws the pixmap \a pm with its origin at point \a p.
3219
\fn void QPainter::drawPixmap(const QRect &r, const QPixmap &pm)
3222
Draws the pixmap \a pm into the rectangle \a r.
3228
Draws the rectanglular portion \a sr, of pixmap \a pm, into rectangle
3229
\a r in the paint device.
3233
void QPainter::drawPixmap(const QRectF &r, const QPixmap &pm, const QRectF &sr)
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());
3244
if (!isActive() || pm.isNull())
3246
d->updateState(d->state);
3250
qreal w = r.width();
3251
qreal h = r.height();
3254
qreal sw = sr.width();
3255
qreal sh = sr.height();
3257
// Sanity-check clipping
3258
if (sw <= 0 || sw + sx > pm.width())
3259
sw = pm.width() - sx;
3261
if (sh <= 0 || sh + sy > pm.height())
3262
sh = pm.height() - sy;
3281
if (w == 0 || h == 0 || sw <= 0 || sh <= 0)
3284
if (d->state->txop > QPainterPrivate::TxTranslate
3285
&& !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
3287
if(sx != 0 || sy != 0 || sw != pm.width() || sh != pm.height()) {
3288
source = pm.copy(qRound(sx), qRound(sy), qRound(sw), qRound(sh));
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
3304
d->state->matrix.map(x, y, &x, &y); // compute position of pixmap
3306
mat.map(0, 0, &dx, &dy);
3307
if (pmx.depth() == 1) {
3309
setClipRect(QRectF(r.x(), r.y(), w, h), Qt::IntersectClip);
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)
3316
if (!d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
3317
x += qRound(d->state->matrix.dx());
3318
y += qRound(d->state->matrix.dy());
3320
d->engine->drawPixmap(QRectF(x, y, w, h), pm, QRectF(sx, sy, sw, sh));
3325
Draws the rectanglular portion \a sourceRect, of image \a image, into rectangle
3326
\a targetRect in the paint device.
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.
3334
void QPainter::drawImage(const QRectF &targetRect, const QImage &image, const QRectF &sourceRect,
3335
Qt::ImageConversionFlags flags)
3337
if (!isActive() || image.isNull())
3341
d->updateState(d->state);
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();
3352
// Sanity-check clipping
3353
if (sw <= 0 || sw + sx > image.width())
3354
sw = image.width() - sx;
3356
if (sh <= 0 || sh + sy > image.height())
3357
sh = image.height() - sy;
3376
if (sw <= 0 || sh <= 0)
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);
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());
3392
d->engine->drawImage(QRectF(x, y, w, h), image, QRectF(sx, sy, sw, sh), flags);
3396
\fn void QPainter::drawText(int x, int y, const QString &text)
3400
Draws the given \a text at position (\a{x}, \a{y}), using the painter's
3401
text layout direction.
3403
\sa layoutDirection(), setLayoutDirection()
3407
\fn void QPainter::drawText(int x, int y, int w, int h, int flags,
3408
const QString &text, QRect *br)
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
3421
Draws the string \a str with the currently defined text direction,
3422
beginning at position \a p.
3424
\sa Qt::LayoutDirection
3427
void QPainter::drawText(const QPointF &p, const QString &str)
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());
3434
if (!isActive() || str.isEmpty())
3438
d->updateState(d->state);
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);
3446
layout.beginLayout();
3447
QTextLine line = layout.createLine();
3449
const QScriptLine &sl = engine->lines[0];
3450
line.draw(this, QPointF(p.x(), p.y() - sl.ascent));
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.
3462
void QPainter::drawText(const QRect &r, int flags, const QString &str, QRect *br)
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());
3470
if (!isActive() || str.length() == 0)
3474
d->updateState(d->state);
3477
qt_format_text(font(), r, flags, str, &bounds, 0, 0, 0, this);
3479
*br = bounds.toRect();
3482
/*! \fn void QPainter::drawText(const QPoint &p, const QString &s)
3486
Draws the string \a s at position \a p, using the painter's layout
3489
\sa layoutDirection(), setLayoutDirection()
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.
3499
void QPainter::drawText(const QRectF &r, int flags, const QString &str, QRectF *br)
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());
3507
if (!isActive() || str.length() == 0)
3511
d->updateState(d->state);
3513
qt_format_text(font(), r, flags, str, br, 0, 0, 0, this);
3517
\fn void QPainter::drawText(const QRectF &rectangle, const QString &text,
3518
const QTextOption &option)
3520
Draws the given \a text in the \a rectangle specified using the \a option
3521
to control its positioning and orientation.
3523
void QPainter::drawText(const QRectF &r, const QString &text, const QTextOption &o)
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());
3531
if (!isActive() || text.length() == 0)
3535
d->updateState(d->state);
3537
int flags = o.alignment();
3539
if (o.wrapMode() == QTextOption::WordWrap)
3540
flags |= Qt::TextWordWrap;
3541
else if (o.wrapMode() == QTextOption::WrapAnywhere)
3542
flags |= Qt::TextWrapAnywhere;
3544
if (o.flags() & QTextOption::IncludeTrailingSpaces)
3545
flags |= Qt::TextIncludeTrailingSpaces;
3547
qt_format_text(font(), r, flags, text, 0, 0, 0, 0, this);
3551
\fn void QPainter::drawTextItem(int x, int y, const QTextItem &ti)
3558
\fn void QPainter::drawTextItem(const QPoint &p, const QTextItem &ti)
3563
Draws the text item \a ti at position \a p.
3567
Draws the text item \a ti at position \a p.
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.
3573
It ignores the font set on the painter as the text item has one of its own.
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.
3580
void QPainter::drawTextItem(const QPointF &p, const QTextItem &ti)
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()));
3590
d->updateState(d->state);
3591
d->engine->drawTextItem(p, ti);
3595
\fn QRect QPainter::boundingRect(int x, int y, int w, int h, int flags,
3596
const QString &text);
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.
3606
\fn QRect QPainter::boundingRect(const QRect &rect, int flags,
3611
Returns the bounding rectangle constrained by rectangle \a rect.
3615
QRect QPainter::boundingRect(const QRect &rect, int flags, const QString &str)
3618
return QRect(rect.x(),rect.y(), 0,0);
3620
drawText(rect, flags | Qt::TextDontPrint, str, &brect);
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.
3631
The \a flags argument is
3632
the bitwise OR of the following flags:
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.
3648
Qt::Horizontal alignment defaults to \c Qt::AlignLeft and vertical
3649
alignment defaults to \c Qt::AlignTop.
3651
If several of the horizontal or several of the vertical alignment flags
3652
are set, the resulting alignment is undefined.
3657
QRectF QPainter::boundingRect(const QRectF &rect, int flags, const QString &str)
3660
return QRectF(rect.x(),rect.y(), 0,0);
3662
drawText(rect, flags | Qt::TextDontPrint, str, &brect);
3667
\fn QRectF QPainter::boundingRect(const QRectF &rectangle,
3668
const QString &text, const QTextOption &option)
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.
3674
QRectF QPainter::boundingRect(const QRectF &r, const QString &text, const QTextOption &o)
3676
if (!isActive() || text.length() == 0)
3677
return QRectF(r.x(),r.y(), 0,0);
3680
d->updateState(d->state);
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;
3691
qt_format_text(font(), r, flags, text, &br, 0, 0, 0, this);
3696
\fn void QPainter::drawTiledPixmap(int x, int y, int w, int h, const
3697
QPixmap &pixmap, int sx, int sy);
3699
Draws a tiled \a pixmap in the specified rectangle.
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).
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
3714
/*! \fn QPainter::drawTiledPixmap(const QRect &rect, const QPixmap &pixmap,
3715
const QPoint &sp = QPoint())
3718
Draws a tiled \a pixmap, inside rectangle \a rect with its origin
3725
Draws a tiled \a pixmap, inside rectangle \a r with its origin
3728
void QPainter::drawTiledPixmap(const QRectF &r, const QPixmap &pixmap, const QPointF &sp)
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(),
3738
if (!isActive() || pixmap.isNull() || r.isEmpty())
3741
d->updateState(d->state);
3743
qreal sw = pixmap.width();
3744
qreal sh = pixmap.height();
3748
sx = qRound(sw) - qRound(-sx) % qRound(sw);
3750
sx = qRound(sx) % qRound(sw);
3752
sy = qRound(sh) - -qRound(sy) % qRound(sh);
3754
sy = qRound(sy) % qRound(sh);
3756
if (d->state->txop > QPainterPrivate::TxTranslate
3757
&& !d->engine->hasFeature(QPaintEngine::PixmapTransform)) {
3759
if (pixmap.hasAlphaChannel()) {
3760
QImage img(qRound(r.width()), qRound(r.height()), QImage::Format_ARGB32_Premultiplied);
3762
pm = QPixmap::fromImage(img);
3764
pm = QPixmap(qRound(r.width()), qRound(r.height()));
3767
// Recursive call ok, since the pixmap is not transformed...
3769
p.setBackground(background());
3770
p.setBackgroundMode(backgroundMode());
3771
p.drawTiledPixmap(QRectF(0, 0, r.width(), r.height()), pixmap, QPointF(sx, sy));
3773
if (backgroundMode() == Qt::TransparentMode && pixmap.depth() == 1) {
3774
QBitmap mask(pm.width(), pm.height());
3777
p.drawTiledPixmap(QRectF(0, 0, r.width(), r.height()), pixmap, QPointF(sx, sy));
3781
drawPixmap(qRound(r.x()), qRound(r.y()), pm);
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());
3793
d->engine->drawTiledPixmap(QRectF(x, y, r.width(), r.height()), pixmap, QPointF(sx, sy));
3798
\fn void QPainter::drawPicture(int x, int y, const QPicture &picture)
3801
Draws picture \a picture at point (\a x, \a y).
3805
\fn void QPainter::drawPicture(const QPoint &p, const QPicture &picture)
3808
Draws picture \a picture at point \a p.
3812
Replays the picture \a picture at point \a p.
3814
This function does exactly the same as QPicture::play() when
3815
called with \a p = QPoint(0, 0).
3818
void QPainter::drawPicture(const QPointF &p, const QPicture &picture)
3823
d->updateState(d->state);
3826
const_cast<QPicture *>(&picture)->play(this);
3830
/*! \fn void QPainter::eraseRect(const QRect &rect)
3834
Erases the area inside the rectangle \a rect. Equivalent to
3835
\c{fillRect(rect, backgroundColor())}.
3839
Erases the area inside the rectangle \a r. Equivalent to
3840
\c{fillRect(r, backgroundColor())}.
3842
void QPainter::eraseRect(const QRectF &r)
3847
d->updateState(d->state);
3849
if (d->state->bgBrush.texture().isNull())
3850
fillRect(r, d->state->bgBrush);
3852
drawTiledPixmap(r, d->state->bgBrush.texture(), -d->state->bgOrigin);
3856
\fn void QPainter::eraseRect(int x, int y, int w, int h)
3859
Erases the area inside \a x, \a y, \a w, \a h. Equivalent to
3860
\c{fillRect(x, y, w, h, backgroundColor())}.
3865
Fills the rectangle \a r with the \a brush.
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
3873
void QPainter::fillRect(const QRectF &r, const QBrush &brush)
3875
QPen oldPen = pen();
3876
bool swap = oldPen.style() != Qt::NoPen;
3879
QBrush oldBrush = this->brush();
3887
void QPainter::fillRect(const QRect &r, const QBrush &brush)
3889
QPen oldPen = pen();
3890
bool swap = oldPen.style() != Qt::NoPen;
3893
QBrush oldBrush = this->brush();
3902
\fn void QPainter::fillRect(const QRect &rect, const QBrush &brush)
3906
Fills the rectangle \a rect with the \a brush.
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
3916
\fn void QPainter::fillRect(int x, int y, int w, int h, const QBrush &brush)
3920
Fills the rectangle (\a{x}, \a{y}, \a{w}, \a{h}) with the \a brush.
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
3931
Sets the render hint \a hint on this painter if \a on is true;
3932
otherwise clears the render hint.
3934
void QPainter::setRenderHint(RenderHint hint, bool on)
3936
#ifdef QT_DEBUG_DRAW
3937
if (qt_show_painter_debug_output)
3938
printf("QPainter::setRenderHint(), hint=%x, %s\n", hint, on ? "on" : "off");
3942
qWarning("Painter must be active to set rendering hints");
3949
d->state->renderHints |= hint;
3951
d->state->renderHints &= ~hint;
3953
d->state->dirtyFlags |= QPaintEngine::DirtyHints;
3957
Returns a flag that specifies the rendering hints that are set for
3960
QPainter::RenderHints QPainter::renderHints() const
3963
qWarning("Painter must be active to set rendering hints");
3966
Q_D(const QPainter);
3967
return d->state->renderHints;
3971
Returns true if view transformation is enabled; otherwise returns
3974
\sa setViewTransformEnabled(), matrix()
3977
bool QPainter::viewTransformEnabled() const
3979
Q_D(const QPainter);
3980
#ifndef QT_NO_TRANSFORMATIONS
3981
return d->state->VxF;
3983
return d->state->xlatex || d->state->xlatey;
3988
\fn void QPainter::setWindow(const QRect &r)
3992
Sets the painter's window to the rectangle \a r.
3996
\fn void QPainter::setWindow(int x, int y, int w, int h)
3998
Sets the window rectangle view transformation for the painter and
3999
enables view transformation.
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.
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.
4010
\sa window(), setViewport(), setViewTransformEnabled(), setMatrix(),
4014
void QPainter::setWindow(const QRect &r)
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());
4022
qWarning("QPainter::setWindow(), painter not active");
4028
d->state->wx = r.x();
4029
d->state->wy = r.y();
4030
d->state->ww = r.width();
4031
d->state->wh = r.height();
4035
setViewTransformEnabled(true);
4039
Returns the window rectangle.
4041
\sa setWindow(), setViewTransformEnabled()
4044
QRect QPainter::window() const
4046
Q_D(const QPainter);
4047
return QRect(d->state->wx, d->state->wy, d->state->ww, d->state->wh);
4051
\fn void QPainter::setViewport(const QRect &r)
4055
Sets the painter's viewport rectangle to \a r.
4059
\fn void QPainter::setViewport(int x, int y, int w, int h)
4061
Sets the viewport rectangle view transformation for the painter
4062
and enables view transformation.
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.
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.
4073
\sa viewport(), setWindow(), setViewTransformEnabled(), setMatrix(),
4077
void QPainter::setViewport(const QRect &r)
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());
4085
qWarning("QPainter::setViewport(), painter not active");
4091
d->state->vx = r.x();
4092
d->state->vy = r.y();
4093
d->state->vw = r.width();
4094
d->state->vh = r.height();
4098
setViewTransformEnabled(true);
4102
Returns the viewport rectangle.
4104
\sa setViewport(), setViewTransformEnabled()
4107
QRect QPainter::viewport() const
4109
Q_D(const QPainter);
4110
return QRect(d->state->vx, d->state->vy, d->state->vw, d->state->vh);
4113
/*! \fn bool QPainter::hasViewXForm() const
4116
Use viewTransformEnabled() instead.
4119
/*! \fn bool QPainter::hasWorldXForm() const
4122
Use matrixEnabled() instead.
4125
/*! \fn void QPainter::resetXForm()
4128
Use resetMatrix() instead.
4131
/*! \fn void QPainter::setViewXForm(bool enabled)
4134
Use setViewTransformEnabled() instead.
4137
/*! \fn void QPainter::setWorldMatrix(const QMatrix &wm, bool combine=false)
4140
Use setMatrix() instead.
4143
/*! \fn void QPainter::setWorldXForm(bool enabled)
4146
Use setMatrixEnabled() instead.
4149
/*! \fn const QMatrix &QPainter::worldMatrix() const
4152
Use matrix() instead.
4156
Enables view transformations if \a enable is true, or disables
4157
view transformations if \a enable is false.
4159
\sa viewTransformEnabled(), setWindow(), setViewport(), setMatrix(),
4163
void QPainter::setViewTransformEnabled(bool enable)
4165
#ifdef QT_DEBUG_DRAW
4166
if (qt_show_painter_debug_output)
4167
printf("QPainter::setViewTransformEnabled(), enable=%d\n", enable);
4171
qWarning("QPainter::setViewTransformEnabled(), painter not active");
4175
if (enable == d->state->VxF)
4178
d->state->VxF = enable;
4184
qreal QPainter::translationX() const
4186
Q_D(const QPainter);
4187
#ifndef QT_NO_TRANSFORMATIONS
4188
return d->state->worldMatrix.dx();
4190
return d->state->xlatex;
4194
qreal QPainter::translationY() const
4196
Q_D(const QPainter);
4197
#ifndef QT_NO_TRANSFORMATIONS
4198
return d->state->worldMatrix.dy();
4200
return d->state->xlatey;
4205
\fn void QPainter::map(int x, int y, int *rx, int *ry) const
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}).
4212
void QPainter::map(int x, int y, int *rx, int *ry) const
4214
Q_D(const QPainter);
4216
p = p * d->state->matrix;
4222
Returns the point \a p transformed from model coordinates to
4225
\sa xFormDev(), QMatrix::map()
4228
QPoint QPainter::xForm(const QPoint &p) const
4230
Q_D(const QPainter);
4231
#ifndef QT_NO_TRANSFORMATIONS
4232
if (d->state->txop == QPainterPrivate::TxNone)
4234
return p * d->state->matrix;
4236
return QPoint(p.x() + d->state->xlatex, p.y() + d->state->xlatey);
4244
Returns the rectangle \a r transformed from model coordinates to
4247
If world transformation is enabled and rotation or shearing has
4248
been specified, then the bounding rectangle is returned.
4250
\sa xFormDev(), QMatrix::map()
4253
QRect QPainter::xForm(const QRect &r) const
4255
Q_D(const QPainter);
4256
#ifndef QT_NO_TRANSFORMATIONS
4257
if (d->state->txop == QPainterPrivate::TxNone)
4259
return d->state->matrix.mapRect(r);
4261
return QRect(r.x()+d->state->xlatex, r.y()+d->state->xlatey, r.width(), r.height());
4268
Returns the point array \a a transformed from model coordinates
4269
to device coordinates.
4271
\sa xFormDev(), QMatrix::map()
4274
QPolygon QPainter::xForm(const QPolygon &a) const
4276
Q_D(const QPainter);
4277
#ifndef QT_NO_TRANSFORMATIONS
4278
if (d->state->txop == QPainterPrivate::TxNone)
4280
return a * d->state->matrix;
4283
p.translate(d->state->xlatex, d->state->xlatey);
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.
4297
The returned point array consists of the number of points that
4304
b = painter.xForm(a, 2, 4); // b.size() == 4
4305
b = painter.xForm(a, 2, -1); // b.size() == 8
4308
\sa xFormDev(), QMatrix::map()
4311
QPolygon QPainter::xForm(const QPolygon &av, int index, int npoints) const
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;
4320
a.translate(d->state->xlatex, d->state->xlatey);
4328
Returns the point \a p transformed from device coordinates to
4331
\sa xForm(), QMatrix::map()
4334
QPoint QPainter::xFormDev(const QPoint &p) const
4336
Q_D(const QPainter);
4337
#ifndef QT_NO_TRANSFORMATIONS
4338
if(d->state->txop == QPainterPrivate::TxNone)
4341
QPainter *that = (QPainter*)this; // mutable
4342
that->d_ptr->updateInvMatrix();
4344
return p * d->invMatrix;
4346
return QPoint(p.x() - xlatex, p.y() - xlatey);
4351
Returns the rectangle \a r transformed from device coordinates to
4354
If world transformation is enabled and rotation or shearing is
4355
used, then the bounding rectangle is returned.
4357
\sa xForm(), QMatrix::map()
4360
QRect QPainter::xFormDev(const QRect &r) const
4362
Q_D(const QPainter);
4363
#ifndef QT_NO_TRANSFORMATIONS
4364
if (d->state->txop == QPainterPrivate::TxNone)
4367
QPainter *that = (QPainter*)this; // mutable
4368
that->d_ptr->updateInvMatrix();
4370
return d->invMatrix.mapRect(r);
4372
return QRect(r.x()-d->state->xlatex, r.y()-d->state->xlatey, r.width(), r.height());
4379
Returns the point array \a a transformed from device coordinates
4380
to model coordinates.
4382
\sa xForm(), QMatrix::map()
4385
QPolygon QPainter::xFormDev(const QPolygon &a) const
4387
Q_D(const QPainter);
4388
#ifndef QT_NO_TRANSFORMATIONS
4389
if (d->state->txop == QPainterPrivate::TxNone)
4392
QPainter *that = (QPainter*)this; // mutable
4393
that->d_ptr->updateInvMatrix();
4395
return a * d->invMatrix;
4398
p.translate(-d->state->xlatex, -d->state->xlatey);
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.
4413
The returned point array consists of the number of points that
4420
b = painter.xFormDev(a, 1, 3); // b.size() == 3
4421
b = painter.xFormDev(a, 1, -1); // b.size() == 9
4424
\sa xForm(), QMatrix::map()
4427
QPolygon QPainter::xFormDev(const QPolygon &ad, int index, int npoints) const
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)
4437
QPainter *that = (QPainter*)this; // mutable
4438
that->d_ptr->updateInvMatrix();
4440
return a * d->invMatrix;
4442
a.translate(-d->state->xlatex, -d->state->xlatey);
4448
\fn void QPainter::drawPoints(const QPolygon &points)
4452
Draws the points in the polygon \a points using the current pen's color.
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).
4460
Control points after \a{a}\e{[index + 3]} are ignored. Nothing happens
4461
if there aren't enough control points.
4463
void QPainter::drawCubicBezier(const QPolygon &a, int index)
4468
d->updateState(d->state);
4470
if ((int)a.size() - index < 4) {
4471
qWarning("QPainter::drawCubicBezier: Cubic Bezier needs 4 control "
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);
4483
struct QPaintDeviceRedirection
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;
4492
bool operator==(const QPaintDevice *pdev) const { return device == pdev; }
4493
Q_DUMMY_COMPARISON_OPERATOR(QPaintDeviceRedirection)
4496
typedef QList<QPaintDeviceRedirection> QPaintDeviceRedirectionList;
4497
Q_GLOBAL_STATIC(QPaintDeviceRedirectionList, globalRedirections)
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().
4507
In general, you'll probably find calling QPixmap::grabWidget() or
4508
QPixmap::grabWindow() is an easier solution.
4512
void QPainter::setRedirected(const QPaintDevice *device,
4513
QPaintDevice *replacement,
4514
const QPoint &offset)
4516
Q_ASSERT(device != 0);
4517
QPaintDeviceRedirectionList *redirections = globalRedirections();
4518
Q_ASSERT(redirections != 0);
4521
QPaintDevice *rdev = redirected(replacement, &roffset);
4522
*redirections += QPaintDeviceRedirection(device, rdev ? rdev : replacement, offset + roffset);
4528
Restores the previous redirection for \a device after a call to
4533
void QPainter::restoreRedirected(const QPaintDevice *device)
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);
4549
Returns the replacement for \a device. The optional out parameter
4550
\a offset returns return the offset within the replaced device.
4552
QPaintDevice *QPainter::redirected(const QPaintDevice *device, QPoint *offset)
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) {
4560
*offset = redirections->at(i).offset;
4561
return redirections->at(i).replacement;
4564
*offset = QPoint(0, 0);
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,
4574
// we need to copy r here to protect against the case (&r == brect).
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);
4583
tf = QStyle::visualAlignment(painter ? painter->layoutDirection() : QApplication::layoutDirection(), QFlag(tf));
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)));
4591
tf |= Qt::TextDontPrint;
4593
int maxUnderlines = 0;
4594
int numUnderlines = 0;
4595
int underlinePositionStack[32];
4596
int *underlinePositions = underlinePositionStack;
4598
QFont fnt(painter ? painter->d_ptr->state->font : font);
4599
QFontMetricsF fm(fnt);
4602
// compatible behaviour to the old implementation. Replace
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'))) {
4609
} else if (*chr == QLatin1Char('\n')) {
4610
*chr = QChar::LineSeparator;
4611
} else if (*chr == QLatin1Char('&')) {
4618
while (chr != end) {
4619
if (*chr == QLatin1Char('\t'))
4620
*chr = QLatin1Char(' ');
4623
} else if (!tabarraylen && !tabstops) {
4624
tabstops = qRound(fm.width(QLatin1Char('x'))*8);
4627
if (hidemnmemonic || showmnemonic) {
4628
if (maxUnderlines > 32)
4629
underlinePositions = new int[maxUnderlines];
4630
QChar *cout = text.data();
4632
int l = str.length();
4634
if (*cin == QLatin1Char('&')) {
4639
if (*cin != QLatin1Char('&') && !hidemnmemonic)
4640
underlinePositions[numUnderlines++] = cout - text.unicode();
4647
int newlen = cout - text.unicode();
4648
if (newlen != text.length())
4649
text.resize(newlen);
4652
// no need to do extra work for underlines if we don't paint
4653
if (tf & Qt::TextDontPrint)
4656
underlinePositions[numUnderlines] = -1;
4660
QTextLayout textLayout(text, fnt);
4661
textLayout.engine()->underlinePositions = underlinePositions;
4663
if (text.isEmpty()) {
4664
height = fm.height();
4666
tf |= Qt::TextDontPrint;
4668
qreal lineWidth = wordwrap ? qMax<qreal>(0, r.width()) : 0x01000000;
4670
tf |= Qt::TextIncludeTrailingSpaces;
4671
textLayout.engine()->ignoreBidi = (tf & Qt::TextDontPrint);
4672
textLayout.beginLayout();
4674
qreal leading = fm.leading();
4678
QTextLine l = textLayout.createLine();
4682
l.setLineWidth(lineWidth);
4684
l.setPosition(QPointF(0., height));
4685
height += l.ascent() + l.descent();
4686
width = qMax(width, l.naturalTextWidth());
4688
textLayout.endLayout();
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;
4702
*brect = QRectF(r.x() + xoff, r.y() + yoff, width, height);
4704
if (!(tf & Qt::TextDontPrint)) {
4705
bool restore = false;
4709
painter->setClipRect(r, Qt::IntersectClip);
4712
for (int i = 0; i < textLayout.lineCount(); i++) {
4713
QTextLine line = textLayout.lineAt(i);
4715
line.draw(painter, QPointF(r.x() + xoff + line.x(), r.y() + yoff));
4723
if (underlinePositions != underlinePositionStack)
4724
delete [] underlinePositions;
4728
Sets the layout direction used by the painter when drawing text to the
4729
\a direction specified.
4731
\sa layoutDirection()
4733
void QPainter::setLayoutDirection(Qt::LayoutDirection direction)
4736
d->state->layoutDirection = direction;
4740
Returns the layout direction used by the painter when drawing text.
4742
\sa setLayoutDirection()
4744
Qt::LayoutDirection QPainter::layoutDirection() const
4746
Q_D(const QPainter);
4747
return d->state->layoutDirection;
4750
QPainterState::QPainterState(const QPainterState *s)
4753
deviceFont = s->deviceFont;
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;
4764
#ifndef QT_NO_TRANSFORMATIONS
4765
worldMatrix = s->worldMatrix;
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;
4787
renderHints = s->renderHints;
4790
QPainterState::QPainterState()
4795
QPainterState::~QPainterState()
4799
void QPainterState::init(QPainter *p) {
4800
bgBrush = Qt::white;
4801
bgMode = Qt::TransparentMode;
4804
wx = wy = ww = wh = 0;
4805
vx = vy = vw = vh = 0;
4808
bgOrigin = QPointF(0, 0);
4810
font = deviceFont = QFont();
4811
clipRegion = QRegion();
4812
clipPath = QPainterPath();
4813
clipOperation = Qt::NoClip;
4814
#ifndef QT_NO_TRANSFORMATIONS
4815
worldMatrix.reset();
4819
xlatex = xlatey = 0;
4821
layoutDirection = QApplication::layoutDirection();
4822
composition_mode = QPainter::CompositionMode_SourceOver;
4823
emulationSpecifier = 0;
4830
static void bitBlt_helper(QPaintDevice *dst, const QPoint &dp,
4831
const QPaintDevice *src, const QRect &sr, bool)
4836
if (src->devType() == QInternal::Pixmap) {
4837
const QPixmap *pixmap = static_cast<const QPixmap *>(src);
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);
4845
qWarning("::bitBlt only works when source is of type pixmap");
4849
void bitBlt(QPaintDevice *dst, int dx, int dy,
4850
const QPaintDevice *src, int sx, int sy, int sw, int sh,
4853
bitBlt_helper(dst, QPoint(dx, dy), src, QRect(sx, sy, sw, sh), ignoreMask);
4856
void bitBlt(QPaintDevice *dst, const QPoint &dp, const QPaintDevice *src, const QRect &sr, bool ignoreMask)
4858
bitBlt_helper(dst, dp, src, sr, ignoreMask);
4861
void bitBlt(QPaintDevice *dst, int dx, int dy,
4862
const QImage *src, int sx, int sy, int sw, int sh, Qt::ImageConversionFlags flags)
4864
QPixmap srcPixmap = QPixmap::fromImage(*src, flags);
4865
bitBlt_helper(dst, QPoint(dx, dy), &srcPixmap, QRect(sx, sy, sw, sh), false);
4868
#endif // QT3_SUPPORT
4871
\fn void QPainter::setBackgroundColor(const QColor &color)
4873
Use setBackground() instead.
4877
\fn const QColor &QPainter::backgroundColor() const
4879
Use background().color() instead.
4883
\fn void QPainter::drawText(int x, int y, const QString &text, int pos, int len)
4886
Use drawText(x, y, text.mid(pos, len)) instead.
4890
\fn void QPainter::drawText(const QPoint &p, const QString &text, int pos, int len)
4893
Use drawText(p, text.mid(pos, len)) instead.
4897
\fn void QPainter::drawText(int x, int y, const QString &text, int len)
4900
Use drawText(x, y, text.left(len)) instead.
4904
\fn void QPainter::drawText(const QPoint &p, const QString &s, int len)
4907
Use drawText(p, text.left(len)) instead.
4911
\fn bool QPainter::begin(QPaintDevice *pdev, const QWidget *init)
4917
\fn void QPainter::drawImage(const QPoint &p, const QImage &image)
4919
Draws the image \a image at point \a p.
4925
\fn void QPainter::drawImage(const QPointF &p, const QImage &image)
4929
Draws the image \a image at point \a p.
4935
\fn void QPainter::drawImage(const QPointF &p, const QImage &image, const QRectF &sr,
4936
Qt::ImageConversionFlags flags = 0)
4938
Draws the rectangle \a sr of image \a image with its origin at point \a p.
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.
4948
\fn void QPainter::drawImage(const QPoint &p, const QImage &image, const QRect &sr,
4949
Qt::ImageConversionFlags flags = 0)
4952
Draws the rectangle \a sr of image \a image with its origin at point \a p.
4958
\fn void QPainter::drawImage(const QRectF &rectangle, const QImage &image)
4960
Draws \a image into \a rectangle.
4966
\fn void QPainter::drawImage(const QRect &rectangle, const QImage &image)
4970
Draws \a image into \a rectangle.
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)
4981
Draws an image at (\a{x}, \a{y}) by copying a part of \a image into
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).
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
4996
\fn void QPainter::drawImage(const QRect &targetRect, const QImage &image, const QRect &sourceRect,
4997
Qt::ImageConversionFlags flags)
5002
\fn void QPainter::redirect(QPaintDevice *pdev, QPaintDevice *replacement)
5004
Use setRedirected() instead.
5008
\fn QPaintDevice *QPainter::redirect(QPaintDevice *pdev)
5010
Use redirected() instead.
5014
\fn QRect QPainter::boundingRect(const QRect &rect, int flags,
5015
const QString &text, int len)
5020
\fn void QPainter::drawText(const QRect &r, int flags, const QString &str,
5026
\fn QRect QPainter::boundingRect(int x, int y, int w, int h, int flags,
5027
const QString &text, int len);
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.
5037
\fn void QPainter::drawText(int x, int y, int w, int h, int flags,
5038
const QString &str, int len, QRect *br)
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
5052
QPen QPaintEngineState::pen() const
5054
return static_cast<const QPainterState *>(this)->pen;
5057
QBrush QPaintEngineState::brush() const
5059
return static_cast<const QPainterState *>(this)->brush;
5062
QPointF QPaintEngineState::brushOrigin() const
5064
return static_cast<const QPainterState *>(this)->bgOrigin;
5067
QBrush QPaintEngineState::backgroundBrush() const
5069
return static_cast<const QPainterState *>(this)->bgBrush;
5072
Qt::BGMode QPaintEngineState::backgroundMode() const
5074
return static_cast<const QPainterState *>(this)->bgMode;
5077
QFont QPaintEngineState::font() const
5079
return static_cast<const QPainterState *>(this)->font;
5082
QMatrix QPaintEngineState::matrix() const
5084
return static_cast<const QPainterState *>(this)->matrix;
5087
Qt::ClipOperation QPaintEngineState::clipOperation() const
5089
return static_cast<const QPainterState *>(this)->clipOperation;
5092
QRegion QPaintEngineState::clipRegion() const
5094
return static_cast<const QPainterState *>(this)->clipRegion;
5097
QPainterPath QPaintEngineState::clipPath() const
5099
return static_cast<const QPainterState *>(this)->clipPath;
5102
QPainter::RenderHints QPaintEngineState::renderHints() const
5104
return static_cast<const QPainterState *>(this)->renderHints;
5107
QPainter::CompositionMode QPaintEngineState::compositionMode() const
5109
return static_cast<const QPainterState *>(this)->composition_mode;
5112
QPainter *QPaintEngineState::painter() const
5114
return static_cast<const QPainterState *>(this)->painter;