crcanvas: A GTK/Cairo Canvas Widget
This is based on libfoocanvas from Gnome CVS; however, it differs in the
The canvas widget has a built in scaling and panning model. It provides
property settings for "maintain center", "maintain aspect", "auto scale", and
infinite scrolling. Additionally it provides a complete set of zooming and
The intent of this widget is to allow more flexibility than the traditional
GtkLayout. The GtkLayout offers hook-ups for horizontal and vertical scrolling.
The CrCanvas widget still supports the GtkAdjustment handles, but it's viewport
coordinates are based on an Cairo affine transformation matrix, so it should be
possible to design controls that are different from the usual scrollbars.
It is trivial to design custom canvas items. In the simplest case for an
item that is based on cairo_path_t, it is necessary only to define a
"make_path"method from the CrPath. A slightly more complicated use requires
redefining methods from the CrItem for "paint", "calculate_bounds", and "test".
Nothing more is required. The methods need not be defined as part of a derived
class, they can be defined as signal handlers connected to an instance of the
The circular dependency between the canvas widget and the canvas item has
been eliminated. The items are not aware of what type of device or how many
devices to which they are rendering. The items communicate up the tree
via GObject signal emissions.
Each canvas item can send invalidate signals on its item coordinate space,
the device coordinate space, or a combination of both. Some use cases for this
feature include: A canvas item that has a label that does not change scale when
the canvas is zoomed in, or a plot that has an arrow pointing to an interesting
feature. When the canvas is zoomed in the feature gets bigger, but the arrow
pointing to the feature does not.
The canvas widget emits a "before paint" signal during its
expose logic. Using this signal to call a clipping or rejection technique can
significantly improve performance when the canvas is zoomed-in. It is
possible to request updates from any item during the "before paint" emission
or just prior to the expose event without triggering multiple re-paints.
A repaint mode allows for all items to be repainted regardless of which ones
requested updates. It avoids running the calculate bounds sequence. This is
useful when you need to continuously repaint for several cycles and want to
avoid the cost of the canvas update loop until the repaint cycles are complete.
The profiling I have done so far indicates this causes the repaint to occur
15-20% faster when N-items > 1000.
The CrBlit grouping item can, in some cases, significantly improve performance.
It groups any arbitrary item tree into an offscreen memory surface. The memory
surface is then painted to the screen in a single operation. It should be used
in cases where the CPU time needed to paint the item tree to the screen is
greater than then frequency at which the tree needs to be repainted.
(Warning: This item is buggy at the moment. It works perfectly on some
hardware and seems to work unpredictably on other hardware.)
The package comes with Python bindings, unit tests,
and 7 example programs that demonstrate the capabilities
The "event" signal parameter list has been changed around. Any application
written prior to release 0.11 will need minor modifications to run properly.
See the NEWS file in the source distribution for more information.
The current release takes advantage of some API additions in cairo 1.2.
Therefore, cairo 1.2 is required. If you have a not-so-recent distribution, it
may be possible to install cairo 1.2.4 into /usr/local and compile this way.
The python binding for this release requires pycairo 1.2 or greater
due to some minor API changes in pycairo.
For questions or comments, please post to the mailing list:
For bug reports look
Download the latest crcanvas
Read the API Reference.
View an example C application from the package.
View an example Python application from the package.