unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
From: Pip Cet <pipcet@gmail.com>
To: "Clément Pit-Claudel" <cpitclaudel@gmail.com>
Cc: 40845@debbugs.gnu.org
Subject: bug#40845: SVG rendering issues
Date: Sat, 25 Apr 2020 14:34:11 +0000	[thread overview]
Message-ID: <CAOqdjBeJOD0J6m8=0nJ_oBs_NE0cMZQHHQfTViK3NaCk50KRkw@mail.gmail.com> (raw)
In-Reply-To: <72ebf5eb-6b00-ebb4-dab3-a047e35ae1ae@gmail.com>

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

On Sat, Apr 25, 2020 at 12:20 PM Clément Pit-Claudel
<cpitclaudel@gmail.com> wrote:
>
> Hi all,
>
> As discussed on the mailing list, a number of issues currently exist with our SVG rendering implementation.  I have tried to summarize the ones I'm aware of in the following example.
>
> (with-current-buffer (get-buffer-create "*svg bugs*")
>   (erase-buffer)
>   (require 'face-remap)
>   (setq text-scale-mode-amount 10)
>   (text-scale-mode)
>   (let ((svg (svg-create 16 16)))
>     (svg-ellipse svg 8 8 4 4)
>     (insert "Text: ")
>     (print (svg-image svg :ascent 100))
>     (insert-image (svg-image svg :ascent 100))
>     (insert-image (svg-image svg :scale 5.0 :ascent 'center :foreground "red" :background "darkgreen"))
>     (add-text-properties
>      (point-min) (point-max)
>      '(face (:foreground "orange" :background "purple")
>             mouse-face '(:foreground "purple" :background "orange"))))
>   (pop-to-buffer (current-buffer)))
>
> The issues:
>
> 1. Manually scaling an image, as is done for the second image, doesn't re-render the svg: is scales the bitmap-rendered version of it, causing blurriness.
> 2. The SVG images don't inherit the background of the current face; instead, they inherit the background of the default face.
> 3. The SVG images don't inherit the foreground of the current face; instead, they use a black foreground.
> 4. The :foreground keyword has no effect on svg images.
> 5. The images are not scaled with the text: changing text-scale-mode-amount doesn't change the size of the images.

I would like to add

6. When the cursor is over an SVG image, it is displayed with a box
around it rather than with inverted video as characters are.

I've played around a while ago in an attempt to fix these issues, and
be able to define "character-like" SVG glyphs. My approach was to add
a display spec of the form (gen FN), which calls FN with the current
face parameters as arguments whenever redisplaying the spec, then uses
the return value (an image spec) as the actual spec to be displayed.

It's probably quite slow, but (as of June last) it works, even when
displaying the same buffer twice. Calling elisp from the redisplay
engine is, of course, something we don't really want to have more of,
but we'd do so anyway for a `when' spec (in fact, an alternative
approach to get this working with old Emacsen was to abuse a `when'
spec to set the image spec correctly).

The attached patch, IIRC, is the main part. As you can see, it leaves
most of the work to the Lisp side of things. It can fix all issues
mentioned above by modifying the SVG as required.

Also, IIRC, 3 is an rsvg issue.

[-- Attachment #2: gen.diff --]
[-- Type: text/x-patch, Size: 3137 bytes --]

commit 0af1850485f3ad1519e52de2b1694efa922917f4
Author: Pip Cet <pipcet@gmail.com>
Date:   Sat Jun 22 07:53:28 2019 +0000

    snapshot

diff --git a/src/callint.c b/src/callint.c
index 88a3c348d0..6f2e5d5066 100644
--- a/src/callint.c
+++ b/src/callint.c
@@ -824,6 +824,7 @@ syms_of_callint (void)
   DEFSYM (Qlet, "let");
   DEFSYM (Qif, "if");
   DEFSYM (Qwhen, "when");
+  DEFSYM (Qgen, "gen");
   DEFSYM (Qletx, "let*");
   DEFSYM (Qsave_excursion, "save-excursion");
   DEFSYM (Qprogn, "progn");
diff --git a/src/xdisp.c b/src/xdisp.c
index 5699aac61b..717fb30ec3 100644
--- a/src/xdisp.c
+++ b/src/xdisp.c
@@ -2728,7 +2728,6 @@ safe_call2 (Lisp_Object fn, Lisp_Object arg1, Lisp_Object arg2)
   return safe_call (3, fn, arg1, arg2);
 }
 
-
 \f
 /***********************************************************************
 			      Debugging
@@ -4893,6 +4892,7 @@ handle_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
 #endif
       && !EQ (XCAR (spec), Qspace)
       && !EQ (XCAR (spec), Qwhen)
+      && !EQ (XCAR (spec), Qgen)
       && !EQ (XCAR (spec), Qslice)
       && !EQ (XCAR (spec), Qspace_width)
       && !EQ (XCAR (spec), Qheight)
@@ -4991,6 +4991,8 @@ display_prop_end (struct it *it, Lisp_Object object, struct text_pos start_pos)
    Value is non-zero if something was found which replaces the display
    of buffer or string text.  */
 
+extern Lisp_Object *lface_id_to_name;
+
 static int
 handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
 			    Lisp_Object overlay, struct text_pos *position,
@@ -5002,6 +5004,46 @@ handle_single_display_spec (struct it *it, Lisp_Object spec, Lisp_Object object,
   struct text_pos start_pos = *position;
   void *itdata = NULL;
 
+  if (it != NULL &&
+      CONSP (spec) &&
+      EQ (XCAR (spec), Qgen))
+    {
+      spec = XCDR (spec);
+      if (!CONSP (spec))
+	return 0;
+      Lisp_Object gen = XCAR (spec);
+      struct face *face = FACE_FROM_ID (it->f, it->face_id);
+      Lisp_Object lface = Qnil;
+      Lisp_Object props[] = {
+	QCtype,
+	QCfamily,
+	QCfoundry,
+	QCwidth,
+	QCheight,
+	QCweight,
+	QCslant,
+	QCunderline,
+	QCinverse_video,
+	QCforeground,
+	QCbackground,
+	QCstipple,
+	QCoverline,
+	QCstrike_through,
+	QCbox,
+	QCfont,
+	QCinherit,
+	QCfontset,
+	QCdistant_foreground,
+      };
+      for (int i = 0; i < LFACE_VECTOR_SIZE; i++)
+	lface = Fcons (Fcons (props[i], face->lface[i]),
+		       lface);
+      Lisp_Object font = Qnil;
+      XSETFONT (font, face->font);
+      lface = Fcons (Fcons (QCfont, font), lface);
+      spec = safe_call1 (gen, lface);
+    }
+
   /* If SPEC is a list of the form `(when FORM . VALUE)', evaluate FORM.
      If the result is non-nil, use VALUE instead of SPEC.  */
   form = Qt;
diff --git a/src/xfaces.c b/src/xfaces.c
index 012cc96470..47453c2b31 100644
--- a/src/xfaces.c
+++ b/src/xfaces.c
@@ -294,7 +294,7 @@ #define FACE_CACHE_BUCKETS_SIZE 1001
 
 /* A vector mapping Lisp face Id's to face names.  */
 
-static Lisp_Object *lface_id_to_name;
+Lisp_Object *lface_id_to_name;
 static ptrdiff_t lface_id_to_name_size;
 
 #ifdef HAVE_WINDOW_SYSTEM


  reply	other threads:[~2020-04-25 14:34 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-04-25 12:19 bug#40845: SVG rendering issues Clément Pit-Claudel
2020-04-25 14:34 ` Pip Cet [this message]
2020-04-25 15:30   ` Eli Zaretskii
2020-04-25 15:48     ` Pip Cet
2020-04-25 16:10       ` Eli Zaretskii
2020-04-25 17:38         ` Pip Cet
2020-04-25 18:07           ` Eli Zaretskii
2020-04-25 19:41             ` Pip Cet
2020-04-25 20:11               ` Eli Zaretskii
2020-04-26 10:15                 ` Pip Cet
2020-04-26 14:38                   ` Eli Zaretskii
2020-04-26 19:00                     ` Pip Cet
2020-04-27 15:47                       ` Eli Zaretskii
2020-04-25 15:46   ` Eli Zaretskii
2020-04-25 16:42     ` Clément Pit-Claudel
2020-04-25 17:02       ` Eli Zaretskii
2020-04-25 17:24         ` Clément Pit-Claudel
2020-04-25 17:46           ` Alan Third
2020-04-25 18:07             ` Pip Cet
2020-04-26 21:17             ` Alan Third
2020-04-26 22:48               ` Clément Pit-Claudel
2020-04-27 15:22                 ` Alan Third
2020-04-27 16:04                   ` Clément Pit-Claudel
2020-05-03 14:13                 ` Alan Third
2020-05-03 14:18                   ` Lars Ingebrigtsen
2020-05-03 16:07                   ` Eli Zaretskii
2020-05-03 16:24                     ` Alan Third
2020-05-03 16:49                       ` Eli Zaretskii
2020-05-03 18:38                         ` Alan Third
2020-05-03 19:17                           ` Eli Zaretskii
2020-05-09 14:27                       ` Alan Third
2020-05-09 19:54                         ` Alan Third
2020-05-15 11:09                           ` Eli Zaretskii
2020-05-15 21:40                             ` Alan Third
2020-08-22 16:15                               ` Alan Third
2020-08-22 16:28                                 ` Lars Ingebrigtsen
2020-08-22 16:54                                 ` Eli Zaretskii
2020-08-22 18:57                                   ` Alan Third
2020-08-22 19:17                                     ` Eli Zaretskii
2020-08-22 21:35                                       ` Alan Third
2020-08-23  5:47                                         ` Eli Zaretskii
2020-08-23  9:09                                           ` Alan Third
2020-08-23  9:11                                             ` Eli Zaretskii
2020-08-23 11:48                                               ` Alan Third
2020-08-23 12:05                                                 ` Eli Zaretskii
2020-08-23 12:19                                                   ` Alan Third
2020-08-23 12:23                                                     ` Eli Zaretskii
2020-08-23 15:29                                                       ` Alan Third
2020-08-23 15:43                                                         ` Lars Ingebrigtsen
2020-08-23 16:08                                                           ` Alan Third
2020-08-23 16:38                                                             ` Lars Ingebrigtsen
2020-04-27  2:27               ` Eli Zaretskii

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='CAOqdjBeJOD0J6m8=0nJ_oBs_NE0cMZQHHQfTViK3NaCk50KRkw@mail.gmail.com' \
    --to=pipcet@gmail.com \
    --cc=40845@debbugs.gnu.org \
    --cc=cpitclaudel@gmail.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 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).