From 5f300dcfcb25e727ceb2da8c7175cbb331bb0546 Mon Sep 17 00:00:00 2001 From: Alan Third Date: Sat, 5 Aug 2023 10:39:31 +0100 Subject: [PATCH] Fix percentage sizes in SVG display (bug#64908) * src/image.c (svg_css_length_to_pixels): Make percent units always return zero. (svg_load_image): Don't rely on the width and height values from the SVG actually having any useful data, even if they're explicitly set. --- src/image.c | 55 +++++++++++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 23 deletions(-) diff --git a/src/image.c b/src/image.c index c9420b48f4a..96e0f2a7225 100644 --- a/src/image.c +++ b/src/image.c @@ -11161,6 +11161,21 @@ svg_css_length_to_pixels (RsvgLength length, double dpi, int font_size) case RSVG_UNIT_IN: value *= dpi; break; + case RSVG_UNIT_PERCENT: + /* Percent is a ratio of the containing "viewport". We don't + have a viewport, as such, as we try to draw the image to it's + own desired size rather than dictate the size as if we were + drawing icons on a toolbar or similar. This means that + percent values are useless to us and we are best off just + drawing the image according to whatever other sizes we can + derive. + + If we do set explicit width and height values in the image + spec, this will work out correctly as librsvg will still + honour the percentage sizes in its final rendering no matter + what size we make the image. */ + value = 0; + break; #if LIBRSVG_CHECK_VERSION (2, 48, 0) /* We don't know exactly what font size is used on older librsvg versions. */ @@ -11169,7 +11184,7 @@ svg_css_length_to_pixels (RsvgLength length, double dpi, int font_size) break; #endif default: - /* Probably ex or %. We can't know what the pixel value is + /* Probably ex. We can't know what the pixel value is without more information. */ value = 0; } @@ -11302,6 +11317,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents, else { RsvgRectangle zero_rect, viewbox, out_logical_rect; + double explicit_width = 0, explicit_height = 0; /* Try the intrinsic dimensions first. */ gboolean has_width, has_height; @@ -11313,34 +11329,27 @@ svg_load_image (struct frame *f, struct image *img, char *contents, &has_height, &iheight, &has_viewbox, &viewbox); - if (has_width && has_height) - { - /* Success! We can use these values directly. */ - viewbox_width = svg_css_length_to_pixels (iwidth, dpi, + if (has_width) + explicit_width = svg_css_length_to_pixels (iwidth, dpi, + img->face_font_size); + if (has_height) + explicit_height = svg_css_length_to_pixels (iheight, dpi, img->face_font_size); - viewbox_height = svg_css_length_to_pixels (iheight, dpi, - img->face_font_size); - /* Here one dimension could be zero because in percent unit. - So calculate this dimension with the other. */ - if (! (0 < viewbox_width) && (iwidth.unit == RSVG_UNIT_PERCENT)) - viewbox_width = (viewbox_height * viewbox.width / viewbox.height) - * iwidth.length; - else if (! (0 < viewbox_height) && (iheight.unit == RSVG_UNIT_PERCENT)) - viewbox_height = (viewbox_width * viewbox.height / viewbox.width) - * iheight.length; + if (explicit_width > 0 && explicit_height > 0) + { + viewbox_width = explicit_width; + viewbox_height = explicit_height; } - else if (has_width && has_viewbox) + else if (explicit_width > 0 && has_viewbox) { - viewbox_width = svg_css_length_to_pixels (iwidth, dpi, - img->face_font_size); - viewbox_height = viewbox_width * viewbox.height / viewbox.width; + viewbox_width = explicit_width; + viewbox_height = explicit_width * viewbox.height / viewbox.width; } - else if (has_height && has_viewbox) + else if (explicit_height > 0 && has_viewbox) { - viewbox_height = svg_css_length_to_pixels (iheight, dpi, - img->face_font_size); - viewbox_width = viewbox_height * viewbox.width / viewbox.height; + viewbox_height = explicit_height; + viewbox_width = explicit_height * viewbox.width / viewbox.height; } else if (has_viewbox) { -- 2.40.1