source: trunk/doc/src/coordsys.qdoc@ 109

Last change on this file since 109 was 2, checked in by Dmitry A. Kuminov, 16 years ago

Initially imported qt-all-opensource-src-4.5.1 from Trolltech.

File size: 19.0 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** Contact: Qt Software Information ([email protected])
5**
6** This file is part of the documentation of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:LGPL$
9** Commercial Usage
10** Licensees holding valid Qt Commercial licenses may use this file in
11** accordance with the Qt Commercial License Agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and Nokia.
14**
15** GNU Lesser General Public License Usage
16** Alternatively, this file may be used under the terms of the GNU Lesser
17** General Public License version 2.1 as published by the Free Software
18** Foundation and appearing in the file LICENSE.LGPL included in the
19** packaging of this file. Please review the following information to
20** ensure the GNU Lesser General Public License version 2.1 requirements
21** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
22**
23** In addition, as a special exception, Nokia gives you certain
24** additional rights. These rights are described in the Nokia Qt LGPL
25** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
26** package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you are unsure which license is appropriate for your use, please
37** contact the sales department at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42/****************************************************************************
43**
44** Qt Coordinate System Documentation.
45**
46** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
47** Contact: Qt Software Information ([email protected])
48**
49** This file is part of the Qt GUI Toolkit.
50** EDITIONS: FREE, PROFESSIONAL, ENTERPRISE
51**
52****************************************************************************/
53
54/*!
55 \page coordsys.html
56 \title The Coordinate System
57 \ingroup architecture
58 \brief Information about the coordinate system used by the paint
59 system.
60
61 The coordinate system is controlled by the QPainter
62 class. Together with the QPaintDevice and QPaintEngine classes,
63 QPainter form the basis of Qt's painting system, Arthur. QPainter
64 is used to perform drawing operations, QPaintDevice is an
65 abstraction of a two-dimensional space that can be painted on
66 using a QPainter, and QPaintEngine provides the interface that the
67 painter uses to draw onto different types of devices.
68
69 The QPaintDevice class is the base class of objects that can be
70 painted: Its drawing capabilities are inherited by the QWidget,
71 QPixmap, QPicture, QImage, and QPrinter classes. The default
72 coordinate system of a paint device has its origin at the top-left
73 corner. The \e x values increase to the right and the \e y values
74 increase downwards. The default unit is one pixel on pixel-based
75 devices and one point (1/72 of an inch) on printers.
76
77 The mapping of the logical QPainter coordinates to the physical
78 QPaintDevice coordinates are handled by QPainter's transformation
79 matrix, viewport and "window". The logical and physical coordinate
80 systems coincide by default. QPainter also supports coordinate
81 transformations (e.g. rotation and scaling).
82
83 \tableofcontents
84
85 \section1 Rendering
86
87 \section2 Logical Representation
88
89 The size (width and height) of a graphics primitive always
90 correspond to its mathematical model, ignoring the width of the
91 pen it is rendered with:
92
93 \table
94 \row
95 \o \inlineimage coordinatesystem-rect.png
96 \o \inlineimage coordinatesystem-line.png
97 \row
98 \o QRect(1, 2, 6, 4)
99 \o QLine(2, 7, 6, 1)
100 \endtable
101
102 \section2 Aliased Painting
103
104 When drawing, the pixel rendering is controlled by the
105 QPainter::Antialiasing render hint.
106
107 The \l {QPainter::RenderHint}{RenderHint} enum is used to specify
108 flags to QPainter that may or may not be respected by any given
109 engine. The QPainter::Antialiasing value indicates that the engine
110 should antialias edges of primitives if possible, i.e. smoothing
111 the edges by using different color intensities.
112
113 But by default the painter is \e aliased and other rules apply:
114 When rendering with a one pixel wide pen the pixels will be
115 rendered to the \e {right and below the mathematically defined
116 points}. For example:
117
118 \table
119 \row
120 \o \inlineimage coordinatesystem-rect-raster.png
121 \o \inlineimage coordinatesystem-line-raster.png
122
123 \row
124 \o
125 \snippet doc/src/snippets/code/doc_src_coordsys.qdoc 0
126
127 \o
128 \snippet doc/src/snippets/code/doc_src_coordsys.qdoc 1
129 \endtable
130
131 When rendering with a pen with an even number of pixels, the
132 pixels will be rendered symetrically around the mathematical
133 defined points, while rendering with a pen with an odd number of
134 pixels, the spare pixel will be rendered to the right and below
135 the mathematical point as in the one pixel case. See the QRectF
136 diagrams below for concrete examples.
137
138 \table
139 \header
140 \o {3,1} QRectF
141 \row
142 \o \inlineimage qrect-diagram-zero.png
143 \o \inlineimage qrectf-diagram-one.png
144 \row
145 \o Logical representation
146 \o One pixel wide pen
147 \row
148 \o \inlineimage qrectf-diagram-two.png
149 \o \inlineimage qrectf-diagram-three.png
150 \row
151 \o Two pixel wide pen
152 \o Three pixel wide pen
153 \endtable
154
155 Note that for historical reasons the return value of the
156 QRect::right() and QRect::bottom() functions deviate from the true
157 bottom-right corner of the rectangle.
158
159 QRect's \l {QRect::right()}{right()} function returns \l
160 {QRect::left()}{left()} + \l {QRect::width()}{width()} - 1 and the
161 \l {QRect::bottom()}{bottom()} function returns \l
162 {QRect::top()}{top()} + \l {QRect::height()}{height()} - 1. The
163 bottom-right green point in the diagrams shows the return
164 coordinates of these functions.
165
166 We recommend that you simply use QRectF instead: The QRectF class
167 defines a rectangle in the plane using floating point coordinates
168 for accuracy (QRect uses integer coordinates), and the
169 QRectF::right() and QRectF::bottom() functions \e do return the
170 true bottom-right corner.
171
172 Alternatively, using QRect, apply \l {QRect::x()}{x()} + \l
173 {QRect::width()}{width()} and \l {QRect::y()}{y()} + \l
174 {QRect::height()}{height()} to find the bottom-right corner, and
175 avoid the \l {QRect::right()}{right()} and \l
176 {QRect::bottom()}{bottom()} functions.
177
178 \section2 Anti-aliased Painting
179
180 If you set QPainter's \l {QPainter::Antialiasing}{anti-aliasing}
181 render hint, the pixels will be rendered symetrically on both
182 sides of the mathematically defined points:
183
184 \table
185 \row
186 \o \inlineimage coordinatesystem-rect-antialias.png
187 \o \inlineimage coordinatesystem-line-antialias.png
188 \row
189 \o
190
191 \snippet doc/src/snippets/code/doc_src_coordsys.qdoc 2
192
193 \o
194 \snippet doc/src/snippets/code/doc_src_coordsys.qdoc 3
195 \endtable
196
197 \section1 Transformations
198
199 By default, the QPainter operates on the associated device's own
200 coordinate system, but it also has complete support for affine
201 coordinate transformations.
202
203 You can scale the coordinate system by a given offset using the
204 QPainter::scale() function, you can rotate it clockwise using the
205 QPainter::rotate() function and you can translate it (i.e. adding
206 a given offset to the points) using the QPainter::translate()
207 function.
208
209 \table
210 \row
211 \o \inlineimage qpainter-clock.png
212 \o \inlineimage qpainter-rotation.png
213 \o \inlineimage qpainter-scale.png
214 \o \inlineimage qpainter-translation.png
215 \row
216 \o nop
217 \o \l {QPainter::rotate()}{rotate()}
218 \o \l {QPainter::scale()}{scale()}
219 \o \l {QPainter::translate()}{translate()}
220 \endtable
221
222 You can also twist the coordinate system around the origin using
223 the QPainter::shear() function. See the \l {demos/affine}{Affine
224 Transformations} demo for a visualization of a sheared coordinate
225 system. All the transformation operations operate on QPainter's
226 transformation matrix that you can retrieve using the
227 QPainter::worldMatrix() function. A matrix transforms a point in the
228 plane to another point.
229
230 If you need the same transformations over and over, you can also
231 use QMatrix objects and the QPainter::worldMatrix() and
232 QPainter::setWorldMatrix() functions. You can at any time save the
233 QPainter's transformation matrix by calling the QPainter::save()
234 function which saves the matrix on an internal stack. The
235 QPainter::restore() function pops it back.
236
237 One frequent need for the transformation matrix is when reusing
238 the same drawing code on a variety of paint devices. Without
239 transformations, the results are tightly bound to the resolution
240 of the paint device. Printers have high resolution, e.g. 600 dots
241 per inch, whereas screens often have between 72 and 100 dots per
242 inch.
243
244 \table 100%
245 \header
246 \o {2,1} Analog Clock Example
247 \row
248 \o \inlineimage coordinatesystem-analogclock.png
249 \o
250 The Analog Clock example shows how to draw the contents of a
251 custom widget using QPainter's transformation matrix.
252
253 Qt's example directory provides a complete walk-through of the
254 example. Here, we will only review the example's \l
255 {QWidget::paintEvent()}{paintEvent()} function to see how we can
256 use the transformation matrix (i.e. QPainter's matrix functions)
257 to draw the clock's face.
258
259 We recommend compiling and running this example before you read
260 any further. In particular, try resizing the window to different
261 sizes.
262
263 \row
264 \o {2,1}
265
266 \snippet examples/widgets/analogclock/analogclock.cpp 9
267
268 First, we set up the painter. We translate the coordinate system
269 so that point (0, 0) is in the widget's center, instead of being
270 at the top-left corner. We also scale the system by \c side / 100,
271 where \c side is either the widget's width or the height,
272 whichever is shortest. We want the clock to be square, even if the
273 device isn't.
274
275 This will give us a 200 x 200 square area, with the origin (0, 0)
276 in the center, that we can draw on. What we draw will show up in
277 the largest possible square that will fit in the widget.
278
279 See also the \l {Window-Viewport Conversion} section.
280
281 \snippet examples/widgets/analogclock/analogclock.cpp 18
282
283 We draw the clock's hour hand by rotating the coordinate system
284 and calling QPainter::drawConvexPolygon(). Thank's to the
285 rotation, it's drawn pointed in the right direction.
286
287 The polygon is specified as an array of alternating \e x, \e y
288 values, stored in the \c hourHand static variable (defined at the
289 beginning of the function), which corresponds to the four points
290 (2, 0), (0, 2), (-2, 0), and (0, -25).
291
292 The calls to QPainter::save() and QPainter::restore() surrounding
293 the code guarantees that the code that follows won't be disturbed
294 by the transformations we've used.
295
296 \snippet examples/widgets/analogclock/analogclock.cpp 24
297
298 We do the same for the clock's minute hand, which is defined by
299 the four points (1, 0), (0, 1), (-1, 0), and (0, -40). These
300 coordinates specify a hand that is thinner and longer than the
301 minute hand.
302
303 \snippet examples/widgets/analogclock/analogclock.cpp 27
304
305 Finally, we draw the clock face, which consists of twelve short
306 lines at 30-degree intervals. At the end of that, the painter is
307 rotated in a way which isn't very useful, but we're done with
308 painting so that doesn't matter.
309 \endtable
310
311 For a demonstation of Qt's ability to perform affine
312 transformations on painting operations, see the \l
313 {demos/affine}{Affine Transformations} demo which allows the user
314 to experiment with the transformation operations. See also the \l
315 {painting/transformations}{Transformations} example which shows
316 how transformations influence the way that QPainter renders
317 graphics primitives. In particular, it shows how the order of
318 transformations affects the result.
319
320 For more information about the transformation matrix, see the
321 QMatrix documentation.
322
323 \section1 Window-Viewport Conversion
324
325 When drawing with QPainter, we specify points using logical
326 coordinates which then are converted into the physical coordinates
327 of the paint device.
328
329 The mapping of the logical coordinates to the physical coordinates
330 are handled by QPainter's world transformation \l
331 {QPainter::worldMatrix()}{worldMatrix()} (described in the \l
332 Transformations section), and QPainter's \l
333 {QPainter::viewport()}{viewport()} and \l
334 {QPainter::window()}{window()}. The viewport represents the
335 physical coordinates specifying an arbitrary rectangle. The
336 "window" describes the same rectangle in logical coordinates. By
337 default the logical and physical coordinate systems coincide, and
338 are equivalent to the paint device's rectangle.
339
340 Using window-viewport conversion you can make the logical
341 coordinate system fit your preferences. The mechanism can also be
342 used to make the drawing code independent of the paint device. You
343 can, for example, make the logical coordinates extend from (-50,
344 -50) to (50, 50) with (0, 0) in the center by calling the
345 QPainter::setWindow() function:
346
347 \snippet doc/src/snippets/code/doc_src_coordsys.qdoc 4
348
349 Now, the logical coordinates (-50,-50) correspond to the paint
350 device's physical coordinates (0, 0). Independent of the paint
351 device, your painting code will always operate on the specified
352 logical coordinates.
353
354 By setting the "window" or viewport rectangle, you perform a
355 linear transformation of the coordinates. Note that each corner of
356 the "window" maps to the corresponding corner of the viewport, and
357 vice versa. For that reason it normally is a good idea to let the
358 viewport and "window" maintain the same aspect ratio to prevent
359 deformation:
360
361 \snippet doc/src/snippets/code/doc_src_coordsys.qdoc 5
362
363 If we make the logical coordinate system a square, we should also
364 make the viewport a square using the QPainter::setViewport()
365 function. In the example above we make it equivalent to the
366 largest square that fit into the paint device's rectangle. By
367 taking the paint device's size into consideration when setting the
368 window or viewport, it is possible to keep the drawing code
369 independent of the paint device.
370
371 Note that the window-viewport conversion is only a linear
372 transformation, i.e. it does not perform clipping. This means that
373 if you paint outside the currently set "window", your painting is
374 still transformed to the viewport using the same linear algebraic
375 approach.
376
377 \image coordinatesystem-transformations.png
378
379 The viewport, "window" and transformation matrix determine how
380 logical QPainter coordinates map to the paint device's physical
381 coordinates. By default the world transformation matrix is the
382 identity matrix, and the "window" and viewport settings are
383 equivalent to the paint device's settings, i.e. the world,
384 "window" and device coordinate systems are equivalent, but as we
385 have seen, the systems can be manipulated using transformation
386 operations and window-viewport conversion. The illustration above
387 describes the process.
388
389 \omit
390 \section1 Related Classes
391
392 Qt's paint system, Arthur, is primarily based on the QPainter,
393 QPaintDevice, and QPaintEngine classes:
394
395 \table
396 \header \o Class \o Description
397 \row
398 \o QPainter
399 \o
400 The QPainter class performs low-level painting on widgets and
401 other paint devices. QPainter can operate on any object that
402 inherits the QPaintDevice class, using the same code.
403 \row
404 \o QPaintDevice
405 \o
406 The QPaintDevice class is the base class of objects that can be
407 painted. Qt provides several devices: QWidget, QImage, QPixmap,
408 QPrinter and QPicture, and other devices can also be defined by
409 subclassing QPaintDevice.
410 \row
411 \o QPaintEngine
412 \o
413 The QPaintEngine class provides an abstract definition of how
414 QPainter draws to a given device on a given platform. Qt 4
415 provides several premade implementations of QPaintEngine for the
416 different painter backends we support; it provides one paint
417 engine for each supported window system and painting
418 frameworkt. You normally don't need to use this class directly.
419 \endtable
420
421 The 2D transformations of the coordinate system are specified
422 using the QMatrix class:
423
424 \table
425 \header \o Class \o Description
426 \row
427 \o QMatrix
428 \o
429 A 3 x 3 transformation matrix. Use QMatrix to rotate, shear,
430 scale, or translate the coordinate system.
431 \endtable
432
433 In addition Qt provides several graphics primitive classes. Some
434 of these classes exist in two versions: an \c{int}-based version
435 and a \c{qreal}-based version. For these, the \c qreal version's
436 name is suffixed with an \c F.
437
438 \table
439 \header \o Class \o Description
440 \row
441 \o \l{QPoint}(\l{QPointF}{F})
442 \o
443 A single 2D point in the coordinate system. Most functions in Qt
444 that deal with points can accept either a QPoint, a QPointF, two
445 \c{int}s, or two \c{qreal}s.
446 \row
447 \o \l{QSize}(\l{QSizeF}{F})
448 \o
449 A single 2D vector. Internally, QPoint and QSize are the same, but
450 a point is not the same as a size, so both classes exist. Again,
451 most functions accept either QSizeF, a QSize, two \c{int}s, or two
452 \c{qreal}s.
453 \row
454 \o \l{QRect}(\l{QRectF}{F})
455 \o
456 A 2D rectangle. Most functions accept either a QRectF, a QRect,
457 four \c{int}s, or four \c {qreal}s.
458 \row
459 \o \l{QLine}(\l{QLineF}{F})
460 \o
461 A 2D finite-length line, characterized by a start point and an end
462 point.
463 \row
464 \o \l{QPolygon}(\l{QPolygonF}{F})
465 \o
466 A 2D polygon. A polygon is a vector of \c{QPoint(F)}s. If the
467 first and last points are the same, the polygon is closed.
468 \row
469 \o QPainterPath
470 \o
471 A vectorial specification of a 2D shape. Painter paths are the
472 ultimate painting primitive, in the sense that any shape
473 (rectange, ellipse, spline) or combination of shapes can be
474 expressed as a path. A path specifies both an outline and an area.
475 \row
476 \o QRegion
477 \o
478 An area in a paint device, expressed as a list of
479 \l{QRect}s. In general, we recommend using the vectorial
480 QPainterPath class instead of QRegion for specifying areas,
481 because QPainterPath handles painter transformations much better.
482 \endtable
483 \endomit
484
485 \sa {Analog Clock Example}, {Transformations Example}
486*/
Note: See TracBrowser for help on using the repository browser.