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