From 27e284644ae30f767d04847fc45accb4f18f33ab Mon Sep 17 00:00:00 2001 From: Alan Third 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 @@ - + 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 @@ - + 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 @@ - + 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 @@ - + 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 @@ - + 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 @@ - + 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 = "" "" @@ -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