latex3 / luaotfload

OpenType font loader for LuaTeX
Other
60 stars 7 forks source link

GSUB/GPOS multiple glyphs per type only partially kerned #182

Open alainstalder opened 3 years ago

alainstalder commented 3 years ago

See https://tex.stackexchange.com/questions/593281/lualatex-gsub-gpos-multiple-glyphs-per-type-only-partially-kerned

There is a workaround (use HarfBuzz as Renderer), but the default renderer seems to have a bug regarding kerning, as exposed there. I am submitting this here since the accepted answer suggested to "raise an issue at luaotfload to see if this could be supported in the default mode as well".

zauguin commented 3 years ago

Probably wontfix since it doesn't really work with LuaTeX's linebreaking, but we can try asking the ConTeXt team.

alainstalder commented 3 years ago

I guess I am too far away from the actual implementation to understand the reply, and it was probably not or not only addressed to me. ;)

What I can say is the following:

For testing I also made a font that defines the same kerning values as Jackwriter.ttf, but with only one glyph per type, i.e. only "a" but not rotated to "a.2" ... "a.9" as in TT2020:

https://www.artecat.ch/jexler/kerning/JackwriterLite.ttf

With that font kerning works in LuaLaTeX both with the default renderer and with the HarfBuzz renderer.

Here's the output with the default renderer:

https://www.artecat.ch/jexler/kerning/kerning-lualatex-lite.pdf

Note that all xxxx's all have the intentional defect at the top right, while for the full Jackwriter font only the first of every 9 glyphs has that defect.

zauguin commented 3 years ago

@jexler Right, it was mostly an internal remark. What I wanted to say was:

The non-HarfBuzz shaper is based on imported ConTeXt code, so this would have to be fixed by the ConTeXt team first. But I think it's unlikely that it will be fixed, since such fonts don't interact nicely with LuaTeX's linebreaking/hyphenation implementation.

If you are interested in the technical details: Basically in LuaTeX shaping is done completely before linebreaking, so variantions which can occur based on linebreaking must be represented in discretionary nodes, which basically correspond to TeX's \discretionary primitive. So they allow separate text pre/post/replacement text around potential breakpoints, but these can't be nested. So every character can be in at most one discretionary node and therefore have at most two possible representations. But e.g. in your iiiiiiiii (which can get hyphenated almost everywhere according to english hyphenation rules) the last i might come after 2, 3, 4, 5, 6, 7, or 8 other is depending on linebreaking. Since these would all lead to different glyphs being used, the shaper can not output all options correctly and therefore sometimes does the wrong replacement. (In the HarfBuzz mode we are working around that by removing linebreaking opportunities when necessary, which leads to other issues)

Your kerning issue is just an indirect consequence of that: Due to the replacement issue, you just get the i, i.2, i.3, i, i, i, i, ... instead of i, i.2, i.3, i.4, i.5, ..., then the kerning between the "i"s isn't applied since the font doesn't set kerning there (since it never expects multiple "i" do come after one another) Of course this doesn't happen if the replacements are removed since then the font is designed for this case.

alainstalder commented 3 years ago

Thanks a lot for the details. :)

I made a version of the font with "full kerning", i.e. from "" to "", ".2", ... ".9" for all combinations:

https://www.artecat.ch/jexler/kerning/JackwriterFullyKerned.ttf

The hope was that this would alleviate things: glyphs not always rotated, but kerning OK. But unless I got something wrong, it only improves things, with still some cases left where no kerning is applied (e.g. last "i" in the "iiiii"s).

I guess I will leave it at that, no workaround seems possible.

ctrlcctrlv commented 2 years ago

Hello friends, I made the original font, and I'm wondering if I can do anything to help.

TT2020 is actually, from our viewpoint in almost entering 2022, based on a bit outdated technology. That's not to say I'm doing anything out of spec, or to say that it's gonna break or be deprecated, no, it will work for all time so long as GSUB spec remains the same.

But, there is a new spec called rand, pseudo randomization built into the font format! If you have a rand feature in GSUB, and use the aalt lookup type, you get randomized glyphs.

Would this help your program? I plan to rerelease a patched TT2020 eventually that will have rand, with the old rotation as a fallback.

By the way, making a proportional font out of my TT2020 with kerning is very interesting and I do like Jackdaw, but I do wonder why you don't just adjust the bearings...?

alainstalder commented 2 years ago

By the way, making a proportional font out of my TT2020 with kerning is very interesting and I do like Jackdaw, but I do wonder why you don't just adjust the bearings...?

Is there a way to do the same without kerning (so far in kern and GPOS tables)? I could adjust the widths of the glyphs and eliminate most kerning pairs, but not all of them—unless maybe there was another way to handle the remaining pairs?

I guess even a partial improvement could make some sense, then, say, MS Word users would at least get a proportional font, although without any glyph rotation and without remaining kerning pairs... My approach in that respect had been to rather fail early and clearly on systems that do not really support the really cool features.