|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2010 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 \group painting |
|
44 \title Painting Classes |
|
45 \ingroup groups |
|
46 |
|
47 \brief Classes that provide support for painting. |
|
48 |
|
49 See also this introduction to the \link coordsys.html Qt |
|
50 coordinate system. \endlink |
|
51 */ |
|
52 |
|
53 /*! |
|
54 \group painting-3D |
|
55 \title Rendering in 3D |
|
56 \ingroup groups |
|
57 |
|
58 \brief Classes that provide support for rendering in 3D. |
|
59 */ |
|
60 |
|
61 /*! |
|
62 \page paintsystem.html |
|
63 \title The Paint System |
|
64 \ingroup frameworks-technologies |
|
65 |
|
66 Qt's paint system enables painting on screen and print devices |
|
67 using the same API, and is primarily based on the QPainter, |
|
68 QPaintDevice, and QPaintEngine classes. |
|
69 |
|
70 QPainter is used to perform drawing operations, QPaintDevice is an |
|
71 abstraction of a two-dimensional space that can be painted on |
|
72 using a QPainter, and QPaintEngine provides the interface that the |
|
73 painter uses to draw onto different types of devices. The |
|
74 QPaintEngine class is used internally by QPainter and |
|
75 QPaintDevice, and is hidden from application programmers unless |
|
76 they create their own device type. |
|
77 |
|
78 \image paintsystem-core.png |
|
79 |
|
80 The main benefit of this approach is that all painting follows the |
|
81 same painting pipeline making it easy to add support for new |
|
82 features and providing default implementations for unsupported |
|
83 ones. |
|
84 |
|
85 \section1 Topics |
|
86 \list |
|
87 \o \l{Classes for Painting} |
|
88 \o \l{Paint Devices and Backends} |
|
89 \o \l{Drawing and Filling} |
|
90 \o \l{The Coordinate System} |
|
91 \o \l{Reading and Writing Image Files} |
|
92 \o \l{Styling} |
|
93 \o \l{Printing with Qt} |
|
94 \endlist |
|
95 |
|
96 \section1 Classes for Painting |
|
97 |
|
98 These classes provide support for painting onto a paint device. |
|
99 |
|
100 \annotatedlist painting |
|
101 |
|
102 Alternatively, Qt provides the QtOpenGL module, offering classes |
|
103 that makes it easy to use OpenGL in Qt applications. Among others, |
|
104 the module provides an OpenGL widget class that can be used just |
|
105 like any other Qt widget, except that it opens an OpenGL display |
|
106 buffer where the OpenGL API can be used to render the contents. |
|
107 */ |
|
108 |
|
109 |
|
110 /*! |
|
111 \page paintsystem-devices.html |
|
112 \title Paint Devices and Backends |
|
113 |
|
114 \contentspage The Paint System |
|
115 \nextpage Drawing and Filling |
|
116 |
|
117 \section1 Creating a Paint Device |
|
118 |
|
119 The QPaintDevice class is the base class of objects that can be |
|
120 painted, i.e. QPainter can draw on any QPaintDevice |
|
121 subclass. QPaintDevice's drawing capabilities are currently |
|
122 implemented by the QWidget, QImage, QPixmap, QGLWidget, |
|
123 QGLPixelBuffer, QPicture and QPrinter subclasses. |
|
124 |
|
125 \image paintsystem-devices.png |
|
126 |
|
127 \table 100% |
|
128 \row \o \bold Widget |
|
129 |
|
130 The QWidget class is the base class of all user interface |
|
131 objects. The widget is the atom of the user interface: it receives |
|
132 mouse, keyboard and other events from the window system, and |
|
133 paints a representation of itself on the screen. |
|
134 |
|
135 \row \o \bold Image |
|
136 |
|
137 The QImage class provides a hardware-independent image |
|
138 representation which is designed and optimized for I/O, and for |
|
139 direct pixel access and manipulation. QImage supports several |
|
140 image formats including monochrome, 8-bit, 32-bit and |
|
141 alpha-blended images. |
|
142 |
|
143 One advantage of using QImage as a paint device is that it is |
|
144 possible to guarantee the pixel exactness of any drawing operation |
|
145 in a platform-independent way. Another benefit is that the |
|
146 painting can be performed in another thread than the current GUI |
|
147 thread. |
|
148 |
|
149 \row \o \bold Pixmap |
|
150 |
|
151 The QPixmap class is an off-screen image representation which is |
|
152 designed and optimized for showing images on screen. Unlike |
|
153 QImage, the pixel data in a pixmap is internal and is managed by |
|
154 the underlying window system, i.e. pixels can only be accessed |
|
155 through QPainter functions or by converting the QPixmap to a |
|
156 QImage. |
|
157 |
|
158 To optimize drawing with QPixmap, Qt provides the QPixmapCache |
|
159 class which can be used to store temporary pixmaps that are |
|
160 expensive to generate without using more storage space than the |
|
161 cache limit. |
|
162 |
|
163 Qt also provides the QBitmap convenience class, inheriting |
|
164 QPixmap. QBitmap guarantees monochrome (1-bit depth) pixmaps, and |
|
165 is mainly used for creating custom QCursor and QBrush objects, |
|
166 constructing QRegion objects, and for setting masks for pixmaps |
|
167 and widgets. |
|
168 |
|
169 \row \o \bold {OpenGL Widget} |
|
170 |
|
171 As mentioned previously, Qt provides the QtOpenGL module offering |
|
172 classes that makes it easy to use OpenGL in Qt applications. For |
|
173 example, the QGLWidget enables the OpenGL API for |
|
174 rendering. |
|
175 |
|
176 But QGLWidget is also a QWidget subclass, and can be used by |
|
177 QPainter as any other paint device. One huge benefit from this is |
|
178 that it enables Qt to utilize the high performance of OpenGL for |
|
179 most drawing operations, such as transformations and pixmap |
|
180 drawing. |
|
181 |
|
182 \row \o \bold {Pixel Buffer} |
|
183 |
|
184 The QtOpenGL module also provides the QGLPixelBuffer class which |
|
185 inherits QPaintDevice directly. |
|
186 |
|
187 QGLPixelBuffer encapsulates an OpenGL pbuffer. Rendering into a |
|
188 pbuffer is normally done using full hardware acceleration which |
|
189 can be significantly faster than rendering into a QPixmap. |
|
190 |
|
191 \row \o \bold {Framebuffer Object} |
|
192 |
|
193 The QtOpenGL module also provides the QGLFramebufferObject class |
|
194 which inherits QPaintDevice directly. |
|
195 |
|
196 QGLFramebufferObject encapsulates an OpenGL framebuffer object. |
|
197 Framebuffer objects can also be used for off-screen rendering, and |
|
198 offer several advantages over pixel buffers for this purpose. |
|
199 These are described in the QGLFramebufferObject class documentation. |
|
200 |
|
201 \row \o \bold {Picture} |
|
202 |
|
203 The QPicture class is a paint device that records and replays |
|
204 QPainter commands. A picture serializes painter commands to an IO |
|
205 device in a platform-independent format. QPicture is also |
|
206 resolution independent, i.e. a QPicture can be displayed on |
|
207 different devices (for example svg, pdf, ps, printer and screen) |
|
208 looking the same. |
|
209 |
|
210 Qt provides the QPicture::load() and QPicture::save() functions |
|
211 as well as streaming operators for loading and saving pictures. |
|
212 |
|
213 \row \o \bold {Printer} |
|
214 |
|
215 The QPrinter class is a paint device that paints on a printer. On |
|
216 Windows or Mac OS X, QPrinter uses the built-in printer |
|
217 drivers. On X11, QPrinter generates postscript and sends that to |
|
218 lpr, lp, or another print program. QPrinter can also print to any |
|
219 other QPrintEngine object. |
|
220 |
|
221 The QPrintEngine class defines an interface for how QPrinter |
|
222 interacts with a given printing subsystem. The common case when |
|
223 creating your own print engine, is to derive from both |
|
224 QPaintEngine and QPrintEngine. |
|
225 |
|
226 The output format is by default determined by the platform the |
|
227 printer is running on, but by explicitly setting the output format |
|
228 to QPrinter::PdfFormat, QPrinter will generate its output as a PDF |
|
229 file. |
|
230 |
|
231 \row \o \bold {Custom Backends} |
|
232 |
|
233 Support for a new backend can be implemented by deriving from the |
|
234 QPaintDevice class and reimplementing the virtual |
|
235 QPaintDevice::paintEngine() function to tell QPainter which paint |
|
236 engine should be used to draw on this particular device. To |
|
237 actually be able to draw on the device, this paint engine must be |
|
238 a custom paint engine created by deriving from the QPaintEngine |
|
239 class. |
|
240 |
|
241 \endtable |
|
242 |
|
243 \section1 Selecting the Painting Backend |
|
244 |
|
245 Since Qt 4.5, it is possible to replace the paint engines and paint |
|
246 devices used for widgets, pixmaps and the offscreen double buffer. By |
|
247 default the backends are: |
|
248 |
|
249 \table |
|
250 \row |
|
251 \o Windows |
|
252 \o Software Rasterizer |
|
253 \row |
|
254 \o X11 |
|
255 \o X11 |
|
256 \row |
|
257 \o Mac OS X |
|
258 \o CoreGraphics |
|
259 \row |
|
260 \o Embedded |
|
261 \o Software Rasterizer |
|
262 \endtable |
|
263 |
|
264 Passing a command line parameter to the application, such as, |
|
265 \c{-graphicssystem raster}, specifies that Qt should use the software |
|
266 rasterizer for this application. The Software rasterizer is fully |
|
267 supported on all platforms. |
|
268 |
|
269 \code |
|
270 > analogclock -graphicssystem raster |
|
271 \endcode |
|
272 |
|
273 There is also a \c{-graphicssystem opengl} mode that uses OpenGL for |
|
274 all drawing. Currently, this engine is experimental as it does not draw |
|
275 everything correctly. |
|
276 |
|
277 Qt also supports being configured using \c {-graphicssystem |
|
278 raster|opengl} in which case all applications will use the |
|
279 specified graphics system for its graphics. |
|
280 */ |
|
281 |
|
282 /*! |
|
283 \page paintsystem-drawing.html |
|
284 \title Drawing and Filling |
|
285 |
|
286 \previouspage Paint Devices and Backends |
|
287 \contentspage The Paint System |
|
288 \nextpage The Coordinate System |
|
289 |
|
290 \section1 Drawing |
|
291 |
|
292 QPainter provides highly optimized functions to do most of the |
|
293 drawing GUI programs require. It can draw everything from simple |
|
294 graphical primitives (represented by the QPoint, QLine, QRect, |
|
295 QRegion and QPolygon classes) to complex shapes like vector |
|
296 paths. In Qt vector paths are represented by the QPainterPath |
|
297 class. QPainterPath provides a container for painting operations, |
|
298 enabling graphical shapes to be constructed and reused. |
|
299 |
|
300 \table 100% |
|
301 \row |
|
302 \o \image paintsystem-painterpath.png |
|
303 \o \bold QPainterPath |
|
304 |
|
305 A painter path is an object composed of lines and curves. For |
|
306 example, a rectangle is composed by lines and an ellipse is |
|
307 composed by curves. |
|
308 |
|
309 The main advantage of painter paths over normal drawing operations |
|
310 is that complex shapes only need to be created once; then they can |
|
311 be drawn many times using only calls to the QPainter::drawPath() |
|
312 function. |
|
313 |
|
314 A QPainterPath object can be used for filling, outlining, and |
|
315 clipping. To generate fillable outlines for a given painter path, |
|
316 use the QPainterPathStroker class. |
|
317 |
|
318 \endtable |
|
319 |
|
320 Lines and outlines are drawn using the QPen class. A pen is |
|
321 defined by its style (i.e. its line-type), width, brush, how the |
|
322 endpoints are drawn (cap-style) and how joins between two |
|
323 connected lines are drawn (join-style). The pen's brush is a |
|
324 QBrush object used to fill strokes generated with the pen, |
|
325 i.e. the QBrush class defines the fill pattern. |
|
326 |
|
327 QPainter can also draw aligned text and pixmaps. |
|
328 |
|
329 When drawing text, the font is specified using the QFont class. Qt |
|
330 will use the font with the specified attributes, or if no matching |
|
331 font exists, Qt will use the closest matching installed font. The |
|
332 attributes of the font that is actually used can be retrieved |
|
333 using the QFontInfo class. In addition, the QFontMetrics class |
|
334 provides the font measurements, and the QFontDatabase class |
|
335 provides information about the fonts available in the underlying |
|
336 window system. |
|
337 |
|
338 Normally, QPainter draws in a "natural" coordinate system, but it |
|
339 is able to perform view and world transformations using the |
|
340 QTransform class. For more information, see \l {The Coordinate |
|
341 System} documentation which also describes the rendering process, |
|
342 i.e. the relation between the logical representation and the |
|
343 rendered pixels, and the benefits of anti-aliased painting. |
|
344 |
|
345 \table 100% |
|
346 \row \o |
|
347 \bold {Anti-Aliased Painting} |
|
348 |
|
349 When drawing, the pixel rendering is controlled by the |
|
350 QPainter::Antialiasing render hint. The QPainter::RenderHint enum |
|
351 is used to specify flags to QPainter that may or may not be |
|
352 respected by any given engine. |
|
353 |
|
354 The QPainter::Antialiasing value indicates that the engine should |
|
355 antialias edges of primitives if possible, i.e. smoothing the |
|
356 edges by using different color intensities. |
|
357 |
|
358 \o \image paintsystem-antialiasing.png |
|
359 |
|
360 \endtable |
|
361 |
|
362 \section1 Filling |
|
363 |
|
364 Shapes are filled using the QBrush class. A brush is defined |
|
365 by its color and its style (i.e. its fill pattern). |
|
366 |
|
367 Any color in Qt is represented by the QColor class which supports |
|
368 the RGB, HSV and CMYK color models. QColor also support |
|
369 alpha-blended outlining and filling (specifying the transparency |
|
370 effect), and the class is platform and device independent (the |
|
371 colors are mapped to hardware using the QColormap class). For more |
|
372 information, see the QColor class documentation. |
|
373 |
|
374 When creating a new widget, it is recommend to use the colors in |
|
375 the widget's palette rather than hard-coding specific colors. All |
|
376 widgets in Qt contain a palette and use their palette to draw |
|
377 themselves. A widget's palette is represented by the QPalette |
|
378 class which contains color groups for each widget state. |
|
379 |
|
380 The available fill patterns are described by the Qt::BrushStyle |
|
381 enum. These include basic patterns spanning from uniform color to |
|
382 very sparse pattern, various line combinations, gradient fills and |
|
383 textures. Qt provides the QGradient class to define custom |
|
384 gradient fills, while texture patterns are specified using the |
|
385 QPixmap class. |
|
386 |
|
387 \table 100% |
|
388 \row |
|
389 \o \image paintsystem-fancygradient.png |
|
390 \o \bold QGradient |
|
391 |
|
392 The QGradient class is used in combination with QBrush to specify |
|
393 gradient fills. |
|
394 |
|
395 \image paintsystem-gradients.png |
|
396 |
|
397 Qt currently supports three types of gradient fills: Linear |
|
398 gradients interpolate colors between start and end points, radial |
|
399 gradients interpolate colors between a focal point and end points |
|
400 on a circle surrounding it, and conical gradients interpolate |
|
401 colors around a center point. |
|
402 |
|
403 \endtable |
|
404 */ |
|
405 |
|
406 /*! |
|
407 \page paintsystem-images.html |
|
408 \title Reading and Writing Image Files |
|
409 |
|
410 \previouspage The Coordinate System |
|
411 \contentspage The Paint System |
|
412 \nextpage Styling |
|
413 |
|
414 The most common way to read images is through QImage and QPixmap's |
|
415 constructors, or by calling the QImage::load() and QPixmap::load() |
|
416 functions. In addition, Qt provides the QImageReader class which |
|
417 gives more control over the process. Depending on the underlying |
|
418 support in the image format, the functions provided by the class |
|
419 can save memory and speed up loading of images. |
|
420 |
|
421 Likewise, Qt provides the QImageWriter class which supports |
|
422 setting format specific options, such as the gamma level, |
|
423 compression level and quality, prior to storing the image. If you |
|
424 do not need such options, you can use QImage::save() or |
|
425 QPixmap::save() instead. |
|
426 |
|
427 \table 100% |
|
428 \row |
|
429 \o \bold QMovie |
|
430 |
|
431 QMovie is a convenience class for displaying animations, using the |
|
432 QImageReader class internally. Once created, the QMovie class |
|
433 provides various functions for both running and controlling the |
|
434 given animation. |
|
435 |
|
436 \o \image paintsystem-movie.png |
|
437 \endtable |
|
438 |
|
439 The QImageReader and QImageWriter classes rely on the |
|
440 QImageIOHandler class which is the common image I/O interface for |
|
441 all image formats in Qt. QImageIOHandler objects are used |
|
442 internally by QImageReader and QImageWriter to add support for |
|
443 different image formats to Qt. |
|
444 |
|
445 A list of the supported file formats are available through the |
|
446 QImageReader::supportedImageFormats() and |
|
447 QImageWriter::supportedImageFormats() functions. Qt supports |
|
448 several file formats by default, and in addition new formats can |
|
449 be added as plugins. The currently supported formats are listed in |
|
450 the QImageReader and QImageWriter class documentation. |
|
451 |
|
452 Qt's plugin mechanism can also be used to write a custom image |
|
453 format handler. This is done by deriving from the QImageIOHandler |
|
454 class, and creating a QImageIOPlugin object which is a factory for |
|
455 creating QImageIOHandler objects. When the plugin is installed, |
|
456 QImageReader and QImageWriter will automatically load the plugin |
|
457 and start using it. |
|
458 |
|
459 \section1 Rendering SVG files |
|
460 |
|
461 \table 100% |
|
462 \row |
|
463 \o \image paintsystem-svg.png |
|
464 \o \bold {SVG Rendering} |
|
465 |
|
466 Scalable Vector Graphics (SVG) is a language for describing two-dimensional |
|
467 graphics and graphical applications in XML. SVG 1.1 is a W3C Recommendation |
|
468 and forms the core of the current SVG developments in Qt. SVG 1.2 is the |
|
469 specification currently being developed by the \l{SVG Working Group}, and it |
|
470 is \l{http://www.w3.org/TR/SVG12/}{available in draft form}. |
|
471 The \l{Mobile SVG Profiles} (SVG Basic and SVG Tiny) are aimed at |
|
472 resource-limited devices and are part of the 3GPP platform for third generation |
|
473 mobile phones. You can read more about SVG at \l{About SVG}. |
|
474 |
|
475 Qt supports the \l{SVG 1.2 Tiny Static Features}{static features} of |
|
476 \l{SVG 1.2 Tiny}. ECMA scripts and DOM manipulation are currently not |
|
477 supported. |
|
478 |
|
479 SVG drawings can be rendered onto any QPaintDevice subclass. This |
|
480 approach gives developers the flexibility to experiment, in order |
|
481 to find the best solution for each application. |
|
482 |
|
483 The easiest way to render SVG files is to construct a QSvgWidget and |
|
484 load an SVG file using one of the QSvgWidget::load() functions. |
|
485 |
|
486 QSvgRenderer is the class responsible for rendering SVG files for |
|
487 QSvgWidget, and it can be used directly to provide SVG support for |
|
488 custom widgets. |
|
489 To load an SVG file, construct a QSvgRenderer with a file name or the |
|
490 contents of a file, or call QSvgRenderer::load() on an existing |
|
491 renderer. If the SVG file has been loaded successfully the |
|
492 QSvgRenderer::isValid() will return true. |
|
493 |
|
494 Once you have loaded the SVG file successfully, you can render it |
|
495 with the QSvgRenderer::render() function. Note that this scheme allows |
|
496 you to render SVG files on all paint devices supported by Qt, including |
|
497 QWidget, QGLWidget, and QImage. See the \l{SVG Viewer Example}{SVG Viewer} |
|
498 example for more details. |
|
499 |
|
500 \endtable |
|
501 */ |
|
502 |
|
503 /*! |
|
504 \page paintsystem-styling.html |
|
505 \title Styling |
|
506 |
|
507 \previouspage Reading and Writing Image Files |
|
508 \contentspage The Paint System |
|
509 \nextpage Printing with Qt |
|
510 |
|
511 Qt's built-in widgets use the QStyle class to perform nearly all |
|
512 of their drawing. QStyle is an abstract base class that |
|
513 encapsulates the look and feel of a GUI, and can be used to make |
|
514 the widgets look exactly like the equivalent native widgets or to |
|
515 give the widgets a custom look. |
|
516 |
|
517 Qt provides a set of QStyle subclasses that emulate the native |
|
518 look of the different platforms supported by Qt (QWindowsStyle, |
|
519 QMacStyle, QMotifStyle, etc.). These styles are built into the |
|
520 QtGui library, other styles can be made available using Qt's |
|
521 plugin mechansim. |
|
522 |
|
523 Most functions for drawing style elements take four arguments: |
|
524 |
|
525 \list |
|
526 \o an enum value specifying which graphical element to draw |
|
527 \o a QStyleOption object specifying how and where to render that element |
|
528 \o a QPainter object that should be used to draw the element |
|
529 \o a QWidget object on which the drawing is performed (optional) |
|
530 \endlist |
|
531 |
|
532 The style gets all the information it needs to render the |
|
533 graphical element from the QStyleOption class. The widget is |
|
534 passed as the last argument in case the style needs it to perform |
|
535 special effects (such as animated default buttons on Mac OS X), |
|
536 but it isn't mandatory. In fact, QStyle can be used to draw on any |
|
537 paint device (not just widgets), in which case the widget argument |
|
538 is a zero pointer. |
|
539 |
|
540 \image paintsystem-stylepainter.png |
|
541 |
|
542 The paint system also provides the QStylePainter class inheriting |
|
543 from QPainter. QStylePainter is a convenience class for drawing |
|
544 QStyle elements inside a widget, and extends QPainter with a set |
|
545 of high-level drawing functions implemented on top of QStyle's |
|
546 API. The advantage of using QStylePainter is that the parameter |
|
547 lists get considerably shorter. |
|
548 |
|
549 \table 100% |
|
550 \row |
|
551 \o \inlineimage paintsystem-icon.png |
|
552 \o \bold QIcon |
|
553 |
|
554 The QIcon class provides scalable icons in different modes and states. |
|
555 |
|
556 QIcon can generate pixmaps reflecting an icon's state, mode and |
|
557 size. These pixmaps are generated from the set of pixmaps |
|
558 made available to the icon, and are used by Qt widgets to show an |
|
559 icon representing a particular action. |
|
560 |
|
561 The rendering of a QIcon object is handled by the QIconEngine |
|
562 class. Each icon has a corresponding icon engine that is |
|
563 responsible for drawing the icon with a requested size, mode and |
|
564 state. |
|
565 |
|
566 \endtable |
|
567 |
|
568 For more information about widget styling and appearance, see the |
|
569 documentation about \l{Implementing Styles and Style Aware Widgets}. |
|
570 */ |