On 19/2/13 22:34, Behdad Esfahbod wrote:
Hi Lóránt,

On 02/19/2013 12:20 PM, Lóránt Pintér wrote:
Hi,

I have a problem with half-colored ligatures, like "(5) mfim" in the image:

Right.  That's one of the harder issues of text rendering.

I figured out two ways to do this, but neither is good enough:

   * I can shape each color range separately, but then I lose the kerning
     between them, breaking (6)

Yes.  Best to not do this.

   * I can tell HarfBuzz to disable ligatures for the last of the first
     character of each color range, but then it breaks (2) or (3) and (4).

Right.  This is a limitation of HarfBuzz currently, that you can't turn off a
pair-wise feature on one pair only, since changing the "liga" bit on one
character affects it in both directions.

I haven't been able to find a satisfactory fix for this yet.  I'll think about 
it.

In general, I don't think it's clear exactly how these sort of "edge cases" ought to work.

Suppose you have a glyph sequence A X B, and the 'liga' feature is enabled for A and B, but not for X; but further suppose that X is a mark glyph, the liga lookup ignores marks, and there's an AB ligature. Should it be applied here?

Another possible approach to "disabling" ligatures at the color change - given that harfbuzz doesn't know anything about color, that must be something that your application is maintaining - might be to insert a ZWNJ character at that position in the text. With the latest harfbuzz code, I believe kerning would still apply correctly across this, but it should prevent the ligature.

Is there maybe a way to tell HarfBuzz to ignore ligatures if they span that
color boundary? Or is there maybe a way to (quickly) assess if "liga" would be
applied to a range of characters?

We don't have a good answer for this right now.  The way I want to eventually
fix this in Pango is different: it is to pain the ligature glyph half in each
color.  I think you can do the same using <canvas>.  Just use a gradient with
a sharp color switch for the ligature.  It's a royal pain, but I think that's
the most desirable rendering.  I may be wrong.

It's a reasonable rendering for typical Latin ligatures in "simple" text fonts. It doesn't work so well for more cursive cases. E.g. using this approach to color the middle "f" of Zapfino's "ffi" will look rather weird, as will coloring the parts of Arabic lam-meem-hah in a font with "stacked" ligature forms.


As for *where* to cut the ligature, here's what you need:

   * Count the number of cursor positions *inside* the ligature.  For the "fi"
ligature it's one.  And we have one cursor position before the ligature, so in
this case we need to cut it in two pieces,

   * The common heuristic then is to cut the advance width of the ligature
(well, cluster really) into two equal pieces.  If you want to be fancy, you
can call hb_ot_layout_get_ligature_carets(), and if the number of carets
matches what you expect (1 in this case I believe?), you can use the returned
caret positions instead of equally dividing the ligature.  I haven't seen
anyone implementing this though, as it gives very marginal improvements over
the heuristic.

Particularly as I suspect that relatively few fonts actually have GDEF tables that define ligature-caret positions with any more care than simply dividing up the advance width into equal parts.

JK

_______________________________________________
HarfBuzz mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/harfbuzz

Reply via email to