source: trunk/src/kernel/qpainter.cpp@ 8

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

Transferred Qt for OS/2 version 3.3.1-rc5 sources from the CVS

  • Property svn:keywords set to Id
File size: 103.4 KB
Line 
1/****************************************************************************
2** $Id: qpainter.cpp 8 2005-11-16 19:36:46Z 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) || defined(Q_WS_PM)
1638 setf(DirtyFont);
1639#endif
1640 }
1641 } else {
1642 txop = TxRotShear;
1643#if defined(Q_WS_WIN) || defined(Q_WS_PM)
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_PM)
2348 if ( !pdev->cmd( QPaintDevice::PdcDrawPixmap, this, param ) || !hps )
2349 return;
2350#elif defined(Q_WS_QWS)
2351 pdev->cmd( QPaintDevice::PdcDrawPixmap, this, param );
2352 return;
2353#elif defined(Q_WS_MAC)
2354 if ( !pdev->cmd( QPaintDevice::PdcDrawPixmap, this, param ) || !pdev->handle())
2355 return;
2356#else
2357 if ( !pdev->cmd( QPaintDevice::PdcDrawPixmap, this, param ) || !hd )
2358 return;
2359#endif
2360 }
2361
2362 QPixmap pixmap = pm;
2363
2364 if ( scale ) {
2365#ifndef QT_NO_IMAGE_SMOOTHSCALE
2366# ifndef QT_NO_PIXMAP_TRANSFORMATION
2367 if ( smooth )
2368# endif
2369 {
2370 QImage i = pm.convertToImage();
2371 pixmap = QPixmap( i.smoothScale( rw, rh ) );
2372 }
2373# ifndef QT_NO_PIXMAP_TRANSFORMATION
2374 else
2375# endif
2376#endif
2377#ifndef QT_NO_PIXMAP_TRANSFORMATION
2378 {
2379 pixmap = pm.xForm( QWMatrix( scaleX, 0, 0, scaleY, 0, 0 ) );
2380 }
2381#endif
2382 }
2383 drawPixmap( r.x(), r.y(), pixmap );
2384}
2385
2386#endif
2387
2388/*!
2389 \overload void QPainter::drawImage( const QPoint &, const QImage &, const QRect &sr, int conversionFlags = 0 );
2390
2391 Draws the rectangle \a sr from the image at the given point.
2392*/
2393
2394/*
2395 Draws at point \a p the \sr rect from image \a pm, using \a
2396 conversionFlags if the image needs to be converted to a pixmap.
2397 The default value for \a conversionFlags is 0; see
2398 convertFromImage() for information about what other values do.
2399
2400 This function may convert \a image to a pixmap and then draw it, if
2401 device() is a QPixmap or a QWidget, or else draw it directly, if
2402 device() is a QPrinter or QPicture.
2403*/
2404
2405/*!
2406 Draws at (\a x, \a y) the \a sw by \a sh area of pixels from (\a
2407 sx, \a sy) in \a image, using \a conversionFlags if the image
2408 needs to be converted to a pixmap. The default value for \a
2409 conversionFlags is 0; see convertFromImage() for information about
2410 what other values do.
2411
2412 This function may convert \a image to a pixmap and then draw it,
2413 if device() is a QPixmap or a QWidget, or else draw it directly,
2414 if device() is a QPrinter or QPicture.
2415
2416 Currently alpha masks of the image are ignored when painting on a QPrinter.
2417
2418 \sa drawPixmap() QPixmap::convertFromImage()
2419*/
2420void QPainter::drawImage( int x, int y, const QImage & image,
2421 int sx, int sy, int sw, int sh,
2422 int conversionFlags )
2423{
2424#ifdef Q_WS_QWS
2425 //### Hackish
2426# ifndef QT_NO_TRANSFORMATIONS
2427 if ( !image.isNull() && gfx &&
2428 (txop==TxNone||txop==TxTranslate) && !testf(ExtDev) )
2429# else
2430 if ( !image.isNull() && gfx && !testf(ExtDev) )
2431# endif
2432 {
2433 if(sw<0)
2434 sw=image.width();
2435 if(sh<0)
2436 sh=image.height();
2437
2438 QImage image2 = qt_screen->mapToDevice( image );
2439
2440 // This is a bit dubious
2441 if(image2.depth()==1) {
2442 image2.setNumColors( 2 );
2443 image2.setColor( 0, qRgb(255,255,255) );
2444 image2.setColor( 1, qRgb(0,0,0) );
2445 }
2446 if ( image2.hasAlphaBuffer() )
2447 gfx->setAlphaType(QGfx::InlineAlpha);
2448 else
2449 gfx->setAlphaType(QGfx::IgnoreAlpha);
2450 gfx->setSource(&image2);
2451 if ( testf(VxF|WxF) ) {
2452 map( x, y, &x, &y );
2453 }
2454 gfx->blt(x,y,sw,sh,sx,sy);
2455 return;
2456 }
2457#endif
2458
2459 if ( !isActive() || image.isNull() )
2460 return;
2461
2462 // right/bottom
2463 if ( sw < 0 )
2464 sw = image.width() - sx;
2465 if ( sh < 0 )
2466 sh = image.height() - sy;
2467
2468 // Sanity-check clipping
2469 if ( sx < 0 ) {
2470 x -= sx;
2471 sw += sx;
2472 sx = 0;
2473 }
2474 if ( sw + sx > image.width() )
2475 sw = image.width() - sx;
2476 if ( sy < 0 ) {
2477 y -= sy;
2478 sh += sy;
2479 sy = 0;
2480 }
2481 if ( sh + sy > image.height() )
2482 sh = image.height() - sy;
2483
2484 if ( sw <= 0 || sh <= 0 )
2485 return;
2486
2487 bool all = image.rect().intersect(QRect(sx,sy,sw,sh)) == image.rect();
2488 QImage subimage = all ? image : image.copy(sx,sy,sw,sh);
2489
2490 if ( testf(ExtDev) ) {
2491 QPDevCmdParam param[2];
2492 QRect r( x, y, subimage.width(), subimage.height() );
2493 param[0].rect = &r;
2494 param[1].image = &subimage;
2495#if defined(Q_WS_WIN)
2496 if ( !pdev->cmd( QPaintDevice::PdcDrawImage, this, param ) || !hdc )
2497 return;
2498#elif defined(Q_WS_PM)
2499 if ( !pdev->cmd( QPaintDevice::PdcDrawImage, this, param ) || !hps )
2500 return;
2501#elif defined (Q_WS_QWS)
2502 pdev->cmd( QPaintDevice::PdcDrawImage, this, param );
2503 return;
2504#elif defined(Q_WS_MAC)
2505 if(!pdev->cmd( QPaintDevice::PdcDrawImage, this, param ) || !pdev->handle() )
2506 return;
2507#else
2508 if ( !pdev->cmd( QPaintDevice::PdcDrawImage, this, param ) || !hd )
2509 return;
2510#endif
2511 }
2512
2513 QPixmap pm;
2514 pm.convertFromImage( subimage, conversionFlags );
2515 drawPixmap( x, y, pm );
2516}
2517
2518/*!
2519 \overload void QPainter::drawImage( const QPoint &p, const QImage &i, int conversion_flags )
2520
2521 Draws the image \a i at point \a p.
2522
2523 If the image needs to be modified to fit in a lower-resolution
2524 result (e.g. converting from 32-bit to 8-bit), use the \a
2525 conversion_flags to specify how you'd prefer this to happen.
2526
2527 \sa Qt::ImageConversionFlags
2528*/
2529void QPainter::drawImage( const QPoint & p, const QImage & i,
2530 int conversion_flags )
2531{
2532 drawImage(p, i, i.rect(), conversion_flags);
2533}
2534
2535#if !defined(QT_NO_IMAGE_TRANSFORMATION) || !defined(QT_NO_IMAGE_SMOOTHSCALE)
2536
2537/*!
2538 \overload
2539
2540 Draws the image \a i into the rectangle \a r. The image will be
2541 scaled to fit the rectangle if image and rectangle dimensions
2542 differ.
2543*/
2544void QPainter::drawImage( const QRect &r, const QImage &i )
2545{
2546 int rw = r.width();
2547 int rh = r.height();
2548 int iw= i.width();
2549 int ih = i.height();
2550 if ( rw <= 0 || rh <= 0 || iw <= 0 || ih <= 0 )
2551 return;
2552
2553 if ( testf(ExtDev) ) {
2554 QPDevCmdParam param[2];
2555 param[0].rect = &r;
2556 param[1].image = &i;
2557#if defined(Q_WS_WIN)
2558 if ( !pdev->cmd( QPaintDevice::PdcDrawImage, this, param ) || !hdc )
2559 return;
2560#elif defined(Q_WS_PM)
2561 if ( !pdev->cmd( QPaintDevice::PdcDrawImage, this, param ) || !hps )
2562 return;
2563#elif defined(Q_WS_QWS)
2564 pdev->cmd( QPaintDevice::PdcDrawImage, this, param );
2565 return;
2566#elif defined(Q_WS_MAC)
2567 if ( !pdev->cmd( QPaintDevice::PdcDrawImage, this, param ) || !pdev->handle() )
2568 return;
2569#else
2570 if ( !pdev->cmd( QPaintDevice::PdcDrawImage, this, param ) || !hd )
2571 return;
2572#endif
2573 }
2574
2575
2576 bool scale = ( rw != iw || rh != ih );
2577 float scaleX = (float)rw/(float)iw;
2578 float scaleY = (float)rh/(float)ih;
2579 bool smooth = ( scaleX < 1.5 || scaleY < 1.5 );
2580
2581 QImage img = scale
2582 ? (
2583#if defined(QT_NO_IMAGE_TRANSFORMATION)
2584 i.smoothScale( rw, rh )
2585#elif defined(QT_NO_IMAGE_SMOOTHSCALE)
2586 i.scale( rw, rh )
2587#else
2588 smooth ? i.smoothScale( rw, rh ) : i.scale( rw, rh )
2589#endif
2590 )
2591 : i;
2592
2593 drawImage( r.x(), r.y(), img );
2594}
2595
2596#endif
2597
2598
2599void bitBlt( QPaintDevice *dst, int dx, int dy,
2600 const QImage *src, int sx, int sy, int sw, int sh,
2601 int conversion_flags )
2602{
2603 QPixmap tmp;
2604 if ( sx == 0 && sy == 0
2605 && (sw<0 || sw==src->width()) && (sh<0 || sh==src->height()) )
2606 {
2607 tmp.convertFromImage( *src, conversion_flags );
2608 } else {
2609 tmp.convertFromImage( src->copy( sx, sy, sw, sh, conversion_flags),
2610 conversion_flags );
2611 }
2612 bitBlt( dst, dx, dy, &tmp );
2613}
2614
2615
2616/*!
2617 \overload void QPainter::drawTiledPixmap( const QRect &r, const QPixmap &pm, const QPoint &sp )
2618
2619 Draws a tiled pixmap, \a pm, inside rectangle \a r with its origin
2620 at point \a sp.
2621*/
2622
2623/*!
2624 \overload void QPainter::drawTiledPixmap( const QRect &r, const QPixmap &pm )
2625
2626 Draws a tiled pixmap, \a pm, inside rectangle \a r.
2627*/
2628
2629/*!
2630 \overload void QPainter::fillRect( const QRect &r, const QBrush &brush )
2631
2632 Fills the rectangle \a r using brush \a brush.
2633*/
2634
2635/*!
2636 \fn void QPainter::eraseRect( int x, int y, int w, int h )
2637
2638 Erases the area inside \a x, \a y, \a w, \a h. Equivalent to
2639 \c{fillRect( x, y, w, h, backgroundColor() )}.
2640*/
2641
2642/*!
2643 \overload void QPainter::eraseRect( const QRect &r )
2644
2645 Erases the area inside the rectangle \a r.
2646*/
2647
2648/*!
2649 \fn QPainter::drawText( int x, int y, const QString &, int len = -1, TextDirection dir = Auto )
2650
2651 \overload
2652
2653 Draws the given text at position \a x, \a y. If \a len is -1 (the
2654 default) all the text is drawn, otherwise the first \a len
2655 characters are drawn. The text's direction is given by \a dir.
2656
2657 \sa QPainter::TextDirection
2658*/
2659
2660/*!
2661 \fn void QPainter::drawText( int x, int y, int w, int h, int flags,
2662 const QString&, int len = -1, QRect *br=0,
2663 QTextParag **internal=0 )
2664
2665 \overload
2666
2667 Draws the given text within the rectangle starting at \a x, \a y,
2668 with width \a w and height \a h. If \a len is -1 (the default) all
2669 the text is drawn, otherwise the first \a len characters are
2670 drawn. The text's flags that are given in the \a flags parameter
2671 are \l{Qt::AlignmentFlags} and \l{Qt::TextFlags} OR'd together. \a
2672 br (if not null) is set to the actual bounding rectangle of the
2673 output. The \a internal parameter is for internal use only.
2674*/
2675
2676/*!
2677 \fn void QPainter::drawText( const QPoint &, const QString &, int len = -1, TextDirection dir = Auto );
2678
2679 \overload
2680
2681 Draws the text at the given point.
2682
2683 \sa QPainter::TextDirection
2684*/
2685
2686/*
2687 Draws the text in \a s at point \a p. If \a len is -1 the entire
2688 string is drawn, otherwise just the first \a len characters. The
2689 text's direction is specified by \a dir.
2690*/
2691
2692
2693/*!
2694 \fn void QPainter::drawText( int x, int y, const QString &, int pos, int len, TextDirection dir = Auto );
2695
2696 \overload
2697
2698 Draws the text from position \a pos, at point \a (x, y). If \a len is
2699 -1 the entire string is drawn, otherwise just the first \a len
2700 characters. The text's direction is specified by \a dir.
2701*/
2702
2703/*!
2704 \fn void QPainter::drawText( const QPoint &p, const QString &, int pos, int len, TextDirection dir = Auto );
2705
2706 Draws the text from position \a pos, at point \a p. If \a len is
2707 -1 the entire string is drawn, otherwise just the first \a len
2708 characters. The text's direction is specified by \a dir.
2709
2710 Note that the meaning of \e y is not the same for the two
2711 drawText() varieties. For overloads that take a simple \e x, \e y
2712 pair (or a point), the \e y value is the text's baseline; for
2713 overloads that take a rectangle, \e rect.y() is the top of the
2714 rectangle and the text is aligned within that rectangle in
2715 accordance with the alignment flags.
2716
2717 \sa QPainter::TextDirection
2718*/
2719
2720/*!
2721 \fn void QPainter::drawTextItem(const QPoint &, const QTextItem &, int)
2722 \internal
2723*/
2724
2725static inline void fix_neg_rect( int *x, int *y, int *w, int *h )
2726{
2727 if ( *w < 0 ) {
2728 *w = -*w;
2729 *x -= *w - 1;
2730 }
2731 if ( *h < 0 ) {
2732 *h = -*h;
2733 *y -= *h - 1;
2734 }
2735}
2736void QPainter::fix_neg_rect( int *x, int *y, int *w, int *h )
2737{
2738 ::fix_neg_rect(x,y,w,h);
2739}
2740
2741//
2742// The drawText function takes two special parameters; 'internal' and 'brect'.
2743//
2744// The 'internal' parameter contains a pointer to an array of encoded
2745// information that keeps internal geometry data.
2746// If the drawText function is called repeatedly to display the same text,
2747// it makes sense to calculate text width and linebreaks the first time,
2748// and use these parameters later to print the text because we save a lot of
2749// CPU time.
2750// The 'internal' parameter will not be used if it is a null pointer.
2751// The 'internal' parameter will be generated if it is not null, but points
2752// to a null pointer, i.e. internal != 0 && *internal == 0.
2753// The 'internal' parameter will be used if it contains a non-null pointer.
2754//
2755// If the 'brect parameter is a non-null pointer, then the bounding rectangle
2756// of the text will be returned in 'brect'.
2757//
2758
2759/*!
2760 \overload
2761
2762 Draws at most \a len characters from \a str in the rectangle \a r.
2763
2764 This function draws formatted text. The \a tf text format is
2765 really of type \l Qt::AlignmentFlags and \l Qt::TextFlags OR'd
2766 together.
2767
2768 Horizontal alignment defaults to AlignAuto and vertical alignment
2769 defaults to AlignTop.
2770
2771 \a brect (if not null) is set to the actual bounding rectangle of
2772 the output. \a internal is, yes, internal.
2773
2774 \sa boundingRect()
2775*/
2776
2777void QPainter::drawText( const QRect &r, int tf,
2778 const QString& str, int len, QRect *brect,
2779 QTextParag **internal )
2780{
2781 if ( !isActive() )
2782 return;
2783 if ( len < 0 )
2784 len = str.length();
2785 if ( len == 0 ) // empty string
2786 return;
2787
2788 if ( testf(DirtyFont|ExtDev) ) {
2789 if ( testf(DirtyFont) )
2790 updateFont();
2791 if ( testf(ExtDev) && (tf & DontPrint) == 0 ) {
2792 QPDevCmdParam param[3];
2793 QString newstr = str;
2794 newstr.truncate( len );
2795 param[0].rect = &r;
2796 param[1].ival = tf;
2797 param[2].str = &newstr;
2798 if ( pdev->devType() != QInternal::Printer ) {
2799#if defined(Q_WS_WIN)
2800 if ( !pdev->cmd( QPaintDevice::PdcDrawText2Formatted,
2801 this, param) ||
2802 !hdc )
2803 return; // QPrinter wants PdcDrawText2
2804#elif defined(Q_WS_PM)
2805 if ( !pdev->cmd( QPaintDevice::PdcDrawText2Formatted,
2806 this, param) ||
2807 !hps )
2808 return;
2809#elif defined(Q_WS_QWS)
2810 pdev->cmd( QPaintDevice::PdcDrawText2Formatted, this, param);
2811 return;
2812#elif defined(Q_WS_MAC)
2813 if ( !pdev->cmd( QPaintDevice::PdcDrawText2Formatted, this, param) ||
2814 !pdev->handle())
2815 return; // QPrinter wants PdcDrawText2
2816#else
2817 if ( !pdev->cmd( QPaintDevice::PdcDrawText2Formatted,
2818 this, param) ||
2819 !hd )
2820 return; // QPrinter wants PdcDrawText2
2821#endif
2822 }
2823 }
2824 }
2825
2826 qt_format_text(font(), r, tf, str, len, brect,
2827 tabstops, tabarray, tabarraylen, internal, this);
2828}
2829
2830//#define QT_FORMAT_TEXT_DEBUG
2831
2832#define QChar_linesep QChar(0x2028U)
2833
2834void qt_format_text( const QFont& font, const QRect &_r,
2835 int tf, const QString& str, int len, QRect *brect,
2836 int tabstops, int* tabarray, int tabarraylen,
2837 QTextParag **, QPainter* painter )
2838{
2839 // we need to copy r here to protect against the case (&r == brect).
2840 QRect r( _r );
2841
2842 bool dontclip = (tf & Qt::DontClip) == Qt::DontClip;
2843 bool wordbreak = (tf & Qt::WordBreak) == Qt::WordBreak;
2844 bool singleline = (tf & Qt::SingleLine) == Qt::SingleLine;
2845 bool showprefix = (tf & Qt::ShowPrefix) == Qt::ShowPrefix;
2846 bool noaccel = ( tf & Qt::NoAccel ) == Qt::NoAccel;
2847
2848 bool isRightToLeft = str.isRightToLeft();
2849 if ( ( tf & Qt::AlignHorizontal_Mask ) == Qt::AlignAuto )
2850 tf |= isRightToLeft ? Qt::AlignRight : Qt::AlignLeft;
2851
2852 bool expandtabs = ( (tf & Qt::ExpandTabs) &&
2853 ( ( (tf & Qt::AlignLeft) && !isRightToLeft ) ||
2854 ( (tf & Qt::AlignRight) && isRightToLeft ) ) );
2855
2856 if ( !painter )
2857 tf |= Qt::DontPrint;
2858
2859 int maxUnderlines = 0;
2860 int numUnderlines = 0;
2861 int underlinePositionStack[32];
2862 int *underlinePositions = underlinePositionStack;
2863
2864 QFont fnt(painter ? (painter->pfont ? *painter->pfont : painter->cfont) : font);
2865 QFontMetrics fm( fnt );
2866
2867 QString text = str;
2868 // str.setLength() always does a deep copy, so the replacement
2869 // code below is safe.
2870 text.setLength( len );
2871 // compatible behaviour to the old implementation. Replace
2872 // tabs by spaces
2873 QChar *chr = (QChar*)text.unicode();
2874 const QChar *end = chr + len;
2875 bool haveLineSep = FALSE;
2876 while ( chr != end ) {
2877 if ( *chr == '\r' || ( singleline && *chr == '\n' ) ) {
2878 *chr = ' ';
2879 } else if ( *chr == '\n' ) {
2880 *chr = QChar_linesep;
2881 haveLineSep = TRUE;
2882 } else if ( *chr == '&' ) {
2883 ++maxUnderlines;
2884 }
2885 ++chr;
2886 }
2887 if ( !expandtabs ) {
2888 chr = (QChar*)text.unicode();
2889 while ( chr != end ) {
2890 if ( *chr == '\t' )
2891 *chr = ' ';
2892 ++chr;
2893 }
2894 } else if (!tabarraylen && !tabstops) {
2895 tabstops = fm.width('x')*8;
2896 }
2897
2898 if ( noaccel || showprefix ) {
2899 if ( maxUnderlines > 32 )
2900 underlinePositions = new int[maxUnderlines];
2901 QChar *cout = (QChar*)text.unicode();
2902 QChar *cin = cout;
2903 int l = len;
2904 while ( l ) {
2905 if ( *cin == '&' ) {
2906 ++cin;
2907 --l;
2908 if ( !l )
2909 break;
2910 if ( *cin != '&' )
2911 underlinePositions[numUnderlines++] = cout - text.unicode();
2912 }
2913 *cout = *cin;
2914 ++cout;
2915 ++cin;
2916 --l;
2917 }
2918 uint newlen = cout - text.unicode();
2919 if ( newlen != text.length())
2920 text.setLength( newlen );
2921 }
2922
2923 // no need to do extra work for underlines if we don't paint
2924 if ( tf & Qt::DontPrint )
2925 numUnderlines = 0;
2926
2927 int height = 0;
2928 int left = r.width();
2929 int right = 0;
2930
2931 QTextLayout textLayout( text, fnt );
2932 int rb = QMAX( 0, -fm.minRightBearing() );
2933 int lb = QMAX( 0, -fm.minLeftBearing() );
2934
2935 if ( text.isEmpty() ) {
2936 height = fm.height();
2937 left = right = 0;
2938 tf |= QPainter::DontPrint;
2939 } else {
2940 textLayout.beginLayout((haveLineSep || expandtabs || wordbreak) ?
2941 QTextLayout::MultiLine :
2942 (tf & Qt::DontPrint) ? QTextLayout::NoBidi : QTextLayout::SingleLine );
2943
2944 // break underline chars into items of their own
2945 for( int i = 0; i < numUnderlines; i++ ) {
2946 textLayout.setBoundary( underlinePositions[i] );
2947 textLayout.setBoundary( underlinePositions[i]+1 );
2948 }
2949
2950 int lineWidth = wordbreak ? QMAX(0, r.width()-rb-lb) : INT_MAX;
2951 if(!wordbreak)
2952 tf |= Qt::IncludeTrailingSpaces;
2953
2954 int leading = fm.leading();
2955 int asc = fm.ascent();
2956 int desc = fm.descent();
2957 height = -leading;
2958
2959 //qDebug("\n\nbeginLayout: lw = %d, rectwidth=%d", lineWidth , r.width());
2960 while ( !textLayout.atEnd() ) {
2961 height += leading;
2962 textLayout.beginLine( lineWidth == INT_MAX ? lineWidth : lineWidth );
2963 //qDebug("-----beginLine( %d )-----", lineWidth );
2964 bool linesep = FALSE;
2965 while ( 1 ) {
2966 QTextItem ti = textLayout.currentItem();
2967 //qDebug("item: from=%d, ch=%x", ti.from(), text.unicode()[ti.from()].unicode() );
2968 if ( expandtabs && ti.isTab() ) {
2969 int tw = 0;
2970 int x = textLayout.widthUsed();
2971 if ( tabarraylen ) {
2972// qDebug("tabarraylen=%d", tabarraylen );
2973 int tab = 0;
2974 while ( tab < tabarraylen ) {
2975 if ( tabarray[tab] > x ) {
2976 tw = tabarray[tab] - x;
2977 break;
2978 }
2979 ++tab;
2980 }
2981 } else {
2982 tw = tabstops - (x % tabstops);
2983 }
2984 //qDebug("tw = %d", tw );
2985 if ( tw )
2986 ti.setWidth( tw );
2987 }
2988 if ( ti.isObject() && text.unicode()[ti.from()] == QChar_linesep )
2989 linesep = TRUE;
2990
2991 if ( linesep || textLayout.addCurrentItem() != QTextLayout::Ok || textLayout.atEnd() )
2992 break;
2993 }
2994
2995 int ascent = asc, descent = desc, lineLeft, lineRight;
2996 textLayout.setLineWidth( r.width()-rb-lb );
2997 textLayout.endLine( 0, height, tf, &ascent, &descent,
2998 &lineLeft, &lineRight );
2999 //qDebug("finalizing line: lw=%d ascent = %d, descent=%d lineleft=%d lineright=%d", lineWidth, ascent, descent,lineLeft, lineRight );
3000 left = QMIN( left, lineLeft );
3001 right = QMAX( right, lineRight );
3002 height += ascent + descent + 1;
3003 if ( linesep )
3004 textLayout.nextItem();
3005 }
3006 }
3007
3008 int yoff = 0;
3009 if ( tf & Qt::AlignBottom )
3010 yoff = r.height() - height;
3011 else if ( tf & Qt::AlignVCenter )
3012 yoff = (r.height() - height)/2;
3013
3014 if ( brect ) {
3015 *brect = QRect( r.x() + left, r.y() + yoff, right-left + lb+rb, height );
3016 //qDebug("br = %d %d %d/%d, left=%d, right=%d", brect->x(), brect->y(), brect->width(), brect->height(), left, right);
3017 }
3018
3019 if (!(tf & QPainter::DontPrint)) {
3020 bool restoreClipping = FALSE;
3021 bool painterHasClip = FALSE;
3022 QRegion painterClipRegion;
3023 if ( !dontclip ) {
3024#ifndef QT_NO_TRANSFORMATIONS
3025 QRegion reg = painter->xmat * r;
3026#else
3027 QRegion reg = r;
3028 reg.translate( painter->xlatex, painter->xlatey );
3029#endif
3030 if ( painter->hasClipping() )
3031 reg &= painter->clipRegion();
3032
3033 painterHasClip = painter->hasClipping();
3034 painterClipRegion = painter->clipRegion();
3035 restoreClipping = TRUE;
3036 painter->setClipRegion( reg );
3037 } else {
3038 if ( painter->hasClipping() ){
3039 painterHasClip = painter->hasClipping();
3040 painterClipRegion = painter->clipRegion();
3041 restoreClipping = TRUE;
3042 painter->setClipping( FALSE );
3043 }
3044 }
3045
3046 int cUlChar = 0;
3047 int _tf = 0;
3048 if (fnt.underline()) _tf |= Qt::Underline;
3049 if (fnt.overline()) _tf |= Qt::Overline;
3050 if (fnt.strikeOut()) _tf |= Qt::StrikeOut;
3051
3052 //qDebug("have %d items",textLayout.numItems());
3053 for ( int i = 0; i < textLayout.numItems(); i++ ) {
3054 QTextItem ti = textLayout.itemAt( i );
3055 //qDebug("Item %d: from=%d, length=%d, space=%d x=%d", i, ti.from(), ti.length(), ti.isSpace(), ti.x() );
3056 if ( ti.isTab() || ti.isObject() )
3057 continue;
3058 int textFlags = _tf;
3059 if ( !noaccel && numUnderlines > cUlChar && ti.from() == underlinePositions[cUlChar] ) {
3060 textFlags |= Qt::Underline;
3061 cUlChar++;
3062 }
3063#if defined(Q_WS_X11) || defined(Q_WS_QWS)
3064 if ( painter->bg_mode == Qt::OpaqueMode )
3065 qt_draw_background( painter, r.x()+lb + ti.x(), r.y() + yoff + ti.y() - ti.ascent(),
3066 ti.width(), ti.ascent() + ti.descent() + 1);
3067#endif
3068 painter->drawTextItem( r.x()+lb, r.y() + yoff, ti, textFlags );
3069 }
3070
3071 if ( restoreClipping ) {
3072 painter->setClipRegion( painterClipRegion );
3073 painter->setClipping( painterHasClip );
3074 }
3075 }
3076
3077 if ( underlinePositions != underlinePositionStack )
3078 delete [] underlinePositions;
3079}
3080
3081/*!
3082 \overload
3083
3084 Returns the bounding rectangle of the aligned text that would be
3085 printed with the corresponding drawText() function using the first
3086 \a len characters from \a str if \a len is > -1, or the whole of
3087 \a str if \a len is -1. The drawing, and hence the bounding
3088 rectangle, is constrained to the rectangle \a r, or to the
3089 rectangle required to draw the text, whichever is the larger.
3090
3091 The \a internal parameter should not be used.
3092
3093 \sa drawText(), fontMetrics(), QFontMetrics::boundingRect(), Qt::TextFlags
3094*/
3095
3096QRect QPainter::boundingRect( const QRect &r, int flags,
3097 const QString& str, int len, QTextParag **internal )
3098{
3099 QRect brect;
3100 if ( str.isEmpty() )
3101 brect.setRect( r.x(),r.y(), 0,0 );
3102 else
3103 drawText( r, flags | DontPrint, str, len, &brect, internal );
3104 return brect;
3105}
3106
3107/*!
3108 \fn QRect QPainter::boundingRect( int x, int y, int w, int h, int flags, const QString&, int len = -1, QTextParag **intern=0 );
3109
3110 Returns the bounding rectangle of the aligned text that would be
3111 printed with the corresponding drawText() function using the first
3112 \a len characters of the string if \a len is > -1, or the whole of
3113 the string if \a len is -1. The drawing, and hence the bounding
3114 rectangle, is constrained to the rectangle that begins at point \a
3115 (x, y) with width \a w and hight \a h, or to the
3116 rectangle required to draw the text, whichever is the larger.
3117
3118 The \a flags argument is
3119 the bitwise OR of the following flags:
3120 \table
3121 \header \i Flag \i Meaning
3122 \row \i \c AlignAuto \i aligns according to the language, usually left.
3123 \row \i \c AlignLeft \i aligns to the left border.
3124 \row \i \c AlignRight \i aligns to the right border.
3125 \row \i \c AlignHCenter \i aligns horizontally centered.
3126 \row \i \c AlignTop \i aligns to the top border.
3127 \row \i \c AlignBottom \i aligns to the bottom border.
3128 \row \i \c AlignVCenter \i aligns vertically centered.
3129 \row \i \c AlignCenter \i (== \c AlignHCenter | \c AlignVCenter).
3130 \row \i \c SingleLine \i ignores newline characters in the text.
3131 \row \i \c ExpandTabs \i expands tabs.
3132 \row \i \c ShowPrefix \i interprets "&x" as "<u>x</u>".
3133 \row \i \c WordBreak \i breaks the text to fit the rectangle.
3134 \endtable
3135
3136 Horizontal alignment defaults to \c AlignLeft and vertical
3137 alignment defaults to \c AlignTop.
3138
3139 If several of the horizontal or several of the vertical alignment flags
3140 are set, the resulting alignment is undefined.
3141
3142 The \a intern parameter should not be used.
3143
3144 \sa Qt::TextFlags
3145*/
3146
3147
3148
3149/*****************************************************************************
3150 QPen member functions
3151 *****************************************************************************/
3152
3153/*!
3154 \class QPen qpen.h
3155 \brief The QPen class defines how a QPainter should draw lines and outlines
3156 of shapes.
3157
3158 \ingroup graphics
3159 \ingroup images
3160 \ingroup shared
3161 \mainclass
3162
3163 A pen has a style, width, color, cap style and join style.
3164
3165 The pen style defines the line type. The default pen style is \c
3166 Qt::SolidLine. Setting the style to \c NoPen tells the painter to
3167 not draw lines or outlines.
3168
3169 When drawing 1 pixel wide diagonal lines you can either use a very
3170 fast algorithm (specified by a line width of 0, which is the
3171 default), or a slower but more accurate algorithm (specified by a
3172 line width of 1). For horizontal and vertical lines a line width
3173 of 0 is the same as a line width of 1. The cap and join style have
3174 no effect on 0-width lines.
3175
3176 The pen color defines the color of lines and text. The default
3177 line color is black. The QColor documentation lists predefined
3178 colors.
3179
3180 The cap style defines how the end points of lines are drawn. The
3181 join style defines how the joins between two lines are drawn when
3182 multiple connected lines are drawn (QPainter::drawPolyline()
3183 etc.). The cap and join styles only apply to wide lines, i.e. when
3184 the width is 1 or greater.
3185
3186 Use the QBrush class to specify fill styles.
3187
3188 Example:
3189 \code
3190 QPainter painter;
3191 QPen pen( red, 2 ); // red solid line, 2 pixels wide
3192 painter.begin( &anyPaintDevice ); // paint something
3193 painter.setPen( pen ); // set the red, wide pen
3194 painter.drawRect( 40,30, 200,100 ); // draw a rectangle
3195 painter.setPen( blue ); // set blue pen, 0 pixel width
3196 painter.drawLine( 40,30, 240,130 ); // draw a diagonal in rectangle
3197 painter.end(); // painting done
3198 \endcode
3199
3200 See the \l Qt::PenStyle enum type for a complete list of pen
3201 styles.
3202
3203 With reference to the end points of lines, for wide (non-0-width)
3204 pens it depends on the cap style whether the end point is drawn or
3205 not. QPainter will try to make sure that the end point is drawn
3206 for 0-width pens, but this cannot be absolutely guaranteed because
3207 the underlying drawing engine is free to use any (typically
3208 accelerated) algorithm for drawing 0-width lines. On all tested
3209 systems, however, the end point of at least all non-diagonal lines
3210 are drawn.
3211
3212 A pen's color(), width(), style(), capStyle() and joinStyle() can
3213 be set in the constructor or later with setColor(), setWidth(),
3214 setStyle(), setCapStyle() and setJoinStyle(). Pens may also be
3215 compared and streamed.
3216
3217 \img pen-styles.png Pen styles
3218
3219 \sa QPainter, QPainter::setPen()
3220*/
3221
3222
3223/*!
3224 \internal
3225 Initializes the pen.
3226*/
3227
3228void QPen::init( const QColor &color, uint width, uint linestyle )
3229{
3230 data = new QPenData;
3231 Q_CHECK_PTR( data );
3232 data->style = (PenStyle)(linestyle & MPenStyle);
3233 data->width = width;
3234 data->color = color;
3235 data->linest = linestyle;
3236}
3237
3238/*!
3239 Constructs a default black solid line pen with 0 width, which
3240 renders lines 1 pixel wide (fast diagonals).
3241*/
3242
3243QPen::QPen()
3244{
3245 init( Qt::black, 0, SolidLine ); // default pen
3246}
3247
3248/*!
3249 Constructs a black pen with 0 width (fast diagonals) and style \a
3250 style.
3251
3252 \sa setStyle()
3253*/
3254
3255QPen::QPen( PenStyle style )
3256{
3257 init( Qt::black, 0, style );
3258}
3259
3260/*!
3261 Constructs a pen with the specified \a color, \a width and \a
3262 style.
3263
3264 \sa setWidth(), setStyle(), setColor()
3265*/
3266
3267QPen::QPen( const QColor &color, uint width, PenStyle style )
3268{
3269 init( color, width, style );
3270}
3271
3272/*!
3273 Constructs a pen with the specified color \a cl and width \a w.
3274 The pen style is set to \a s, the pen cap style to \a c and the
3275 pen join style to \a j.
3276
3277 A line width of 0 will produce a 1 pixel wide line using a fast
3278 algorithm for diagonals. A line width of 1 will also produce a 1
3279 pixel wide line, but uses a slower more accurate algorithm for
3280 diagonals. For horizontal and vertical lines a line width of 0 is
3281 the same as a line width of 1. The cap and join style have no
3282 effect on 0-width lines.
3283
3284 \sa setWidth(), setStyle(), setColor()
3285*/
3286
3287QPen::QPen( const QColor &cl, uint w, PenStyle s, PenCapStyle c,
3288 PenJoinStyle j )
3289{
3290 init( cl, w, s | c | j );
3291}
3292
3293/*!
3294 Constructs a pen that is a copy of \a p.
3295*/
3296
3297QPen::QPen( const QPen &p )
3298{
3299 data = p.data;
3300 data->ref();
3301}
3302
3303/*!
3304 Destroys the pen.
3305*/
3306
3307QPen::~QPen()
3308{
3309 if ( data->deref() )
3310 delete data;
3311}
3312
3313
3314/*!
3315 Detaches from shared pen data to make sure that this pen is the
3316 only one referring the data.
3317
3318 If multiple pens share common data, this pen dereferences the data
3319 and gets a copy of the data. Nothing is done if there is just a
3320 single reference.
3321*/
3322
3323void QPen::detach()
3324{
3325 if ( data->count != 1 )
3326 *this = copy();
3327}
3328
3329
3330/*!
3331 Assigns \a p to this pen and returns a reference to this pen.
3332*/
3333
3334QPen &QPen::operator=( const QPen &p )
3335{
3336 p.data->ref();
3337 if ( data->deref() )
3338 delete data;
3339 data = p.data;
3340 return *this;
3341}
3342
3343
3344/*!
3345 Returns a \link shclass.html deep copy\endlink of the pen.
3346*/
3347
3348QPen QPen::copy() const
3349{
3350 QPen p( data->color, data->width, data->style, capStyle(), joinStyle() );
3351 return p;
3352}
3353
3354
3355/*!
3356 \fn PenStyle QPen::style() const
3357
3358 Returns the pen style.
3359
3360 \sa setStyle()
3361*/
3362
3363/*!
3364 Sets the pen style to \a s.
3365
3366 See the \l Qt::PenStyle documentation for a list of all the
3367 styles.
3368
3369 \warning On Windows 95/98 and Macintosh, the style setting (other
3370 than \c NoPen and \c SolidLine) has no effect for lines with width
3371 greater than 1.
3372
3373 \sa style()
3374*/
3375
3376void QPen::setStyle( PenStyle s )
3377{
3378 if ( data->style == s )
3379 return;
3380 detach();
3381 data->style = s;
3382 data->linest = (data->linest & ~MPenStyle) | s;
3383}
3384
3385
3386/*!
3387 \fn uint QPen::width() const
3388
3389 Returns the pen width.
3390
3391 \sa setWidth()
3392*/
3393
3394/*!
3395 Sets the pen width to \a w.
3396
3397 A line width of 0 will produce a 1 pixel wide line using a fast
3398 algorithm for diagonals. A line width of 1 will also produce a 1
3399 pixel wide line, but uses a slower more accurate algorithm for
3400 diagonals. For horizontal and vertical lines a line width of 0 is
3401 the same as a line width of 1. The cap and join style have no
3402 effect on 0-width lines.
3403
3404 \sa width()
3405*/
3406
3407void QPen::setWidth( uint w )
3408{
3409 if ( data->width == w )
3410 return;
3411 detach();
3412 data->width = w;
3413}
3414
3415
3416/*!
3417 Returns the pen's cap style.
3418
3419 \sa setCapStyle()
3420*/
3421Qt::PenCapStyle QPen::capStyle() const
3422{
3423 return (PenCapStyle)(data->linest & MPenCapStyle);
3424}
3425
3426/*!
3427 Sets the pen's cap style to \a c.
3428
3429 The default value is \c FlatCap. The cap style has no effect on
3430 0-width pens.
3431
3432 \img pen-cap-styles.png Pen Cap Styles
3433
3434 \warning On Windows 95/98 and Macintosh, the cap style setting has
3435 no effect. Wide lines are rendered as if the cap style was \c
3436 SquareCap.
3437
3438 \sa capStyle()
3439*/
3440
3441void QPen::setCapStyle( PenCapStyle c )
3442{
3443 if ( (data->linest & MPenCapStyle) == c )
3444 return;
3445 detach();
3446 data->linest = (data->linest & ~MPenCapStyle) | c;
3447}
3448
3449/*!
3450 Returns the pen's join style.
3451
3452 \sa setJoinStyle()
3453*/
3454Qt::PenJoinStyle QPen::joinStyle() const
3455{
3456 return (PenJoinStyle)(data->linest & MPenJoinStyle);
3457}
3458
3459/*!
3460 Sets the pen's join style to \a j.
3461
3462 The default value is \c MiterJoin. The join style has no effect on
3463 0-width pens.
3464
3465 \img pen-join-styles.png Pen Join Styles
3466
3467 \warning On Windows 95/98 and Macintosh, the join style setting
3468 has no effect. Wide lines are rendered as if the join style was \c
3469 BevelJoin.
3470
3471 \sa joinStyle()
3472*/
3473
3474void QPen::setJoinStyle( PenJoinStyle j )
3475{
3476 if ( (data->linest & MPenJoinStyle) == j )
3477 return;
3478 detach();
3479 data->linest = (data->linest & ~MPenJoinStyle) | j;
3480}
3481
3482/*!
3483 \fn const QColor &QPen::color() const
3484
3485 Returns the pen color.
3486
3487 \sa setColor()
3488*/
3489
3490/*!
3491 Sets the pen color to \a c.
3492
3493 \sa color()
3494*/
3495
3496void QPen::setColor( const QColor &c )
3497{
3498 detach();
3499 data->color = c;
3500}
3501
3502
3503/*!
3504 \fn bool QPen::operator!=( const QPen &p ) const
3505
3506 Returns TRUE if the pen is different from \a p; otherwise returns
3507 FALSE.
3508
3509 Two pens are different if they have different styles, widths or
3510 colors.
3511
3512 \sa operator==()
3513*/
3514
3515/*!
3516 Returns TRUE if the pen is equal to \a p; otherwise returns FALSE.
3517
3518 Two pens are equal if they have equal styles, widths and colors.
3519
3520 \sa operator!=()
3521*/
3522
3523bool QPen::operator==( const QPen &p ) const
3524{
3525 return (p.data == data) || (p.data->linest == data->linest &&
3526 p.data->width == data->width && p.data->color == data->color);
3527}
3528
3529
3530/*****************************************************************************
3531 QPen stream functions
3532 *****************************************************************************/
3533#ifndef QT_NO_DATASTREAM
3534/*!
3535 \relates QPen
3536
3537 Writes the pen \a p to the stream \a s and returns a reference to
3538 the stream.
3539
3540 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
3541*/
3542
3543QDataStream &operator<<( QDataStream &s, const QPen &p )
3544{
3545 // ### width() should not be restricted to 8-bit values
3546 if ( s.version() < 3 )
3547 return s << (Q_UINT8)p.style() << (Q_UINT8)p.width() << p.color();
3548 else
3549 return s << (Q_UINT8)( p.style() | p.capStyle() | p.joinStyle() )
3550 << (Q_UINT8)p.width() << p.color();
3551}
3552
3553/*!
3554 \relates QPen
3555
3556 Reads a pen from the stream \a s into \a p and returns a reference
3557 to the stream.
3558
3559 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
3560*/
3561
3562QDataStream &operator>>( QDataStream &s, QPen &p )
3563{
3564 Q_UINT8 style, width;
3565 QColor color;
3566 s >> style;
3567 s >> width;
3568 s >> color;
3569 p = QPen( color, (uint)width, (Qt::PenStyle)style ); // owl
3570 return s;
3571}
3572#endif //QT_NO_DATASTREAM
3573
3574/*****************************************************************************
3575 QBrush member functions
3576 *****************************************************************************/
3577
3578/*!
3579 \class QBrush qbrush.h
3580
3581 \brief The QBrush class defines the fill pattern of shapes drawn by a QPainter.
3582
3583 \ingroup graphics
3584 \ingroup images
3585 \ingroup shared
3586
3587 A brush has a style and a color. One of the brush styles is a
3588 custom pattern, which is defined by a QPixmap.
3589
3590 The brush style defines the fill pattern. The default brush style
3591 is \c NoBrush (depending on how you construct a brush). This style
3592 tells the painter to not fill shapes. The standard style for
3593 filling is \c SolidPattern.
3594
3595 The brush color defines the color of the fill pattern. The QColor
3596 documentation lists the predefined colors.
3597
3598 Use the QPen class for specifying line/outline styles.
3599
3600 Example:
3601 \code
3602 QPainter painter;
3603 QBrush brush( yellow ); // yellow solid pattern
3604 painter.begin( &anyPaintDevice ); // paint something
3605 painter.setBrush( brush ); // set the yellow brush
3606 painter.setPen( NoPen ); // do not draw outline
3607 painter.drawRect( 40,30, 200,100 ); // draw filled rectangle
3608 painter.setBrush( NoBrush ); // do not fill
3609 painter.setPen( black ); // set black pen, 0 pixel width
3610 painter.drawRect( 10,10, 30,20 ); // draw rectangle outline
3611 painter.end(); // painting done
3612 \endcode
3613
3614 See the setStyle() function for a complete list of brush styles.
3615
3616 \img brush-styles.png Brush Styles
3617
3618 \sa QPainter, QPainter::setBrush(), QPainter::setBrushOrigin()
3619*/
3620
3621
3622/*!
3623 \internal
3624 Initializes the brush.
3625*/
3626
3627void QBrush::init( const QColor &color, BrushStyle style )
3628{
3629 data = new QBrushData;
3630 Q_CHECK_PTR( data );
3631 data->style = style;
3632 data->color = color;
3633 data->pixmap = 0;
3634}
3635
3636/*!
3637 Constructs a default black brush with the style \c NoBrush (will
3638 not fill shapes).
3639*/
3640
3641QBrush::QBrush()
3642{
3643 static QBrushData* defBrushData = 0;
3644 if ( !defBrushData ) {
3645 static QSharedCleanupHandler<QBrushData> defBrushCleanup;
3646 defBrushData = new QBrushData;
3647 defBrushData->style = NoBrush;
3648 defBrushData->color = Qt::black;
3649 defBrushData->pixmap = 0;
3650 defBrushCleanup.set( &defBrushData );
3651 }
3652 data = defBrushData;
3653 data->ref();
3654}
3655
3656/*!
3657 Constructs a black brush with the style \a style.
3658
3659 \sa setStyle()
3660*/
3661
3662QBrush::QBrush( BrushStyle style )
3663{
3664 init( Qt::black, style );
3665}
3666
3667/*!
3668 Constructs a brush with the color \a color and the style \a style.
3669
3670 \sa setColor(), setStyle()
3671*/
3672
3673QBrush::QBrush( const QColor &color, BrushStyle style )
3674{
3675 init( color, style );
3676}
3677
3678/*!
3679 Constructs a brush with the color \a color and a custom pattern
3680 stored in \a pixmap.
3681
3682 The color will only have an effect for monochrome pixmaps, i.e.
3683 for QPixmap::depth() == 1.
3684
3685 Pixmap brushes are currently not supported when printing on X11.
3686
3687 \sa setColor(), setPixmap()
3688*/
3689
3690QBrush::QBrush( const QColor &color, const QPixmap &pixmap )
3691{
3692 init( color, CustomPattern );
3693 setPixmap( pixmap );
3694}
3695
3696/*!
3697 Constructs a brush that is a \link shclass.html shallow
3698 copy\endlink of \a b.
3699*/
3700
3701QBrush::QBrush( const QBrush &b )
3702{
3703 data = b.data;
3704 data->ref();
3705}
3706
3707/*!
3708 Destroys the brush.
3709*/
3710
3711QBrush::~QBrush()
3712{
3713 if ( data->deref() ) {
3714 delete data->pixmap;
3715 delete data;
3716 }
3717}
3718
3719
3720/*!
3721 Detaches from shared brush data to make sure that this brush is
3722 the only one referring the data.
3723
3724 If multiple brushes share common data, this brush dereferences the
3725 data and gets a copy of the data. Nothing is done if there is just
3726 a single reference.
3727*/
3728
3729void QBrush::detach()
3730{
3731 if ( data->count != 1 )
3732 *this = copy();
3733}
3734
3735
3736/*!
3737 Assigns \a b to this brush and returns a reference to this brush.
3738*/
3739
3740QBrush &QBrush::operator=( const QBrush &b )
3741{
3742 b.data->ref(); // beware of b = b
3743 if ( data->deref() ) {
3744 delete data->pixmap;
3745 delete data;
3746 }
3747 data = b.data;
3748 return *this;
3749}
3750
3751
3752/*!
3753 Returns a \link shclass.html deep copy\endlink of the brush.
3754*/
3755
3756QBrush QBrush::copy() const
3757{
3758 if ( data->style == CustomPattern ) { // brush has pixmap
3759 QBrush b( data->color, *data->pixmap );
3760 return b;
3761 } else { // brush has std pattern
3762 QBrush b( data->color, data->style );
3763 return b;
3764 }
3765}
3766
3767
3768/*!
3769 \fn BrushStyle QBrush::style() const
3770
3771 Returns the brush style.
3772
3773 \sa setStyle()
3774*/
3775
3776/*!
3777 Sets the brush style to \a s.
3778
3779 The brush styles are:
3780 \table
3781 \header \i Pattern \i Meaning
3782 \row \i NoBrush \i will not fill shapes (default).
3783 \row \i SolidPattern \i solid (100%) fill pattern.
3784 \row \i Dense1Pattern \i11 94% fill pattern.
3785 \row \i Dense2Pattern \i11 88% fill pattern.
3786 \row \i Dense3Pattern \i11 63% fill pattern.
3787 \row \i Dense4Pattern \i11 50% fill pattern.
3788 \row \i Dense5Pattern \i11 37% fill pattern.
3789 \row \i Dense6Pattern \i11 12% fill pattern.
3790 \row \i Dense7Pattern \i11 6% fill pattern.
3791 \row \i HorPattern \i horizontal lines pattern.
3792 \row \i VerPattern \i vertical lines pattern.
3793 \row \i CrossPattern \i crossing lines pattern.
3794 \row \i BDiagPattern \i diagonal lines (directed /) pattern.
3795 \row \i FDiagPattern \i diagonal lines (directed \) pattern.
3796 \row \i DiagCrossPattern \i diagonal crossing lines pattern.
3797 \row \i CustomPattern \i set when a pixmap pattern is being used.
3798 \endtable
3799
3800 On Windows, dense and custom patterns cannot be transparent.
3801
3802 See the \link #details Detailed Description\endlink for a picture
3803 of all the styles.
3804
3805 \sa style()
3806*/
3807
3808void QBrush::setStyle( BrushStyle s ) // set brush style
3809{
3810 if ( data->style == s )
3811 return;
3812#if defined(QT_CHECK_RANGE)
3813 if ( s == CustomPattern )
3814 qWarning( "QBrush::setStyle: CustomPattern is for internal use" );
3815#endif
3816 detach();
3817 data->style = s;
3818}
3819
3820
3821/*!
3822 \fn const QColor &QBrush::color() const
3823
3824 Returns the brush color.
3825
3826 \sa setColor()
3827*/
3828
3829/*!
3830 Sets the brush color to \a c.
3831
3832 \sa color(), setStyle()
3833*/
3834
3835void QBrush::setColor( const QColor &c )
3836{
3837 detach();
3838 data->color = c;
3839}
3840
3841
3842/*!
3843 \fn QPixmap *QBrush::pixmap() const
3844
3845 Returns a pointer to the custom brush pattern, or 0 if no custom
3846 brush pattern has been set.
3847
3848 \sa setPixmap()
3849*/
3850
3851/*!
3852 Sets the brush pixmap to \a pixmap. The style is set to \c
3853 CustomPattern.
3854
3855 The current brush color will only have an effect for monochrome
3856 pixmaps, i.e. for QPixmap::depth() == 1.
3857
3858 Pixmap brushes are currently not supported when printing on X11.
3859
3860 \sa pixmap(), color()
3861*/
3862
3863void QBrush::setPixmap( const QPixmap &pixmap )
3864{
3865 detach();
3866 if ( data->pixmap )
3867 delete data->pixmap;
3868 if ( pixmap.isNull() ) {
3869 data->style = NoBrush;
3870 data->pixmap = 0;
3871 } else {
3872 data->style = CustomPattern;
3873 data->pixmap = new QPixmap( pixmap );
3874 if ( data->pixmap->optimization() == QPixmap::MemoryOptim )
3875 data->pixmap->setOptimization( QPixmap::NormalOptim );
3876 }
3877}
3878
3879
3880/*!
3881 \fn bool QBrush::operator!=( const QBrush &b ) const
3882
3883 Returns TRUE if the brush is different from \a b; otherwise
3884 returns FALSE.
3885
3886 Two brushes are different if they have different styles, colors or
3887 pixmaps.
3888
3889 \sa operator==()
3890*/
3891
3892/*!
3893 Returns TRUE if the brush is equal to \a b; otherwise returns
3894 FALSE.
3895
3896 Two brushes are equal if they have equal styles, colors and
3897 pixmaps.
3898
3899 \sa operator!=()
3900*/
3901
3902bool QBrush::operator==( const QBrush &b ) const
3903{
3904 return (b.data == data) || (b.data->style == data->style &&
3905 b.data->color == data->color &&
3906 b.data->pixmap == data->pixmap);
3907}
3908
3909
3910/*!
3911 \fn inline double QPainter::translationX() const
3912 \internal
3913*/
3914
3915/*!
3916 \fn inline double QPainter::translationY() const
3917 \internal
3918*/
3919
3920
3921/*****************************************************************************
3922 QBrush stream functions
3923 *****************************************************************************/
3924#ifndef QT_NO_DATASTREAM
3925/*!
3926 \relates QBrush
3927
3928 Writes the brush \a b to the stream \a s and returns a reference
3929 to the stream.
3930
3931 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
3932*/
3933
3934QDataStream &operator<<( QDataStream &s, const QBrush &b )
3935{
3936 s << (Q_UINT8)b.style() << b.color();
3937 if ( b.style() == Qt::CustomPattern )
3938#ifndef QT_NO_IMAGEIO
3939 s << *b.pixmap();
3940#else
3941 qWarning("No Image Brush I/O");
3942#endif
3943 return s;
3944}
3945
3946/*!
3947 \relates QBrush
3948
3949 Reads the brush \a b from the stream \a s and returns a reference
3950 to the stream.
3951
3952 \sa \link datastreamformat.html Format of the QDataStream operators \endlink
3953*/
3954
3955QDataStream &operator>>( QDataStream &s, QBrush &b )
3956{
3957 Q_UINT8 style;
3958 QColor color;
3959 s >> style;
3960 s >> color;
3961 if ( style == Qt::CustomPattern ) {
3962#ifndef QT_NO_IMAGEIO
3963 QPixmap pm;
3964 s >> pm;
3965 b = QBrush( color, pm );
3966#else
3967 qWarning("No Image Brush I/O");
3968#endif
3969 }
3970 else
3971 b = QBrush( color, (Qt::BrushStyle)style );
3972 return s;
3973}
3974#endif // QT_NO_DATASTREAM
Note: See TracBrowser for help on using the repository browser.