emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to use "smart kerning" font features in Emacs using composition-


From: Steve Molitor
Subject: Re: How to use "smart kerning" font features in Emacs using composition-function-table
Date: Sun, 26 Nov 2023 13:49:13 -0600

Thanks for the clear response! It makes perfect sense and confirms what
I was seeing.

> So to use kerning like the one you describe, I think you must have a
> rule that matches any sequence of ASCII letters, not just the triplets
> where the kerning is supposed to happen.

Thanks. This indeed does work (matching against the characters Commit
Mono applies its kerning effect to):

(set-char-table-range
 composition-function-table
 t
 `(["[ ,-.:;A-Z_a-z]+" 0 font-shape-gstring]))

I see the "smart kerning" effect as expected. So far after a quick test
performance seems ok but we'll see. I did notice that if I changed the
PREV-CHARS value from 0 to 1 I would get seconds-long redisplay delays!

> But -- and it's a very significant "but" -- displaying text via the
> shaping engine is expensive -- it involves calls from the display
> engine to Lisp, which then calls back into C. So rules that match any
> sequence of ASCII letters will slow down redisplay of almost any text
> in Emacs. This is why Emacs by default doesn't use the text-shaping
> engine except for scripts that cannot be displayed without non-trivial
> character compositions.

Which scripts use the text-shaping engine? Is it possible to optionally
use the text-shaping engine and bypass Lisp in say the "English" script?
I understand that certain features like mode-specific ligatures might
stop working, but it could be a nice option.

Thanks again,

Steve



On Sun, Nov 26, 2023 at 11:53 AM Eli Zaretskii <eliz@gnu.org> wrote:
>
> > From: Steve Molitor <stevemolitor@gmail.com>
> > Date: Sun, 26 Nov 2023 09:48:34 -0600
> >
> > Using composition-function-table, is it possible to have the font
> > render a glyph for each character, based on the previous and following
> > character, in a moving window? For example, the rendering of character
> > 1 will depend on what characters 0 and 2 are, character 2 depends on 1
> > and 3, etc.
>
> Not really, see below.
>
> > I decided to see if I could get it to work just for the "Commit"
> > string by adding the following elisp:
> >
> >     (set-char-table-range composition-function-table ?o
> >                                      '(["Com" 1 font-shape-gstring]))
> >     (set-char-table-range composition-function-table ?m
> >                                     '(["mmi" 1 font-shape-gstring]))
> >
> > My thinking was if the current character is "o", preceded by a "C" and
> > followed by an "m", let the font replace the "o". Next, if the current
> > character is an "m" preceded by an "m" and followed by an "i", let the
> > font render the middle "m". If that worked I was going to do something
> > more generic.
> >
> > It half worked. If I type "Com" it works as expected - the "o" shifts
> > slightly to the left when I type the "m":
> >
> > https://cdn.zappy.app/f1506de028c470750428ebf984dfbe41.gif
> >
> > If I type "mmi" on a separate line it also works - the second "m"
> > shifts to the left when I type the "i":
> >
> > https://cdn.zappy.app/6a1a90013d102bfb494fc7d1de54ca32.gif
> >
> > However, if I type "Commit", the "Com" works (the "o" shifts"), but
> > nothing happens when I type "mit". If I use three m's and type
> > "Commmit" I do see the effect on the final "mit":
> >
> > https://cdn.zappy.app/e98141872235a25bf52f6e332b610d7b.gif
> >
> > It seems I've created 3 character, non-overlapping gifs, which is not
> > the effect I want.
> >
> > For comparison, here it is in VSCode, typing "Commit". Various
> > shifting effects happen as expected:
> >
> > https://cdn.zappy.app/8f3bc49a174c4673747c402f7b39d54b.gif
> >
> > I think when Emacs matches the 3 character regexp in the composition
> > function table, it assumes that those 3 characters constitute a single
> > glyph or ligature. That makes sense for ligatures, but it's not what I
> > want here. I want a "moving window" where the glyph for each character
> > depends on the previous and following character.
> >
> > Is this possible to do in Emacs currently?
>
> No, it's not possible.  When characters are composed successfully
> (i.e., they match some rule in composition-function-table, and the
> font support their composition), Emacs will not examine them again for
> other rules.  It will restart examining from the first character
> _after_ those which matched.
>
> So to use kerning like the one you describe, I think you must have a
> rule that matches any sequence of ASCII letters, not just the triplets
> where the kerning is supposed to happen.  Which means that every word
> using ASCII characters will be passed to the text-shaping engine.
> Then the shaping engine will decide on its own where to use the
> kerning, and I think you should get what you want, appearance-wise.
>
> But -- and it's a very significant "but" -- displaying text via the
> shaping engine is expensive -- it involves calls from the display
> engine to Lisp, which then calls back into C.  So rules that match any
> sequence of ASCII letters will slow down redisplay of almost any text
> in Emacs.  This is why Emacs by default doesn't use the text-shaping
> engine except for scripts that cannot be displayed without non-trivial
> character compositions.  So if you go the above way, don't be
> surprised if you see slower redisplay.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]