|
Many of the features of the canvas are implemented via
translations between different coordinate systems. Canvas
items can be moved, rotated, or scaled via affine transformations, described in more
detail below. (Short version: an affine transformation is
a way to convert from one coordinate system to another.)
Here are the important coordinate systems which come up
when using the canvas and writing custom canvas items:
-
World coordinates are an
absolute coordinate system; i.e., the same world
coordinate refers to the same place on the canvas in
all cases. World coordinates are conceptually
infinite and are represented by a double. World coordinates are the
real, toplevel, untransformed, canonical coordinate
system. Consistent with the X Window System and GDK,
Y coordinates increase as they move downward, so lower Y coordinates are
toward the top of the canvas.
-
Item coordinates are the
coordinates used by a particular canvas item. Item
coordinates exist because each canvas item has an
affine transformation associated with it. In the case
of GnomeCanvasGroup,
this transformation is applied to the group's
children. To convert from world coordinates to item
coordinates for some particular item, you apply the
transform for each canvas group in the item's
ancestry, starting with the root canvas group; then
you apply the item's own transform. (Don't worry,
Gnome comes with a function to do this for you.) Like
world coordinates, item coordinates are conceptually
infinite.
-
Canvas coordinates are pixel
coordinates. While item and world coordinates are
floating-point numbers, canvas pixel coordinates are
integers. To use the canvas, you must specify a
"scroll region," which is the rectangle in world
coordinate space you want the user to be able to see.
Canvas pixel coordinates are relative to this
rectangle. Canvas pixel coordinates also take into
account a scaling factor representing the number of
pixels per world coordinate unit. To convert from
world coordinates to canvas coordinates, the canvas
subtracts the X and Y coordinates of the scroll
region, multiplies by the scaling factor, and then
rounds to an integer. Thus,
(0,0) in canvas coordinates will be the top left
corner of the scroll region.
-
Buffer coordinates are
canvas coordinates modified by some offset. Item
implementations use these during rendering. The
canvas passes the item implementation a buffer (which
is either a
GdkDrawable or an RGB buffer, depending on the
canvas mode). The canvas tells the item
implementation which region of the screen the buffer
represents---the buffer region is defined by an X
offset, Y offset, width and height. The X and Y
offsets are in canvas coordinates, and are equivalent
to (0,0) in buffer
coordinates. To convert from canvas coordinates to
buffer coordinates, simply subtract the offset.
Buffer coordinates are only valid from (0,0) to the maximum width and
height of the buffer.
-
Window coordinates are
rarely used. The canvas eventually copies each
temporary buffer to a
GdkWindow (to be precise,it copies them to
GTK_LAYOUT(canvas)->bin_window). Window
coordinates are relative to this GdkWindow. In some rare cases you
might want to draw to the window directly rather than
using a canvas item, or you might want to respond to
an event on the window (such as a drag-and-drop).
Then you need to convert from window coordinates to
one of the other coordinate systems.
When using preexisting canvas items, you will mostly be
interested in world and item coordinates. When writing
your own items, you will also need to use canvas and
buffer coordinates.
There are two ways to convert between the various
coordinate systems; one way is to obtain and use affines
directly---this is described in the next section. The
easy way is to use one of the convenience functions
provided for the purpose, shown in Figure 2. Conversion
between canvas and item coordinates requires you to
convert to world coordinates first as an intermediate
step. There is no function to convert to or from buffer
coordinates, because this is a simple matter of
subtracting the buffer offsets from the canvas
coordinates (canvas to buffer), or adding the buffer
offsets to the buffer coordinates (buffer to canvas).
|
|