[cairo] Transformations usage
Daniele Dario
d.dario76 at gmail.com
Wed Dec 6 10:46:26 UTC 2017
Hello everyone,
I'm trying to create my own widget on GTK+ to display a clip of a 2D
map where I placed some polygons. The point of view can be moved inside
the map and may rotate.
The main idea is that I draw the map on a cairo_surface_t once and than
on expose event I use coordinates of POV to center the device surface
to paint on the map, rotate the map, scale, clip and paint.
To start I tried to use a transformation matrix to be able to draw
using native coordinates on a surface but I'm getting confused on how
transformation affects drawing.
At the end of the code below I expect to have a map painted on the
surface. In order to paint it on the widget I'd need another
transformation because:
- map size in the example is 165x165 and scale is 1 pixel = 1 [m]
- widget will have a different ratio
Can someone point me out on some examples or with some hint on how to
achieve what I'm looking for?
Thanks in advance,
Daniele.
/*
* Create a surface for the map:
* - 1 pixel = 1 [m]
* - assume map width >= height
* - coordinates of polygons are relative to an
* arbitrary origin placed at
* O = (x = height/2, y = height/2)
*/
gint site_width = 165;
gint site_height = 165;
cairo_surface_t *map = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
site_width, site_height);
/* Origin coordinates are relative */
gdouble offset = site_height / 2.;
/* Create a context to draw on the surface */
cr = cairo_create (map);
/*
* FIXME: Need a transformation in order to use
* coordinates relative to O:
* - x axis is correct just needs translation of offset
* - y axis is inverse and needs translation of offset
*/
cairo_matrix_t mat;
cairo_matrix_init (&mat, 1.0, 0.0, 0.0, -1.0, offset, offset);
cairo_transform (cr, &mat);
/* TODO: draw all objects on the map */
/* Array of (x,y) coordinates to represent a polygon */
GtkScuiPoint v1 [4] = {
{ -20., -40.},
{ -20., 0.},
{ -50., 0.},
{ -50., -40.}
};
//cairo_set_line_width (cr, 0.1);
cairo_set_source_rgba (cr, 1., 0., 0., .7);
/* Wrapper to draw and fill polygon */
scui_cairo_draw_polygon (cr, TRUE, v1, 4);
GtkScuiPoint v2 [4] = {
{ 40., 0.},
{ 40., 20.},
{ 20., 20.},
{ 20., 0.}
};
cairo_set_source_rgba (cr, 0., 0., 1., .7);
/* Wrapper to draw an empty polygon */
scui_cairo_draw_polygon (cr, FALSE, v2, 4);
/* TODO: Store surface to avoid re-painting it */
/* Destroy context */
cairo_destroy (cr);
More information about the cairo
mailing list