Dear Moazin, Please browse the attached SVG: which paints a big blue square (1024 x 1024), and clip small circle at the center of it (r=64). How do you evaluate the bitmap_left and bitmap_top? bitmap_left is 512 - 64 = 448? Or, bitmap_left is 0?
Moazin Khatri wrote: > `Resvg' works with two graphic backends, `cairo' and `qt', so it would be > interesting to look at how they calculate the bounding box. From a quick > look, it looks like they use some recursive mechanism to calculate the > bounding box of each element and then expanding it with every iteration until > the final bounding box is calculated. Yes, yes, it is good starting point for the implementers. If we focus to the simple SVG consists from path objects (path, polygon, polyline, ellipse, rectangle etc etc), the task is already completed. It would not be so difficult in SVG Native Viewer, I hope. But, if we want the renderer to calculate the bitmap_left of attached SVG as 448, instead of 0, finding a boundingbox without real drawing becomes difficult task. If we deal a SVG including the raster image with alpha channel (and if we hope as the transparent pixel in embedded image should be dealt as un-inked), it would become more harder. I confirmed that resvg_get_image_bbox() evaluates bitmap_left of the attached SVG as 0 (the returned bbox is 1024 x 1024, instead of 64 x 64). And, I confirmed that even cairo_recording_surface_ink_extents() evaluates the bitmap_left as 0, either! Sigh. Regards, mpsuzuki P.S. I attached a program I used for the confirmation (it's a modified version of resvg's example.c, to avoid GTK+).
#include <stdio.h> #include <stdlib.h> #include <resvg.h> #include <cairo.h> static resvg_render_tree *tree = NULL; static resvg_options opt; void draw_cb (const char *path) { if (!tree || !path) return; cairo_rectangle_t docExtents = { 0, 0, 0, 0 }; resvg_rect viewBox = resvg_get_image_viewbox(tree); docExtents.x = viewBox.x; docExtents.y = viewBox.y; docExtents.width = viewBox.width; docExtents.height = viewBox.height; cairo_surface_t* cairoSurface = cairo_recording_surface_create( CAIRO_CONTENT_COLOR_ALPHA, &docExtents ); cairo_t* cr = cairo_create( cairoSurface ); resvg_size svgSize = { viewBox.width, viewBox.height }; resvg_cairo_render_to_canvas(tree, &opt, svgSize, cr); cairo_destroy( cr ); cairo_surface_write_to_png( cairoSurface, path ); double x0, y0, w, h; cairo_recording_surface_ink_extents( cairoSurface, &x0, &y0, &w, &h); printf("cairo-ink-extent: {%f, %f, %f, %f}\n", x0, y0, w, h); cairo_surface_destroy( cairoSurface ); } void print_bbox() { resvg_rect viewBox = resvg_get_image_viewbox(tree); printf("viewBox: {%f, %f, %f, %f}\n", viewBox.x, viewBox.y, viewBox.width, viewBox.height); resvg_rect boundingBox; resvg_get_image_bbox(tree, &boundingBox); printf("boundingBox: {%f, %f, %f, %f}\n", boundingBox.x, boundingBox.y, boundingBox.width, boundingBox.height); } void parse_doc (const char *path) { resvg_init_options(&opt); opt.path = path; opt.font_family = "Liberation Sans"; opt.languages = "en"; int err = resvg_parse_tree_from_file(path, &opt, &tree); if (err != RESVG_OK) { fprintf(stderr, "Error id: %i\n", err); abort(); } } int main(int argc, char **argv) { if (argc < 3) abort(); parse_doc(argv[1]); print_bbox(); draw_cb(argv[2]); }
_______________________________________________ Freetype-devel mailing list Freetype-devel@nongnu.org https://lists.nongnu.org/mailman/listinfo/freetype-devel