|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the documentation of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 /*! |
|
43 \page qt4-arthur.html |
|
44 \title The Arthur Paint System |
|
45 |
|
46 \contentspage {What's New in Qt 4}{Home} |
|
47 \previouspage The Interview Framework |
|
48 \nextpage The Scribe Classes |
|
49 |
|
50 This document describes Qt 4's painting system, providing a |
|
51 comparison between the approaches used by Qt when rendering |
|
52 graphics in Qt 3 and Qt 4. |
|
53 |
|
54 \tableofcontents |
|
55 |
|
56 \section1 Architecture |
|
57 |
|
58 The Qt 4 Paint System is primarily based on the classes |
|
59 QPainter, QPaintDevice, and QPaintEngine. QPainter is the |
|
60 class used to perform drawing operations, such as drawLine() |
|
61 and drawRect(). QPaintDevice represents a device that can be |
|
62 painted on using a QPainter; both QWidget and QPixmap are |
|
63 QPaintDevices. QPaintEngine provides the interface that the |
|
64 painter uses to draw onto different types of devices. |
|
65 |
|
66 \section2 A Look Back at Qt 3 |
|
67 |
|
68 In Qt 3, QPainter could be used to draw on widgets and pixmaps. |
|
69 (It could also be used to draw to printers on Windows and Mac OS |
|
70 X.) When other paint devices needed to be supported, such as |
|
71 QPrinter on X11, this was done by deriving from QPaintDevice and |
|
72 reimplementing the virtual function QPaintDevice::cmd(). A |
|
73 reimplemented paint device was treated as an external device. |
|
74 |
|
75 QPainter was capable of recognizing external devices and could |
|
76 serialize each paint operation to the reimplemented cmd() |
|
77 function. This allowed reimplementation of arbitrary devices, but |
|
78 the approach has some disadvantages which we have addressed in |
|
79 Qt 4. One of these is that an external device could not reuse any |
|
80 functionality implemented in QPainter since QPainter was tied to |
|
81 widget/pixmap painting on that platform. Supporting multiple |
|
82 device backends, such as OpenGL, was therefore inconvenient and |
|
83 not very efficient. |
|
84 |
|
85 This has led us to devise a more convenient and intuitive API for |
|
86 Qt 4. |
|
87 |
|
88 \section2 How Painting is Done in Qt 4 |
|
89 |
|
90 In Qt 4 we have introduced the QPaintEngine abstract class. |
|
91 Implementations of this class provide the concrete functionality |
|
92 needed to draw to specific device types. The QPaintEngine class |
|
93 is only used internally by QPainter and QPaintDevice, and it is |
|
94 hidden from application programmers unless they reimplement their own |
|
95 device types for their own QPaintEngine subclasses. Qt currently |
|
96 provides paint engines for the following platforms and APIs: |
|
97 |
|
98 \list |
|
99 \o A pixel-based engine for the Windows platform that is |
|
100 also used to draw onto QImages on all platforms |
|
101 \o OpenGL on all platforms |
|
102 \o PostScript on Linux, Unix, and Mac OS X |
|
103 \o QuickDraw and CoreGraphics on Mac OS X |
|
104 \o X11 and the X Render Extension on Linux and Unix systems |
|
105 \omit |
|
106 \o QVFb, VNC, and LinuxFb for Qt for Embedded Linux |
|
107 \endomit |
|
108 \endlist |
|
109 |
|
110 To implement support for a new backend, you must derive from |
|
111 QPaintEngine and reimplement its virtual functions. You also need |
|
112 to derive from QPaintDevice and reimplement the virtual function |
|
113 QPaintDevice::paintEngine() to tell QPainter which paint engine |
|
114 should be used to draw on this particular device. |
|
115 |
|
116 The main benefit of this approach is that all painting follows the |
|
117 same painting pipeline. This means that adding support for new features |
|
118 and providing default implementations for unsupported ones has |
|
119 become much simpler. |
|
120 |
|
121 \section1 New Features in the Qt 4 Paint System |
|
122 |
|
123 \section2 Gradient Brushes |
|
124 |
|
125 With Qt 4 it is possible to fill shapes using gradient |
|
126 brushes. A gradient in this case is used to describe the transition |
|
127 from one color at a given point to different color at another point. A |
|
128 gradient can span from one color to another or over a |
|
129 number of colors by specifying multiple colors at positions in the |
|
130 gradient area. Qt 4 supports linear, radial, and conical gradients. |
|
131 |
|
132 Linear gradients are specified using two control points. |
|
133 Setting a linear gradient brush is done by creating a QLinearGradient |
|
134 object and setting it as a brush. |
|
135 |
|
136 \snippet doc/src/snippets/code/doc_src_qt4-arthur.qdoc 0 |
|
137 |
|
138 The code shown above produces a pattern as show in the following |
|
139 pixmap: |
|
140 |
|
141 \img diagonalGradient.png |
|
142 |
|
143 Radial gradients are specified using a center, a radius, and a |
|
144 focal point. Setting a radial brush is done by creating a QRadialGradient |
|
145 object and setting it as a brush. |
|
146 |
|
147 \snippet doc/src/snippets/code/doc_src_qt4-arthur.qdoc 1 |
|
148 |
|
149 The code shown above produces a pattern as shown in the following |
|
150 pixmap: |
|
151 |
|
152 \img radialGradient.png |
|
153 |
|
154 Conical gradients are specified using a center and a start |
|
155 angle. Setting a conical brush is done by creating a |
|
156 QConicalGradient object and setting it as a brush. |
|
157 |
|
158 \snippet doc/src/snippets/code/doc_src_qt4-arthur.qdoc 2 |
|
159 |
|
160 The code shown above produces a pattern as shown in the following |
|
161 pixmap: |
|
162 |
|
163 \img conicalGradient.png |
|
164 |
|
165 \section2 Alpha-Blended Drawing |
|
166 |
|
167 With Qt 4 we support alpha-blended outlining and filling. The |
|
168 alpha channel of a color is defined through QColor. The alpha |
|
169 channel specifies the transparency effect, 0 represents a fully |
|
170 transparent color, while 255 represents a fully opaque color. For |
|
171 example: |
|
172 |
|
173 \snippet doc/src/snippets/code/doc_src_qt4-arthur.qdoc 3 |
|
174 |
|
175 The code shown above produces the following output: |
|
176 |
|
177 \img alphafill.png |
|
178 |
|
179 Alpha-blended drawing is supported on Windows, Mac OS X, and on |
|
180 X11 systems that have the X Render extension installed. |
|
181 |
|
182 |
|
183 \section2 QPainter and QGLWidget |
|
184 |
|
185 It is now possible to open a QPainter on a QGLWidget as if it |
|
186 were a normal QWidget. One huge benefit from this is that we |
|
187 utilize the high performance of OpenGL for most drawing |
|
188 operations, such as transformations and pixmap drawing. |
|
189 |
|
190 |
|
191 \section2 Anti-Aliased Edges |
|
192 |
|
193 On platforms where this is supported by the native drawing API, we |
|
194 provide the option of turning on anti-aliased edges when drawing |
|
195 graphics primitives. |
|
196 |
|
197 \snippet doc/src/snippets/code/doc_src_qt4-arthur.qdoc 4 |
|
198 |
|
199 This produces the following output: |
|
200 |
|
201 \img antialiased.png |
|
202 |
|
203 Anti-aliasing is supported when drawing to a QImage and on all |
|
204 systems, except on X11 when XRender is not present. |
|
205 |
|
206 |
|
207 \section2 Extensive Use of Native Graphics Operations |
|
208 |
|
209 Where this makes sense, Qt uses native graphics |
|
210 operations. The benefit we gain from this is that these operations |
|
211 can potentially be performed in hardware, giving significant |
|
212 speed improvements over many pure-software implementations. |
|
213 |
|
214 Among these are native transformations (Mac OS X and OpenGL), |
|
215 making painting with a world matrix much faster. Some pixmap |
|
216 operations have also been moved closer to the underlying |
|
217 hardware implementations. |
|
218 |
|
219 |
|
220 \section2 Painter Paths |
|
221 |
|
222 A painter path is an object composed of a number of graphical |
|
223 building blocks, such as rectangles, ellipses, lines, and curves. |
|
224 A painter path can be used for filling, outlining, and for clipping. |
|
225 The main advantage of painter paths over normal drawing operations |
|
226 is that it is possible to build up non-linear shapes which can be |
|
227 drawn later in one go. |
|
228 |
|
229 Building blocks can be joined in closed subpaths, such as a |
|
230 rectangle or an ellipse, or they can exist independently as unclosed |
|
231 subpaths, although an unclosed path will not be filled. |
|
232 |
|
233 Below is a code example on how a path can be used. The |
|
234 painter in this case has a pen width of 3 and a light blue brush. We |
|
235 first add a rectangle, which becomes a closed subpath. We then add |
|
236 two bezier curves, and finally draw the entire path. |
|
237 |
|
238 \snippet doc/src/snippets/code/doc_src_qt4-arthur.qdoc 5 |
|
239 |
|
240 The code above produces the following output: |
|
241 |
|
242 \img pathexample.png |
|
243 |
|
244 |
|
245 \section2 Widget Double-Buffering |
|
246 |
|
247 In Qt 4, all widgets are double-buffered by default. |
|
248 |
|
249 In previous versions of Qt double-buffering was achieved by |
|
250 painting to an off-screen pixmap then copying the pixmap to the |
|
251 screen. For example: |
|
252 |
|
253 \snippet doc/src/snippets/code/doc_src_qt4-arthur.qdoc 6 |
|
254 |
|
255 Since the double-buffering is handled by QWidget internally this |
|
256 now becomes: |
|
257 |
|
258 \snippet doc/src/snippets/code/doc_src_qt4-arthur.qdoc 7 |
|
259 |
|
260 Double-buffering is turned on by default, but can be turned off for |
|
261 individual widgets by setting the widget attribute |
|
262 Qt::WA_PaintOnScreen. |
|
263 |
|
264 \snippet doc/src/snippets/code/doc_src_qt4-arthur.qdoc 8 |
|
265 |
|
266 \section2 Pen and Brush Transformation |
|
267 |
|
268 In Qt 3, pens and brushes weren't affected by the painter's |
|
269 transformation matrix. For example, if you drew a rectangle with a |
|
270 pen width of 1 using a scaled painter, the resulting line width |
|
271 would still be 1. This made it difficult to implement features |
|
272 such as zooming and high-resolution printing. |
|
273 |
|
274 In Qt 4, pens and brushes honor the painter's transformation |
|
275 matrix. |
|
276 |
|
277 Note that this feature is still in development and not yet |
|
278 supported on all platforms. |
|
279 |
|
280 \section2 Custom Filled Pens |
|
281 |
|
282 In Qt 4, it is possible to specify how an outline should be |
|
283 filled. It can be a solid color or a QBrush, which makes it |
|
284 possible to specify both texture and gradient fills for both |
|
285 text and outlines. |
|
286 |
|
287 \snippet doc/src/snippets/code/doc_src_qt4-arthur.qdoc 9 |
|
288 |
|
289 The code above produces the following output: |
|
290 |
|
291 \img gradientText.png |
|
292 |
|
293 \section2 QImage as a Paint Device |
|
294 |
|
295 A great improvement of Qt 4 over previous versions it that it now |
|
296 provides a pixel-based raster paint engine which allows users to |
|
297 open a painter on a QImage. The QImage paint engine supports the |
|
298 full feature set of QPainter (paths, antialiasing, alphablending, |
|
299 etc.) and can be used on all platforms. |
|
300 |
|
301 One advantage of this is that it is possible to guarantee the |
|
302 pixel exactness of any drawing operation in a platform-independent |
|
303 way. |
|
304 |
|
305 Painting on an image is as simple as drawing on any other paint device. |
|
306 |
|
307 \snippet doc/src/snippets/code/doc_src_qt4-arthur.qdoc 10 |
|
308 |
|
309 \section2 SVG Rendering Support |
|
310 |
|
311 \l{Scalable Vector Graphics} (SVG) is an language for describing both static |
|
312 and animated two-dimensional vector graphics. Qt includes support for the |
|
313 \l{SVG 1.2 Tiny Static Features}{static features} of \l{SVG 1.2 Tiny}, taking |
|
314 advantage of the improved paint system in Qt 4. SVG drawings can be rendered |
|
315 onto any QPaintDevice subclass, such as QWidget, QImage, and QGLWidget, to |
|
316 take advantage of specific advantages of each device. This approach gives |
|
317 developers the flexibility to experiment, in order to find the best solution |
|
318 for each application. |
|
319 |
|
320 \image svg-image.png |
|
321 |
|
322 Since SVG is an XML-based format, the QtXml module is required to read SVG |
|
323 files. For this reason, classes for SVG handling are provided separately in |
|
324 the QtSvg module. |
|
325 |
|
326 Displaying an SVG drawing in an application is as simple as displaying a |
|
327 bitmap image. QSvgWidget is a display widget that can be placed in an |
|
328 appropriate place in a user interface, and new content can be loaded as |
|
329 required. For example, a predetermined file can be loaded and displayed in |
|
330 a widget with little effort: |
|
331 |
|
332 \snippet doc/src/snippets/qsvgwidget/main.cpp 0 |
|
333 |
|
334 For applications with more specialized requirements, the QSvgRenderer class |
|
335 provides more control over the way SVG drawings are rendered and animated. |
|
336 */ |