emacs-devel
[Top][All Lists]
Advanced

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

Re: Ligatures (was: Unify the Platforms: Cairo+FreeType+Harfbuzz Everywh


From: Pip Cet
Subject: Re: Ligatures (was: Unify the Platforms: Cairo+FreeType+Harfbuzz Everywhere (except TTY))
Date: Thu, 21 May 2020 21:06:27 +0000

On Thu, May 21, 2020 at 7:08 PM Eli Zaretskii <address@hidden> wrote:
> > From: Pip Cet <address@hidden>
> > Date: Thu, 21 May 2020 16:26:13 +0000
> > Cc: address@hidden, address@hidden, address@hidden
> >
> > On Thu, May 21, 2020 at 2:11 PM Eli Zaretskii <address@hidden> wrote:
> > No. I didn't touch the "static compositions" part at all, except for
> > passing an extra NULL pointer to an API I'd extended. (At least,
> > that's what I intended, for all the changes to be in the IT_CHARACTER
> > part).
>
> I mean this part:
>
>   @@ -30433,8 +30483,9 @@ gui_produce_glyphs (struct it *it)
>                 else
>                   {
>                     get_char_face_and_encoding (it->f, ch, face_id,
>   -                                           &char2b, false);
>   -               pcm = get_per_char_metric (font, &char2b);
>   +                                           &char2b, false,
>   +                                           make_context (it));
>   +               pcm = get_per_char_metric (font, &char2b, make_context 
> (it));
>                   }
>
> This calls make_context and passes it to these functions.  This code
> handles static compositions only.

Oops, sorry. You're right, that change was harmless but unintended;
the relevant change is

@@ -29989,9 +30033,11 @@ gui_produce_glyphs (struct it *it)
            it->descent = FONT_DESCENT (font) - boff;
          }

-      if (get_char_glyph_code (it->char_to_display, font, &char2b))
+      context = make_context (it);
+      if (get_char_glyph_code (it->char_to_display, font, &char2b,
+                   context))
         {
-          pcm = get_per_char_metric (font, &char2b);
+          pcm = get_per_char_metric (font, &char2b, context);
           if (pcm->width == 0
           && pcm->rbearing == 0 && pcm->lbearing == 0)
         pcm = NULL;


> > > The "modern" way of composing text in Emacs uses automatic
> > > compositions, which are controlled by data in
> > > composition-function-table.  This is where we call the shaping
> > > engine to produce the glyphs according to rules stored in the
> > > font.  I don't see in your patch any changes that affect ligatures
> > > created by automatic compositions; did I miss something?
> >
> > I don't think so; I went for a third route, that of leaving all
> > compositions handling to the shaper and doing none of it in Emacs
> > itself.
>
> But automatic compositions do work by calling the shaper.

Yes, that observation is correct. What I'm doing is still very
different from the (semi-)automatic compositions composite.c does.

> > Perhaps I can digress a little and describe what I think the
> > interaction with the shaper should be like:
> >
> > Emacs: I'd like to display codepoint 'f'
> > Harfbuzz: you'll have to tell me the codepoint before that
> > Emacs: 'f'
> > Harfbuzz: and the one after those two
> > Emacs: 'i'
> > Harfbuzz: and the one before all of those
> > Emacs: That's too expensive for me to compute / it's the beginning of
> > paragraph / a bidi boundary / an object without an assigned codepoint
> > / ...
> > Harfbuzz: okay, display it as the middle slice of the "ffi" glyph
> >
> > I.e., I'd like Harfbuzz to be asynchronous, and request more
> > information, parsimoniously, about the context of the codepoint we're
> > describing, rather than working in one go from "complete" information
> > to an indefinitely-long line of glyphs. And deal well with us deciding
> > it's too expensive to perform that much look-back/look-ahead. (Because
> > in real life, ligatures depend on knowing some amount of the context,
> > but not all of it, or people could never start writing.)
>
> That would prevent Emacs from controlling what is and what isn't
> composed, leaving the shaper in charge.

Well, yes and no: the shaper is in charge, and I see absolutely
nothing wrong with that. You can tell the shaper not to perform
ligatures (or perform only some of them), or kerning, if you want to.

> We currently allow Lisp to
> control that via composition-function-table, which provides a regexp
> that text around a character must match in order for the matching
> substring to be passed to the shaper.

And you're suggesting that regexp be set to, say, ".+"? Because that's
the only way I've found of getting it to do kerning.

> We never call the shaper unless
> composition-function-table tells us to do so.

...whereas I want to call it every time, which is why having
composition-function-table in the loop seemed wasteful.

> I'm not sure I understand what problems do you see with this design.

I meant the redisplay engine in general, not the way automatic
compositions work.

(That's not to say I'm happy with automatic compositions, but that's a
different subject).



reply via email to

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