Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cairo flips a drawing

Tags:

c++

cairo

I want to draw a triangle and text using C++ and Cairo like this:

|\
| \
|PP\
|___\

If I add the triangle and the text using Cairo I get:

 ___
|   /
|PP/
| /
|/

So the y-axis is from top to bottom, but I want it from bottom to top. So I tried to changed the viewpoint matrix (cairo_transform(p, &mat);) or scale the data (cairo_scale(p, 1.0, -1.0);). I get:

|\
| \
|bb\
|___\

Now the triangle is the way I want it BUT the TEXT is MIRRORED, which I do not want to be mirrored.

Any idea how to handle this problem?

like image 269
user3144699 Avatar asked Nov 29 '25 07:11

user3144699


1 Answers

I was in a similar situation as the OP that required me to change a variety of coordinates in the cartesian coordinate system with the origin at the bottom left. (I had to port an old video game that was developed with a coordinate system different from Cairo's, and because of time constraints/possible calculation mistakes/port precision I decided it was better to not rewrite the whole bunch) Luckily, I found an okay approach to change Cairo's coordinate system. The approach is based around Cairo's internal transformation matrix, that transforms Cairo's input to the user device. The solution was to change this matrix to a reflection matrix, a matrix that mirrors it's input through the x-axis, like so:

cairo_t *cr;
cairo_matrix_t x_reflection_matrix; 
cairo_matrix_init_identity(&x_reflection_matrix); // could not find a oneliner
/* reflection through the x axis equals the identity matrix with the bottom 
left value negated  */
x_reflection_matrix.yy = -1.0;
cairo_set_matrix(cr, &x_reflection_matrix);
// This would result in your drawing being done on top of the destination 
// surface, so we translate the surface down the full height
cairo_translate(cr, 0, SURFACE_HEIGHT); // replace SURFACE_HEIGHT
// ... do your drawing

There is one catch however: text will also get mirrored. To solve this, one could alter the font transformation matrix. The required code for this would be:

cairo_matrix_t font_reflection_matrix;
// We first set the size, and then change it to a reflection matrix
cairo_set_font_size(cr, YOUR_SIZE);
cairo_get_font_matrix(cr, &font_reflection_matrix);
// reverse mirror the font drawing matrix
font_reflection_matrix.yy = font_reflection_matrix.yy * -1;
cairo_set_font_matrix(cr, &font_reflection_matrix);
like image 199
rien333 Avatar answered Dec 01 '25 19:12

rien333