[cairo] How to get extents of transformed graphics

Andreas Falkenhahn andreas at falkenhahn.com
Thu Sep 8 16:22:40 UTC 2022


Is there really nobody who knows how to solve this? There surely must be a way to find out the *exact* extents of transformed graphics? The idea is to find out the exact dimensions in order to allocate a Cairo surface that *exactly* matches the size of the path.

On 28.08.2022 at 21:47 Andreas Falkenhahn wrote:

> Hi,

> is there any way to get the *exact* extents of transformed
> graphics? AFAICS, cairo_fill_extents() is in user coordinates, i.e.
> it doesn't take any transformation settings into account. So I've
> tried to apply the transformation manually to what I get from
> cairo_fill_extents() but I don't seem to get it 100% right. It looks
> like one row is missing at the bottom. 

> This is what I've tried:

>         cairo_t *cr;
>         cairo_surface_t *surface;
>         cairo_matrix_t cm;
>         int k;
>         double tx = 0, ty = 0;
>         double x1, y1, x2, y2;
>         
>         surface = cairo_image_surface_create(CAIRO_FORMAT_A8, 1000, 1000);
>         cr = cairo_create(surface);

>         for(k = 0; k < 2; k++) {
>         
>                 cairo_new_path(cr);
>                 cairo_move_to(cr, tx, ty);
>                 cairo_set_font_size(cr, 100);
>                 cairo_text_path(cr, "C");                          
>                 
>                 if(!k) {        
>                 
>                         double width, height;
>                         
>                         cairo_fill_extents(cr, &x1, &y1, &x2, &y2);
>                         
>                         tx = -x1;
>                         ty = -y1;               
>                         
>                         width = fabs(x2 - x1);
>                         height = fabs(y2 - y1);

>                         width = ceil(width * 4.6);
>                         height = ceil(height * 4.6);
>                         
>                         cairo_destroy(cr);
>                         cairo_surface_destroy(surface);
>                         
>                         surface =
> cairo_image_surface_create(CAIRO_FORMAT_A8, width, height);
>                         cr = cairo_create(surface);                
>                                 
>                         cairo_matrix_init(&cm, 4.6, 0, 0, 4.6, 0, 0);
>                         cairo_set_matrix(cr, &cm);                 
>                 }
>         }
>         
>         cairo_fill(cr);

>         cairo_surface_flush(surface);
>         cairo_surface_write_to_png(surface, "tmp.png");
>         
>         cairo_destroy(cr);
>         cairo_surface_destroy(surface);

> I'm attaching the resulting image. As you can see, there's at least
> one row of the "C" shape missing at the bottom of the image.

> Any ideas how to get this right? Is this some sort of floating
> point inaccuracy and should I just add 1 to width/height to solve
> this or am I doing something wrong here and there is a better way?



-- 
Best regards,
 Andreas Falkenhahn                            mailto:andreas at falkenhahn.com



More information about the cairo mailing list