all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Alan Third <alan@idiocy.org>
To: Stephen Berman <stephen.berman@gmx.net>
Cc: 44065@debbugs.gnu.org, Lars Ingebrigtsen <larsi@gnus.org>,
	styang@fastmail.com
Subject: bug#44065: 28.0.50; SVG image not shown completely
Date: Mon, 19 Oct 2020 21:43:13 +0100	[thread overview]
Message-ID: <20201019204313.GF1166@breton.holly.idiocy.org> (raw)
In-Reply-To: <87imb61t05.fsf@gmx.net>

[-- Attachment #1: Type: text/plain, Size: 1579 bytes --]

On Mon, Oct 19, 2020 at 11:10:02AM +0200, Stephen Berman wrote:
> On Mon, 19 Oct 2020 10:43:53 +0200 Lars Ingebrigtsen <larsi@gnus.org> wrote:
> 
> > Eli Zaretskii <eliz@gnu.org> 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

[-- Attachment #2: 0001-Fix-SVG-image-dimension-calculations-bug-44065.patch --]
[-- Type: text/plain, Size: 6058 bytes --]

From 9da7933d902f69bbfe0ed185cf3d2889958ac63b Mon Sep 17 00:00:00 2001
From: Alan Third <alan@idiocy.org>
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 =
       "<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" "
       "xmlns:xi=\"http://www.w3.org/2001/XInclude\" "
-      "style=\"color: #%06X; fill: currentColor;\" "
       "width=\"%d\" height=\"%d\" preserveAspectRatio=\"none\" "
-      "viewBox=\"0 0 %d %d\">"
+      "viewBox=\"0 0 %f %f\">"
       "<rect width=\"100%%\" height=\"100%%\" fill=\"#%06X\"/>"
       "<xi:include href=\"data:image/svg+xml;base64,%s\"></xi:include>"
       "</svg>";
@@ -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


  reply	other threads:[~2020-10-19 20:43 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-17 23:27 bug#44065: 28.0.50; SVG image not shown completely styang
2020-10-18 15:17 ` Eli Zaretskii
2020-10-18 16:02   ` Sheng Yang
2020-10-18 16:13     ` Eli Zaretskii
2020-10-18 16:24       ` Lars Ingebrigtsen
2020-10-18 17:03         ` Eli Zaretskii
2020-10-18 17:42           ` Stephen Berman
2020-10-18 17:48             ` Eli Zaretskii
2020-10-18 18:00               ` Stephen Berman
2020-10-18 18:03                 ` Eli Zaretskii
2020-10-19  8:43                   ` Lars Ingebrigtsen
2020-10-19  9:10                     ` Stephen Berman
2020-10-19 20:43                       ` Alan Third [this message]
2020-10-19 22:34                         ` Sheng Yang
2020-10-20 12:31                           ` Alan Third
2020-10-20 17:15                             ` Sheng Yang
2020-10-20 19:54                               ` Alan Third
2020-10-21 10:54                                 ` Lars Ingebrigtsen
2020-10-21 15:58                                   ` Corwin Brust
2020-10-21 16:31                                 ` Eli Zaretskii
2020-10-21 17:28                                   ` Sheng Yang
2020-10-21 19:03                                   ` Alan Third
2020-10-22 11:42                                     ` Lars Ingebrigtsen
2020-10-22 12:51                                       ` Eli Zaretskii
2020-10-22 19:11                                         ` Alan Third
2020-10-19 14:51                     ` Eli Zaretskii
2020-10-18 19:18                 ` Sheng Yang
2020-10-18 23:13 ` Alan Third
2020-10-23 20:17 ` Andy Moreton
2020-10-24  7:09   ` Eli Zaretskii
2020-10-24 17:01     ` Alan Third
2020-10-24 17:04       ` Eli Zaretskii
2020-10-24 10:43 ` Andy Moreton
2020-10-25 12:26 ` Andy Moreton
2020-10-25 16:25   ` Alan Third
2020-10-25 17:12 ` Andy Moreton
2020-10-25 17:27   ` Eli Zaretskii
2020-10-25 23:12   ` Alan Third

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201019204313.GF1166@breton.holly.idiocy.org \
    --to=alan@idiocy.org \
    --cc=44065@debbugs.gnu.org \
    --cc=larsi@gnus.org \
    --cc=stephen.berman@gmx.net \
    --cc=styang@fastmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.