Subject: bug#40845: SVG rendering issues

From: Pip Cet <[email-masked]>
Date: Sun, 26 Apr 2020 10:15:39 +0000

On Sat, Apr 25, 2020 at 8:11 PM Eli Zaretskii <[email-masked]> wrote:
> > From: Pip Cet <[email-masked]>
> > Date: Sat, 25 Apr 2020 19:41:31 +0000
> > Cc: [email-masked], [email-masked]
> >
> > My use case is to include a glyph which is supposed to look like a
> > character, but doesn't actually have a unicode codepoint.
> >
> > That means that we want to use an image spec, not a character in a
> > font; but that image spec depends on face/font properties, because we
> > want to blend in with surrounding text. The most obvious ones are
> > foreground and background color and size, but slant and weight would
> > also affect properly-rendered character-like images.
>
> If we want to display an image, the logical way would be to use an
> image spec, which is already supported, enhancing it as needed.

I want to display a glyph that looks different depending on its
textual context. That means it's not "an image", in the traditional
sense. and enhancing image specs to handle such context-dependent
glyphs is wrong, because it moves code into the image backend that
applies to all image backends.

To be clear, to me "an image" is a compressed way of storing RGBA
information for each pixel in a rectangle. It has no concept of
foreground color or background color or slant or weight.

The enhancement I propose is a layer of indirection, allowing the
image spec itself to be adjusted to face/font properties. Whether or
not it's best to use a Lisp function for that, or a hash table, is
something I'm not clear about yet.

> I don't see anything in the above attributes that would be hard to have
> within the existing framework of how we display images.

I don't see anything in the above attributes that would be possible to
have without major changes to image backends, for features that do not
depend on the image backend.

> I don't
> really understand how you can make images "slant" or "bold" (unless
> they were like that to begin with), or why would we want to, but maybe
> there's some way of interpreting that as well.

Because we want the glyph to blend in with surrounding text. Like a
character. Thus "character-like glyph". It's not an image. My use case
is displaying character-like glyphs, implemented as
dynamically-generated images, not to display final images.

And, no, there's no way for an image backend to interpret that. We
have to use different image specs.

> None of this requires a new spec or calling Lisp.

I don't see how to do it without a new spec. I do see an obvious way
of doing it without calling Lisp, by using, say, a hash table. That's
an implementation detail, and one I'm willing to argue about, but "you
want images, not character-like glyphs" isn't an argument, it's simply
a statement that you don't want my use case to be supported.

> All of the metrics
> of the current face's font are known by the display code, and there
> are many that cannot be obtained from Lisp, like the current line
> height.

Indeed, so the display code has to expose those to Lisp.

> Doing these calculations in Lisp is IMO the worst possible
> way of using Lisp callouts from the display engine: this has all the
> disadvantages of calling Lisp, and none of the advantages.

The advantage is my use case is supported, and with your proposal
(which I don't understand completely, but it appears to be a
perfunctory implementation of "foreground"/"background" colors for
images) it isn't.

Whether we should call Lisp (which would, in practice, return a cached
image spec most of the time) or use a hash table (and we'd have to
somehow trigger Lisp updating that hash table) is something I'm not
clear about. Since we're already calling Lisp from code in the
vicinity, it seems relatively safe to do so.

> > It seems fairly obvious to me that it's a bad idea to do all the work
> > in the display engine or in C code: sub-pixel rendering and
> > anti-aliasing are hard to get right.
>
> Aren't we talking about displaying existing images, which someone
> already prepared while using all those techniques?

I'm talking about displaying character-like glyphs.

> Why would the
> display engine want or need to modify the image using them?

To make the glyph character-like.

> > A character-like glyph might need a third color which provides
> > sufficient contrast to the foreground and background colors, and
> > that color space calculation is complicated enough to be moved to
> > Lisp.
>
> Within the context of what these icons are supposed to be used for, I
> envision the images coming with bright, catchy colors that should be
> left alone, not enhanced by color and contrast tweaking of whatever
> happens to be the face colors the user wants.

I'm not sure which icons you're thinking about, but I certainly don't
want my symbols to have "bright, catchy colors that should be left
alone". That's one valid thing for the Lisp code to do, to leave the
image alone and not modify it, but I want the option to have
character-like glyphs, which look like characters but aren't, and that
means they don't have bright, catchy colors that should be left alone.

> Those who design such
> icons do a much better job than any Lisp program.

That's an end user decision, not something we should assume a priori.

> > But all these limitations are fixable.
> They wouldn't have existed if you used the code which displays images.

I want to display character-like glyphs. I don't see a way doing that
with existing image specs, because the image specs do not depend on
face/font properties. I'm still not sure what you're proposing, but
making images depend in a brutish way on "foreground" and "background"
color is a highly specific and limited solution that doesn't solve my
use case at all.

> So I still don't understand the motivation for this approach.  (Read:
> I think it's wrong.)

I'm still not sure whether you're suggesting anything that would
handle my use case even remotely, or simply saying it's not a use case
that Emacs should be extensible to. I've certainly not seen any
suggestion that would do the former.

But, just to be clear, I posted this code because I'd already made the
minor effort to get a new (and, IMHO, important) Emacs feature to
work. I deliberately decided not to submit it, because while it is a
new, generally useful feature Emacs sorely lacks, there are both
productive discussions to have about it (such as whether it uses a
hash table or a Lisp function calls) and unproductive ones, and the
latter in particular translate to a major effort that I did not at the
time feel was worth it.