Wt provides a vector graphics painting system, which depending on the
browser support, uses inline SVG, inline VML, HTML5 <canvas> or a
raster image to paint the graphics.
The Wt API provides different classes that provide support for vector
graphics painting. To use the paint system, you need to specialize
WPaintedWidget and use a WPainter to paint the
contents of the widget inside its WPaintedWidget::paintEvent().
In addition, a PDF backend is included in the library, which can be used
to make a PDF version of a painting, or
to embed a painting in a PDF document.
To use inline SVG, you need to enable XHTML support in your configuration
file (wt_config.xml) by enabling send-xhtml-mimetype .
Vector graphics painting class
The painter class WPainter provides a vector graphics
interface for painting. It has to be used in conjunction with a
WPaintDevice, onto which it paints:
Use WSvgImage to render with SVG (Scalable Vector
Use WVmlImage to render with the VML pseudo-standard.
WSvgImage and WVmlImage are paint devices for rendering using native
vector graphics. The benefit of vector graphics is a lower bandwidth
usage compared to raster images; indepedent of the image size.
To start painting on a device, either pass the device through the
constructor, or use begin().
A typical use is to instantiate a WPainter from within a
specialized WPaintedWidget::paintEvent() implementation, to
paint on the given paint device, but you can also use a painter to paint
directly to a particular paint device of choice, for example to create
SVG, PDF or PNG images (as resources). A painted widget can dynamically
be updated as shown in the following example.
the current pen, which you can define with
the current brush, which you can define with
the current font, which you can define with
the current world transformation matrix, which you
can get with worldTransform(),
the clipping settings (See setClipping()
A particular state can be saved using save() and later restored
The painting system distinguishes between different coordinate types:
logical coordinates, and
Each coordinate type corresponds to a coordinate system:
The device coordinate system
ranges from (0, 0) in the top left corner of the device, to
device->width().toPixels(), device->height().toPixels() for
the bottom right corner.
The logical coordinate system
defines a coordinate system that may be chosen independent of the
geometry of the device, which is convenient to make abstraction of
the actual device size.
The local coordinate system
may be different from the logical coordinate system because of a
transformation (which you can set with translate(),
rotate(), and scale()).
Initially, the local coordinate system coincides with the logical
coordinate system, which coincides with the device coordinate system.
The device coordinates are defined in terms of pixels. Even though most
underlying devices are actual vector graphics formats, when used in
conjunction with a WPaintedWidget, these vector graphics are
rendered by the browser onto a pixel-based canvas (like the rest of the
user-interface). The coordinates are defined such that integer values
correspond to an imaginary raster which separates the individual pixels,
as in the figure below.
The device coordinate system for a 6x5 pixel device
As a consequence, to avoid anti-aliasing effects when drawing straight
lines of width one pixel, you will need to use vertices that indicate the
middle of a pixel to get a crisp one-pixel wide line, as shown in the
You can map logical coordinates onto device coordinates by setting a
viewPort() and a window(); this defines a viewPort
You can define how the current local coordinates map onto
logical coordinates by changing the world transformation using
translate(), rotate(), scale() and
The painter provides support for clipping using an arbitrary
WPainterPath. Please note that the WVmlImage
paint device only has limited support for clipping.
Besides the different transformation methods which you can apply to a
drawing (i.e. translate, rotate, and scale), there are also two other
methods which are indispensable once you start generating more complex
WPainter::save() to save the current painter state on a
WPainter::restore() to restore a painter state from the
The painter state that is saved is the current pen,
brush, font, shadow, transformation and clipping settings (See
Translate the origin
The method WPainter::translate() translates the origin of the
logical coordinate system to a new location relative to the current
logical coordinate system. It's a good practice to save the painter
state before doing any transformations because usually, it's easier to
call restore() compared to a reverse translation to return to
the oiginal state. In addition, if you're translating in a loop you might
end up missing a part of your drawing because it was drawn outside the
the paint device's edge.
Rotate to the paint device
The method WPainter::rotate() rotates the logical coordinate
system around its origin by an angle. The angle is specified in degrees,
and positive values are clockwise. Use this method to rotate an object
around its origin before it is drawn on the paint device.
Scale to the paint device
The method WPainter::scale() scales the logical coordinate
system around its origin, by a factor in the X and Y directions.
Use this method to scale what you draw on the paint device.
Reset the transformations
Use the method WPainter::resetTransform() to reset the current
transformation to the identity transformation matrix, so that the logical
coordinate system coincides with the device coordinate system.
One of the more fun features of WPainter is that you can
render one or more images on a painting using the method
drawImage(). Images can be used for dynamic photo compositing or
as a background for a drawing (e.g. with shapes, graphs, etc.).
An image is specified in terms of a URL, and the width and height.
An image can be drawn in different ways:
Draw an image at a starting point.
Draw a part of an image at a starting point.
Draw an image in a rectangle and scale it to the width and heigth of
Draw a part of an image in a rectangle and scale it to the width and
heigth of it.
Please note that the image can become blurry when scaling up or grainy
when scaling down too much.
In order to avoid server roundtrips, it's possible to change some of the
properties of a WPaintedWidget and redraw it entirely on the client side.
The interactive features of WCartesianChart use this
functionality, for example.