unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
From: Steve Molitor <stevemolitor@gmail.com>
To: Eli Zaretskii <eliz@gnu.org>
Cc: emacs-devel@gnu.org
Subject: Re: How to use "smart kerning" font features in Emacs using composition-function-table
Date: Sun, 26 Nov 2023 13:49:13 -0600	[thread overview]
Message-ID: <CAJrM8VUCHroxFfsWqJgcMo_Bx9W+PprVEvZjZ-pA11iO3kzaNA@mail.gmail.com> (raw)
In-Reply-To: <83ttp89zbk.fsf@gnu.org>

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	other threads:[~2023-11-26 19:49 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-11-26 15:48 How to use "smart kerning" font features in Emacs using composition-function-table Steve Molitor
2023-11-26 17:52 ` Eli Zaretskii
2023-11-26 19:49   ` Steve Molitor [this message]
2023-11-26 20:16     ` Eli Zaretskii
2023-11-26 20:42       ` Steve Molitor
2023-11-27 12:03         ` Eli Zaretskii
     [not found]           ` <CAJrM8VW0P+-cO_cup6W-teoJV46nZTcsPrFbaKdXDD_CK_5Rxw@mail.gmail.com>
2023-11-27 15:22             ` Eli Zaretskii
2023-11-27 16:16               ` Steve Molitor
2023-11-28  5:18           ` Yuan Fu
2023-11-28 13:27             ` Steve Molitor
2023-11-29  0:58               ` Yuan Fu
2023-11-28 14:20             ` Eli Zaretskii
2023-11-29  0:57               ` Yuan Fu

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=CAJrM8VUCHroxFfsWqJgcMo_Bx9W+PprVEvZjZ-pA11iO3kzaNA@mail.gmail.com \
    --to=stevemolitor@gmail.com \
    --cc=eliz@gnu.org \
    --cc=emacs-devel@gnu.org \
    /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).