unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Alan Third <alan@idiocy.org>
To: Stefan Kangas <stefan@marxist.se>
Cc: 47074@debbugs.gnu.org
Subject: bug#47074: Replace XPM icons with Unicode codepoints in customize/widgets
Date: Sun, 14 Mar 2021 13:46:59 +0000	[thread overview]
Message-ID: <YE4T06VXJSJje0nH@breton.holly.idiocy.org> (raw)
In-Reply-To: <CADwFkmku9WpSHr1qLCD5q2a02jPxQ35pzfdd3BzSxo6v4jhGSQ@mail.gmail.com>

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

On Fri, Mar 12, 2021 at 08:44:55PM -0600, Stefan Kangas wrote:
> Alan Third <alan@idiocy.org> writes:
> 
> > On Thu, Mar 11, 2021 at 10:01:11PM +0200, Eli Zaretskii wrote:
> >> >
> >> > I think SVG is obviously much preferable to XPM, but there is still the
> >> > problem that the images don't scale with the text.  Do we have a general
> >> > solution to that?  If not, should we have one?
> >>
> >> With SVG, I believe we could.  (We can scale other kinds of images as
> >> well, but they don't look well when enlarged, AFAIK.)
> >
> > I've been thinking about this, and assuming we can extract the font
> > name and size from the face in C then we can create a default CSS
> > stylesheet that should make 1em in an SVG equivalent to the actual
> > Emacs font height.
> 
> I took a stab at adding SVG icons, as found in the GNOME Adwaita Icon
> Theme.  I had to scrub some color details from the SVG files by hand,
> but they now seem to automagically adapt to the :foreground and
> :background of the current face (but I could be wrong about that as I
> don't understand how this is supposed to work).
> 
> How would a patch like the attached relate to the changes you propose,
> Alan?

I've attached a proof of concept patch for what I'm talking about.
Stefan's patch must be applied first and it requires at least librsvg
2.48 and might foul up if create-image starts automatically changing
scale (it's fine here).

Does this look like the sort of behaviour you were thinking of, in
terms of icon sizing?
-- 
Alan Third

[-- Attachment #2: 0001-Autoresizing-SVG-files-PoC.patch --]
[-- Type: text/plain, Size: 10311 bytes --]

From 27e284644ae30f767d04847fc45accb4f18f33ab Mon Sep 17 00:00:00 2001
From: Alan Third <alan@idiocy.org>
Date: Sun, 14 Mar 2021 13:41:25 +0000
Subject: [PATCH] Autoresizing SVG files PoC

Requires librsvg 2.48.
---
 etc/images/ui/checkbox-checked.svg |  2 +-
 etc/images/ui/checkbox-mixed.svg   |  2 +-
 etc/images/ui/checkbox.svg         |  2 +-
 etc/images/ui/radio-checked.svg    |  2 +-
 etc/images/ui/radio-mixed.svg      |  2 +-
 etc/images/ui/radio.svg            |  2 +-
 src/dispextern.h                   |  4 ++++
 src/image.c                        | 25 +++++++++++++++++++------
 8 files changed, 29 insertions(+), 12 deletions(-)

diff --git a/etc/images/ui/checkbox-checked.svg b/etc/images/ui/checkbox-checked.svg
index 6fefd5569e..559c24af72 100644
--- a/etc/images/ui/checkbox-checked.svg
+++ b/etc/images/ui/checkbox-checked.svg
@@ -1,4 +1,4 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
+<svg xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid meet" width="1em" height="1em" viewBox="0 0 16 16">
   <g>
     <path d="M3.5 1A2.506 2.506 0 001 3.5v9C1 13.876 2.124 15 3.5 15h9c1.376 0 2.5-1.124 2.5-2.5v-9C15 2.124 13.876 1 12.5 1zm0 1h9c.84 0 1.5.66 1.5 1.5v9c0 .84-.66 1.5-1.5 1.5h-9c-.84 0-1.5-.66-1.5-1.5v-9C2 2.66 2.66 2 3.5 2z" overflow="visible" />
     <path d="M14.5 3l-.5-.5L7.5 9 5 6.5l-2 2L7.5 13l7-7z" overflow="visible" />
diff --git a/etc/images/ui/checkbox-mixed.svg b/etc/images/ui/checkbox-mixed.svg
index 13bccaa7ce..4dc71c3764 100644
--- a/etc/images/ui/checkbox-mixed.svg
+++ b/etc/images/ui/checkbox-mixed.svg
@@ -1,4 +1,4 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
+<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16">
   <g>
     <path d="M3.5 1A2.506 2.506 0 001 3.5v9C1 13.876 2.124 15 3.5 15h9c1.376 0 2.5-1.124 2.5-2.5v-9C15 2.124 13.876 1 12.5 1zm0 1h9c.84 0 1.5.66 1.5 1.5v9c0 .84-.66 1.5-1.5 1.5h-9c-.84 0-1.5-.66-1.5-1.5v-9C2 2.66 2.66 2 3.5 2z" overflow="visible" />
     <path d="M5 6a2 2 0 100 4h6a2 2 0 100-4z" overflow="visible" />
diff --git a/etc/images/ui/checkbox.svg b/etc/images/ui/checkbox.svg
index 18cd25b43f..28e350c46b 100644
--- a/etc/images/ui/checkbox.svg
+++ b/etc/images/ui/checkbox.svg
@@ -1,3 +1,3 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
+<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16">
   <path d="M3.5 1A2.506 2.506 0 001 3.5v9C1 13.876 2.124 15 3.5 15h9c1.376 0 2.5-1.124 2.5-2.5v-9C15 2.124 13.876 1 12.5 1zm0 1h9c.84 0 1.5.66 1.5 1.5v9c0 .84-.66 1.5-1.5 1.5h-9c-.84 0-1.5-.66-1.5-1.5v-9C2 2.66 2.66 2 3.5 2z" overflow="visible" />
 </svg>
diff --git a/etc/images/ui/radio-checked.svg b/etc/images/ui/radio-checked.svg
index db711841cf..e7a22ccf3f 100644
--- a/etc/images/ui/radio-checked.svg
+++ b/etc/images/ui/radio-checked.svg
@@ -1,4 +1,4 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
+<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16">
   <g>
     <path d="M8 5a3.001 3.001 0 000 6 3.001 3.001 0 000-6z" overflow="visible"/>
     <path d="M8.004 1C4.144 1 1 4.144 1 8.004c0 3.86 3.144 7.006 7.004 7.006 3.86 0 7.006-3.146 7.006-7.006C15.01 4.144 11.864 1 8.004 1zm0 1a6.002 6.002 0 016.006 6.004 6.004 6.004 0 01-6.006 6.006A6.002 6.002 0 012 8.004 6 6 0 018.004 2z" overflow="visible"/>
diff --git a/etc/images/ui/radio-mixed.svg b/etc/images/ui/radio-mixed.svg
index 5a8be0cf65..bdd76f85a0 100644
--- a/etc/images/ui/radio-mixed.svg
+++ b/etc/images/ui/radio-mixed.svg
@@ -1,4 +1,4 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
+<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16">
   <g font-weight="400" fill="#474747">
     <path d="M8 1C4.142 1 1 4.142 1 8s3.142 7 7 7 7-3.142 7-7-3.142-7-7-7zm0 1c3.316 0 6 2.684 6 6s-2.684 6-6 6-6-2.684-6-6 2.684-6 6-6z" overflow="visible" />
     <path d="M5 6a2 2 0 100 4h6a2 2 0 100-4z" overflow="visible" />
diff --git a/etc/images/ui/radio.svg b/etc/images/ui/radio.svg
index 0d649c99cd..f076ad78d4 100644
--- a/etc/images/ui/radio.svg
+++ b/etc/images/ui/radio.svg
@@ -1,3 +1,3 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16">
+<svg xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" viewBox="0 0 16 16">
   <path d="M8 1C4.142 1 1 4.142 1 8s3.142 7 7 7 7-3.142 7-7-3.142-7-7-7zm0 1c3.316 0 6 2.684 6 6s-2.684 6-6 6-6-2.684-6-6 2.684-6 6-6z" overflow="visible" />
 </svg>
diff --git a/src/dispextern.h b/src/dispextern.h
index f4e872644d..3e801672ec 100644
--- a/src/dispextern.h
+++ b/src/dispextern.h
@@ -3066,6 +3066,10 @@ reset_mouse_highlight (Mouse_HLInfo *hlinfo)
      is created.  */
   unsigned long face_foreground, face_background;
 
+  /* Size of the font, only really relevant for types like SVG that
+     allow us to draw text. */
+  int face_font_size;
+
   /* True if this image has a `transparent' background -- that is, is
      uses an image mask.  The accessor macro for this is
      `IMAGE_BACKGROUND_TRANSPARENT'.  */
diff --git a/src/image.c b/src/image.c
index b85418c690..4810329537 100644
--- a/src/image.c
+++ b/src/image.c
@@ -1605,7 +1605,7 @@ make_image_cache (void)
 static struct image *
 search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash,
                     unsigned long foreground, unsigned long background,
-                    bool ignore_colors)
+                    int font_size, bool ignore_colors)
 {
   struct image *img;
   struct image_cache *c = FRAME_IMAGE_CACHE (f);
@@ -1629,7 +1629,8 @@ search_image_cache (struct frame *f, Lisp_Object spec, EMACS_UINT hash,
     if (img->hash == hash
 	&& !NILP (Fequal (img->spec, spec))
 	&& (ignore_colors || (img->face_foreground == foreground
-                              && img->face_background == background)))
+                              && img->face_background == background
+			      && img->face_font_size == font_size)))
       break;
   return img;
 }
@@ -1647,7 +1648,7 @@ uncache_image (struct frame *f, Lisp_Object spec)
      can have multiple copies of an image with the same spec. We want
      to remove them all to ensure the user doesn't see an old version
      of the image when the face changes.  */
-  while ((img = search_image_cache (f, spec, hash, 0, 0, true)))
+  while ((img = search_image_cache (f, spec, hash, 0, 0, 0, true)))
     {
       free_image (f, img);
       /* As display glyphs may still be referring to the image ID, we
@@ -2419,6 +2420,7 @@ lookup_image (struct frame *f, Lisp_Object spec, int face_id)
   struct face *face = FACE_FROM_ID (f, face_id);
   unsigned long foreground = FACE_COLOR_TO_PIXEL (face->foreground, f);
   unsigned long background = FACE_COLOR_TO_PIXEL (face->background, f);
+  int font_size = face->font->height;
 
   /* F must be a window-system frame, and SPEC must be a valid image
      specification.  */
@@ -2427,7 +2429,7 @@ lookup_image (struct frame *f, Lisp_Object spec, int face_id)
 
   /* Look up SPEC in the hash table of the image cache.  */
   hash = sxhash (spec);
-  img = search_image_cache (f, spec, hash, foreground, background, false);
+  img = search_image_cache (f, spec, hash, foreground, background, font_size, false);
   if (img && img->load_failed_p)
     {
       free_image (f, img);
@@ -2442,6 +2444,7 @@ lookup_image (struct frame *f, Lisp_Object spec, int face_id)
       cache_image (f, img);
       img->face_foreground = foreground;
       img->face_background = background;
+      img->face_font_size = font_size;
       img->load_failed_p = ! img->type->load_img (f, img);
 
       /* If we can't load the image, and we don't have a width and
@@ -9912,6 +9915,12 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
   g_type_init ();
 #endif
 
+  /* Generate the CSS for the SVG image.  */
+  char *css_spec = "svg{font-size:%4dpx}";
+  char *css = malloc(strlen (css_spec + 1));
+  sprintf (css, css_spec, img->face_font_size);
+  fprintf (stderr, "%s\n\n", css);
+
   /* Parse the unmodified SVG data so we can get its initial size.  */
 
 #if LIBRSVG_CHECK_VERSION (2, 32, 0)
@@ -9929,6 +9938,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
   /* Check rsvg_handle too, to avoid librsvg 2.40.13 bug (Bug#36773#26).  */
   if (!rsvg_handle || err) goto rsvg_error;
 
+  rsvg_handle_set_stylesheet (rsvg_handle, css, strlen (css), NULL);
   rsvg_handle_set_dpi_x_y (rsvg_handle, FRAME_DISPLAY_INFO (f)->resx,
                            FRAME_DISPLAY_INFO (f)->resy);
 #else
@@ -10054,7 +10064,7 @@ 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;\" "
+      "style=\"color: #%06X; fill: currentColor\" "
       "width=\"%d\" height=\"%d\" preserveAspectRatio=\"none\" "
       "viewBox=\"0 0 %f %f\">"
       "<rect width=\"100%%\" height=\"100%%\" fill=\"#%06X\"/>"
@@ -10080,7 +10090,8 @@ 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,
+                                    foreground & 0xFFFFFF,
+				    width, height,
                                     viewbox_width, viewbox_height,
                                     background & 0xFFFFFF,
                                     SSDATA (encoded_contents)))
@@ -10088,6 +10099,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
 
     wrapped_size = strlen (wrapped_contents);
   }
+  fprintf (stderr, "%s\n\n", wrapped_contents);
 
   /* Now we parse the wrapped version.  */
 
@@ -10105,6 +10117,7 @@ svg_load_image (struct frame *f, struct image *img, char *contents,
   /* Check rsvg_handle too, to avoid librsvg 2.40.13 bug (Bug#36773#26).  */
   if (!rsvg_handle || err) goto rsvg_error;
 
+  rsvg_handle_set_stylesheet (rsvg_handle, css, strlen (css), NULL);
   rsvg_handle_set_dpi_x_y (rsvg_handle, FRAME_DISPLAY_INFO (f)->resx,
                            FRAME_DISPLAY_INFO (f)->resy);
 #else
-- 
2.29.2


  parent reply	other threads:[~2021-03-14 13:46 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-03-11 16:51 bug#47074: Replace XPM icons with Unicode codepoints in customize/widgets Stefan Kangas
2021-03-11 17:01 ` Lars Ingebrigtsen
2021-03-11 17:22   ` Stefan Kangas
2021-03-11 17:38   ` Eli Zaretskii
2021-03-11 17:51     ` Stefan Kangas
2021-03-11 19:59       ` Eli Zaretskii
2021-03-11 17:28 ` Eli Zaretskii
2021-03-11 17:51   ` Stefan Kangas
2021-03-11 18:03     ` Lars Ingebrigtsen
2021-03-11 20:21       ` Eli Zaretskii
2021-03-11 20:27         ` Lars Ingebrigtsen
2021-03-12  1:38           ` Stefan Kangas
2021-03-12  1:43             ` Lars Ingebrigtsen
2021-03-12  2:24               ` Stefan Kangas
2021-03-12  2:34                 ` Lars Ingebrigtsen
2021-03-12  8:12             ` Eli Zaretskii
2021-03-11 20:01     ` Eli Zaretskii
2021-03-11 23:49       ` Alan Third
2021-03-12  0:12         ` Lars Ingebrigtsen
2021-03-12 18:21           ` Alan Third
2021-03-12  7:27         ` Eli Zaretskii
2021-03-12 18:25           ` Alan Third
2021-03-12 18:37             ` Eli Zaretskii
2021-03-12 18:43               ` Alan Third
2021-03-12 19:27                 ` Eli Zaretskii
2021-03-13  2:44         ` Stefan Kangas
2021-03-13  7:29           ` Eli Zaretskii
2021-03-13  7:47             ` Stefan Kangas
2021-03-13  8:37               ` Eli Zaretskii
2021-03-13 10:35                 ` Stefan Kangas
2021-03-13 10:54                   ` Eli Zaretskii
2021-03-13 11:51                     ` Stefan Kangas
2021-03-13 16:27                       ` Eli Zaretskii
2021-03-13 16:44                         ` Stefan Kangas
2021-03-13 17:02                           ` Eli Zaretskii
2021-03-13 20:24           ` Alan Third
2021-03-14 13:46           ` Alan Third [this message]
2021-03-14 18:44             ` Stefan Kangas
2021-03-14 18:49               ` Eli Zaretskii
2021-03-14 19:37                 ` Alan Third
2021-03-14 19:52                   ` Eli Zaretskii
2021-03-15 21:34                     ` Alan Third
2021-03-16  3:29                       ` Eli Zaretskii
2021-04-03 20:06                         ` Stefan Kangas
2021-04-03 22:28                           ` Alan Third
2021-04-04  9:21                             ` Stefan Kangas
2021-04-04 11:37                             ` Eli Zaretskii
2021-04-04 11:44                               ` Alan Third
2021-04-04 11:55                                 ` Eli Zaretskii
2021-04-04  6:55                           ` Eli Zaretskii
2021-04-04  9:21                             ` Stefan Kangas
2021-04-04 11:13                               ` Eli Zaretskii
2021-04-04 11:37                                 ` Alan Third
2021-04-04 11:48                                   ` Eli Zaretskii
2021-04-04 12:38                                     ` Eli Zaretskii
2021-04-04 13:15                                       ` Alan Third
2021-04-04 13:14                                     ` Alan Third
2021-04-04 13:22                                       ` Eli Zaretskii
2021-04-04 13:28                                         ` Alan Third
2021-04-04 13:36                                           ` Eli Zaretskii
2021-04-04 11:39                                 ` Stefan Kangas

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

  List information: https://www.gnu.org/software/emacs/

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

  git send-email \
    --in-reply-to=YE4T06VXJSJje0nH@breton.holly.idiocy.org \
    --to=alan@idiocy.org \
    --cc=47074@debbugs.gnu.org \
    --cc=stefan@marxist.se \
    /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 public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).