source: vendor/trolltech/current/src/kernel/qpainter.cpp

Last change on this file was 2, checked in by dmik, 20 years ago

Imported xplatform parts of the official release 3.3.1 from Trolltech

  • Property svn:keywords set to Id
File size: 102.9 KB
Line 
1/****************************************************************************
2** $Id: qpainter.cpp 2 2005-11-16 15:49:26Z dmik $
3**
4** Implementation of QPainter, QPen and QBrush classes
5**
6** Created : 940112
7**
8** Copyright (C) 1992-2002 Trolltech AS. All rights reserved.
9**
10** This file is part of the kernel module of the Qt GUI Toolkit.
11**
12** This file may be distributed under the terms of the Q Public License
13** as defined by Trolltech AS of Norway and appearing in the file
14** LICENSE.QPL included in the packaging of this file.
15**
16** This file may be distributed and/or modified under the terms of the
17** GNU General Public License version 2 as published by the Free Software
18** Foundation and appearing in the file LICENSE.GPL included in the
19** packaging of this file.
20**
21** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
22** licenses may use this file in accordance with the Qt Commercial License
23** Agreement provided with the Software.
24**
25** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
26** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
27**
28** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
29** information about Qt Commercial License Agreements.
30** See http://www.trolltech.com/qpl/ for QPL licensing information.
31** See http://www.trolltech.com/gpl/ for GPL licensing information.
32**
33** Contact info@trolltech.com if any conditions of this licensing are
34** not clear to you.
35**
36**********************************************************************/
37
38#include "qpainter.h"
39#include "qpainter_p.h"
40#include "qbitmap.h"
41#include "qptrstack.h"
42#include "qptrdict.h"
43#include "qdatastream.h"
44#include "qwidget.h"
45#include "qimage.h"
46#include "qpaintdevicemetrics.h"
47#include "qapplication.h"
48#include "qrichtext_p.h"
49#include "qregexp.h"
50#include "qcleanuphandler.h"
51#ifdef Q_WS_QWS
52#include "qgfx_qws.h"
53#endif
54#include <string.h>
55
56#include "qtextlayout_p.h"
57#include "qfontengine_p.h"
58
59#ifndef QT_NO_TRANSFORMATIONS
60typedef QPtrStack<QWMatrix> QWMatrixStack;
61#endif
62
63// POSIX Large File Support redefines truncate -> truncate64
64#if defined(truncate)
65# undef truncate
66#endif
67
68/*!
69 \class QPainter qpainter.h
70 \brief The QPainter class does low-level painting e.g. on widgets.
71
72 \ingroup graphics
73 \ingroup images
74 \mainclass
75
76 The painter provides highly optimized functions to do most of the
77 drawing GUI programs require. QPainter can draw everything from
78 simple lines to complex shapes like pies and chords. It can also
79 draw aligned text and pixmaps. Normally, it draws in a "natural"
80 coordinate system, but it can also do view and world
81 transformation.
82
83 The typical use of a painter is:
84
85 \list
86 \i Construct a painter.
87 \i Set a pen, a brush etc.
88 \i Draw.
89 \i Destroy the painter.
90 \endlist
91
92 Mostly, all this is done inside a paint event. (In fact, 99% of
93 all QPainter use is in a reimplementation of
94 QWidget::paintEvent(), and the painter is heavily optimized for
95 such use.) Here's one very simple example:
96
97 \code
98 void SimpleExampleWidget::paintEvent()
99 {
100 QPainter paint( this );
101 paint.setPen( Qt::blue );
102 paint.drawText( rect(), AlignCenter, "The Text" );
103 }
104 \endcode
105
106 Usage is simple, and there are many settings you can use:
107
108 \list
109
110 \i font() is the currently set font. If you set a font that isn't
111 available, Qt finds a close match. In fact font() returns what
112 you set using setFont() and fontInfo() returns the font actually
113 being used (which may be the same).
114
115 \i brush() is the currently set brush; the color or pattern that's
116 used for filling e.g. circles.
117
118 \i pen() is the currently set pen; the color or stipple that's
119 used for drawing lines or boundaries.
120
121 \i backgroundMode() is \c Opaque or \c Transparent, i.e. whether
122 backgroundColor() is used or not.
123
124 \i backgroundColor() only applies when backgroundMode() is Opaque
125 and pen() is a stipple. In that case, it describes the color of
126 the background pixels in the stipple.
127
128 \i rasterOp() is how pixels drawn interact with the pixels already
129 there.
130
131 \i brushOrigin() is the origin of the tiled brushes, normally the
132 origin of the window.
133
134 \i viewport(), window(), worldMatrix() and many more make up the
135 painter's coordinate transformation system. See \link
136 coordsys.html The Coordinate System \endlink for an explanation of
137 this, or see below for a very brief overview of the functions.
138
139 \i hasClipping() is whether the painter clips at all. (The paint
140 device clips, too.) If the painter clips, it clips to clipRegion().
141
142 \i pos() is the current position, set by moveTo() and used by
143 lineTo().
144
145 \endlist
146
147 Note that some of these settings mirror settings in some paint
148 devices, e.g. QWidget::font(). QPainter::begin() (or the QPainter
149 constructor) copies these attributes from the paint device.
150 Calling, for example, QWidget::setFont() doesn't take effect until
151 the next time a painter begins painting on it.
152
153 save() saves all of these settings on an internal stack, restore()
154 pops them back.
155
156 The core functionality of QPainter is drawing, and there are
157 functions to draw most primitives: drawPoint(), drawPoints(),
158 drawLine(), drawRect(), drawWinFocusRect(), drawRoundRect(),
159 drawEllipse(), drawArc(), drawPie(), drawChord(),
160 drawLineSegments(), drawPolyline(), drawPolygon(),
161 drawConvexPolygon() and drawCubicBezier(). All of these functions
162 take integer coordinates; there are no floating-point versions
163 since we want drawing to be as fast as possible.
164
165 There are functions to draw pixmaps/images, namely drawPixmap(),
166 drawImage() and drawTiledPixmap(). drawPixmap() and drawImage()
167 produce the same result, except that drawPixmap() is faster
168 on-screen and drawImage() faster and sometimes better on QPrinter
169 and QPicture.
170
171 Text drawing is done using drawText(), and when you need
172 fine-grained positioning, boundingRect() tells you where a given
173 drawText() command would draw.
174
175 There is a drawPicture() function that draws the contents of an
176 entire QPicture using this painter. drawPicture() is the only
177 function that disregards all the painter's settings: the QPicture
178 has its own settings.
179
180 Normally, the QPainter operates on the device's own coordinate
181 system (usually pixels), but QPainter has good support for
182 coordinate transformation. See \link coordsys.html The Coordinate
183 System \endlink for a more general overview and a simple example.
184
185 The most common functions used are scale(), rotate(), translate()
186 and shear(), all of which operate on the worldMatrix().
187 setWorldMatrix() can replace or add to the currently set
188 worldMatrix().
189
190 setViewport() sets the rectangle on which QPainter operates. The
191 default is the entire device, which is usually fine, except on
192 printers. setWindow() sets the coordinate system, that is, the
193 rectangle that maps to viewport(). What's drawn inside the
194 window() ends up being inside the viewport(). The window's
195 default is the same as the viewport, and if you don't use the
196 transformations, they are optimized away, gaining another little
197 bit of speed.
198
199 After all the coordinate transformation is done, QPainter can clip
200 the drawing to an arbitrary rectangle or region. hasClipping() is
201 TRUE if QPainter clips, and clipRegion() returns the clip region.
202 You can set it using either setClipRegion() or setClipRect().
203 Note that the clipping can be slow. It's all system-dependent,
204 but as a rule of thumb, you can assume that drawing speed is
205 inversely proportional to the number of rectangles in the clip
206 region.
207
208 After QPainter's clipping, the paint device may also clip. For
209 example, most widgets clip away the pixels used by child widgets,
210 and most printers clip away an area near the edges of the paper.
211 This additional clipping is not reflected by the return value of
212 clipRegion() or hasClipping().
213
214 QPainter also includes some less-used functions that are very
215 useful on those occasions when they're needed.
216
217 isActive() indicates whether the painter is active. begin() (and
218 the most usual constructor) makes it active. end() (and the
219 destructor) deactivates it. If the painter is active, device()
220 returns the paint device on which the painter paints.
221
222 Sometimes it is desirable to make someone else paint on an unusual
223 QPaintDevice. QPainter supports a static function to do this,
224 redirect(). We recommend not using it, but for some hacks it's
225 perfect.
226
227 setTabStops() and setTabArray() can change where the tab stops
228 are, but these are very seldomly used.
229
230 \warning Note that QPainter does not attempt to work around
231 coordinate limitations in the underlying window system. Some
232 platforms may behave incorrectly with coordinates as small as
233 +/-4000.
234
235 \headerfile qdrawutil.h
236
237 \sa QPaintDevice QWidget QPixmap QPrinter QPicture
238 \link simple-application.html Application Walkthrough \endlink
239 \link coordsys.html Coordinate System Overview \endlink
240*/
241
242/*!
243 \fn QGfx * QPainter::internalGfx()
244
245 \internal
246*/
247
248/*!
249 \enum QPainter::CoordinateMode
250 \value CoordDevice
251 \value CoordPainter
252
253 \sa clipRegion()
254*/
255/*!
256 \enum QPainter::TextDirection
257 \value Auto
258 \value RTL right to left
259 \value LTR left to right
260
261 \sa drawText()
262*/
263
264/*!
265 \enum Qt::PaintUnit
266 \value PixelUnit
267 \value LoMetricUnit \e obsolete
268 \value HiMetricUnit \e obsolete
269 \value LoEnglishUnit \e obsolete
270 \value HiEnglishUnit \e obsolete
271 \value TwipsUnit \e obsolete
272*/
273
274/*!
275 \enum Qt::BrushStyle
276
277 \value NoBrush
278 \value SolidPattern
279 \value Dense1Pattern
280 \value Dense2Pattern
281 \value Dense3Pattern
282 \value Dense4Pattern
283 \value Dense5Pattern
284 \value Dense6Pattern
285 \value Dense7Pattern
286 \value HorPattern
287 \value VerPattern
288 \value CrossPattern
289 \value BDiagPattern
290 \value FDiagPattern
291 \value DiagCrossPattern
292 \value CustomPattern
293
294 \img brush-styles.png Brush Styles
295
296*/
297
298/*!
299 \enum Qt::RasterOp
300
301 \keyword raster operation
302 \keyword raster op
303
304 This enum type is used to describe the way things are written to
305 the paint device. Each bit of the \e src (what you write)
306 interacts with the corresponding bit of the \e dst pixel.
307
308 \value CopyROP dst = src
309 \value OrROP dst = src OR dst
310 \value XorROP dst = src XOR dst
311 \value NotAndROP dst = (NOT src) AND dst
312 \value EraseROP an alias for \c NotAndROP
313 \value NotCopyROP dst = NOT src
314 \value NotOrROP dst = (NOT src) OR dst
315 \value NotXorROP dst = (NOT src) XOR dst
316 \value AndROP dst = src AND dst
317 \value NotEraseROP an alias for \c AndROP
318 \value NotROP dst = NOT dst
319 \value ClearROP dst = 0
320 \value SetROP dst = 1
321 \value NopROP dst = dst
322 \value AndNotROP dst = src AND (NOT dst)
323 \value OrNotROP dst = src OR (NOT dst)
324 \value NandROP dst = NOT (src AND dst)
325 \value NorROP dst = NOT (src OR dst)
326
327 By far the most useful ones are \c CopyROP and \c XorROP.
328
329 On Qt/Mac, only \c CopyROP, \c XorROP, are supported for color
330 pixels (\e src or \e dst). \c OrROP \c NotAndROP, \c NotCopyROP, \c
331 NotOrROP, \c NotXorROP, and \c AndROP are supported for black and
332 white pixels (\e src or \e dst).
333
334 On Qt/Embedded, only \c CopyROP, \c XorROP, and \c NotROP are supported.
335*/
336
337/*!
338 \enum Qt::AlignmentFlags
339
340 This enum type is used to describe alignment. It contains
341 horizontal and vertical flags.
342
343 The horizontal flags are:
344
345 \value AlignAuto Aligns according to the language. Left for most,
346 right for Arabic and Hebrew.
347 \value AlignLeft Aligns with the left edge.
348 \value AlignRight Aligns with the right edge.
349 \value AlignHCenter Centers horizontally in the available space.
350 \value AlignJustify Justifies the text in the available space.
351 Does not work for everything and may be interpreted as
352 AlignAuto in some cases.
353
354 The vertical flags are:
355
356 \value AlignTop Aligns with the top.
357 \value AlignBottom Aligns with the bottom.
358 \value AlignVCenter Centers vertically in the available space.
359
360 You can use only one of the horizontal flags at a time. There is
361 one two-dimensional flag:
362
363 \value AlignCenter Centers in both dimensions.
364
365 You can use at most one horizontal and one vertical flag at a time. \c
366 AlignCenter counts as both horizontal and vertical.
367
368 Masks:
369
370 \value AlignHorizontal_Mask
371 \value AlignVertical_Mask
372
373 Conflicting combinations of flags have undefined meanings.
374*/
375
376/*!
377 \enum Qt::TextFlags
378
379 This enum type is used to define some modifier flags. Some of
380 these flags only make sense in the context of printing:
381
382 \value SingleLine Treats all whitespace as spaces and prints just
383 one line.
384 \value DontClip If it's impossible to stay within the given bounds,
385 it prints outside.
386 \value ExpandTabs Makes the U+0009 (ASCII tab) character move to
387 the next tab stop.
388 \value ShowPrefix Displays the string "\&P" as <u>P</u>
389 (see QButton for an example). For an ampersand, use "\&\&".
390 \value WordBreak Breaks lines at appropriate points, e.g. at word
391 boundaries.
392 \value BreakAnywhere Breaks lines anywhere, even within words.
393 \value NoAccel Same as ShowPrefix but doesn't draw the underlines.
394
395 You can use as many modifier flags as you want, except that \c
396 SingleLine and \c WordBreak cannot be combined.
397
398 Flags that are inappropriate for a given use (e.g. ShowPrefix to
399 QGridLayout::addWidget()) are generally ignored.
400
401*/
402
403/*!
404 \enum Qt::PenStyle
405
406 This enum type defines the pen styles that can be drawn using
407 QPainter. The styles are
408
409 \value NoPen no line at all. For example, QPainter::drawRect()
410 fills but does not draw any boundary line.
411
412 \value SolidLine a simple line.
413
414 \value DashLine dashes separated by a few pixels.
415
416 \value DotLine dots separated by a few pixels.
417
418 \value DashDotLine alternate dots and dashes.
419
420 \value DashDotDotLine one dash, two dots, one dash, two dots.
421
422 \value MPenStyle mask of the pen styles.
423
424 \img pen-styles.png Pen Styles
425*/
426
427/*!
428 \enum Qt::PenCapStyle
429
430 This enum type defines the pen cap styles supported by Qt, i.e.
431 the line end caps that can be drawn using QPainter.
432
433 \value FlatCap a square line end that does not cover the end
434 point of the line.
435 \value SquareCap a square line end that covers the end point and
436 extends beyond it with half the line width.
437 \value RoundCap a rounded line end.
438 \value MPenCapStyle mask of the pen cap styles.
439
440 \img pen-cap-styles.png Pen Cap Styles
441*/
442
443/*!
444 \enum Qt::PenJoinStyle
445
446 This enum type defines the pen join styles supported by Qt, i.e.
447 which joins between two connected lines can be drawn using
448 QPainter.
449
450 \value MiterJoin The outer edges of the lines are extended to
451 meet at an angle, and this area is filled.
452 \value BevelJoin The triangular notch between the two lines is filled.
453 \value RoundJoin A circular arc between the two lines is filled.
454 \value MPenJoinStyle mask of the pen join styles.
455
456 \img pen-join-styles.png Pen Join Styles
457*/
458
459/*!
460 \enum Qt::BGMode
461
462 Background mode
463
464 \value TransparentMode
465 \value OpaqueMode
466*/
467
468/*!
469 Constructs a painter.
470
471 Notice that all painter settings (setPen, setBrush etc.) are reset
472 to default values when begin() is called.
473
474 \sa begin(), end()
475*/
476
477QPainter::QPainter()
478{
479 init();
480}
481
482
483/*!
484 Constructs a painter that begins painting the paint device \a pd
485 immediately. Depending on the underlying graphic system the
486 painter will paint over children of the paintdevice if \a
487 unclipped is TRUE.
488
489 This constructor is convenient for short-lived painters, e.g. in a
490 \link QWidget::paintEvent() paint event\endlink and should be used
491 only once. The constructor calls begin() for you and the QPainter
492 destructor automatically calls end().
493
494 Here's an example using begin() and end():
495 \code
496 void MyWidget::paintEvent( QPaintEvent * )
497 {
498 QPainter p;
499 p.begin( this );
500 p.drawLine( ... ); // drawing code
501 p.end();
502 }
503 \endcode
504
505 The same example using this constructor:
506 \code
507 void MyWidget::paintEvent( QPaintEvent * )
508 {
509 QPainter p( this );
510 p.drawLine( ... ); // drawing code
511 }
512 \endcode
513
514 Since the constructor cannot provide feedback when the initialization
515 of the painter failed you should rather use begin() and end() to paint
516 on external devices, e.g. printers.
517
518 \sa begin(), end()
519*/
520
521QPainter::QPainter( const QPaintDevice *pd, bool unclipped )
522{
523 init();
524 if ( begin( pd, unclipped ) )
525 flags |= CtorBegin;
526}
527
528
529/*!
530 Constructs a painter that begins painting the paint device \a pd
531 immediately, with the default arguments taken from \a
532 copyAttributes. The painter will paint over children of the paint
533 device if \a unclipped is TRUE (although this is not supported on
534 all platforms).
535
536 \sa begin()
537*/
538
539QPainter::QPainter( const QPaintDevice *pd,
540 const QWidget *copyAttributes, bool unclipped )
541{
542 init();
543 if ( begin( pd, copyAttributes, unclipped ) )
544 flags |= CtorBegin;
545}
546
547
548/*!
549 Destroys the painter.
550*/
551
552QPainter::~QPainter()
553{
554 if ( isActive() )
555 end();
556 else
557 killPStack();
558 if ( tabarray ) // delete tab array
559 delete [] tabarray;
560#ifndef QT_NO_TRANSFORMATIONS
561 if ( wm_stack )
562 delete (QWMatrixStack *)wm_stack;
563#endif
564 destroy();
565}
566
567
568/*!
569 \overload bool QPainter::begin( const QPaintDevice *pd, const QWidget *copyAttributes, bool unclipped )
570
571 This version opens the painter on a paint device \a pd and sets
572 the initial pen, background color and font from \a copyAttributes,
573 painting over the paint device's children when \a unclipped is
574 TRUE. This is equivalent to:
575
576 \code
577 QPainter p;
578 p.begin( pd );
579 p.setPen( copyAttributes->foregroundColor() );
580 p.setBackgroundColor( copyAttributes->backgroundColor() );
581 p.setFont( copyAttributes->font() );
582 \endcode
583
584 This begin function is convenient for double buffering. When you
585 draw in a pixmap instead of directly in a widget (to later bitBlt
586 the pixmap into the widget) you will need to set the widget's
587 font etc. This function does exactly that.
588
589 Example:
590 \code
591 void MyWidget::paintEvent( QPaintEvent * )
592 {
593 QPixmap pm(size());
594 QPainter p;
595 p.begin(&pm, this);
596 // ... potentially flickering paint operation ...
597 p.end();
598 bitBlt(this, 0, 0, &pm);
599 }
600 \endcode
601
602 \sa end()
603*/
604
605bool QPainter::begin( const QPaintDevice *pd, const QWidget *copyAttributes, bool unclipped )
606{
607 if ( copyAttributes == 0 ) {
608#if defined(QT_CHECK_NULL)
609 qWarning( "QPainter::begin: The widget to copy attributes from cannot "
610 "be null" );
611#endif
612 return FALSE;
613 }
614 if ( begin( pd, unclipped ) ) {
615 setPen( copyAttributes->foregroundColor() );
616 setBackgroundColor( copyAttributes->backgroundColor() );
617 setFont( copyAttributes->font() );
618 return TRUE;
619 }
620 return FALSE;
621}
622
623
624/*!
625 \internal
626 Sets or clears a pointer flag.
627*/
628
629void QPainter::setf( uint b, bool v )
630{
631 if ( v )
632 setf( b );
633 else
634 clearf( b );
635}
636
637
638/*!
639 \fn bool QPainter::isActive() const
640
641 Returns TRUE if the painter is active painting, i.e. begin() has
642 been called and end() has not yet been called; otherwise returns
643 FALSE.
644
645 \sa QPaintDevice::paintingActive()
646*/
647
648/*!
649 \fn QPaintDevice *QPainter::device() const
650
651 Returns the paint device on which this painter is currently
652 painting, or 0 if the painter is not active.
653
654 \sa QPaintDevice::paintingActive()
655*/
656
657
658struct QPState { // painter state
659 QFont font;
660 QPen pen;
661 QPoint curPt;
662 QBrush brush;
663 QColor bgc;
664 uchar bgm;
665 uchar rop;
666 QPoint bro;
667 QRect wr, vr;
668#ifndef QT_NO_TRANSFORMATIONS
669 QWMatrix wm;
670#else
671 int xlatex;
672 int xlatey;
673#endif
674 bool vxf;
675 bool wxf;
676 QRegion rgn;
677 bool clip;
678 int ts;
679 int *ta;
680 void* wm_stack;
681};
682
683//TODO lose the worldmatrix stack
684
685typedef QPtrStack<QPState> QPStateStack;
686
687
688void QPainter::killPStack()
689{
690#if defined(QT_CHECK_STATE)
691 if ( ps_stack && !((QPStateStack *)ps_stack)->isEmpty() )
692 qWarning( "QPainter::killPStack: non-empty save/restore stack when "
693 "end() was called" );
694#endif
695 delete (QPStateStack *)ps_stack;
696 ps_stack = 0;
697}
698
699/*!
700 Saves the current painter state (pushes the state onto a stack). A
701 save() must be followed by a corresponding restore(). end()
702 unwinds the stack.
703
704 \sa restore()
705*/
706
707void QPainter::save()
708{
709 if ( testf(ExtDev) ) {
710 if ( testf(DirtyFont) )
711 updateFont();
712 if ( testf(DirtyPen) )
713 updatePen();
714 if ( testf(DirtyBrush) )
715 updateBrush();
716 pdev->cmd( QPaintDevice::PdcSave, this, 0 );
717 }
718 QPStateStack *pss = (QPStateStack *)ps_stack;
719 if ( pss == 0 ) {
720 pss = new QPtrStack<QPState>;
721 Q_CHECK_PTR( pss );
722 pss->setAutoDelete( TRUE );
723 ps_stack = pss;
724 }
725 QPState *ps = new QPState;
726 Q_CHECK_PTR( ps );
727 ps->font = cfont;
728 ps->pen = cpen;
729 ps->curPt = pos();
730 ps->brush = cbrush;
731 ps->bgc = bg_col;
732 ps->bgm = bg_mode;
733 ps->rop = rop;
734 ps->bro = bro;
735#ifndef QT_NO_TRANSFORMATIONS
736 ps->wr = QRect( wx, wy, ww, wh );
737 ps->vr = QRect( vx, vy, vw, vh );
738 ps->wm = wxmat;
739 ps->vxf = testf(VxF);
740 ps->wxf = testf(WxF);
741#else
742 ps->xlatex = xlatex;
743 ps->xlatey = xlatey;
744#endif
745 ps->rgn = crgn;
746 ps->clip = testf(ClipOn);
747 ps->ts = tabstops;
748 ps->ta = tabarray;
749 ps->wm_stack = wm_stack;
750 wm_stack = 0;
751 pss->push( ps );
752}
753
754/*!
755 Restores the current painter state (pops a saved state off the
756 stack).
757
758 \sa save()
759*/
760
761void QPainter::restore()
762{
763 if ( testf(ExtDev) ) {
764 pdev->cmd( QPaintDevice::PdcRestore, this, 0 );
765 if ( pdev->devType() == QInternal::Picture )
766 block_ext = TRUE;
767 }
768 QPStateStack *pss = (QPStateStack *)ps_stack;
769 if ( pss == 0 || pss->isEmpty() ) {
770#if defined(QT_CHECK_STATE)
771 qWarning( "QPainter::restore: Empty stack error" );
772#endif
773 return;
774 }
775 QPState *ps = pss->pop();
776 bool hardRestore = testf(VolatileDC);
777
778 if ( ps->font != cfont || hardRestore )
779 setFont( ps->font );
780 if ( ps->pen != cpen || hardRestore )
781 setPen( ps->pen );
782 if ( ps->brush != cbrush || hardRestore )
783 setBrush( ps->brush );
784 if ( ps->bgc != bg_col || hardRestore )
785 setBackgroundColor( ps->bgc );
786 if ( ps->bgm != bg_mode || hardRestore )
787 setBackgroundMode( (BGMode)ps->bgm );
788 if ( ps->rop != rop || hardRestore )
789 setRasterOp( (RasterOp)ps->rop );
790 if ( ps->bro != bro || hardRestore )
791 setBrushOrigin( ps->bro );
792#ifndef QT_NO_TRANSFORMATIONS
793 QRect wr( wx, wy, ww, wh );
794 QRect vr( vx, vy, vw, vh );
795 if ( ps->wr != wr || hardRestore )
796 setWindow( ps->wr );
797 if ( ps->vr != vr || hardRestore )
798 setViewport( ps->vr );
799 if ( ps->wm != wxmat || hardRestore )
800 setWorldMatrix( ps->wm );
801 if ( ps->vxf != testf(VxF) || hardRestore )
802 setViewXForm( ps->vxf );
803 if ( ps->wxf != testf(WxF) || hardRestore )
804 setWorldXForm( ps->wxf );
805#else
806 xlatex = ps->xlatex;
807 xlatey = ps->xlatey;
808 setf( VxF, xlatex || xlatey );
809#endif
810 if ( ps->curPt != pos() || hardRestore )
811 moveTo( ps->curPt );
812 if ( ps->rgn != crgn || hardRestore )
813 setClipRegion( ps->rgn );
814 if ( ps->clip != testf(ClipOn) || hardRestore )
815 setClipping( ps->clip );
816 tabstops = ps->ts;
817 tabarray = ps->ta;
818
819#ifndef QT_NO_TRANSFORMATIONS
820 if ( wm_stack )
821 delete (QWMatrixStack *)wm_stack;
822 wm_stack = ps->wm_stack;
823#endif
824 delete ps;
825 block_ext = FALSE;
826}
827
828typedef QPtrDict<QPaintDevice> QPaintDeviceDict;
829static QPaintDeviceDict *pdev_dict = 0;
830
831/*!
832 Redirects all paint commands for a paint device, \a pdev, to
833 another paint device, \a replacement, unless \a replacement is 0.
834 If \a replacement is 0, the redirection for \a pdev is removed.
835
836 In general, you'll probably find calling QPixmap::grabWidget() or
837 QPixmap::grabWindow() is an easier solution.
838*/
839
840void QPainter::redirect( QPaintDevice *pdev, QPaintDevice *replacement )
841{
842 if ( pdev_dict == 0 ) {
843 if ( replacement == 0 )
844 return;
845 pdev_dict = new QPaintDeviceDict;
846 Q_CHECK_PTR( pdev_dict );
847 }
848#if defined(QT_CHECK_NULL)
849 if ( pdev == 0 )
850 qWarning( "QPainter::redirect: The pdev argument cannot be 0" );
851#endif
852 if ( replacement ) {
853 pdev_dict->insert( pdev, replacement );
854 } else {
855 pdev_dict->remove( pdev );
856 if ( pdev_dict->count() == 0 ) {
857 delete pdev_dict;
858 pdev_dict = 0;
859 }
860 }
861}
862
863/*!
864 \internal
865 Returns the replacement for \a pdev, or 0 if there is no replacement.
866*/
867QPaintDevice *QPainter::redirect( QPaintDevice *pdev )
868{
869 return pdev_dict ? pdev_dict->find( pdev ) : 0;
870}
871
872/*!
873 Returns the font metrics for the painter, if the painter is
874 active. It is not possible to obtain metrics for an inactive
875 painter, so the return value is undefined if the painter is not
876 active.
877
878 \sa fontInfo(), isActive()
879*/
880
881QFontMetrics QPainter::fontMetrics() const
882{
883 if ( pdev && pdev->devType() == QInternal::Picture )
884 return QFontMetrics( cfont );
885
886 return QFontMetrics(this);
887}
888
889/*!
890 Returns the font info for the painter, if the painter is active.
891 It is not possible to obtain font information for an inactive
892 painter, so the return value is undefined if the painter is not
893 active.
894
895 \sa fontMetrics(), isActive()
896*/
897
898QFontInfo QPainter::fontInfo() const
899{
900 if ( pdev && pdev->devType() == QInternal::Picture )
901 return QFontInfo( cfont );
902
903 return QFontInfo(this);
904}
905
906
907/*!
908 \fn const QPen &QPainter::pen() const
909
910 Returns the painter's current pen.
911
912 \sa setPen()
913*/
914
915/*!
916 Sets a new painter pen.
917
918 The \a pen defines how to draw lines and outlines, and it also
919 defines the text color.
920
921 \sa pen()
922*/
923
924void QPainter::setPen( const QPen &pen )
925{
926#if defined(QT_CHECK_STATE)
927 if ( !isActive() )
928 qWarning( "QPainter::setPen: Will be reset by begin()" );
929#endif
930 if ( cpen == pen )
931 return;
932 cpen = pen;
933 updatePen();
934}
935
936/*!
937 \overload
938
939 Sets the painter's pen to have style \a style, width 0 and black
940 color.
941
942 \sa pen(), QPen
943*/
944
945void QPainter::setPen( PenStyle style )
946{
947#if defined(QT_CHECK_STATE)
948 if ( !isActive() )
949 qWarning( "QPainter::setPen: Will be reset by begin()" );
950#endif
951 QPen::QPenData *d = cpen.data; // low level access
952 if ( d->style == style && d->linest == style && !d->width && d->color == Qt::black )
953 return;
954 if ( d->count != 1 ) {
955 cpen.detach();
956 d = cpen.data;
957 }
958 d->style = style;
959 d->width = 0;
960 d->color = Qt::black;
961 d->linest = style;
962 updatePen();
963}
964
965/*!
966 \overload
967
968 Sets the painter's pen to have style \c SolidLine, width 0 and the
969 specified \a color.
970
971 \sa pen(), QPen
972*/
973
974void QPainter::setPen( const QColor &color )
975{
976#if defined(QT_CHECK_STATE)
977 if ( !isActive() )
978 qWarning( "QPainter::setPen: Will be reset by begin()" );
979#endif
980 QPen::QPenData *d = cpen.data; // low level access
981 if ( d->color == color && !d->width && d->style == SolidLine && d->linest == SolidLine )
982 return;
983 if ( d->count != 1 ) {
984 cpen.detach();
985 d = cpen.data;
986 }
987 d->style = SolidLine;
988 d->width = 0;
989 d->color = color;
990 d->linest = SolidLine;
991 updatePen();
992}
993
994/*!
995 \fn const QBrush &QPainter::brush() const
996
997 Returns the painter's current brush.
998
999 \sa QPainter::setBrush()
1000*/
1001
1002/*!
1003 \overload
1004
1005 Sets the painter's brush to \a brush.
1006
1007 The \a brush defines how shapes are filled.
1008
1009 \sa brush()
1010*/
1011
1012void QPainter::setBrush( const QBrush &brush )
1013{
1014#if defined(QT_CHECK_STATE)
1015 if ( !isActive() )
1016 qWarning( "QPainter::setBrush: Will be reset by begin()" );
1017#endif
1018 if ( cbrush == brush )
1019 return;
1020 cbrush = brush;
1021 updateBrush();
1022}
1023
1024/*!
1025 Sets the painter's brush to black color and the specified \a
1026 style.
1027
1028 \sa brush(), QBrush
1029*/
1030
1031void QPainter::setBrush( BrushStyle style )
1032{
1033#if defined(QT_CHECK_STATE)
1034 if ( !isActive() )
1035 qWarning( "QPainter::setBrush: Will be reset by begin()" );
1036#endif
1037 QBrush::QBrushData *d = cbrush.data; // low level access
1038 if ( d->style == style && d->color == Qt::black && !d->pixmap )
1039 return;
1040 if ( d->count != 1 ) {
1041 cbrush.detach();
1042 d = cbrush.data;
1043 }
1044 d->style = style;
1045 d->color = Qt::black;
1046 if ( d->pixmap ) {
1047 delete d->pixmap;
1048 d->pixmap = 0;
1049 }
1050 updateBrush();
1051}
1052
1053/*!
1054 \overload
1055
1056 Sets the painter's brush to have style \c SolidPattern and the
1057 specified \a color.
1058
1059 \sa brush(), QBrush
1060*/
1061
1062void QPainter::setBrush( const QColor &color )
1063{
1064#if defined(QT_CHECK_STATE)
1065 if ( !isActive() )
1066 qWarning( "QPainter::setBrush: Will be reset by begin()" );
1067#endif
1068 QBrush::QBrushData *d = cbrush.data; // low level access
1069 if ( d->color == color && d->style == SolidPattern && !d->pixmap )
1070 return;
1071 if ( d->count != 1 ) {
1072 cbrush.detach();
1073 d = cbrush.data;
1074 }
1075 d->style = SolidPattern;
1076 d->color = color;
1077 if ( d->pixmap ) {
1078 delete d->pixmap;
1079 d->pixmap = 0;
1080 }
1081 updateBrush();
1082}
1083
1084
1085/*!
1086 \fn const QColor &QPainter::backgroundColor() const
1087
1088 Returns the current background color.
1089
1090 \sa setBackgroundColor() QColor
1091*/
1092
1093/*!
1094 \fn BGMode QPainter::backgroundMode() const
1095
1096 Returns the current background mode.
1097
1098 \sa setBackgroundMode() BGMode
1099*/
1100
1101/*!
1102 \fn RasterOp QPainter::rasterOp() const
1103
1104 Returns the current raster operation.
1105
1106 \sa setRasterOp() RasterOp
1107*/
1108
1109/*!
1110 \fn const QPoint &QPainter::brushOrigin() const
1111
1112 Returns the brush origin currently set.
1113
1114 \sa setBrushOrigin()
1115*/
1116
1117
1118/*!
1119 \fn int QPainter::tabStops() const
1120
1121 Returns the tab stop setting.
1122
1123 \sa setTabStops()
1124*/
1125
1126/*!
1127 Set the tab stop width to \a ts, i.e. locates tab stops at \a ts,
1128 2*\a ts, 3*\a ts and so on.
1129
1130 Tab stops are used when drawing formatted text with \c ExpandTabs
1131 set. This fixed tab stop value is used only if no tab array is set
1132 (which is the default case).
1133
1134 A value of 0 (the default) implies a tabstop setting of 8 times the width of the
1135 character 'x' in the font currently set on the painter.
1136
1137 \sa tabStops(), setTabArray(), drawText(), fontMetrics()
1138*/
1139
1140void QPainter::setTabStops( int ts )
1141{
1142#if defined(QT_CHECK_STATE)
1143 if ( !isActive() )
1144 qWarning( "QPainter::setTabStops: Will be reset by begin()" );
1145#endif
1146 tabstops = ts;
1147 if ( isActive() && testf(ExtDev) ) { // tell extended device
1148 QPDevCmdParam param[1];
1149 param[0].ival = ts;
1150 pdev->cmd( QPaintDevice::PdcSetTabStops, this, param );
1151 }
1152}
1153
1154/*!
1155 \fn int *QPainter::tabArray() const
1156
1157 Returns the currently set tab stop array.
1158
1159 \sa setTabArray()
1160*/
1161
1162/*!
1163 Sets the tab stop array to \a ta. This puts tab stops at \a ta[0],
1164 \a ta[1] and so on. The array is null-terminated.
1165
1166 If both a tab array and a tab top size is set, the tab array wins.
1167
1168 \sa tabArray(), setTabStops(), drawText(), fontMetrics()
1169*/
1170
1171void QPainter::setTabArray( int *ta )
1172{
1173#if defined(QT_CHECK_STATE)
1174 if ( !isActive() )
1175 qWarning( "QPainter::setTabArray: Will be reset by begin()" );
1176#endif
1177 if ( ta != tabarray ) {
1178 tabarraylen = 0;
1179 if ( tabarray ) // Avoid purify complaint
1180 delete [] tabarray; // delete old array
1181 if ( ta ) { // tabarray = copy of 'ta'
1182 while ( ta[tabarraylen] )
1183 tabarraylen++;
1184 tabarraylen++; // and 0 terminator
1185 tabarray = new int[tabarraylen]; // duplicate ta
1186 memcpy( tabarray, ta, sizeof(int)*tabarraylen );
1187 } else {
1188 tabarray = 0;
1189 }
1190 }
1191 if ( isActive() && testf(ExtDev) ) { // tell extended device
1192 QPDevCmdParam param[2];
1193 param[0].ival = tabarraylen;
1194 param[1].ivec = tabarray;
1195 pdev->cmd( QPaintDevice::PdcSetTabArray, this, param );
1196 }
1197}
1198
1199
1200/*!
1201 \fn HANDLE QPainter::handle() const
1202
1203 Returns the platform-dependent handle used for drawing. Using this
1204 function is not portable.
1205*/
1206
1207
1208/*****************************************************************************
1209 QPainter xform settings
1210 *****************************************************************************/
1211
1212#ifndef QT_NO_TRANSFORMATIONS
1213
1214/*!
1215 Enables view transformations if \a enable is TRUE, or disables
1216 view transformations if \a enable is FALSE.
1217
1218 \sa hasViewXForm(), setWindow(), setViewport(), setWorldMatrix(),
1219 setWorldXForm(), xForm()
1220*/
1221
1222void QPainter::setViewXForm( bool enable )
1223{
1224#if defined(QT_CHECK_STATE)
1225 if ( !isActive() )
1226 qWarning( "QPainter::setViewXForm: Will be reset by begin()" );
1227#endif
1228 if ( !isActive() || enable == testf(VxF) )
1229 return;
1230 setf( VxF, enable );
1231 if ( testf(ExtDev) ) {
1232 QPDevCmdParam param[1];
1233 param[0].ival = enable;
1234 pdev->cmd( QPaintDevice::PdcSetVXform, this, param );
1235 }
1236 updateXForm();
1237}
1238
1239/*!
1240 \fn bool QPainter::hasViewXForm() const
1241
1242 Returns TRUE if view transformation is enabled; otherwise returns
1243 FALSE.
1244
1245 \sa setViewXForm(), xForm()
1246*/
1247
1248/*!
1249 Returns the window rectangle.
1250
1251 \sa setWindow(), setViewXForm()
1252*/
1253
1254QRect QPainter::window() const
1255{
1256 return QRect( wx, wy, ww, wh );
1257}
1258
1259/*!
1260 Sets the window rectangle view transformation for the painter and
1261 enables view transformation.
1262
1263 The window rectangle is part of the view transformation. The
1264 window specifies the logical coordinate system and is specified by
1265 the \a x, \a y, \a w width and \a h height parameters. Its sister,
1266 the viewport(), specifies the device coordinate system.
1267
1268 The default window rectangle is the same as the device's
1269 rectangle. See the \link coordsys.html Coordinate System Overview
1270 \endlink for an overview of coordinate transformation.
1271
1272 \sa window(), setViewport(), setViewXForm(), setWorldMatrix(),
1273 setWorldXForm()
1274*/
1275
1276void QPainter::setWindow( int x, int y, int w, int h )
1277{
1278#if defined(QT_CHECK_STATE)
1279 if ( !isActive() )
1280 qWarning( "QPainter::setWindow: Will be reset by begin()" );
1281#endif
1282 wx = x;
1283 wy = y;
1284 ww = w;
1285 wh = h;
1286 if ( testf(ExtDev) ) {
1287 QRect r( x, y, w, h );
1288 QPDevCmdParam param[1];
1289 param[0].rect = (QRect*)&r;
1290 pdev->cmd( QPaintDevice::PdcSetWindow, this, param );
1291 }
1292 if ( testf(VxF) )
1293 updateXForm();
1294 else
1295 setViewXForm( TRUE );
1296}
1297
1298/*!
1299 Returns the viewport rectangle.
1300
1301 \sa setViewport(), setViewXForm()
1302*/
1303
1304QRect QPainter::viewport() const // get viewport
1305{
1306 return QRect( vx, vy, vw, vh );
1307}
1308
1309/*!
1310 Sets the viewport rectangle view transformation for the painter
1311 and enables view transformation.
1312
1313 The viewport rectangle is part of the view transformation. The
1314 viewport specifies the device coordinate system and is specified
1315 by the \a x, \a y, \a w width and \a h height parameters. Its
1316 sister, the window(), specifies the logical coordinate system.
1317
1318 The default viewport rectangle is the same as the device's
1319 rectangle. See the \link coordsys.html Coordinate System Overview
1320 \endlink for an overview of coordinate transformation.
1321
1322 \sa viewport(), setWindow(), setViewXForm(), setWorldMatrix(),
1323 setWorldXForm(), xForm()
1324*/
1325
1326void QPainter::setViewport( int x, int y, int w, int h )
1327{
1328#if defined(QT_CHECK_STATE)
1329 if ( !isActive() )
1330 qWarning( "QPainter::setViewport: Will be reset by begin()" );
1331#endif
1332 vx = x;
1333 vy = y;
1334 vw = w;
1335 vh = h;
1336 if ( testf(ExtDev) ) {
1337 QRect r( x, y, w, h );
1338 QPDevCmdParam param[1];
1339 param[0].rect = (QRect*)&r;
1340 pdev->cmd( QPaintDevice::PdcSetViewport, this, param );
1341 }
1342 if ( testf(VxF) )
1343 updateXForm();
1344 else
1345 setViewXForm( TRUE );
1346}
1347
1348
1349/*!
1350 Enables world transformations if \a enable is TRUE, or disables
1351 world transformations if \a enable is FALSE. The world
1352 transformation matrix is not changed.
1353
1354 \sa setWorldMatrix(), setWindow(), setViewport(), setViewXForm(),
1355 xForm()
1356*/
1357
1358void QPainter::setWorldXForm( bool enable )
1359{
1360#if defined(QT_CHECK_STATE)
1361 if ( !isActive() )
1362 qWarning( "QPainter::setWorldXForm: Will be reset by begin()" );
1363#endif
1364 if ( !isActive() || enable == testf(WxF) )
1365 return;
1366 setf( WxF, enable );
1367 if ( testf(ExtDev) ) {
1368 QPDevCmdParam param[1];
1369 param[0].ival = enable;
1370 pdev->cmd( QPaintDevice::PdcSetWXform, this, param );
1371 }
1372 updateXForm();
1373}
1374
1375/*!
1376 \fn bool QPainter::hasWorldXForm() const
1377
1378 Returns TRUE if world transformation is enabled; otherwise returns
1379 FALSE.
1380
1381 \sa setWorldXForm()
1382*/
1383
1384/*!
1385 Returns the world transformation matrix.
1386
1387 \sa setWorldMatrix()
1388*/
1389
1390const QWMatrix &QPainter::worldMatrix() const
1391{
1392 return wxmat;
1393}
1394
1395/*!
1396 Sets the world transformation matrix to \a m and enables world
1397 transformation.
1398
1399 If \a combine is TRUE, then \a m is combined with the current
1400 transformation matrix, otherwise \a m replaces the current
1401 transformation matrix.
1402
1403 If \a m is the identity matrix and \a combine is FALSE, this
1404 function calls setWorldXForm(FALSE). (The identity matrix is the
1405 matrix where QWMatrix::m11() and QWMatrix::m22() are 1.0 and the
1406 rest are 0.0.)
1407
1408 World transformations are applied after the view transformations
1409 (i.e. \link setWindow() window\endlink and \link setViewport()
1410 viewport\endlink).
1411
1412 The following functions can transform the coordinate system without using
1413 a QWMatrix:
1414 \list
1415 \i translate()
1416 \i scale()
1417 \i shear()
1418 \i rotate()
1419 \endlist
1420
1421 They operate on the painter's worldMatrix() and are implemented like this:
1422
1423 \code
1424 void QPainter::rotate( double a )
1425 {
1426 QWMatrix m;
1427 m.rotate( a );
1428 setWorldMatrix( m, TRUE );
1429 }
1430 \endcode
1431
1432 Note that you should always use \a combine when you are drawing
1433 into a QPicture. Otherwise it may not be possible to replay the
1434 picture with additional transformations. Using translate(),
1435 scale(), etc., is safe.
1436
1437 For a brief overview of coordinate transformation, see the \link
1438 coordsys.html Coordinate System Overview. \endlink
1439
1440 \sa worldMatrix() setWorldXForm() setWindow() setViewport()
1441 setViewXForm() xForm() QWMatrix
1442*/
1443
1444void QPainter::setWorldMatrix( const QWMatrix &m, bool combine )
1445{
1446#if defined(QT_CHECK_STATE)
1447 if ( !isActive() )
1448 qWarning( "QPainter::setWorldMatrix: Will be reset by begin()" );
1449#endif
1450 if ( combine )
1451 wxmat = m * wxmat; // combines
1452 else
1453 wxmat = m; // set new matrix
1454 bool identity = wxmat.m11() == 1.0F && wxmat.m22() == 1.0F &&
1455 wxmat.m12() == 0.0F && wxmat.m21() == 0.0F &&
1456 wxmat.dx() == 0.0F && wxmat.dy() == 0.0F;
1457 if ( testf(ExtDev) && !block_ext ) {
1458 QPDevCmdParam param[2];
1459 param[0].matrix = &m;
1460 param[1].ival = combine;
1461 pdev->cmd( QPaintDevice::PdcSetWMatrix, this, param );
1462 }
1463 if ( identity && pdev->devType() != QInternal::Picture )
1464 setWorldXForm( FALSE );
1465 else if ( !testf(WxF) )
1466 setWorldXForm( TRUE );
1467 else
1468 updateXForm();
1469}
1470
1471/*! \obsolete
1472
1473 We recommend using save() instead.
1474*/
1475
1476void QPainter::saveWorldMatrix()
1477{
1478 QWMatrixStack *stack = (QWMatrixStack *)wm_stack;
1479 if ( stack == 0 ) {
1480 stack = new QPtrStack<QWMatrix>;
1481 Q_CHECK_PTR( stack );
1482 stack->setAutoDelete( TRUE );
1483 wm_stack = stack;
1484 }
1485
1486 stack->push( new QWMatrix( wxmat ) );
1487
1488}
1489
1490/*! \obsolete
1491 We recommend using restore() instead.
1492*/
1493
1494void QPainter::restoreWorldMatrix()
1495{
1496 QWMatrixStack *stack = (QWMatrixStack *)wm_stack;
1497 if ( stack == 0 || stack->isEmpty() ) {
1498#if defined(QT_CHECK_STATE)
1499 qWarning( "QPainter::restoreWorldMatrix: Empty stack error" );
1500#endif
1501 return;
1502 }
1503 QWMatrix* m = stack->pop();
1504 setWorldMatrix( *m );
1505 delete m;
1506}
1507
1508#endif // QT_NO_TRANSFORMATIONS
1509
1510/*!
1511 Translates the coordinate system by \a (dx, dy). After this call,
1512 \a (dx, dy) is added to points.
1513
1514 For example, the following code draws the same point twice:
1515 \code
1516 void MyWidget::paintEvent()
1517 {
1518 QPainter paint( this );
1519
1520 paint.drawPoint( 0, 0 );
1521
1522 paint.translate( 100.0, 40.0 );
1523 paint.drawPoint( -100, -40 );
1524 }
1525 \endcode
1526
1527 \sa scale(), shear(), rotate(), resetXForm(), setWorldMatrix(), xForm()
1528*/
1529
1530void QPainter::translate( double dx, double dy )
1531{
1532#ifndef QT_NO_TRANSFORMATIONS
1533 QWMatrix m;
1534 m.translate( dx, dy );
1535 setWorldMatrix( m, TRUE );
1536#else
1537 xlatex += (int)dx;
1538 xlatey += (int)dy;
1539 setf( VxF, xlatex || xlatey );
1540#endif
1541}
1542
1543
1544#ifndef QT_NO_TRANSFORMATIONS
1545/*!
1546 Scales the coordinate system by \a (sx, sy).
1547
1548 \sa translate(), shear(), rotate(), resetXForm(), setWorldMatrix(),
1549 xForm()
1550*/
1551
1552void QPainter::scale( double sx, double sy )
1553{
1554 QWMatrix m;
1555 m.scale( sx, sy );
1556 setWorldMatrix( m, TRUE );
1557}
1558
1559/*!
1560 Shears the coordinate system by \a (sh, sv).
1561
1562 \sa translate(), scale(), rotate(), resetXForm(), setWorldMatrix(),
1563 xForm()
1564*/
1565
1566void QPainter::shear( double sh, double sv )
1567{
1568 QWMatrix m;
1569 m.shear( sv, sh );
1570 setWorldMatrix( m, TRUE );
1571}
1572
1573/*!
1574 Rotates the coordinate system \a a degrees counterclockwise.
1575
1576 \sa translate(), scale(), shear(), resetXForm(), setWorldMatrix(),
1577 xForm()
1578*/
1579
1580void QPainter::rotate( double a )
1581{
1582 QWMatrix m;
1583 m.rotate( a );
1584 setWorldMatrix( m, TRUE );
1585}
1586
1587
1588/*!
1589 Resets any transformations that were made using translate(), scale(),
1590 shear(), rotate(), setWorldMatrix(), setViewport() and
1591 setWindow().
1592
1593 \sa worldMatrix(), viewport(), window()
1594*/
1595
1596void QPainter::resetXForm()
1597{
1598 if ( !isActive() )
1599 return;
1600 wx = wy = vx = vy = 0; // default view origins
1601 ww = vw = pdev->metric( QPaintDeviceMetrics::PdmWidth );
1602 wh = vh = pdev->metric( QPaintDeviceMetrics::PdmHeight );
1603 wxmat = QWMatrix();
1604 setWorldXForm( FALSE );
1605 setViewXForm( FALSE );
1606}
1607
1608/*!
1609 \internal
1610 Updates an internal integer transformation matrix.
1611*/
1612
1613void QPainter::updateXForm()
1614{
1615 QWMatrix m;
1616 if ( testf(VxF) ) {
1617 double scaleW = (double)vw/(double)ww;
1618 double scaleH = (double)vh/(double)wh;
1619 m.setMatrix( scaleW, 0, 0, scaleH, vx - wx*scaleW, vy - wy*scaleH );
1620 }
1621 if ( testf(WxF) ) {
1622 if ( testf(VxF) )
1623 m = wxmat * m;
1624 else
1625 m = wxmat;
1626 }
1627 xmat = m;
1628
1629 txinv = FALSE; // no inverted matrix
1630 txop = TxNone;
1631 if ( m12()==0.0 && m21()==0.0 && m11() >= 0.0 && m22() >= 0.0 ) {
1632 if ( m11()==1.0 && m22()==1.0 ) {
1633 if ( dx()!=0.0 || dy()!=0.0 )
1634 txop = TxTranslate;
1635 } else {
1636 txop = TxScale;
1637#if defined(Q_WS_WIN)
1638 setf(DirtyFont);
1639#endif
1640 }
1641 } else {
1642 txop = TxRotShear;
1643#if defined(Q_WS_WIN)
1644 setf(DirtyFont);
1645#endif
1646 }
1647}
1648
1649
1650/*!
1651 \internal
1652 Updates an internal integer inverse transformation matrix.
1653*/
1654
1655void QPainter::updateInvXForm()
1656{
1657#if defined(QT_CHECK_STATE)
1658 Q_ASSERT( txinv == FALSE );
1659#endif
1660 txinv = TRUE; // creating inverted matrix
1661 bool invertible;
1662 QWMatrix m;
1663 if ( testf(VxF) ) {
1664 m.translate( vx, vy );
1665 m.scale( 1.0*vw/ww, 1.0*vh/wh );
1666 m.translate( -wx, -wy );
1667 }
1668 if ( testf(WxF) ) {
1669 if ( testf(VxF) )
1670 m = wxmat * m;
1671 else
1672 m = wxmat;
1673 }
1674 ixmat = m.invert( &invertible ); // invert matrix
1675}
1676
1677#else
1678void QPainter::resetXForm()
1679{
1680 xlatex = 0;
1681 xlatey = 0;
1682 clearf( VxF );
1683}
1684#endif // QT_NO_TRANSFORMATIONS
1685
1686
1687extern bool qt_old_transformations;
1688
1689/*!
1690 \internal
1691 Maps a point from logical coordinates to device coordinates.
1692*/
1693
1694void QPainter::map( int x, int y, int *rx, int *ry ) const
1695{
1696#ifndef QT_NO_TRANSFORMATIONS
1697 if ( qt_old_transformations ) {
1698 switch ( txop ) {
1699 case TxNone:
1700 *rx = x; *ry = y;
1701 break;
1702 case TxTranslate:
1703 // #### "Why no rounding here?", Warwick asked of Haavard.
1704 *rx = int(x + dx());
1705 *ry = int(y + dy());
1706 break;
1707 case TxScale: {
1708 double tx = m11()*x + dx();
1709 double ty = m22()*y + dy();
1710 *rx = tx >= 0 ? int(tx + 0.5) : int(tx - 0.5);
1711 *ry = ty >= 0 ? int(ty + 0.5) : int(ty - 0.5);
1712 } break;
1713 default: {
1714 double tx = m11()*x + m21()*y+dx();
1715 double ty = m12()*x + m22()*y+dy();
1716 *rx = tx >= 0 ? int(tx + 0.5) : int(tx - 0.5);
1717 *ry = ty >= 0 ? int(ty + 0.5) : int(ty - 0.5);
1718 } break;
1719 }
1720 } else {
1721 switch ( txop ) {
1722 case TxNone:
1723 *rx = x;
1724 *ry = y;
1725 break;
1726 case TxTranslate:
1727 *rx = qRound( x + dx() );
1728 *ry = qRound( y + dy() );
1729 break;
1730 case TxScale:
1731 *rx = qRound( m11()*x + dx() );
1732 *ry = qRound( m22()*y + dy() );
1733 break;
1734 default:
1735 *rx = qRound( m11()*x + m21()*y+dx() );
1736 *ry = qRound( m12()*x + m22()*y+dy() );
1737 break;
1738 }
1739 }
1740#else
1741 *rx = x + xlatex;
1742 *ry = y + xlatey;
1743#endif
1744}
1745
1746/*!
1747 \internal
1748 Maps a rectangle from logical coordinates to device coordinates.
1749 This internal function does not handle rotation and/or shear.
1750*/
1751
1752void QPainter::map( int x, int y, int w, int h,
1753 int *rx, int *ry, int *rw, int *rh ) const
1754{
1755#ifndef QT_NO_TRANSFORMATIONS
1756 if ( qt_old_transformations ) {
1757 switch ( txop ) {
1758 case TxNone:
1759 *rx = x; *ry = y;
1760 *rw = w; *rh = h;
1761 break;
1762 case TxTranslate:
1763 // #### "Why no rounding here?", Warwick asked of Haavard.
1764 *rx = int(x + dx());
1765 *ry = int(y + dy());
1766 *rw = w; *rh = h;
1767 break;
1768 case TxScale: {
1769 double tx1 = m11()*x + dx();
1770 double ty1 = m22()*y + dy();
1771 double tx2 = m11()*(x + w - 1) + dx();
1772 double ty2 = m22()*(y + h - 1) + dy();
1773 *rx = qRound( tx1 );
1774 *ry = qRound( ty1 );
1775 *rw = qRound( tx2 ) - *rx + 1;
1776 *rh = qRound( ty2 ) - *ry + 1;
1777 } break;
1778 default:
1779#if defined(QT_CHECK_STATE)
1780 qWarning( "QPainter::map: Internal error" );
1781#endif
1782 break;
1783 }
1784 } else {
1785 switch ( txop ) {
1786 case TxNone:
1787 *rx = x; *ry = y;
1788 *rw = w; *rh = h;
1789 break;
1790 case TxTranslate:
1791 *rx = qRound(x + dx() );
1792 *ry = qRound(y + dy() );
1793 *rw = w; *rh = h;
1794 break;
1795 case TxScale:
1796 *rx = qRound( m11()*x + dx() );
1797 *ry = qRound( m22()*y + dy() );
1798 *rw = qRound( m11()*w );
1799 *rh = qRound( m22()*h );
1800 break;
1801 default:
1802#if defined(QT_CHECK_STATE)
1803 qWarning( "QPainter::map: Internal error" );
1804#endif
1805 break;
1806 }
1807 }
1808#else
1809 *rx = x + xlatex;
1810 *ry = y + xlatey;
1811 *rw = w; *rh = h;
1812#endif
1813}
1814
1815/*!
1816 \internal
1817 Maps a point from device coordinates to logical coordinates.
1818*/
1819
1820void QPainter::mapInv( int x, int y, int *rx, int *ry ) const
1821{
1822#ifndef QT_NO_TRANSFORMATIONS
1823#if defined(QT_CHECK_STATE)
1824 if ( !txinv )
1825 qWarning( "QPainter::mapInv: Internal error" );
1826#endif
1827 if ( qt_old_transformations ) {
1828 double tx = im11()*x + im21()*y+idx();
1829 double ty = im12()*x + im22()*y+idy();
1830 *rx = tx >= 0 ? int(tx + 0.5) : int(tx - 0.5);
1831 *ry = ty >= 0 ? int(ty + 0.5) : int(ty - 0.5);
1832 } else {
1833 *rx = qRound( im11()*x + im21()*y + idx() );
1834 *ry = qRound( im12()*x + im22()*y + idy() );
1835 }
1836#else
1837 *rx = x - xlatex;
1838 *ry = y - xlatey;
1839#endif
1840}
1841
1842/*!
1843 \internal
1844 Maps a rectangle from device coordinates to logical coordinates.
1845 Cannot handle rotation and/or shear.
1846*/
1847
1848void QPainter::mapInv( int x, int y, int w, int h,
1849 int *rx, int *ry, int *rw, int *rh ) const
1850{
1851#ifndef QT_NO_TRANSFORMATIONS
1852#if defined(QT_CHECK_STATE)
1853 if ( !txinv || txop == TxRotShear )
1854 qWarning( "QPainter::mapInv: Internal error" );
1855#endif
1856 if ( qt_old_transformations ) {
1857 double tx = im11()*x + idx();
1858 double ty = im22()*y + idy();
1859 double tw = im11()*w;
1860 double th = im22()*h;
1861 *rx = tx >= 0 ? int(tx + 0.5) : int(tx - 0.5);
1862 *ry = ty >= 0 ? int(ty + 0.5) : int(ty - 0.5);
1863 *rw = tw >= 0 ? int(tw + 0.5) : int(tw - 0.5);
1864 *rh = th >= 0 ? int(th + 0.5) : int(th - 0.5);
1865 } else {
1866 *rx = qRound( im11()*x + idx() );
1867 *ry = qRound( im22()*y + idy() );
1868 *rw = qRound( im11()*w );
1869 *rh = qRound( im22()*h );
1870 }
1871#else
1872 *rx = x - xlatex;
1873 *ry = y - xlatey;
1874 *rw = w;
1875 *rh = h;
1876#endif
1877}
1878
1879
1880/*!
1881 Returns the point \a pv transformed from model coordinates to
1882 device coordinates.
1883
1884 \sa xFormDev(), QWMatrix::map()
1885*/
1886
1887QPoint QPainter::xForm( const QPoint &pv ) const
1888{
1889#ifndef QT_NO_TRANSFORMATIONS
1890 if ( txop == TxNone )
1891 return pv;
1892 int x=pv.x(), y=pv.y();
1893 map( x, y, &x, &y );
1894 return QPoint( x, y );
1895#else
1896 return QPoint( pv.x()+xlatex, pv.y()+xlatey );
1897#endif
1898}
1899
1900/*!
1901 \overload
1902
1903 Returns the rectangle \a rv transformed from model coordinates to
1904 device coordinates.
1905
1906 If world transformation is enabled and rotation or shearing has
1907 been specified, then the bounding rectangle is returned.
1908
1909 \sa xFormDev(), QWMatrix::map()
1910*/
1911
1912QRect QPainter::xForm( const QRect &rv ) const
1913{
1914#ifndef QT_NO_TRANSFORMATIONS
1915 if ( txop == TxNone )
1916 return rv;
1917 if ( txop == TxRotShear ) { // rotation/shear
1918 return xmat.mapRect( rv );
1919 }
1920 // Just translation/scale
1921 int x, y, w, h;
1922 rv.rect( &x, &y, &w, &h );
1923 map( x, y, w, h, &x, &y, &w, &h );
1924 return QRect( x, y, w, h );
1925#else
1926 return QRect( rv.x()+xlatex, rv.y()+xlatey, rv.width(), rv.height() );
1927#endif
1928}
1929
1930/*!
1931 \overload
1932
1933 Returns the point array \a av transformed from model coordinates
1934 to device coordinates.
1935
1936 \sa xFormDev(), QWMatrix::map()
1937*/
1938
1939QPointArray QPainter::xForm( const QPointArray &av ) const
1940{
1941 QPointArray a = av;
1942#ifndef QT_NO_TRANSFORMATIONS
1943 if ( txop != TxNone )
1944 {
1945 return xmat * av;
1946 }
1947#else
1948 a.translate( xlatex, xlatey );
1949#endif
1950 return a;
1951}
1952
1953/*!
1954 \overload
1955
1956 Returns the point array \a av transformed from model coordinates
1957 to device coordinates. The \a index is the first point in the
1958 array and \a npoints denotes the number of points to be
1959 transformed. If \a npoints is negative, all points from \a
1960 av[index] until the last point in the array are transformed.
1961
1962 The returned point array consists of the number of points that
1963 were transformed.
1964
1965 Example:
1966 \code
1967 QPointArray a(10);
1968 QPointArray b;
1969 b = painter.xForm(a, 2, 4); // b.size() == 4
1970 b = painter.xForm(a, 2, -1); // b.size() == 8
1971 \endcode
1972
1973 \sa xFormDev(), QWMatrix::map()
1974*/
1975
1976QPointArray QPainter::xForm( const QPointArray &av, int index,
1977 int npoints ) const
1978{
1979 int lastPoint = npoints < 0 ? av.size() : index+npoints;
1980 QPointArray a( lastPoint-index );
1981 memcpy( a.data(), av.data()+index, (lastPoint-index)*sizeof( QPoint ) );
1982#ifndef QT_NO_TRANSFORMATIONS
1983 return xmat*a;
1984#else
1985 a.translate( xlatex, xlatey );
1986 return a;
1987#endif
1988}
1989
1990/*!
1991 \overload
1992
1993 Returns the point \a pd transformed from device coordinates to
1994 model coordinates.
1995
1996 \sa xForm(), QWMatrix::map()
1997*/
1998
1999QPoint QPainter::xFormDev( const QPoint &pd ) const
2000{
2001#ifndef QT_NO_TRANSFORMATIONS
2002 if ( txop == TxNone )
2003 return pd;
2004 if ( !txinv ) {
2005 QPainter *that = (QPainter*)this; // mutable
2006 that->updateInvXForm();
2007 }
2008#endif
2009 int x=pd.x(), y=pd.y();
2010 mapInv( x, y, &x, &y );
2011 return QPoint( x, y );
2012}
2013
2014/*!
2015 Returns the rectangle \a rd transformed from device coordinates to
2016 model coordinates.
2017
2018 If world transformation is enabled and rotation or shearing is
2019 used, then the bounding rectangle is returned.
2020
2021 \sa xForm(), QWMatrix::map()
2022*/
2023
2024QRect QPainter::xFormDev( const QRect &rd ) const
2025{
2026#ifndef QT_NO_TRANSFORMATIONS
2027 if ( txop == TxNone )
2028 return rd;
2029 if ( !txinv ) {
2030 QPainter *that = (QPainter*)this; // mutable
2031 that->updateInvXForm();
2032 }
2033 if ( txop == TxRotShear ) { // rotation/shear
2034 return ixmat.mapRect( rd );
2035 }
2036#endif
2037 // Just translation/scale
2038 int x, y, w, h;
2039 rd.rect( &x, &y, &w, &h );
2040 mapInv( x, y, w, h, &x, &y, &w, &h );
2041 return QRect( x, y, w, h );
2042}
2043
2044/*!
2045 \overload
2046
2047 Returns the point array \a ad transformed from device coordinates
2048 to model coordinates.
2049
2050 \sa xForm(), QWMatrix::map()
2051*/
2052
2053QPointArray QPainter::xFormDev( const QPointArray &ad ) const
2054{
2055#ifndef QT_NO_TRANSFORMATIONS
2056 if ( txop == TxNone )
2057 return ad;
2058 if ( !txinv ) {
2059 QPainter *that = (QPainter*)this; // mutable
2060 that->updateInvXForm();
2061 }
2062 return ixmat * ad;
2063#else
2064 // ###
2065 return ad;
2066#endif
2067}
2068
2069/*!
2070 \overload
2071
2072 Returns the point array \a ad transformed from device coordinates
2073 to model coordinates. The \a index is the first point in the array
2074 and \a npoints denotes the number of points to be transformed. If
2075 \a npoints is negative, all points from \a ad[index] until the
2076 last point in the array are transformed.
2077
2078 The returned point array consists of the number of points that
2079 were transformed.
2080
2081 Example:
2082 \code
2083 QPointArray a(10);
2084 QPointArray b;
2085 b = painter.xFormDev(a, 1, 3); // b.size() == 3
2086 b = painter.xFormDev(a, 1, -1); // b.size() == 9
2087 \endcode
2088
2089 \sa xForm(), QWMatrix::map()
2090*/
2091
2092QPointArray QPainter::xFormDev( const QPointArray &ad, int index,
2093 int npoints ) const
2094{
2095 int lastPoint = npoints < 0 ? ad.size() : index+npoints;
2096 QPointArray a( lastPoint-index );
2097 memcpy( a.data(), ad.data()+index, (lastPoint-index)*sizeof( QPoint ) );
2098#ifndef QT_NO_TRANSFORMATIONS
2099 if ( txop == TxNone )
2100 return a;
2101 if ( !txinv ) {
2102 QPainter *that = (QPainter*)this; // mutable
2103 that->updateInvXForm();
2104 }
2105 return ixmat * a;
2106#else
2107 // ###
2108 return a;
2109#endif
2110}
2111
2112
2113/*!
2114 Fills the rectangle \a (x, y, w, h) with the \a brush.
2115
2116 You can specify a QColor as \a brush, since there is a QBrush
2117 constructor that takes a QColor argument and creates a solid
2118 pattern brush.
2119
2120 \sa drawRect()
2121*/
2122
2123void QPainter::fillRect( int x, int y, int w, int h, const QBrush &brush )
2124{
2125 QPen oldPen = pen(); // save pen
2126 QBrush oldBrush = this->brush(); // save brush
2127 setPen( NoPen );
2128 setBrush( brush );
2129 drawRect( x, y, w, h ); // draw filled rect
2130 setBrush( oldBrush ); // restore brush
2131 setPen( oldPen ); // restore pen
2132}
2133
2134
2135/*!
2136 \overload void QPainter::setBrushOrigin( const QPoint &p )
2137
2138 Sets the brush origin to point \a p.
2139*/
2140
2141/*!
2142 \overload void QPainter::setWindow( const QRect &r )
2143
2144 Sets the painter's window to rectangle \a r.
2145*/
2146
2147
2148/*!
2149 \overload void QPainter::setViewport( const QRect &r )
2150
2151 Sets the painter's viewport to rectangle \a r.
2152*/
2153
2154
2155/*!
2156 \fn bool QPainter::hasClipping() const
2157
2158 Returns TRUE if clipping has been set; otherwise returns FALSE.
2159
2160 \sa setClipping()
2161*/
2162
2163/*!
2164 Returns the currently set clip region. Note that the clip region
2165 is given in physical device coordinates and \e not subject to any
2166 \link coordsys.html coordinate transformation \endlink if \a m is
2167 equal to \c CoordDevice (the default). If \a m equals \c
2168 CoordPainter the returned region is in model coordinates.
2169
2170 \sa setClipRegion(), setClipRect(), setClipping() QPainter::CoordinateMode
2171*/
2172QRegion QPainter::clipRegion( CoordinateMode m ) const
2173{
2174 // ### FIXME in 4.0:
2175 // If the transformation mode is CoordPainter, we should transform the
2176 // clip region with painter transformations.
2177
2178#ifndef QT_NO_TRANSFORMATIONS
2179 QRegion r;
2180 if ( m == CoordDevice ) {
2181 r = crgn;
2182 } else {
2183 if ( !txinv ) {
2184 QPainter *that = (QPainter*)this; // mutable
2185 that->updateInvXForm();
2186 }
2187
2188 r = ixmat * crgn;
2189 }
2190 return r;
2191#else
2192 return crgn;
2193#endif
2194}
2195
2196/*!
2197 \fn void QPainter::setClipRect( int x, int y, int w, int h, CoordinateMode m)
2198
2199 Sets the clip region to the rectangle \a x, \a y, \a w, \a h and
2200 enables clipping. The clip mode is set to \a m.
2201
2202 If \a m is \c CoordDevice (the default), the coordinates given for
2203 the clip region are taken to be physical device coordinates and
2204 are \e not subject to any \link coordsys.html coordinate
2205 transformations\endlink. If \a m is \c CoordPainter, the
2206 coordinates given for the clip region are taken to be model
2207 coordinates.
2208
2209 \sa setClipRegion(), clipRegion(), setClipping() QPainter::CoordinateMode
2210*/
2211
2212/*!
2213 \overload void QPainter::drawPoint( const QPoint &p )
2214
2215 Draws the point \a p.
2216*/
2217
2218
2219/*!
2220 \overload void QPainter::moveTo( const QPoint &p )
2221
2222 Moves to the point \a p.
2223*/
2224
2225/*!
2226 \overload void QPainter::lineTo( const QPoint &p )
2227
2228 Draws a line to the point \a p.
2229*/
2230
2231/*!
2232 \overload void QPainter::drawLine( const QPoint &p1, const QPoint &p2 )
2233
2234 Draws a line from point \a p1 to point \a p2.
2235*/
2236
2237/*!
2238 \overload void QPainter::drawRect( const QRect &r )
2239
2240 Draws the rectangle \a r.
2241*/
2242
2243/*!
2244 \overload void QPainter::drawWinFocusRect( const QRect &r )
2245
2246 Draws rectangle \a r as a window focus rectangle.
2247*/
2248
2249/*!
2250 \overload void QPainter::drawWinFocusRect( const QRect &r, const QColor &bgColor )
2251
2252 Draws rectangle \a r as a window focus rectangle using background
2253 color \a bgColor.
2254*/
2255
2256
2257#if !defined(Q_WS_X11) && !defined(Q_WS_QWS) && !defined(Q_WS_MAC)
2258// The doc and X implementation of this functions is in qpainter_x11.cpp
2259void QPainter::drawWinFocusRect( int, int, int, int,
2260 bool, const QColor & )
2261{
2262 // do nothing, only called from X11 specific functions
2263}
2264#endif
2265
2266
2267/*!
2268 \overload void QPainter::drawRoundRect( const QRect &r, int xRnd, int yRnd )
2269
2270 Draws a rounded rectangle \a r, rounding to the x position \a xRnd
2271 and the y position \a yRnd on each corner.
2272*/
2273
2274/*!
2275 \overload void QPainter::drawEllipse( const QRect &r )
2276
2277 Draws the ellipse that fits inside rectangle \a r.
2278*/
2279
2280/*!
2281 \overload void QPainter::drawArc( const QRect &r, int a, int alen )
2282
2283 Draws the arc that fits inside the rectangle \a r with start angle
2284 \a a and arc length \a alen.
2285*/
2286
2287/*!
2288 \overload void QPainter::drawPie( const QRect &r, int a, int alen )
2289
2290 Draws a pie segment that fits inside the rectangle \a r with start
2291 angle \a a and arc length \a alen.
2292*/
2293
2294/*!
2295 \overload void QPainter::drawChord( const QRect &r, int a, int alen )
2296
2297 Draws a chord that fits inside the rectangle \a r with start angle
2298 \a a and arc length \a alen.
2299*/
2300
2301/*!
2302 \overload void QPainter::drawPixmap( const QPoint &p, const QPixmap &pm, const QRect &sr )
2303
2304 Draws the rectangle \a sr of pixmap \a pm with its origin at point
2305 \a p.
2306*/
2307
2308/*!
2309 \overload void QPainter::drawPixmap( const QPoint &p, const QPixmap &pm )
2310
2311 Draws the pixmap \a pm with its origin at point \a p.
2312*/
2313
2314void QPainter::drawPixmap( const QPoint &p, const QPixmap &pm )
2315{
2316 drawPixmap( p.x(), p.y(), pm, 0, 0, pm.width(), pm.height() );
2317}
2318
2319#if !defined(QT_NO_IMAGE_SMOOTHSCALE) || !defined(QT_NO_PIXMAP_TRANSFORMATION)
2320
2321/*!
2322 \overload
2323
2324 Draws the pixmap \a pm into the rectangle \a r. The pixmap is
2325 scaled to fit the rectangle, if image and rectangle size disagree.
2326*/
2327void QPainter::drawPixmap( const QRect &r, const QPixmap &pm )
2328{
2329 int rw = r.width();
2330 int rh = r.height();
2331 int iw= pm.width();
2332 int ih = pm.height();
2333 if ( rw <= 0 || rh <= 0 || iw <= 0 || ih <= 0 )
2334 return;
2335 bool scale = ( rw != iw || rh != ih );
2336 float scaleX = (float)rw/(float)iw;
2337 float scaleY = (float)rh/(float)ih;
2338 bool smooth = ( scaleX < 1.5 || scaleY < 1.5 );
2339
2340 if ( testf(ExtDev) ) {
2341 QPDevCmdParam param[2];
2342 param[0].rect = &r;
2343 param[1].pixmap = &pm;
2344#if defined(Q_WS_WIN)
2345 if ( !pdev->cmd( QPaintDevice::PdcDrawPixmap, this, param ) || !hdc )
2346 return;
2347#elif defined(Q_WS_QWS)
2348 pdev->cmd( QPaintDevice::PdcDrawPixmap, this, param );
2349 return;
2350#elif defined(Q_WS_MAC)
2351 if ( !pdev->cmd( QPaintDevice::PdcDrawPixmap, this, param ) || !pdev->handle())
2352 return;
2353#else
2354 if ( !pdev->cmd( QPaintDevice::PdcDrawPixmap, this, param ) || !hd )
2355 return;
2356#endif
2357 }
2358
2359 QPixmap pixmap = pm;
2360
2361 if ( scale ) {
2362#ifndef QT_NO_IMAGE_SMOOTHSCALE
2363# ifndef QT_NO_PIXMAP_TRANSFORMATION
2364 if ( smooth )
2365# endif
2366 {
2367 QImage i = pm.convertToImage();
2368 pixmap = QPixmap( i.smoothScale( rw, rh ) );
2369 }
2370# ifndef QT_NO_PIXMAP_TRANSFORMATION
2371 else
2372# endif
2373#endif
2374#ifndef QT_NO_PIXMAP_TRANSFORMATION
2375 {
2376 pixmap = pm.xForm( QWMatrix( scaleX, 0, 0, scaleY, 0, 0 ) );
2377 }
2378#endif
2379 }
2380 drawPixmap( r.x(), r.y(), pixmap );
2381}
2382
2383#endif
2384
2385/*!
2386 \overload void QPainter::drawImage( const QPoint &, const QImage &, const QRect &sr, int conversionFlags = 0 );
2387
2388 Draws the rectangle \a sr from the image at the given point.
2389*/
2390
2391/*
2392 Draws at point \a p the \sr rect from image \a pm, using \a
2393 conversionFlags if the image needs to be converted to a pixmap.
2394 The default value for \a conversionFlags is 0; see
2395 convertFromImage() for information about what other values do.
2396
2397 This function may convert \a image to a pixmap and then draw it, if
2398 device() is a QPixmap or a QWidget, or else draw it directly, if
2399 device() is a QPrinter or QPicture.
2400*/
2401
2402/*!
2403 Draws at (\a x, \a y) the \a sw by \a sh area of pixels from (\a
2404 sx, \a sy) in \a image, using \a conversionFlags if the image
2405 needs to be converted to a pixmap. The default value for \a
2406 conversionFlags is 0; see convertFromImage() for information about
2407 what other values do.
2408
2409 This function may convert \a image to a pixmap and then draw it,
2410 if device() is a QPixmap or a QWidget, or else draw it directly,
2411 if device() is a QPrinter or QPicture.
2412
2413 Currently alpha masks of the image are ignored when painting on a QPrinter.
2414
2415 \sa drawPixmap() QPixmap::convertFromImage()
2416*/
2417void QPainter::drawImage( int x, int y, const QImage & image,
2418 int sx, int sy, int sw, int sh,
2419 int conversionFlags )
2420{
2421#ifdef Q_WS_QWS
2422 //### Hackish
2423# ifndef QT_NO_TRANSFORMATIONS
2424 if ( !image.isNull() && gfx &&
2425 (txop==TxNone||txop==TxTranslate) && !testf(ExtDev) )
2426# else
2427 if ( !image.isNull() && gfx && !testf(ExtDev) )
2428# endif
2429 {
2430 if(sw<0)
2431 sw=image.width();
2432 if(sh<0)
2433 sh=image.height();
2434
2435 QImage image2 = qt_screen->mapToDevice( image );
2436
2437 // This is a bit dubious
2438 if(image2.depth()==1) {
2439 image2.setNumColors( 2 );
2440 image2.setColor( 0, qRgb(255,255,255) );
2441 image2.setColor( 1, qRgb(0,0,0) );
2442 }
2443 if ( image2.hasAlphaBuffer() )
2444 gfx->setAlphaType(QGfx::InlineAlpha);
2445 else
2446 gfx->setAlphaType(QGfx::IgnoreAlpha);
2447 gfx->setSource(&image2);
2448 if ( testf(VxF|WxF) ) {
2449 map( x, y, &x, &y );
2450 }
2451 gfx->blt(x,y,sw,sh,sx,sy);
2452 return;
2453 }
2454#endif
2455
2456 if ( !isActive() || image.isNull() )
2457 return;
2458
2459 // right/bottom
2460 if ( sw < 0 )
2461 sw = image.width() - sx;
2462 if ( sh < 0 )
2463 sh = image.height() - sy;
2464
2465 // Sanity-check clipping
2466 if ( sx < 0 ) {
2467 x -= sx;
2468 sw += sx;
2469 sx = 0;
2470 }
2471 if ( sw + sx > image.width() )
2472 sw = image.width() - sx;
2473 if ( sy < 0 ) {
2474 y -= sy;
2475 sh += sy;
2476 sy = 0;
2477 }
2478 if ( sh + sy > image.height() )
2479 sh = image.height() - sy;
2480
2481 if ( sw <= 0 || sh <= 0 )
2482 return;
2483
2484 bool all = image.rect().intersect(QRect(sx,sy,sw,sh)) == image.rect();
2485 QImage subimage = all ? image : image.copy(sx,sy,sw,sh);
2486
2487 if ( testf(ExtDev) ) {
2488 QPDevCmdParam param[2];
2489 QRect r( x, y, subimage.width(), subimage.height() );
2490 param[0].rect = &r;
2491 param[1].image = &subimage;
2492#if defined(Q_WS_WIN)
2493 if ( !pdev->cmd( QPaintDevice::PdcDrawImage, this, param ) || !hdc )
2494 return;
2495#elif defined (Q_WS_QWS)
2496 pdev->cmd( QPaintDevice::PdcDrawImage, this, param );
2497 return;
2498#elif defined(Q_WS_MAC)
2499 if(!pdev->cmd( QPaintDevice::PdcDrawImage, this, param ) || !pdev->handle() )
2500 return;
2501#else
2502 if ( !pdev->cmd( QPaintDevice::PdcDrawImage, this, param ) || !hd )
2503 return;
2504#endif
2505 }
2506
2507 QPixmap pm;
2508 pm.convertFromImage( subimage, conversionFlags );
2509 drawPixmap( x, y, pm );
2510}
2511
2512/*!
2513 \overload void QPainter::drawImage( const QPoint &p, const QImage &i, int conversion_flags )
2514
2515 Draws the image \a i at point \a p.
2516
2517 If the image needs to be modified to fit in a lower-resolution
2518 result (e.g. converting from 32-bit to 8-bit), use the \a
2519 conversion_flags to specify how you'd prefer this to happen.
2520
2521 \sa Qt::ImageConversionFlags
2522*/
2523void QPainter::drawImage( const QPoint & p, const QImage & i,
2524 int conversion_flags )
2525{
2526 drawImage(p, i, i.rect(), conversion_flags);
2527}
2528
2529#if !defined(QT_NO_IMAGE_TRANSFORMATION) || !defined(QT_NO_IMAGE_SMOOTHSCALE)
2530
2531/*!
2532 \overload
2533
2534 Draws the image \a i into the rectangle \a r. The image will be
2535 scaled to fit the rectangle if image and rectangle dimensions
2536 differ.
2537*/
2538void QPainter::drawImage( const QRect &r, const QImage &i )
2539{
2540 int rw = r.width();
2541 int rh = r.height();
2542 int iw= i.width();
2543 int ih = i.height();
2544 if ( rw <= 0 || rh <= 0 || iw <= 0 || ih <= 0 )
2545 return;
2546
2547 if ( testf(ExtDev) ) {
2548 QPDevCmdParam param[2];
2549 param[0].rect = &r;
2550 param[1].image = &i;
2551#if defined(Q_WS_WIN)
2552 if ( !pdev->cmd( QPaintDevice::PdcDrawImage, this, param ) || !hdc )
2553 return;
2554#elif defined(Q_WS_QWS)
2555 pdev->cmd( QPaintDevice::PdcDrawImage, this, param );
2556 return;
2557#elif defined(Q_WS_MAC)
2558 if ( !pdev->cmd( QPaintDevice::PdcDrawImage, this, param ) || !pdev->handle() )
2559 return;
2560#else
2561 if ( !pdev->cmd( QPaintDevice::PdcDrawImage, this, param ) || !hd )
2562 return;
2563#endif
2564 }
2565
2566
2567 bool scale = ( rw != iw || rh != ih );
2568 float scaleX = (float)rw/(float)iw;
2569 float scaleY = (float)rh/(float)ih;
2570 bool smooth = ( scaleX < 1.5 || scaleY < 1.5 );
2571
2572 QImage img = scale
2573 ? (
2574#if defined(QT_NO_IMAGE_TRANSFORMATION)
2575 i.smoothScale( rw, rh )
2576#elif defined(QT_NO_IMAGE_SMOOTHSCALE)
2577 i.scale( rw, rh )
2578#else
2579 smooth ? i.smoothScale( rw, rh ) : i.scale( rw, rh )
2580#endif
2581 )
2582 : i;
2583
2584 drawImage( r.x(), r.y(), img );
2585}
2586
2587#endif
2588
2589
2590void bitBlt( QPaintDevice *dst, int dx, int dy,
2591 const QImage *src, int sx, int sy, int sw, int sh,
2592 int conversion_flags )
2593{
2594 QPixmap tmp;
2595 if ( sx == 0 && sy == 0
2596 && (sw<0 || sw==src->width()) && (sh<0 || sh==src->height()) )
2597 {
2598 tmp.convertFromImage( *src, conversion_flags );
2599 } else {
2600 tmp.convertFromImage( src->copy( sx, sy, sw, sh, conversion_flags),
2601 conversion_flags );
2602 }
2603 bitBlt( dst, dx, dy, &tmp );
2604}
2605
2606
2607/*!
2608 \overload void QPainter::drawTiledPixmap( const QRect &r, const QPixmap &pm, const QPoint &sp )
2609
2610 Draws a tiled pixmap, \a pm, inside rectangle \a r with its origin
2611 at point \a sp.
2612*/
2613
2614/*!
2615 \overload void QPainter::drawTiledPixmap( const QRect &r, const QPixmap &pm )
2616
2617 Draws a tiled pixmap, \a pm, inside rectangle \a r.
2618*/
2619
2620/*!
2621 \overload void QPainter::fillRect( const QRect &r, const QBrush &brush )
2622
2623 Fills the rectangle \a r using brush \a brush.
2624*/
2625
2626/*!
2627 \fn void QPainter::eraseRect( int x, int y, int w, int h )
2628
2629 Erases the area inside \a x, \a y, \a w, \a h. Equivalent to
2630 \c{fillRect( x, y, w, h, backgroundColor() )}.
2631*/
2632
2633/*!
2634 \overload void QPainter::eraseRect( const QRect &r )
2635
2636 Erases the area inside the rectangle \a r.
2637*/
2638
2639/*!
2640 \fn QPainter::drawText( int x, int y, const QString &, int len = -1, TextDirection dir = Auto )
2641
2642 \overload
2643
2644 Draws the given text at position \a x, \a y. If \a len is -1 (the
2645 default) all the text is drawn, otherwise the first \a len
2646 characters are drawn. The text's direction is given by \a dir.
2647
2648 \sa QPainter::TextDirection
2649*/
2650
2651/*!
2652 \fn void QPainter::drawText( int x, int y, int w, int h, int flags,
2653 const QString&, int len = -1, QRect *br=0,
2654 QTextParag **internal=0 )
2655
2656 \overload
2657
2658 Draws the given text within the rectangle starting at \a x, \a y,
2659 with width \a w and height \a h. If \a len is -1 (the default) all
2660 the text is drawn, otherwise the first \a len characters are
2661 drawn. The text's flags that are given in the \a flags parameter
2662 are \l{Qt::AlignmentFlags} and \l{Qt::TextFlags} OR'd together. \a
2663 br (if not null) is set to the actual bounding rectangle of the
2664 output. The \a internal parameter is for internal use only.
2665*/
2666
2667/*!
2668 \fn void QPainter::drawText( const QPoint &, const QString &, int len = -1, TextDirection dir = Auto );
2669
2670 \overload
2671
2672 Draws the text at the given point.
2673
2674 \sa QPainter::TextDirection
2675*/
2676
2677/*
2678 Draws the text in \a s at point \a p. If \a len is -1 the entire
2679 string is drawn, otherwise just the first \a len characters. The
2680 text's direction is specified by \a dir.
2681*/
2682
2683
2684/*!
2685 \fn void QPainter::drawText( int x, int y, const QString &, int pos, int len, TextDirection dir = Auto );
2686
2687 \overload
2688
2689 Draws the text from position \a pos, at point \a (x, y). If \a len is
2690 -1 the entire string is drawn, otherwise just the first \a len
2691 characters. The text's direction is specified by \a dir.
2692*/
2693
2694/*!
2695 \fn void QPainter::drawText( const QPoint &p, const QString &, int pos, int len, TextDirection dir = Auto );
2696
2697 Draws the text from position \a pos, at point \a p. If \a len is
2698 -1 the entire string is drawn, otherwise just the first \a len
2699 characters. The text's direction is specified by \a dir.
2700
2701 Note that the meaning of \e y is not the same for the two
2702 drawText() varieties. For overloads that take a simple \e x, \e y
2703 pair (or a point), the \e y value is the text's baseline; for
2704 overloads that take a rectangle, \e rect.y() is the top of the
2705 rectangle and the text is aligned within that rectangle in
2706 accordance with the alignment flags.
2707
2708 \sa QPainter::TextDirection
2709*/
2710
2711/*!
2712 \fn void QPainter::drawTextItem(const QPoint &, const QTextItem &, int)
2713 \internal
2714*/
2715
2716static inline void fix_neg_rect( int *x, int *y, int *w, int *h )
2717{
2718 if ( *w < 0 ) {
2719 *w = -*w;
2720 *x -= *w - 1;
2721 }
2722 if ( *h < 0 ) {
2723 *h = -*h;
2724 *y -= *h - 1;
2725 }
2726}
2727void QPainter::fix_neg_rect( int *x, int *y, int *w, int *h )
2728{
2729 ::fix_neg_rect(x,y,w,h);
2730}
2731
2732//
2733// The drawText function takes two special parameters; 'internal' and 'brect'.
2734//
2735// The 'internal' parameter contains a pointer to an array of encoded
2736// information that keeps internal geometry data.
2737// If the drawText function is called repeatedly to display the same text,
2738// it makes sense to calculate text width and linebreaks the first time,
2739// and use these parameters later to print the text because we save a lot of
2740// CPU time.
2741// The 'internal' parameter will not be used if it is a null pointer.
2742// The 'internal' parameter will be generated if it is not null, but points
2743// to a null pointer, i.e. internal != 0 && *internal == 0.
2744// The 'internal' parameter will be used if it contains a non-null pointer.
2745//
2746// If the 'brect parameter is a non-null pointer, then the bounding rectangle
2747// of the text will be returned in 'brect'.
2748//
2749
2750/*!
2751 \overload
2752
2753 Draws at most \a len characters from \a str in the rectangle \a r.
2754
2755 This function draws formatted text. The \a tf text format is
2756 really of type \l Qt::AlignmentFlags and \l Qt::TextFlags OR'd
2757 together.
2758
2759 Horizontal alignment defaults to AlignAuto and vertical alignment
2760 defaults to AlignTop.
2761
2762 \a brect (if not null) is set to the actual bounding rectangle of
2763 the output. \a internal is, yes, internal.
2764
2765 \sa boundingRect()
2766*/
2767
2768void QPainter::drawText( const QRect &r, int tf,
2769 const QString& str, int len, QRect *brect,
2770 QTextParag **internal )
2771{
2772 if ( !isActive() )
2773 return;
2774 if ( len < 0 )
2775 len = str.length();
2776 if ( len == 0 ) // empty string
2777 return;
2778
2779 if ( testf(DirtyFont|ExtDev) ) {
2780 if ( testf(DirtyFont) )
2781 updateFont();
2782 if ( testf(ExtDev) && (tf & DontPrint) == 0 ) {
2783 QPDevCmdParam param[3];
2784 QString newstr = str;
2785 newstr.truncate( len );
2786 param[0].rect = &r;
2787 param[1].ival = tf;
2788 param[2].str = &newstr;
2789 if ( pdev->devType() != QInternal::Printer ) {
2790#if defined(Q_WS_WIN)
2791 if ( !pdev->cmd( QPaintDevice::PdcDrawText2Formatted,
2792 this, param) ||
2793 !hdc )
2794 return; // QPrinter wants PdcDrawText2
2795#elif defined(Q_WS_QWS)
2796 pdev->cmd( QPaintDevice::PdcDrawText2Formatted, this, param);
2797 return;
2798#elif defined(Q_WS_MAC)
2799 if ( !pdev->cmd( QPaintDevice::PdcDrawText2Formatted, this, param) ||
2800 !pdev->handle())
2801 return; // QPrinter wants PdcDrawText2
2802#else
2803 if ( !pdev->cmd( QPaintDevice::PdcDrawText2Formatted,
2804 this, param) ||
2805 !hd )
2806 return; // QPrinter wants PdcDrawText2
2807#endif
2808 }
2809 }
2810 }
2811
2812 qt_format_text(font(), r, tf, str, len, brect,
2813 tabstops, tabarray, tabarraylen, internal, this);
2814}
2815
2816//#define QT_FORMAT_TEXT_DEBUG
2817
2818#define QChar_linesep QChar(0x2028U)
2819
2820void qt_format_text( const QFont& font, const QRect &_r,
2821 int tf, const QString& str, int len, QRect *brect,
2822 int tabstops, int* tabarray, int tabarraylen,
2823 QTextParag **, QPainter* painter )
2824{
2825 // we need to copy r here to protect against the case (&r == brect).
2826 QRect r( _r );
2827
2828 bool dontclip = (tf & Qt::DontClip) == Qt::DontClip;
2829 bool wordbreak = (tf & Qt::WordBreak) == Qt::WordBreak;
2830 bool singleline = (tf & Qt::SingleLine) == Qt::SingleLine;
2831 bool showprefix = (tf & Qt::ShowPrefix) == Qt::ShowPrefix;
2832 bool noaccel = ( tf & Qt::NoAccel ) == Qt::NoAccel;
2833
2834 bool isRightToLeft = str.isRightToLeft();
2835 if ( ( tf & Qt::AlignHorizontal_Mask ) == Qt::AlignAuto )
2836 tf |= isRightToLeft ? Qt::AlignRight : Qt::AlignLeft;
2837
2838 bool expandtabs = ( (tf & Qt::ExpandTabs) &&
2839 ( ( (tf & Qt::AlignLeft) && !isRightToLeft ) ||
2840 ( (tf & Qt::AlignRight) && isRightToLeft ) ) );
2841
2842 if ( !painter )
2843 tf |= Qt::DontPrint;
2844
2845 int maxUnderlines = 0;
2846 int numUnderlines = 0;
2847 int underlinePositionStack[32];
2848 int *underlinePositions = underlinePositionStack;
2849
2850 QFont fnt(painter ? (painter->pfont ? *painter->pfont : painter->cfont) : font);
2851 QFontMetrics fm( fnt );
2852
2853 QString text = str;
2854 // str.setLength() always does a deep copy, so the replacement
2855 // code below is safe.
2856 text.setLength( len );
2857 // compatible behaviour to the old implementation. Replace
2858 // tabs by spaces
2859 QChar *chr = (QChar*)text.unicode();
2860 const QChar *end = chr + len;
2861 bool haveLineSep = FALSE;
2862 while ( chr != end ) {
2863 if ( *chr == '\r' || ( singleline && *chr == '\n' ) ) {
2864 *chr = ' ';
2865 } else if ( *chr == '\n' ) {
2866 *chr = QChar_linesep;
2867 haveLineSep = TRUE;
2868 } else if ( *chr == '&' ) {
2869 ++maxUnderlines;
2870 }
2871 ++chr;
2872 }
2873 if ( !expandtabs ) {
2874 chr = (QChar*)text.unicode();
2875 while ( chr != end ) {
2876 if ( *chr == '\t' )
2877 *chr = ' ';
2878 ++chr;
2879 }
2880 } else if (!tabarraylen && !tabstops) {
2881 tabstops = fm.width('x')*8;
2882 }
2883
2884 if ( noaccel || showprefix ) {
2885 if ( maxUnderlines > 32 )
2886 underlinePositions = new int[maxUnderlines];
2887 QChar *cout = (QChar*)text.unicode();
2888 QChar *cin = cout;
2889 int l = len;
2890 while ( l ) {
2891 if ( *cin == '&' ) {
2892 ++cin;
2893 --l;
2894 if ( !l )
2895 break;
2896 if ( *cin != '&' )
2897 underlinePositions[numUnderlines++] = cout - text.unicode();
2898 }
2899 *cout = *cin;
2900 ++cout;
2901 ++cin;
2902 --l;
2903 }
2904 uint newlen = cout - text.unicode();
2905 if ( newlen != text.length())
2906 text.setLength( newlen );
2907 }
2908
2909 // no need to do extra work for underlines if we don't paint
2910 if ( tf & Qt::DontPrint )
2911 numUnderlines = 0;
2912
2913 int height = 0;
2914 int left = r.width();
2915 int right = 0;
2916
2917 QTextLayout textLayout( text, fnt );
2918 int rb = QMAX( 0, -fm.minRightBearing() );
2919 int lb = QMAX( 0, -fm.minLeftBearing() );
2920
2921 if ( text.isEmpty() ) {
2922 height = fm.height();
2923 left = right = 0;
2924 tf |= QPainter::DontPrint;
2925 } else {
2926 textLayout.beginLayout((haveLineSep || expandtabs || wordbreak) ?
2927 QTextLayout::MultiLine :
2928 (tf & Qt::DontPrint) ? QTextLayout::NoBidi : QTextLayout::SingleLine );
2929
2930 // break underline chars into items of their own
2931 for( int i = 0; i < numUnderlines; i++ ) {
2932 textLayout.setBoundary( underlinePositions[i] );
2933 textLayout.setBoundary( underlinePositions[i]+1 );
2934 }
2935
2936 int lineWidth = wordbreak ? QMAX(0, r.width()-rb-lb) : INT_MAX;
2937 if(!wordbreak)
2938 tf |= Qt::IncludeTrailingSpaces;
2939
2940 int leading = fm.leading();
2941 int asc = fm.ascent();
2942 int desc = fm.descent();
2943 height = -leading;
2944
2945 //qDebug("\n\nbeginLayout: lw = %d, rectwidth=%d", lineWidth , r.width());
2946 while ( !textLayout.atEnd() ) {
2947 height += leading;
2948 textLayout.beginLine( lineWidth == INT_MAX ? lineWidth : lineWidth );
2949 //qDebug("-----beginLine( %d )-----", lineWidth );
2950 bool linesep = FALSE;
2951 while ( 1 ) {
2952 QTextItem ti = textLayout.currentItem();
2953 //qDebug("item: from=%d, ch=%x", ti.from(), text.unicode()[ti.from()].unicode() );
2954 if ( expandtabs && ti.isTab() ) {
2955 int tw = 0;
2956 int x = textLayout.widthUsed();
2957 if ( tabarraylen ) {
2958// qDebug("tabarraylen=%d", tabarraylen );
2959 int tab = 0;
2960 while ( tab < tabarraylen ) {
2961 if ( tabarray[tab] > x ) {
2962 tw = tabarray[tab] - x;
2963 break;
2964 }
2965 ++tab;
2966 }
2967 } else {
2968 tw = tabstops - (x % tabstops);
2969 }
2970 //qDebug("tw = %d", tw );
2971 if ( tw )
2972 ti.setWidth( tw );
2973 }
2974 if ( ti.isObject() && text.unicode()[ti.from()] == QChar_linesep )
2975 linesep = TRUE;
2976
2977 if ( linesep || textLayout.addCurrentItem() != QTextLayout::Ok || textLayout.atEnd() )
2978 break;
2979 }
2980
2981 int ascent = asc, descent = desc, lineLeft, lineRight;
2982 textLayout.setLineWidth( r.width()-rb-lb );
2983 textLayout.endLine( 0, height, tf, &ascent, &descent,
2984 &lineLeft, &lineRight );
2985 //qDebug("finalizing line: lw=%d ascent = %d, descent=%d lineleft=%d lineright=%d", lineWidth, ascent, descent,lineLeft, lineRight );
2986 left = QMIN( left, lineLeft );
2987 right = QMAX( right, lineRight );
2988 height += ascent + descent + 1;
2989 if ( linesep )
2990 textLayout.nextItem();
2991 }
2992 }
2993
2994 int yoff = 0;
2995 if ( tf & Qt::AlignBottom )
2996 yoff = r.height() - height;
2997 else if ( tf & Qt::AlignVCenter )
2998 yoff = (r.height() - height)/2;
2999
3000 if ( brect ) {
3001 *brect = QRect( r.x() + left, r.y() + yoff, right-left + lb+rb, height );
3002 //qDebug("br = %d %d %d/%d, left=%d, right=%d", brect->x(), brect->y(), brect->width(), brect->height(), left, right);
3003 }
3004
3005 if (!(tf & QPainter::DontPrint)) {
3006 bool restoreClipping = FALSE;
3007 bool painterHasClip = FALSE;
3008 QRegion painterClipRegion;
3009 if ( !dontclip ) {
3010#ifndef QT_NO_TRANSFORMATIONS
3011 QRegion reg = painter->xmat * r;
3012#else
3013 QRegion reg = r;
3014 reg.translate( painter->xlatex, painter->xlatey );
3015#endif
3016 if ( painter->hasClipping() )
3017 reg &= painter->clipRegion();
3018
3019 painterHasClip = painter->hasClipping();
3020 painterClipRegion = painter->clipRegion();
3021 restoreClipping = TRUE;
3022 painter->setClipRegion( reg );
3023 } else {
3024 if ( painter->hasClipping() ){
3025 painterHasClip = painter->hasClipping();
3026 painterClipRegion = painter->clipRegion();
3027 restoreClipping = TRUE;
3028 painter->setClipping( FALSE );
3029 }
3030 }
3031
3032 int cUlChar = 0;
3033 int _tf = 0;
3034 if (fnt.underline()) _tf |= Qt::Underline;
3035 if (fnt.overline()) _tf |= Qt::Overline;
3036 if (fnt.strikeOut()) _tf |= Qt::StrikeOut;
3037
3038 //qDebug("have %d items",textLayout.numItems());
3039 for ( int i = 0; i < textLayout.numItems(); i++ ) {
3040 QTextItem ti = textLayout.itemAt( i );
3041 //qDebug("Item %d: from=%d, length=%d, space=%d x=%d", i, ti.from(), ti.length(), ti.isSpace(), ti.x() );
3042 if ( ti.isTab() || ti.isObject() )
3043 continue;
3044 int textFlags = _tf;
3045 if ( !noaccel && numUnderlines > cUlChar && ti.from() == underlinePositions[cUlChar] ) {
3046 textFlags |= Qt::Underline;
3047 cUlChar++;
3048 }
3049#if defined(Q_WS_X11) || defined(Q_WS_QWS)
3050 if ( painter->bg_mode == Qt::OpaqueMode )
3051 qt_draw_background( painter, r.x()+lb + ti.x(), r.y() + yoff + ti.y() - ti.ascent(),
3052 ti.width(), ti.ascent() + ti.descent() + 1);
3053#endif
3054 painter->drawTextItem( r.x()+lb, r.y() + yoff, ti, textFlags );
3055 }
3056
3057 if ( restoreClipping ) {
3058 painter->setClipRegion( painterClipRegion );
3059 painter->setClipping( painterHasClip );
3060 }
3061 }
3062
3063 if ( underlinePositions != underlinePositionStack )
3064 delete [] underlinePositions;
3065}
3066
3067/*!
3068 \overload
3069
3070 Returns the bounding rectangle of the aligned text that would be
3071 printed with the corresponding drawText() function using the first
3072 \a len characters from \a str if \a len is > -1, or the whole of
3073 \a str if \a len is -1. The drawing, and hence the bounding
3074 rectangle, is constrained to the rectangle \a r, or to the
3075 rectangle required to draw the text, whichever is the larger.
3076
3077 The \a internal parameter should not be used.
3078
3079 \sa drawText(), fontMetrics(), QFontMetrics::boundingRect(), Qt::TextFlags
3080*/
3081
3082QRect QPainter::boundingRect( const QRect &r, int flags,
3083 const QString& str, int len, QTextParag **internal )
3084{
3085 QRect brect;
3086 if ( str.isEmpty() )
3087 brect.setRect( r.x(),r.y(), 0,0 );
3088 else
3089 drawText( r, flags | DontPrint, str, len, &brect, internal );
3090 return brect;
3091}
3092
3093/*!
3094 \fn QRect QPainter::boundingRect( int x, int y, int w, int h, int flags, const QString&, int len = -1, QTextParag **intern=0 );
3095
3096 Returns the bounding rectangle of the aligned text that would be
3097 printed with the corresponding drawText() function using the first
3098 \a len characters of the string if \a len is > -1, or the whole of
3099 the string if \a len is -1. The drawing, and hence the bounding
3100 rectangle, is constrained to the rectangle that begins at point \a
3101 (x, y) with width \a w and hight \a h, or to the
3102 rectangle required to draw the text, whichever is the larger.
3103
3104 The \a flags argument is
3105 the bitwise OR of the following flags:
3106 \table
3107 \header \i Flag \i Meaning
3108 \row \i \c AlignAuto \i aligns according to the language, usually left.
3109 \row \i \c AlignLeft \i aligns to the left border.
3110 \row \i \c AlignRight \i aligns to the right border.
3111 \row \i \c AlignHCenter \i aligns horizontally centered.
3112 \row \i \c AlignTop \i aligns to the top border.
3113 \row \i \c AlignBottom \i aligns to the bottom border.
3114 \row \i \c AlignVCenter \i aligns vertically centered.
3115 \row \i \c AlignCenter \i (== \c AlignHCenter | \c AlignVCenter).
3116 \row \i \c SingleLine \i ignores newline characters in the text.
3117 \row \i \c ExpandTabs \i expands tabs.
3118 \row \i \c ShowPrefix \i interprets "&x" as "<u>x</u>".
3119 \row \i \c WordBreak \i breaks the text to fit the rectangle.
3120 \endtable
3121
3122 Horizontal alignment defaults to \c AlignLeft and vertical
3123 alignment defaults to \c AlignTop.
3124
3125 If several of the horizontal or several of the vertical alignment flags
3126 are set, the resulting alignment is undefined.
3127
3128 The \a intern parameter should not be used.
3129
3130 \sa Qt::TextFlags
3131*/
3132
3133
3134
3135/*****************************************************************************
3136 QPen member functions
3137 *****************************************************************************/
3138
3139/*!
3140 \class QPen qpen.h
3141 \brief The QPen class defines how a QPainter should draw lines and outlines
3142 of shapes.
3143
3144 \ingroup graphics
3145 \ingroup images
3146 \ingroup shared
3147 \mainclass
3148
3149 A pen has a style, width, color, cap style and join style.
3150
3151 The pen style defines the line type. The default pen style is \c
3152 Qt::SolidLine. Setting the style to \c NoPen tells the painter to
3153 not draw lines or outlines.
3154
3155 When drawing 1 pixel wide diagonal lines you can either use a very
3156 fast algorithm (specified by a line width of 0, which is the
3157 default), or a slower but more accurate algorithm (specified by a
3158 line width of 1). For horizontal and vertical lines a line width
3159 of 0 is the same as a line width of 1. The cap and join style have
3160 no effect on 0-width lines.
3161
3162 The pen color defines the color of lines and text. The default
3163 line color is black. The QColor documentation lists predefined
3164 colors.
3165
3166 The cap style defines how the end points of lines are drawn. The
3167 join style defines how the joins between two lines are drawn when
3168 multiple connected lines are drawn (QPainter::drawPolyline()
3169 etc.). The cap and join styles only apply to wide lines, i.e. when
3170 the width is 1 or greater.
3171
3172 Use the QBrush class to specify fill styles.
3173
3174 Example:
3175 \code
3176 QPainter painter;
3177 QPen pen( red, 2 ); // red solid line, 2 pixels wide
3178 painter.begin( &anyPaintDevice ); // paint something
3179 painter.setPen( pen ); // set the red, wide pen
3180 painter.drawRect( 40,30, 200,100 ); // draw a rectangle
3181 painter.setPen( blue ); // set blue pen, 0 pixel width
3182 painter.drawLine( 40,30, 240,130 ); // draw a diagonal in rectangle
3183 painter.end(); // painting done
3184 \endcode
3185
3186 See the \l Qt::PenStyle enum type for a complete list of pen
3187 styles.
3188
3189 With reference to the end points of lines, for wide (non-0-width)
3190 pens it depends on the cap style whether the end point is drawn or
3191 not. QPainter will try to make sure that the end point is drawn
3192 for 0-width pens, but this cannot be absolutely guaranteed because
3193 the underlying drawing engine is free to use any (typically
3194 accelerated) algorithm for drawing 0-width lines. On all tested
3195 systems, however, the end point of at least all non-diagonal lines
3196 are drawn.
3197
3198 A pen's color(), width(), style(), capStyle() and joinStyle() can
3199 be set in the constructor or later with setColor(), setWidth(),
3200 setStyle(), setCapStyle() and setJoinStyle(). Pens may also be
3201 compared and streamed.
3202
3203 \img pen-styles.png Pen styles
3204
3205 \sa QPainter, QPainter::setPen()
3206*/
3207
3208
3209/*!
3210 \internal
3211 Initializes the pen.
3212*/
3213
3214void QPen::init( const QColor &color, uint width, uint linestyle )
3215{
3216 data = new QPenData;
3217 Q_CHECK_PTR( data );
3218 data->style = (PenStyle)(linestyle & MPenStyle);
3219 data->width = width;
3220 data->color = color;
3221 data->linest = linestyle;
3222}
3223
3224/*!
3225 Constructs a default black solid line pen with 0 width, which
3226 renders lines 1 pixel wide (fast diagonals).
3227*/
3228
3229QPen::QPen()
3230{
3231 init( Qt::black, 0, SolidLine ); // default pen
3232}
3233
3234/*!
3235 Constructs a black pen with 0 width (fast diagonals) and style \a
3236 style.
3237
3238 \sa setStyle()
3239*/
3240
3241QPen::QPen( PenStyle style )
3242{
3243 init( Qt::black, 0, style );
3244}
3245
3246/*!
3247 Constructs a pen with the specified \a color, \a width and \a
3248 style.
3249
3250 \sa setWidth(), setStyle(), setColor()
3251*/
3252
3253QPen::QPen( const QColor &color, uint width, PenStyle style )
3254{
3255 init( color, width, style );
3256}
3257
3258/*!
3259 Constructs a pen with the specified color \a cl and width \a w.
3260 The pen style is set to \a s, the pen cap style to \a c and the
3261 pen join style to \a j.
3262
3263 A line width of 0 will produce a 1 pixel wide line using a fast
3264 algorithm for diagonals. A line width of 1 will also produce a 1
3265 pixel wide line, but uses a slower more accurate algorithm for
3266 diagonals. For horizontal and vertical lines a line width of 0 is
3267 the same as a line width of 1. The cap and join style have no
3268 effect on 0-width lines.
3269
3270 \sa setWidth(), setStyle(), setColor()
3271*/
3272
3273QPen::QPen( const QColor &cl, uint w, PenStyle s, PenCapStyle c,
3274 PenJoinStyle j )
3275{
3276 init( cl, w, s | c | j );
3277}
3278
3279/*!
3280 Constructs a pen that is a copy of \a p.
3281*/
3282
3283QPen::QPen( const QPen &p )
3284{
3285 data = p.data;
3286 data->ref();
3287}
3288
3289/*!
3290 Destroys the pen.
3291*/
3292
3293QPen::~QPen()
3294{
3295 if ( data->deref() )
3296 delete data;
3297}
3298
3299
3300/*!
3301 Detaches from shared pen data to make sure that this pen is the
3302 only one referring the data.
3303
3304 If multiple pens share common data, this pen dereferences the data
3305 and gets a copy of the data. Nothing is done if there is just a
3306 single reference.
3307*/
3308
3309void QPen::detach()
3310{
3311 if ( data->count != 1 )
3312 *this = copy();
3313}
3314
3315
3316/*!
3317 Assigns \a p to this pen and returns a reference to this pen.
3318*/
3319
3320QPen &QPen::operator=( const QPen &p )
3321{
3322 p.data->ref();
3323 if ( data->deref() )
3324 delete data;
3325 data = p.data;
3326 return *this;
3327}
3328
3329
3330/*!
3331 Returns a \link shclass.html deep copy\endlink of the pen.
3332*/
3333
3334QPen QPen::copy() const
3335{
3336 QPen p( data->color, data->width, data->style, capStyle(), joinStyle() );
3337 return p;
3338}
3339
3340
3341/*!
3342 \fn PenStyle QPen::style() const
3343
3344 Returns the pen style.
3345
3346 \sa setStyle()
3347*/
3348
3349/*!
3350 Sets the pen style to \a s.
3351
3352 See the \l Qt::PenStyle documentation for a list of all the
3353 styles.
3354
3355 \warning On Windows 95/98 and Macintosh, the style setting (other
3356 than \c NoPen and \c SolidLine) has no effect for lines with width
3357 greater than 1.
3358
3359 \sa style()
3360*/
3361
3362void QPen::setStyle( PenStyle s )
3363{
3364 if ( data->style == s )
3365 return;
3366 detach();
3367 data->style = s;
3368 data->linest = (data->linest & ~MPenStyle) | s;
3369}
3370
3371
3372/*!
3373 \fn uint QPen::width() const
3374
3375 Returns the pen width.
3376
3377 \sa setWidth()
3378*/
3379
3380/*!
3381 Sets the pen width to \a w.
3382
3383 A line width of 0 will produce a 1 pixel wide line using a fast
3384 algorithm for diagonals. A line width of 1 will also produce a 1
3385 pixel wide line, but uses a slower more accurate algorithm for
3386 diagonals. For horizontal and vertical lines a line width of 0 is
3387 the same as a line width of 1. The cap and join style have no
3388 effect on 0-width lines.
3389
3390 \sa width()
3391*/
3392
3393void QPen::setWidth( uint w )
3394{
3395 if ( data->width == w )
3396 return;
3397 detach();
3398 data->width = w;
3399}
3400
3401
3402/*!
3403 Returns the pen's cap style.
3404
3405 \sa setCapStyle()
3406*/
3407Qt::PenCapStyle QPen::capStyle() const
3408{
3409 return (PenCapStyle)(data->linest & MPenCapStyle);
3410}
3411
3412/*!
3413 Sets the pen's cap style to \a c.
3414
3415 The default value is \c FlatCap. The cap style has no effect on
3416 0-width pens.
3417
3418 \img pen-cap-styles.png Pen Cap Styles
3419
3420 \warning On Windows 95/98 and Macintosh, the cap style setting has
3421 no effect. Wide lines are rendered as if the cap style was \c
3422 SquareCap.
3423
3424 \sa capStyle()
3425*/
3426
3427void QPen::setCapStyle( PenCapStyle c )
3428{
3429 if ( (data->linest & MPenCapStyle) == c )
3430 return;
3431 detach();
3432 data->linest = (data->linest & ~MPenCapStyle) | c;
3433}
3434
3435/*!
3436 Returns the pen's join style.
3437
3438 \sa setJoinStyle()
3439*/
3440Qt::PenJoinStyle QPen::joinStyle() const
3441{
3442 return (PenJoinStyle)(data->linest & MPenJoinStyle);
3443}
3444
3445/*!
3446 Sets the pen's join style to \a j.
3447
3448 The default value is \c MiterJoin. The join style has no effect on
3449 0-width pens.
3450
3451 \img pen-join-styles.png Pen Join Styles
3452
3453 \warning On Windows 95/98 and Macintosh, the join style setting
3454 has no effect. Wide lines are rendered as if the join style was \c
3455 BevelJoin.
3456
3457 \sa joinStyle()
3458*/
3459
3460void QPen::setJoinStyle( PenJoinStyle j )
3461{
3462 if ( (data->linest & MPenJoinStyle) == j )
3463 return;
3464 detach();
3465 data->linest = (data->linest & ~MPenJoinStyle) | j;
3466}
3467
3468/*!
3469 \fn const QColor &QPen::color() const
3470
3471 Returns the pen color.
3472
3473 \sa setColor()
3474*/
3475
3476/*!
3477 Sets the pen color to \a c.
3478
3479 \sa color()
3480*/
3481
3482void QPen::setColor( const QColor &c )
3483{
3484 detach();
3485 data->color = c;
3486}
3487
3488
3489/*!
3490 \fn bool QPen::operator!=( const QPen &p ) const
3491
3492 Returns TRUE if the pen is different from \a p; otherwise returns
3493 FALSE.
3494
3495 Two pens are different if they have different styles, widths or
3496 colors.
3497
3498 \sa operator==()
3499*/
3500
3501/*!
3502 Returns TRUE if the pen is equal to \a p; otherwise returns FALSE.
3503
3504 Two pens are equal if they have equal styles, widths and colors.
3505
3506 \sa operator!=()
3507*/
3508
3509bool QPen::operator==( const QPen &p ) const
3510{
3511 return (p.data == data) || (p.data->linest == data->linest &&
3512 p.data->width == data->width && p.data->color == data->color);
3513}
3514
3515
3516/*****************************************************************************
3517 QPen stream functions
3518 *****************************************************************************/
3519#ifndef QT_NO_DATASTREAM
3520/*!
3521 \relates QPen
3522
3523 Writes the pen \a p to the stream \a s and returns a reference to
3524 the stream.
3525
3526 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
3527*/
3528
3529QDataStream &operator<<( QDataStream &s, const QPen &p )
3530{
3531 // ### width() should not be restricted to 8-bit values
3532 if ( s.version() < 3 )
3533 return s << (Q_UINT8)p.style() << (Q_UINT8)p.width() << p.color();
3534 else
3535 return s << (Q_UINT8)( p.style() | p.capStyle() | p.joinStyle() )
3536 << (Q_UINT8)p.width() << p.color();
3537}
3538
3539/*!
3540 \relates QPen
3541
3542 Reads a pen from the stream \a s into \a p and returns a reference
3543 to the stream.
3544
3545 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
3546*/
3547
3548QDataStream &operator>>( QDataStream &s, QPen &p )
3549{
3550 Q_UINT8 style, width;
3551 QColor color;
3552 s >> style;
3553 s >> width;
3554 s >> color;
3555 p = QPen( color, (uint)width, (Qt::PenStyle)style ); // owl
3556 return s;
3557}
3558#endif //QT_NO_DATASTREAM
3559
3560/*****************************************************************************
3561 QBrush member functions
3562 *****************************************************************************/
3563
3564/*!
3565 \class QBrush qbrush.h
3566
3567 \brief The QBrush class defines the fill pattern of shapes drawn by a QPainter.
3568
3569 \ingroup graphics
3570 \ingroup images
3571 \ingroup shared
3572
3573 A brush has a style and a color. One of the brush styles is a
3574 custom pattern, which is defined by a QPixmap.
3575
3576 The brush style defines the fill pattern. The default brush style
3577 is \c NoBrush (depending on how you construct a brush). This style
3578 tells the painter to not fill shapes. The standard style for
3579 filling is \c SolidPattern.
3580
3581 The brush color defines the color of the fill pattern. The QColor
3582 documentation lists the predefined colors.
3583
3584 Use the QPen class for specifying line/outline styles.
3585
3586 Example:
3587 \code
3588 QPainter painter;
3589 QBrush brush( yellow ); // yellow solid pattern
3590 painter.begin( &anyPaintDevice ); // paint something
3591 painter.setBrush( brush ); // set the yellow brush
3592 painter.setPen( NoPen ); // do not draw outline
3593 painter.drawRect( 40,30, 200,100 ); // draw filled rectangle
3594 painter.setBrush( NoBrush ); // do not fill
3595 painter.setPen( black ); // set black pen, 0 pixel width
3596 painter.drawRect( 10,10, 30,20 ); // draw rectangle outline
3597 painter.end(); // painting done
3598 \endcode
3599
3600 See the setStyle() function for a complete list of brush styles.
3601
3602 \img brush-styles.png Brush Styles
3603
3604 \sa QPainter, QPainter::setBrush(), QPainter::setBrushOrigin()
3605*/
3606
3607
3608/*!
3609 \internal
3610 Initializes the brush.
3611*/
3612
3613void QBrush::init( const QColor &color, BrushStyle style )
3614{
3615 data = new QBrushData;
3616 Q_CHECK_PTR( data );
3617 data->style = style;
3618 data->color = color;
3619 data->pixmap = 0;
3620}
3621
3622/*!
3623 Constructs a default black brush with the style \c NoBrush (will
3624 not fill shapes).
3625*/
3626
3627QBrush::QBrush()
3628{
3629 static QBrushData* defBrushData = 0;
3630 if ( !defBrushData ) {
3631 static QSharedCleanupHandler<QBrushData> defBrushCleanup;
3632 defBrushData = new QBrushData;
3633 defBrushData->style = NoBrush;
3634 defBrushData->color = Qt::black;
3635 defBrushData->pixmap = 0;
3636 defBrushCleanup.set( &defBrushData );
3637 }
3638 data = defBrushData;
3639 data->ref();
3640}
3641
3642/*!
3643 Constructs a black brush with the style \a style.
3644
3645 \sa setStyle()
3646*/
3647
3648QBrush::QBrush( BrushStyle style )
3649{
3650 init( Qt::black, style );
3651}
3652
3653/*!
3654 Constructs a brush with the color \a color and the style \a style.
3655
3656 \sa setColor(), setStyle()
3657*/
3658
3659QBrush::QBrush( const QColor &color, BrushStyle style )
3660{
3661 init( color, style );
3662}
3663
3664/*!
3665 Constructs a brush with the color \a color and a custom pattern
3666 stored in \a pixmap.
3667
3668 The color will only have an effect for monochrome pixmaps, i.e.
3669 for QPixmap::depth() == 1.
3670
3671 Pixmap brushes are currently not supported when printing on X11.
3672
3673 \sa setColor(), setPixmap()
3674*/
3675
3676QBrush::QBrush( const QColor &color, const QPixmap &pixmap )
3677{
3678 init( color, CustomPattern );
3679 setPixmap( pixmap );
3680}
3681
3682/*!
3683 Constructs a brush that is a \link shclass.html shallow
3684 copy\endlink of \a b.
3685*/
3686
3687QBrush::QBrush( const QBrush &b )
3688{
3689 data = b.data;
3690 data->ref();
3691}
3692
3693/*!
3694 Destroys the brush.
3695*/
3696
3697QBrush::~QBrush()
3698{
3699 if ( data->deref() ) {
3700 delete data->pixmap;
3701 delete data;
3702 }
3703}
3704
3705
3706/*!
3707 Detaches from shared brush data to make sure that this brush is
3708 the only one referring the data.
3709
3710 If multiple brushes share common data, this brush dereferences the
3711 data and gets a copy of the data. Nothing is done if there is just
3712 a single reference.
3713*/
3714
3715void QBrush::detach()
3716{
3717 if ( data->count != 1 )
3718 *this = copy();
3719}
3720
3721
3722/*!
3723 Assigns \a b to this brush and returns a reference to this brush.
3724*/
3725
3726QBrush &QBrush::operator=( const QBrush &b )
3727{
3728 b.data->ref(); // beware of b = b
3729 if ( data->deref() ) {
3730 delete data->pixmap;
3731 delete data;
3732 }
3733 data = b.data;
3734 return *this;
3735}
3736
3737
3738/*!
3739 Returns a \link shclass.html deep copy\endlink of the brush.
3740*/
3741
3742QBrush QBrush::copy() const
3743{
3744 if ( data->style == CustomPattern ) { // brush has pixmap
3745 QBrush b( data->color, *data->pixmap );
3746 return b;
3747 } else { // brush has std pattern
3748 QBrush b( data->color, data->style );
3749 return b;
3750 }
3751}
3752
3753
3754/*!
3755 \fn BrushStyle QBrush::style() const
3756
3757 Returns the brush style.
3758
3759 \sa setStyle()
3760*/
3761
3762/*!
3763 Sets the brush style to \a s.
3764
3765 The brush styles are:
3766 \table
3767 \header \i Pattern \i Meaning
3768 \row \i NoBrush \i will not fill shapes (default).
3769 \row \i SolidPattern \i solid (100%) fill pattern.
3770 \row \i Dense1Pattern \i11 94% fill pattern.
3771 \row \i Dense2Pattern \i11 88% fill pattern.
3772 \row \i Dense3Pattern \i11 63% fill pattern.
3773 \row \i Dense4Pattern \i11 50% fill pattern.
3774 \row \i Dense5Pattern \i11 37% fill pattern.
3775 \row \i Dense6Pattern \i11 12% fill pattern.
3776 \row \i Dense7Pattern \i11 6% fill pattern.
3777 \row \i HorPattern \i horizontal lines pattern.
3778 \row \i VerPattern \i vertical lines pattern.
3779 \row \i CrossPattern \i crossing lines pattern.
3780 \row \i BDiagPattern \i diagonal lines (directed /) pattern.
3781 \row \i FDiagPattern \i diagonal lines (directed \) pattern.
3782 \row \i DiagCrossPattern \i diagonal crossing lines pattern.
3783 \row \i CustomPattern \i set when a pixmap pattern is being used.
3784 \endtable
3785
3786 On Windows, dense and custom patterns cannot be transparent.
3787
3788 See the \link #details Detailed Description\endlink for a picture
3789 of all the styles.
3790
3791 \sa style()
3792*/
3793
3794void QBrush::setStyle( BrushStyle s ) // set brush style
3795{
3796 if ( data->style == s )
3797 return;
3798#if defined(QT_CHECK_RANGE)
3799 if ( s == CustomPattern )
3800 qWarning( "QBrush::setStyle: CustomPattern is for internal use" );
3801#endif
3802 detach();
3803 data->style = s;
3804}
3805
3806
3807/*!
3808 \fn const QColor &QBrush::color() const
3809
3810 Returns the brush color.
3811
3812 \sa setColor()
3813*/
3814
3815/*!
3816 Sets the brush color to \a c.
3817
3818 \sa color(), setStyle()
3819*/
3820
3821void QBrush::setColor( const QColor &c )
3822{
3823 detach();
3824 data->color = c;
3825}
3826
3827
3828/*!
3829 \fn QPixmap *QBrush::pixmap() const
3830
3831 Returns a pointer to the custom brush pattern, or 0 if no custom
3832 brush pattern has been set.
3833
3834 \sa setPixmap()
3835*/
3836
3837/*!
3838 Sets the brush pixmap to \a pixmap. The style is set to \c
3839 CustomPattern.
3840
3841 The current brush color will only have an effect for monochrome
3842 pixmaps, i.e. for QPixmap::depth() == 1.
3843
3844 Pixmap brushes are currently not supported when printing on X11.
3845
3846 \sa pixmap(), color()
3847*/
3848
3849void QBrush::setPixmap( const QPixmap &pixmap )
3850{
3851 detach();
3852 if ( data->pixmap )
3853 delete data->pixmap;
3854 if ( pixmap.isNull() ) {
3855 data->style = NoBrush;
3856 data->pixmap = 0;
3857 } else {
3858 data->style = CustomPattern;
3859 data->pixmap = new QPixmap( pixmap );
3860 if ( data->pixmap->optimization() == QPixmap::MemoryOptim )
3861 data->pixmap->setOptimization( QPixmap::NormalOptim );
3862 }
3863}
3864
3865
3866/*!
3867 \fn bool QBrush::operator!=( const QBrush &b ) const
3868
3869 Returns TRUE if the brush is different from \a b; otherwise
3870 returns FALSE.
3871
3872 Two brushes are different if they have different styles, colors or
3873 pixmaps.
3874
3875 \sa operator==()
3876*/
3877
3878/*!
3879 Returns TRUE if the brush is equal to \a b; otherwise returns
3880 FALSE.
3881
3882 Two brushes are equal if they have equal styles, colors and
3883 pixmaps.
3884
3885 \sa operator!=()
3886*/
3887
3888bool QBrush::operator==( const QBrush &b ) const
3889{
3890 return (b.data == data) || (b.data->style == data->style &&
3891 b.data->color == data->color &&
3892 b.data->pixmap == data->pixmap);
3893}
3894
3895
3896/*!
3897 \fn inline double QPainter::translationX() const
3898 \internal
3899*/
3900
3901/*!
3902 \fn inline double QPainter::translationY() const
3903 \internal
3904*/
3905
3906
3907/*****************************************************************************
3908 QBrush stream functions
3909 *****************************************************************************/
3910#ifndef QT_NO_DATASTREAM
3911/*!
3912 \relates QBrush
3913
3914 Writes the brush \a b to the stream \a s and returns a reference
3915 to the stream.
3916
3917 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
3918*/
3919
3920QDataStream &operator<<( QDataStream &s, const QBrush &b )
3921{
3922 s << (Q_UINT8)b.style() << b.color();
3923 if ( b.style() == Qt::CustomPattern )
3924#ifndef QT_NO_IMAGEIO
3925 s << *b.pixmap();
3926#else
3927 qWarning("No Image Brush I/O");
3928#endif
3929 return s;
3930}
3931
3932/*!
3933 \relates QBrush
3934
3935 Reads the brush \a b from the stream \a s and returns a reference
3936 to the stream.
3937
3938 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
3939*/
3940
3941QDataStream &operator>>( QDataStream &s, QBrush &b )
3942{
3943 Q_UINT8 style;
3944 QColor color;
3945 s >> style;
3946 s >> color;
3947 if ( style == Qt::CustomPattern ) {
3948#ifndef QT_NO_IMAGEIO
3949 QPixmap pm;
3950 s >> pm;
3951 b = QBrush( color, pm );
3952#else
3953 qWarning("No Image Brush I/O");
3954#endif
3955 }
3956 else
3957 b = QBrush( color, (Qt::BrushStyle)style );
3958 return s;
3959}
3960#endif // QT_NO_DATASTREAM
Note: See TracBrowser for help on using the repository browser.