From mboxrd@z Thu Jan 1 00:00:00 1970 Path: news.gmane.io!.POSTED.blaine.gmane.org!not-for-mail From: Alan Third Newsgroups: gmane.emacs.bugs Subject: bug#44065: 28.0.50; SVG image not shown completely Date: Mon, 19 Oct 2020 21:43:13 +0100 Message-ID: <20201019204313.GF1166@breton.holly.idiocy.org> References: <83pn5fqzqc.fsf@gnu.org> <874kmrijs5.fsf@gnus.org> <83o8kzqxeq.fsf@gnu.org> <87r1pve8h5.fsf@gmx.net> <83h7qrqvbj.fsf@gnu.org> <87mu0je7mt.fsf@gmx.net> <83blgzqunb.fsf@gnu.org> <87pn5efvw6.fsf@gnus.org> <87imb61t05.fsf@gmx.net> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="4Ckj6UjgE2iN1+kY" Injection-Info: ciao.gmane.io; posting-host="blaine.gmane.org:116.202.254.214"; logging-data="16272"; mail-complaints-to="usenet@ciao.gmane.io" Cc: 44065@debbugs.gnu.org, Lars Ingebrigtsen , styang@fastmail.com To: Stephen Berman Original-X-From: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Mon Oct 19 22:44:15 2020 Return-path: Envelope-to: geb-bug-gnu-emacs@m.gmane-mx.org Original-Received: from lists.gnu.org ([209.51.188.17]) by ciao.gmane.io with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kUc0s-00046m-FM for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 19 Oct 2020 22:44:14 +0200 Original-Received: from localhost ([::1]:52156 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kUc0r-0000Lq-FF for geb-bug-gnu-emacs@m.gmane-mx.org; Mon, 19 Oct 2020 16:44:13 -0400 Original-Received: from eggs.gnu.org ([2001:470:142:3::10]:35054) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kUc0h-0000L8-Uq for bug-gnu-emacs@gnu.org; Mon, 19 Oct 2020 16:44:03 -0400 Original-Received: from debbugs.gnu.org ([209.51.188.43]:59253) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kUc0g-0005YE-Hj for bug-gnu-emacs@gnu.org; Mon, 19 Oct 2020 16:44:03 -0400 Original-Received: from Debian-debbugs by debbugs.gnu.org with local (Exim 4.84_2) (envelope-from ) id 1kUc0g-0002Df-Do for bug-gnu-emacs@gnu.org; Mon, 19 Oct 2020 16:44:02 -0400 X-Loop: help-debbugs@gnu.org Resent-From: Alan Third Original-Sender: "Debbugs-submit" Resent-CC: bug-gnu-emacs@gnu.org Resent-Date: Mon, 19 Oct 2020 20:44:02 +0000 Resent-Message-ID: Resent-Sender: help-debbugs@gnu.org X-GNU-PR-Message: followup 44065 X-GNU-PR-Package: emacs Original-Received: via spool by 44065-submit@debbugs.gnu.org id=B44065.16031402048477 (code B ref 44065); Mon, 19 Oct 2020 20:44:02 +0000 Original-Received: (at 44065) by debbugs.gnu.org; 19 Oct 2020 20:43:24 +0000 Original-Received: from localhost ([127.0.0.1]:42566 helo=debbugs.gnu.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kUc03-0002Ce-Us for submit@debbugs.gnu.org; Mon, 19 Oct 2020 16:43:24 -0400 Original-Received: from idiocy.org ([217.169.17.33]:57239 helo=breton.holly.idiocy.org) by debbugs.gnu.org with esmtp (Exim 4.84_2) (envelope-from ) id 1kUc01-0002CM-KO for 44065@debbugs.gnu.org; Mon, 19 Oct 2020 16:43:22 -0400 Original-Received: by breton.holly.idiocy.org (Postfix, from userid 501) id 9129B20262661A; Mon, 19 Oct 2020 21:43:13 +0100 (BST) Mail-Followup-To: Alan Third , Stephen Berman , Lars Ingebrigtsen , 44065@debbugs.gnu.org, styang@fastmail.com Content-Disposition: inline In-Reply-To: <87imb61t05.fsf@gmx.net> X-BeenThere: debbugs-submit@debbugs.gnu.org X-Mailman-Version: 2.1.18 Precedence: list X-BeenThere: bug-gnu-emacs@gnu.org List-Id: "Bug reports for GNU Emacs, the Swiss army knife of text editors" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: bug-gnu-emacs-bounces+geb-bug-gnu-emacs=m.gmane-mx.org@gnu.org Original-Sender: "bug-gnu-emacs" Xref: news.gmane.io gmane.emacs.bugs:191043 Archived-At: --4Ckj6UjgE2iN1+kY Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Mon, Oct 19, 2020 at 11:10:02AM +0200, Stephen Berman wrote: > On Mon, 19 Oct 2020 10:43:53 +0200 Lars Ingebrigtsen wrote: > > > Eli Zaretskii writes: > > > >>> > Maybe it depends on the version of librsvg? or some dependency of > >>> > librsvg? > >>> > >>> My system uses librsvg-2.48.2. > >> > >> 2.40.1 here. > > > > 2.50.1 here. So it looks like something changed between 2.40 and 2.48 > > somewhere. > > One thing that changed with 2.41 is the implementation of librsvg: > > https://download.gnome.org/sources/librsvg/2.41/librsvg-2.41.0.news > > Version 2.41.0 > - The big news is that parts of librsvg are now implemented in the > Rust programming language, instead of C. [...] > - Code that has been converted to Rust: marker orientations and > rendering, path data parser, path building, length normalization, > gradient inheritance, bounding boxes with affine transformations. > > Maybe that led to the clipping? (But I can't readily check how 2.41 > displays SVGs in Emacs.) A lot of stuff is deprecated in 2.46, presumably because of this change. I've got something that works for me. I'm using 2.50, so I'd appreciate it if someone using 2.45 or below could check that it builds and isn't completely broken. I don't expect this bug to be fixed on libsrvg 2.45 or below. I don't see any obvious way around it while still being able to resize the image and set background colours, etc., and since it works on recent versions of librsvg I don't think it's worth putting too much effort in. -- Alan Third --4Ckj6UjgE2iN1+kY Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="0001-Fix-SVG-image-dimension-calculations-bug-44065.patch" >From 9da7933d902f69bbfe0ed185cf3d2889958ac63b Mon Sep 17 00:00:00 2001 From: Alan Third Date: Mon, 19 Oct 2020 21:19:57 +0100 Subject: [PATCH] Fix SVG image dimension calculations (bug#44065) * src/image.c (svg_load_image): Calculate the image size by using the viewBox size and applying it to the image. Work out CSS so it remains the same across all SVG calculations. --- src/image.c | 69 ++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 19 deletions(-) diff --git a/src/image.c b/src/image.c index 25d5af8a8d..aa305dfebf 100644 --- a/src/image.c +++ b/src/image.c @@ -9736,7 +9736,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents, ptrdiff_t size, char *filename) { RsvgHandle *rsvg_handle; - RsvgDimensionData dimension_data; + double viewbox_width, viewbox_height; GError *err = NULL; GdkPixbuf *pixbuf; int width; @@ -9745,6 +9745,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents, int rowstride; char *wrapped_contents = NULL; ptrdiff_t wrapped_size; + char *css; #if ! GLIB_CHECK_VERSION (2, 36, 0) /* g_type_init is a glib function that must be called prior to @@ -9788,22 +9789,60 @@ svg_load_image (struct frame *f, struct image *img, char *contents, if (err) goto rsvg_error; #endif + /* Generate the default CSS for the image. */ + int buffer_size; + Lisp_Object value; + unsigned long foreground = img->face_foreground; + value = image_spec_value (img->spec, QCforeground, NULL); + if (!NILP (value)) + foreground = image_alloc_image_color (f, img, value, img->face_foreground); + + /* TODO: Use the actual font size or at least make it configurable. */ + char *css_format = "svg {color: #%06X; fill: currentColor; font-size: 14;}"; + + /* Add 3 to cover the extra size of the color string and the null byte. */ + buffer_size = strlen (css_format) + 3; + css = xmalloc (buffer_size); + if (! css || buffer_size <= snprintf (css, buffer_size, css_format, + foreground & 0xFFFFFF)) + goto rsvg_error; + + rsvg_handle_set_stylesheet (rsvg_handle, css, strlen (css), NULL); + /* Get the image dimensions. */ +#if LIBRSVG_CHECK_VERSION (2, 46, 0) + RsvgRectangle zero_rect, viewbox; + + rsvg_handle_get_geometry_for_layer (rsvg_handle, NULL, + &zero_rect, &viewbox, + NULL, NULL); + viewbox_width = viewbox.x + viewbox.width; + viewbox_height = viewbox.y + viewbox.height; +#else + RsvgDimensionData dimension_data; + rsvg_handle_get_dimensions (rsvg_handle, &dimension_data); + viewbox_width = dimension_data.width; + viewbox_height = dimension_data.height; +#endif + compute_image_size (viewbox_width, viewbox_height, img->spec, + &width, &height); + + if (! check_image_size (f, width, height)) + { + image_size_error (); + goto rsvg_error; + } + /* We are now done with the unmodified data. */ g_object_unref (rsvg_handle); - /* Calculate the final image size. */ - compute_image_size (dimension_data.width, dimension_data.height, - img->spec, &width, &height); - /* Wrap the SVG data in another SVG. This allows us to set the width and height, as well as modify the foreground and background colors. */ { Lisp_Object value; - unsigned long foreground = img->face_foreground; unsigned long background = img->face_background; Lisp_Object encoded_contents @@ -9818,9 +9857,8 @@ svg_load_image (struct frame *f, struct image *img, char *contents, const char *wrapper = "" + "viewBox=\"0 0 %f %f\">" "" "" ""; @@ -9829,9 +9867,6 @@ svg_load_image (struct frame *f, struct image *img, char *contents, width and height strings and things. */ int buffer_size = SBYTES (encoded_contents) + strlen (wrapper) + 64; - value = image_spec_value (img->spec, QCforeground, NULL); - if (!NILP (value)) - foreground = image_alloc_image_color (f, img, value, img->face_foreground); value = image_spec_value (img->spec, QCbackground, NULL); if (!NILP (value)) { @@ -9844,8 +9879,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents, if (!wrapped_contents || buffer_size <= snprintf (wrapped_contents, buffer_size, wrapper, - foreground & 0xFFFFFF, width, height, - dimension_data.width, dimension_data.height, + width, height, viewbox_width, viewbox_height, background & 0xFFFFFF, SSDATA (encoded_contents))) goto rsvg_error; @@ -9887,12 +9921,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents, if (err) goto rsvg_error; #endif - rsvg_handle_get_dimensions (rsvg_handle, &dimension_data); - if (! check_image_size (f, dimension_data.width, dimension_data.height)) - { - image_size_error (); - goto rsvg_error; - } + rsvg_handle_set_stylesheet (rsvg_handle, css, strlen (css), NULL); /* We can now get a valid pixel buffer from the svg file, if all went ok. */ @@ -9971,6 +10000,8 @@ svg_load_image (struct frame *f, struct image *img, char *contents, g_object_unref (rsvg_handle); if (wrapped_contents) xfree (wrapped_contents); + if (css) + xfree (css); /* FIXME: Use error->message so the user knows what is the actual problem with the image. */ image_error ("Error parsing SVG image `%s'", img->spec); -- 2.26.1 --4Ckj6UjgE2iN1+kY--