1 /****************************************************************************
3 ** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the documentation of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:FDL$
10 ** GNU Free Documentation License
11 ** Alternatively, this file may be used under the terms of the GNU Free
12 ** Documentation License version 1.3 as published by the Free Software
13 ** Foundation and appearing in the file included in the packaging of
17 ** Alternatively, this file may be used in accordance with the terms
18 ** and conditions contained in a signed written agreement between you
26 ****************************************************************************/
30 \title Coordinate System
32 \ingroup best-practices
33 \brief Information about the coordinate system used by the paint
36 The coordinate system is controlled by the QPainter
37 class. Together with the QPaintDevice and QPaintEngine classes,
38 QPainter form the basis of Qt's painting system, Arthur. QPainter
39 is used to perform drawing operations, QPaintDevice is an
40 abstraction of a two-dimensional space that can be painted on
41 using a QPainter, and QPaintEngine provides the interface that the
42 painter uses to draw onto different types of devices.
44 The QPaintDevice class is the base class of objects that can be
45 painted: Its drawing capabilities are inherited by the QWidget,
46 QPixmap, QPicture, QImage, and QPrinter classes. The default
47 coordinate system of a paint device has its origin at the top-left
48 corner. The \e x values increase to the right and the \e y values
49 increase downwards. The default unit is one pixel on pixel-based
50 devices and one point (1/72 of an inch) on printers.
52 The mapping of the logical QPainter coordinates to the physical
53 QPaintDevice coordinates are handled by QPainter's transformation
54 matrix, viewport and "window". The logical and physical coordinate
55 systems coincide by default. QPainter also supports coordinate
56 transformations (e.g. rotation and scaling).
62 \section2 Logical Representation
64 The size (width and height) of a graphics primitive always
65 correspond to its mathematical model, ignoring the width of the
66 pen it is rendered with:
70 \o \inlineimage coordinatesystem-rect.png
71 \o \inlineimage coordinatesystem-line.png
77 \section2 Aliased Painting
79 When drawing, the pixel rendering is controlled by the
80 QPainter::Antialiasing render hint.
82 The \l {QPainter::RenderHint}{RenderHint} enum is used to specify
83 flags to QPainter that may or may not be respected by any given
84 engine. The QPainter::Antialiasing value indicates that the engine
85 should antialias edges of primitives if possible, i.e. smoothing
86 the edges by using different color intensities.
88 But by default the painter is \e aliased and other rules apply:
89 When rendering with a one pixel wide pen the pixels will be
90 rendered to the \e {right and below the mathematically defined
95 \o \inlineimage coordinatesystem-rect-raster.png
96 \o \inlineimage coordinatesystem-line-raster.png
100 \snippet doc/src/snippets/code/doc_src_coordsys.cpp 0
103 \snippet doc/src/snippets/code/doc_src_coordsys.cpp 1
106 When rendering with a pen with an even number of pixels, the
107 pixels will be rendered symetrically around the mathematical
108 defined points, while rendering with a pen with an odd number of
109 pixels, the spare pixel will be rendered to the right and below
110 the mathematical point as in the one pixel case. See the QRectF
111 diagrams below for concrete examples.
117 \o \inlineimage qrect-diagram-zero.png
118 \o \inlineimage qrectf-diagram-one.png
120 \o Logical representation
121 \o One pixel wide pen
123 \o \inlineimage qrectf-diagram-two.png
124 \o \inlineimage qrectf-diagram-three.png
126 \o Two pixel wide pen
127 \o Three pixel wide pen
130 Note that for historical reasons the return value of the
131 QRect::right() and QRect::bottom() functions deviate from the true
132 bottom-right corner of the rectangle.
134 QRect's \l {QRect::right()}{right()} function returns \l
135 {QRect::left()}{left()} + \l {QRect::width()}{width()} - 1 and the
136 \l {QRect::bottom()}{bottom()} function returns \l
137 {QRect::top()}{top()} + \l {QRect::height()}{height()} - 1. The
138 bottom-right green point in the diagrams shows the return
139 coordinates of these functions.
141 We recommend that you simply use QRectF instead: The QRectF class
142 defines a rectangle in the plane using floating point coordinates
143 for accuracy (QRect uses integer coordinates), and the
144 QRectF::right() and QRectF::bottom() functions \e do return the
145 true bottom-right corner.
147 Alternatively, using QRect, apply \l {QRect::x()}{x()} + \l
148 {QRect::width()}{width()} and \l {QRect::y()}{y()} + \l
149 {QRect::height()}{height()} to find the bottom-right corner, and
150 avoid the \l {QRect::right()}{right()} and \l
151 {QRect::bottom()}{bottom()} functions.
153 \section2 Anti-aliased Painting
155 If you set QPainter's \l {QPainter::Antialiasing}{anti-aliasing}
156 render hint, the pixels will be rendered symetrically on both
157 sides of the mathematically defined points:
161 \o \inlineimage coordinatesystem-rect-antialias.png
162 \o \inlineimage coordinatesystem-line-antialias.png
166 \snippet doc/src/snippets/code/doc_src_coordsys.cpp 2
169 \snippet doc/src/snippets/code/doc_src_coordsys.cpp 3
172 \section1 Transformations
174 By default, the QPainter operates on the associated device's own
175 coordinate system, but it also has complete support for affine
176 coordinate transformations.
178 You can scale the coordinate system by a given offset using the
179 QPainter::scale() function, you can rotate it clockwise using the
180 QPainter::rotate() function and you can translate it (i.e. adding
181 a given offset to the points) using the QPainter::translate()
186 \o \inlineimage qpainter-clock.png
187 \o \inlineimage qpainter-rotation.png
188 \o \inlineimage qpainter-scale.png
189 \o \inlineimage qpainter-translation.png
192 \o \l {QPainter::rotate()}{rotate()}
193 \o \l {QPainter::scale()}{scale()}
194 \o \l {QPainter::translate()}{translate()}
197 You can also twist the coordinate system around the origin using
198 the QPainter::shear() function. See the \l {painting/affine}{Affine
199 Transformations} example for a visualization of a sheared coordinate
200 system. All the transformation operations operate on QPainter's
201 transformation matrix that you can retrieve using the
202 QPainter::worldTransform() function. A matrix transforms a point
203 in the plane to another point.
205 If you need the same transformations over and over, you can also
206 use QTransform objects and the QPainter::worldTransform() and
207 QPainter::setWorldTransform() functions. You can at any time save the
208 QPainter's transformation matrix by calling the QPainter::save()
209 function which saves the matrix on an internal stack. The
210 QPainter::restore() function pops it back.
212 One frequent need for the transformation matrix is when reusing
213 the same drawing code on a variety of paint devices. Without
214 transformations, the results are tightly bound to the resolution
215 of the paint device. Printers have high resolution, e.g. 600 dots
216 per inch, whereas screens often have between 72 and 100 dots per
221 \o {2,1} Analog Clock Example
223 \o \inlineimage coordinatesystem-analogclock.png
225 The Analog Clock example shows how to draw the contents of a
226 custom widget using QPainter's transformation matrix.
228 Qt's example directory provides a complete walk-through of the
229 example. Here, we will only review the example's \l
230 {QWidget::paintEvent()}{paintEvent()} function to see how we can
231 use the transformation matrix (i.e. QPainter's matrix functions)
232 to draw the clock's face.
234 We recommend compiling and running this example before you read
235 any further. In particular, try resizing the window to different
241 \snippet examples/widgets/analogclock/analogclock.cpp 9
243 First, we set up the painter. We translate the coordinate system
244 so that point (0, 0) is in the widget's center, instead of being
245 at the top-left corner. We also scale the system by \c side / 100,
246 where \c side is either the widget's width or the height,
247 whichever is shortest. We want the clock to be square, even if the
250 This will give us a 200 x 200 square area, with the origin (0, 0)
251 in the center, that we can draw on. What we draw will show up in
252 the largest possible square that will fit in the widget.
254 See also the \l {Window-Viewport Conversion} section.
256 \snippet examples/widgets/analogclock/analogclock.cpp 18
258 We draw the clock's hour hand by rotating the coordinate system
259 and calling QPainter::drawConvexPolygon(). Thank's to the
260 rotation, it's drawn pointed in the right direction.
262 The polygon is specified as an array of alternating \e x, \e y
263 values, stored in the \c hourHand static variable (defined at the
264 beginning of the function), which corresponds to the four points
265 (2, 0), (0, 2), (-2, 0), and (0, -25).
267 The calls to QPainter::save() and QPainter::restore() surrounding
268 the code guarantees that the code that follows won't be disturbed
269 by the transformations we've used.
271 \snippet examples/widgets/analogclock/analogclock.cpp 24
273 We do the same for the clock's minute hand, which is defined by
274 the four points (1, 0), (0, 1), (-1, 0), and (0, -40). These
275 coordinates specify a hand that is thinner and longer than the
278 \snippet examples/widgets/analogclock/analogclock.cpp 27
280 Finally, we draw the clock face, which consists of twelve short
281 lines at 30-degree intervals. At the end of that, the painter is
282 rotated in a way which isn't very useful, but we're done with
283 painting so that doesn't matter.
286 For a demonstation of Qt's ability to perform affine
287 transformations on painting operations, see the \l
288 {painting/affine}{Affine Transformations} example which allows the user
289 to experiment with the transformation operations. See also the \l
290 {painting/transformations}{Transformations} example which shows
291 how transformations influence the way that QPainter renders
292 graphics primitives. In particular, it shows how the order of
293 transformations affects the result.
295 For more information about the transformation matrix, see the
296 QTransform documentation.
298 \section1 Window-Viewport Conversion
300 When drawing with QPainter, we specify points using logical
301 coordinates which then are converted into the physical coordinates
304 The mapping of the logical coordinates to the physical coordinates
305 are handled by QPainter's world transformation \l
306 {QPainter::worldTransform()}{worldTransform()} (described in the \l
307 Transformations section), and QPainter's \l
308 {QPainter::viewport()}{viewport()} and \l
309 {QPainter::window()}{window()}. The viewport represents the
310 physical coordinates specifying an arbitrary rectangle. The
311 "window" describes the same rectangle in logical coordinates. By
312 default the logical and physical coordinate systems coincide, and
313 are equivalent to the paint device's rectangle.
315 Using window-viewport conversion you can make the logical
316 coordinate system fit your preferences. The mechanism can also be
317 used to make the drawing code independent of the paint device. You
318 can, for example, make the logical coordinates extend from (-50,
319 -50) to (50, 50) with (0, 0) in the center by calling the
320 QPainter::setWindow() function:
322 \snippet doc/src/snippets/code/doc_src_coordsys.cpp 4
324 Now, the logical coordinates (-50,-50) correspond to the paint
325 device's physical coordinates (0, 0). Independent of the paint
326 device, your painting code will always operate on the specified
329 By setting the "window" or viewport rectangle, you perform a
330 linear transformation of the coordinates. Note that each corner of
331 the "window" maps to the corresponding corner of the viewport, and
332 vice versa. For that reason it normally is a good idea to let the
333 viewport and "window" maintain the same aspect ratio to prevent
336 \snippet doc/src/snippets/code/doc_src_coordsys.cpp 5
338 If we make the logical coordinate system a square, we should also
339 make the viewport a square using the QPainter::setViewport()
340 function. In the example above we make it equivalent to the
341 largest square that fit into the paint device's rectangle. By
342 taking the paint device's size into consideration when setting the
343 window or viewport, it is possible to keep the drawing code
344 independent of the paint device.
346 Note that the window-viewport conversion is only a linear
347 transformation, i.e. it does not perform clipping. This means that
348 if you paint outside the currently set "window", your painting is
349 still transformed to the viewport using the same linear algebraic
352 \image coordinatesystem-transformations.png
354 The viewport, "window" and transformation matrix determine how
355 logical QPainter coordinates map to the paint device's physical
356 coordinates. By default the world transformation matrix is the
357 identity matrix, and the "window" and viewport settings are
358 equivalent to the paint device's settings, i.e. the world,
359 "window" and device coordinate systems are equivalent, but as we
360 have seen, the systems can be manipulated using transformation
361 operations and window-viewport conversion. The illustration above
362 describes the process.
365 \section1 Related Classes
367 Qt's paint system, Arthur, is primarily based on the QPainter,
368 QPaintDevice, and QPaintEngine classes:
371 \header \o Class \o Description
375 The QPainter class performs low-level painting on widgets and
376 other paint devices. QPainter can operate on any object that
377 inherits the QPaintDevice class, using the same code.
381 The QPaintDevice class is the base class of objects that can be
382 painted. Qt provides several devices: QWidget, QImage, QPixmap,
383 QPrinter and QPicture, and other devices can also be defined by
384 subclassing QPaintDevice.
388 The QPaintEngine class provides an abstract definition of how
389 QPainter draws to a given device on a given platform. Qt 4
390 provides several premade implementations of QPaintEngine for the
391 different painter backends we support; it provides one paint
392 engine for each supported window system and painting
393 frameworkt. You normally don't need to use this class directly.
396 The 2D transformations of the coordinate system are specified
397 using the QTransform class:
400 \header \o Class \o Description
404 A 3 x 3 transformation matrix. Use QTransform to rotate, shear,
405 scale, or translate the coordinate system.
408 In addition Qt provides several graphics primitive classes. Some
409 of these classes exist in two versions: an \c{int}-based version
410 and a \c{qreal}-based version. For these, the \c qreal version's
411 name is suffixed with an \c F.
414 \header \o Class \o Description
416 \o \l{QPoint}(\l{QPointF}{F})
418 A single 2D point in the coordinate system. Most functions in Qt
419 that deal with points can accept either a QPoint, a QPointF, two
420 \c{int}s, or two \c{qreal}s.
422 \o \l{QSize}(\l{QSizeF}{F})
424 A single 2D vector. Internally, QPoint and QSize are the same, but
425 a point is not the same as a size, so both classes exist. Again,
426 most functions accept either QSizeF, a QSize, two \c{int}s, or two
429 \o \l{QRect}(\l{QRectF}{F})
431 A 2D rectangle. Most functions accept either a QRectF, a QRect,
432 four \c{int}s, or four \c {qreal}s.
434 \o \l{QLine}(\l{QLineF}{F})
436 A 2D finite-length line, characterized by a start point and an end
439 \o \l{QPolygon}(\l{QPolygonF}{F})
441 A 2D polygon. A polygon is a vector of \c{QPoint(F)}s. If the
442 first and last points are the same, the polygon is closed.
446 A vectorial specification of a 2D shape. Painter paths are the
447 ultimate painting primitive, in the sense that any shape
448 (rectange, ellipse, spline) or combination of shapes can be
449 expressed as a path. A path specifies both an outline and an area.
453 An area in a paint device, expressed as a list of
454 \l{QRect}s. In general, we recommend using the vectorial
455 QPainterPath class instead of QRegion for specifying areas,
456 because QPainterPath handles painter transformations much better.
460 \sa {Analog Clock Example}, {Transformations Example}