[2] | 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
|
---|
| 60 | typedef 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 |
|
---|
| 477 | QPainter::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 |
|
---|
| 521 | QPainter::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 |
|
---|
| 539 | QPainter::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 |
|
---|
| 552 | QPainter::~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 |
|
---|
| 605 | bool 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 |
|
---|
| 629 | void 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 |
|
---|
| 658 | struct 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 |
|
---|
| 685 | typedef QPtrStack<QPState> QPStateStack;
|
---|
| 686 |
|
---|
| 687 |
|
---|
| 688 | void 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 |
|
---|
| 707 | void 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 |
|
---|
| 761 | void 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 |
|
---|
| 828 | typedef QPtrDict<QPaintDevice> QPaintDeviceDict;
|
---|
| 829 | static 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 |
|
---|
| 840 | void 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 | */
|
---|
| 867 | QPaintDevice *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 |
|
---|
| 881 | QFontMetrics 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 |
|
---|
| 898 | QFontInfo 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 |
|
---|
| 924 | void 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 |
|
---|
| 945 | void 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 |
|
---|
| 974 | void 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 |
|
---|
| 1012 | void 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 |
|
---|
| 1031 | void 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 |
|
---|
| 1062 | void 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 |
|
---|
| 1140 | void 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 |
|
---|
| 1171 | void 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 |
|
---|
| 1222 | void 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 |
|
---|
| 1254 | QRect 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 |
|
---|
| 1276 | void 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 |
|
---|
| 1304 | QRect 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 |
|
---|
| 1326 | void 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 |
|
---|
| 1358 | void 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 |
|
---|
| 1390 | const 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 |
|
---|
| 1444 | void 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 |
|
---|
| 1476 | void 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 |
|
---|
| 1494 | void 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 |
|
---|
| 1530 | void 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 |
|
---|
| 1552 | void 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 |
|
---|
| 1566 | void 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 |
|
---|
| 1580 | void 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 |
|
---|
| 1596 | void 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 |
|
---|
| 1613 | void 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;
|
---|
[8] | 1637 | #if defined(Q_WS_WIN) || defined(Q_WS_PM)
|
---|
[2] | 1638 | setf(DirtyFont);
|
---|
| 1639 | #endif
|
---|
| 1640 | }
|
---|
| 1641 | } else {
|
---|
| 1642 | txop = TxRotShear;
|
---|
[8] | 1643 | #if defined(Q_WS_WIN) || defined(Q_WS_PM)
|
---|
[2] | 1644 | setf(DirtyFont);
|
---|
| 1645 | #endif
|
---|
| 1646 | }
|
---|
| 1647 | }
|
---|
| 1648 |
|
---|
| 1649 |
|
---|
| 1650 | /*!
|
---|
| 1651 | \internal
|
---|
| 1652 | Updates an internal integer inverse transformation matrix.
|
---|
| 1653 | */
|
---|
| 1654 |
|
---|
| 1655 | void 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
|
---|
| 1678 | void QPainter::resetXForm()
|
---|
| 1679 | {
|
---|
| 1680 | xlatex = 0;
|
---|
| 1681 | xlatey = 0;
|
---|
| 1682 | clearf( VxF );
|
---|
| 1683 | }
|
---|
| 1684 | #endif // QT_NO_TRANSFORMATIONS
|
---|
| 1685 |
|
---|
| 1686 |
|
---|
| 1687 | extern bool qt_old_transformations;
|
---|
| 1688 |
|
---|
| 1689 | /*!
|
---|
| 1690 | \internal
|
---|
| 1691 | Maps a point from logical coordinates to device coordinates.
|
---|
| 1692 | */
|
---|
| 1693 |
|
---|
| 1694 | void 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 |
|
---|
| 1752 | void 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 |
|
---|
| 1820 | void 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 |
|
---|
| 1848 | void 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 |
|
---|
| 1887 | QPoint 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 |
|
---|
| 1912 | QRect 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 |
|
---|
| 1939 | QPointArray 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 |
|
---|
| 1976 | QPointArray 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 |
|
---|
| 1999 | QPoint 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 |
|
---|
| 2024 | QRect 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 |
|
---|
| 2053 | QPointArray 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 |
|
---|
| 2092 | QPointArray 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 |
|
---|
| 2123 | void 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 | */
|
---|
| 2172 | QRegion 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
|
---|
| 2259 | void 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 |
|
---|
| 2314 | void 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 | */
|
---|
| 2327 | void 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 = ±
|
---|
| 2344 | #if defined(Q_WS_WIN)
|
---|
| 2345 | if ( !pdev->cmd( QPaintDevice::PdcDrawPixmap, this, param ) || !hdc )
|
---|
| 2346 | return;
|
---|
[8] | 2347 | #elif defined(Q_WS_PM)
|
---|
| 2348 | if ( !pdev->cmd( QPaintDevice::PdcDrawPixmap, this, param ) || !hps )
|
---|
| 2349 | return;
|
---|
[2] | 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 | */
|
---|
| 2420 | void 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;
|
---|
[8] | 2498 | #elif defined(Q_WS_PM)
|
---|
| 2499 | if ( !pdev->cmd( QPaintDevice::PdcDrawImage, this, param ) || !hps )
|
---|
| 2500 | return;
|
---|
[2] | 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 | */
|
---|
| 2529 | void 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 | */
|
---|
| 2544 | void 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;
|
---|
[8] | 2560 | #elif defined(Q_WS_PM)
|
---|
| 2561 | if ( !pdev->cmd( QPaintDevice::PdcDrawImage, this, param ) || !hps )
|
---|
| 2562 | return;
|
---|
[2] | 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 |
|
---|
| 2599 | void 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 |
|
---|
| 2725 | static 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 | }
|
---|
| 2736 | void 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 |
|
---|
| 2777 | void 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
|
---|
[8] | 2804 | #elif defined(Q_WS_PM)
|
---|
| 2805 | if ( !pdev->cmd( QPaintDevice::PdcDrawText2Formatted,
|
---|
| 2806 | this, param) ||
|
---|
| 2807 | !hps )
|
---|
| 2808 | return;
|
---|
[2] | 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 |
|
---|
| 2834 | void 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 |
|
---|
| 3096 | QRect 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 |
|
---|
| 3228 | void 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 |
|
---|
| 3243 | QPen::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 |
|
---|
| 3255 | QPen::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 |
|
---|
| 3267 | QPen::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 |
|
---|
| 3287 | QPen::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 |
|
---|
| 3297 | QPen::QPen( const QPen &p )
|
---|
| 3298 | {
|
---|
| 3299 | data = p.data;
|
---|
| 3300 | data->ref();
|
---|
| 3301 | }
|
---|
| 3302 |
|
---|
| 3303 | /*!
|
---|
| 3304 | Destroys the pen.
|
---|
| 3305 | */
|
---|
| 3306 |
|
---|
| 3307 | QPen::~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 |
|
---|
| 3323 | void 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 |
|
---|
| 3334 | QPen &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 |
|
---|
| 3348 | QPen 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 |
|
---|
| 3376 | void 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 |
|
---|
| 3407 | void 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 | */
|
---|
| 3421 | Qt::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 |
|
---|
| 3441 | void 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 | */
|
---|
| 3454 | Qt::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 |
|
---|
| 3474 | void 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 |
|
---|
| 3496 | void 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 |
|
---|
| 3523 | bool 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 |
|
---|
| 3543 | QDataStream &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 |
|
---|
| 3562 | QDataStream &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 |
|
---|
| 3627 | void 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 |
|
---|
| 3641 | QBrush::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 |
|
---|
| 3662 | QBrush::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 |
|
---|
| 3673 | QBrush::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 |
|
---|
| 3690 | QBrush::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 |
|
---|
| 3701 | QBrush::QBrush( const QBrush &b )
|
---|
| 3702 | {
|
---|
| 3703 | data = b.data;
|
---|
| 3704 | data->ref();
|
---|
| 3705 | }
|
---|
| 3706 |
|
---|
| 3707 | /*!
|
---|
| 3708 | Destroys the brush.
|
---|
| 3709 | */
|
---|
| 3710 |
|
---|
| 3711 | QBrush::~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 |
|
---|
| 3729 | void 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 |
|
---|
| 3740 | QBrush &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 |
|
---|
| 3756 | QBrush 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 |
|
---|
| 3808 | void 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 |
|
---|
| 3835 | void 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 |
|
---|
| 3863 | void 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 |
|
---|
| 3902 | bool 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 |
|
---|
| 3934 | QDataStream &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 |
|
---|
| 3955 | QDataStream &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
|
---|