doc/src/painting-and-printing/coordsys.qdoc
branchRCL_3
changeset 8 3f74d0d4af4c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/src/painting-and-printing/coordsys.qdoc	Thu Apr 08 14:19:33 2010 +0300
@@ -0,0 +1,477 @@
+/****************************************************************************
+**
+** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+    \page coordsys.html
+    \title The Coordinate System
+    \brief Information about the coordinate system used by the paint
+    system.
+
+    \previouspage Drawing and Filling
+    \contentspage The Paint System
+    \nextpage Reading and Writing Image Files
+
+    The coordinate system is controlled by the QPainter
+    class. Together with the QPaintDevice and QPaintEngine classes,
+    QPainter form the basis of Qt's painting system, Arthur. QPainter
+    is used to perform drawing operations, QPaintDevice is an
+    abstraction of a two-dimensional space that can be painted on
+    using a QPainter, and QPaintEngine provides the interface that the
+    painter uses to draw onto different types of devices.
+
+    The QPaintDevice class is the base class of objects that can be
+    painted: Its drawing capabilities are inherited by the QWidget,
+    QPixmap, QPicture, QImage, and QPrinter classes. The default
+    coordinate system of a paint device has its origin at the top-left
+    corner. The \e x values increase to the right and the \e y values
+    increase downwards. The default unit is one pixel on pixel-based
+    devices and one point (1/72 of an inch) on printers.
+
+    The mapping of the logical QPainter coordinates to the physical
+    QPaintDevice coordinates are handled by QPainter's transformation
+    matrix, viewport and "window". The logical and physical coordinate
+    systems coincide by default. QPainter also supports coordinate
+    transformations (e.g. rotation and scaling).
+
+    \tableofcontents
+
+    \section1 Rendering
+
+    \section2 Logical Representation
+
+    The size (width and height) of a graphics primitive always
+    correspond to its mathematical model, ignoring the width of the
+    pen it is rendered with:
+
+    \table
+    \row
+    \o \inlineimage coordinatesystem-rect.png
+    \o \inlineimage coordinatesystem-line.png
+    \row
+    \o QRect(1, 2, 6, 4)
+    \o QLine(2, 7, 6, 1)
+    \endtable
+
+    \section2 Aliased Painting
+
+    When drawing, the pixel rendering is controlled by the
+    QPainter::Antialiasing render hint.
+
+    The \l {QPainter::RenderHint}{RenderHint} enum is used to specify
+    flags to QPainter that may or may not be respected by any given
+    engine. The QPainter::Antialiasing value indicates that the engine
+    should antialias edges of primitives if possible, i.e. smoothing
+    the edges by using different color intensities.
+
+    But by default the painter is \e aliased and other rules apply:
+    When rendering with a one pixel wide pen the pixels will be
+    rendered to the \e {right and below the mathematically defined
+    points}. For example:
+
+    \table
+    \row
+    \o \inlineimage coordinatesystem-rect-raster.png
+    \o \inlineimage coordinatesystem-line-raster.png
+
+    \row
+    \o
+    \snippet doc/src/snippets/code/doc_src_coordsys.qdoc 0
+
+    \o
+    \snippet doc/src/snippets/code/doc_src_coordsys.qdoc 1
+    \endtable
+
+    When rendering with a pen with an even number of pixels, the
+    pixels will be rendered symetrically around the mathematical
+    defined points, while rendering with a pen with an odd number of
+    pixels, the spare pixel will be rendered to the right and below
+    the mathematical point as in the one pixel case. See the QRectF
+    diagrams below for concrete examples.
+
+    \table
+    \header
+    \o {3,1} QRectF
+    \row
+    \o \inlineimage qrect-diagram-zero.png
+    \o \inlineimage qrectf-diagram-one.png
+    \row
+    \o Logical representation
+    \o One pixel wide pen
+    \row
+    \o \inlineimage qrectf-diagram-two.png
+    \o \inlineimage qrectf-diagram-three.png
+    \row
+    \o Two pixel wide pen
+    \o Three pixel wide pen
+    \endtable
+
+    Note that for historical reasons the return value of the
+    QRect::right() and QRect::bottom() functions deviate from the true
+    bottom-right corner of the rectangle.
+
+    QRect's \l {QRect::right()}{right()} function returns \l
+    {QRect::left()}{left()} + \l {QRect::width()}{width()} - 1 and the
+    \l {QRect::bottom()}{bottom()} function returns \l
+    {QRect::top()}{top()} + \l {QRect::height()}{height()} - 1.  The
+    bottom-right green point in the diagrams shows the return
+    coordinates of these functions.
+
+    We recommend that you simply use QRectF instead: The QRectF class
+    defines a rectangle in the plane using floating point coordinates
+    for accuracy (QRect uses integer coordinates), and the
+    QRectF::right() and QRectF::bottom() functions \e do return the
+    true bottom-right corner.
+
+    Alternatively, using QRect, apply \l {QRect::x()}{x()} + \l
+    {QRect::width()}{width()} and \l {QRect::y()}{y()} + \l
+    {QRect::height()}{height()} to find the bottom-right corner, and
+    avoid the \l {QRect::right()}{right()} and \l
+    {QRect::bottom()}{bottom()} functions.
+
+    \section2 Anti-aliased Painting
+
+    If you set QPainter's \l {QPainter::Antialiasing}{anti-aliasing}
+    render hint, the pixels will be rendered symetrically on both
+    sides of the mathematically defined points:
+
+    \table
+    \row
+    \o \inlineimage coordinatesystem-rect-antialias.png
+    \o \inlineimage coordinatesystem-line-antialias.png
+    \row
+    \o
+
+    \snippet doc/src/snippets/code/doc_src_coordsys.qdoc 2
+
+    \o
+    \snippet doc/src/snippets/code/doc_src_coordsys.qdoc 3
+    \endtable
+
+    \section1 Transformations
+
+    By default, the QPainter operates on the associated device's own
+    coordinate system, but it also has complete support for affine
+    coordinate transformations.
+
+    You can scale the coordinate system by a given offset using the
+    QPainter::scale() function, you can rotate it clockwise using the
+    QPainter::rotate() function and you can translate it (i.e. adding
+    a given offset to the points) using the QPainter::translate()
+    function.
+
+    \table
+    \row
+    \o \inlineimage qpainter-clock.png
+    \o \inlineimage qpainter-rotation.png
+    \o \inlineimage qpainter-scale.png
+    \o \inlineimage qpainter-translation.png
+    \row
+    \o nop
+    \o \l {QPainter::rotate()}{rotate()}
+    \o \l {QPainter::scale()}{scale()}
+    \o \l {QPainter::translate()}{translate()}
+    \endtable
+
+    You can also twist the coordinate system around the origin using
+    the QPainter::shear() function. See the \l {demos/affine}{Affine
+    Transformations} demo for a visualization of a sheared coordinate
+    system. All the transformation operations operate on QPainter's
+    transformation matrix that you can retrieve using the
+    QPainter::worldTransform() function. A matrix transforms a point
+    in the plane to another point.
+
+    If you need the same transformations over and over, you can also
+    use QTransform objects and the QPainter::worldTransform() and
+    QPainter::setWorldTransform() functions. You can at any time save the
+    QPainter's transformation matrix by calling the QPainter::save()
+    function which saves the matrix on an internal stack. The
+    QPainter::restore() function pops it back.
+
+    One frequent need for the transformation matrix is when reusing
+    the same drawing code on a variety of paint devices. Without
+    transformations, the results are tightly bound to the resolution
+    of the paint device. Printers have high resolution, e.g. 600 dots
+    per inch, whereas screens often have between 72 and 100 dots per
+    inch.
+
+    \table 100%
+    \header
+    \o {2,1} Analog Clock Example
+    \row
+    \o \inlineimage coordinatesystem-analogclock.png
+    \o
+    The Analog Clock example shows how to draw the contents of a
+    custom widget using QPainter's transformation matrix.
+
+    Qt's example directory provides a complete walk-through of the
+    example. Here, we will only review the example's \l
+    {QWidget::paintEvent()}{paintEvent()} function to see how we can
+    use the transformation matrix (i.e. QPainter's matrix functions)
+    to draw the clock's face.
+
+    We recommend compiling and running this example before you read
+    any further. In particular, try resizing the window to different
+    sizes.
+
+    \row
+    \o {2,1}
+
+    \snippet examples/widgets/analogclock/analogclock.cpp 9
+
+    First, we set up the painter. We translate the coordinate system
+    so that point (0, 0) is in the widget's center, instead of being
+    at the top-left corner. We also scale the system by \c side / 100,
+    where \c side is either the widget's width or the height,
+    whichever is shortest. We want the clock to be square, even if the
+    device isn't.
+
+    This will give us a 200 x 200 square area, with the origin (0, 0)
+    in the center, that we can draw on. What we draw will show up in
+    the largest possible square that will fit in the widget.
+
+    See also the \l {Window-Viewport Conversion} section.
+
+    \snippet examples/widgets/analogclock/analogclock.cpp 18
+
+    We draw the clock's hour hand by rotating the coordinate system
+    and calling QPainter::drawConvexPolygon(). Thank's to the
+    rotation, it's drawn pointed in the right direction.
+
+    The polygon is specified as an array of alternating \e x, \e y
+    values, stored in the \c hourHand static variable (defined at the
+    beginning of the function), which corresponds to the four points
+    (2, 0), (0, 2), (-2, 0), and (0, -25).
+
+    The calls to QPainter::save() and QPainter::restore() surrounding
+    the code guarantees that the code that follows won't be disturbed
+    by the transformations we've used.
+
+    \snippet examples/widgets/analogclock/analogclock.cpp 24
+
+    We do the same for the clock's minute hand, which is defined by
+    the four points (1, 0), (0, 1), (-1, 0), and (0, -40). These
+    coordinates specify a hand that is thinner and longer than the
+    minute hand.
+
+    \snippet examples/widgets/analogclock/analogclock.cpp 27
+
+    Finally, we draw the clock face, which consists of twelve short
+    lines at 30-degree intervals. At the end of that, the painter is
+    rotated in a way which isn't very useful, but we're done with
+    painting so that doesn't matter.
+    \endtable
+
+    For a demonstation of Qt's ability to perform affine
+    transformations on painting operations, see the \l
+    {demos/affine}{Affine Transformations} demo which allows the user
+    to experiment with the transformation operations.  See also the \l
+    {painting/transformations}{Transformations} example which shows
+    how transformations influence the way that QPainter renders
+    graphics primitives. In particular, it shows how the order of
+    transformations affects the result.
+
+    For more information about the transformation matrix, see the
+    QTransform documentation.
+
+    \section1 Window-Viewport Conversion
+
+    When drawing with QPainter, we specify points using logical
+    coordinates which then are converted into the physical coordinates
+    of the paint device.
+
+    The mapping of the logical coordinates to the physical coordinates
+    are handled by QPainter's world transformation \l
+    {QPainter::worldTransform()}{worldTransform()} (described in the \l
+    Transformations section), and QPainter's \l
+    {QPainter::viewport()}{viewport()} and \l
+    {QPainter::window()}{window()}.  The viewport represents the
+    physical coordinates specifying an arbitrary rectangle. The
+    "window" describes the same rectangle in logical coordinates. By
+    default the logical and physical coordinate systems coincide, and
+    are equivalent to the paint device's rectangle.
+
+    Using window-viewport conversion you can make the logical
+    coordinate system fit your preferences. The mechanism can also be
+    used to make the drawing code independent of the paint device. You
+    can, for example, make the logical coordinates extend from (-50,
+    -50) to (50, 50) with (0, 0) in the center by calling the
+    QPainter::setWindow() function:
+
+    \snippet doc/src/snippets/code/doc_src_coordsys.qdoc 4
+
+    Now, the logical coordinates (-50,-50) correspond to the paint
+    device's physical coordinates (0, 0). Independent of the paint
+    device, your painting code will always operate on the specified
+    logical coordinates.
+
+    By setting the "window" or viewport rectangle, you perform a
+    linear transformation of the coordinates. Note that each corner of
+    the "window" maps to the corresponding corner of the viewport, and
+    vice versa. For that reason it normally is a good idea to let the
+    viewport and "window" maintain the same aspect ratio to prevent
+    deformation:
+
+    \snippet doc/src/snippets/code/doc_src_coordsys.qdoc 5
+
+    If we make the logical coordinate system a square, we should also
+    make the viewport a square using the QPainter::setViewport()
+    function. In the example above we make it equivalent to the
+    largest square that fit into the paint device's rectangle. By
+    taking the paint device's size into consideration when setting the
+    window or viewport, it is possible to keep the drawing code
+    independent of the paint device.
+
+    Note that the window-viewport conversion is only a linear
+    transformation, i.e. it does not perform clipping. This means that
+    if you paint outside the currently set "window", your painting is
+    still transformed to the viewport using the same linear algebraic
+    approach.
+
+    \image coordinatesystem-transformations.png
+
+    The viewport, "window" and transformation matrix determine how
+    logical QPainter coordinates map to the paint device's physical
+    coordinates. By default the world transformation matrix is the
+    identity matrix, and the "window" and viewport settings are
+    equivalent to the paint device's settings, i.e. the world,
+    "window" and device coordinate systems are equivalent, but as we
+    have seen, the systems can be manipulated using transformation
+    operations and window-viewport conversion. The illustration above
+    describes the process.
+
+    \omit
+    \section1 Related Classes
+
+    Qt's paint system, Arthur, is primarily based on the QPainter,
+    QPaintDevice, and QPaintEngine classes:
+
+    \table
+    \header \o Class \o Description
+    \row
+    \o QPainter
+    \o
+    The QPainter class performs low-level painting on widgets and
+    other paint devices.  QPainter can operate on any object that
+    inherits the QPaintDevice class, using the same code.
+    \row
+    \o QPaintDevice
+    \o
+    The QPaintDevice class is the base class of objects that can be
+    painted. Qt provides several devices: QWidget, QImage, QPixmap,
+    QPrinter and QPicture, and other devices can also be defined by
+    subclassing QPaintDevice.
+    \row
+    \o QPaintEngine
+    \o
+    The QPaintEngine class provides an abstract definition of how
+    QPainter draws to a given device on a given platform.  Qt 4
+    provides several premade implementations of QPaintEngine for the
+    different painter backends we support; it provides one paint
+    engine for each supported window system and painting
+    frameworkt. You normally don't need to use this class directly.
+    \endtable
+
+    The 2D transformations of the coordinate system are specified
+    using the QTransform class:
+
+    \table
+    \header \o Class \o Description
+    \row
+    \o QTransform
+    \o
+    A 3 x 3 transformation matrix. Use QTransform to rotate, shear,
+    scale, or translate the coordinate system.
+    \endtable
+
+    In addition Qt provides several graphics primitive classes. Some
+    of these classes exist in two versions: an \c{int}-based version
+    and a \c{qreal}-based version. For these, the \c qreal version's
+    name is suffixed with an \c F.
+
+    \table
+    \header \o Class \o Description
+    \row
+    \o \l{QPoint}(\l{QPointF}{F})
+    \o
+    A single 2D point in the coordinate system. Most functions in Qt
+    that deal with points can accept either a QPoint, a QPointF, two
+    \c{int}s, or two \c{qreal}s.
+    \row
+    \o \l{QSize}(\l{QSizeF}{F})
+    \o
+    A single 2D vector. Internally, QPoint and QSize are the same, but
+    a point is not the same as a size, so both classes exist.  Again,
+    most functions accept either QSizeF, a QSize, two \c{int}s, or two
+    \c{qreal}s.
+    \row
+    \o \l{QRect}(\l{QRectF}{F})
+    \o
+    A 2D rectangle. Most functions accept either a QRectF, a QRect,
+    four \c{int}s, or four \c {qreal}s.
+    \row
+    \o \l{QLine}(\l{QLineF}{F})
+    \o
+    A 2D finite-length line, characterized by a start point and an end
+    point.
+    \row
+    \o \l{QPolygon}(\l{QPolygonF}{F})
+    \o
+    A 2D polygon. A polygon is a vector of \c{QPoint(F)}s. If the
+    first and last points are the same, the polygon is closed.
+    \row
+    \o QPainterPath
+    \o
+    A vectorial specification of a 2D shape. Painter paths are the
+    ultimate painting primitive, in the sense that any shape
+    (rectange, ellipse, spline) or combination of shapes can be
+    expressed as a path. A path specifies both an outline and an area.
+    \row
+    \o QRegion
+    \o
+    An area in a paint device, expressed as a list of
+    \l{QRect}s. In general, we recommend using the vectorial
+    QPainterPath class instead of QRegion for specifying areas,
+    because QPainterPath handles painter transformations much better.
+    \endtable
+    \endomit
+
+    \sa {Analog Clock Example}, {Transformations Example}
+*/