I've been trying to implement OpenType justification (JSTF table) in SILE, and, well, I can see why nobody else has done much with it so far. If I were writing the specification, here are some things about JSTF that I would change:
- The concept of extender glyphs is underspecified. Here is what the spec says about it: "Each script also may supply a list of extender glyphs, such as kashidas in Arabic. A client may use the extender glyphs in addition to the justification suggestions." This does not tell you (a) where extender glyphs may be inserted; (b) when they may be inserted and how this interacts with the other extension suggestions (at the start? before each one? at the end?); and (c) how this interacts with shaping. (If the client inserts a tatweel between beh and reh, are we expected to get another round of shaping to tidy up the connections?) I'm also unconvinced that the idea is necessary. You can get around all of the above problems by removing the extender glyphs concept altogether and encoding the kashida insertion rules as substitution suggestions. (suggestion 1: "sub beh' reh' by beh_tatweel1_reh", suggestion 2: "sub beh' reh' by beh_tatweel2_reh", etc.)
- The fact that each suggestion includes ways of shrinking and expanding a line is confusing. Are we supposed to use both at the same time? A list of ways to make a line longer and a list of ways to make a line shorter would make more sense and be easier to process.
- A priority list of suggestions is not the most flexible way to communicate extension/shrinkage opportunites. From a layout engine perspective, justification is normally implemented using a dynamic programming algorithm to minimize a penalty variable. It would be helpful to have the font specify penalty values for each substitution, rather than a flat order of execution.
- The OpenType Specification's references to "clients" are not helpful. There is often a division of labour in OpenType into three parts - font, shaper, layout engine. Shapers deal with text runs and don't really know about lines. Layout engines, which know about lines and talk to shapers, can tell shapers about features but not about lookups. So specifying the suggestions in terms of lookups doesn't help anyone. More generally, implementation-wise, the JSTF table is a mess. It's patterned somewhat after GSUB/GPOS, but not enough that we can reuse code. It contains references to data in two different external tables, so you have to jump into those anyway, but it uses its *own* language/script matrix instead of theirs.
I've written some code to add a JSTF table to a font by pulling lookups out of specially named GPOS/GSUB features, but I can't help thinking that if the specially-named features were the way that the justification system was specified in the first place, it would be an awful lot easier for layout engines to implement.
Now, given that the table's already in the spec, (Harfbuzz has code to parse the thing even if it does nothing else with it) if there anything that can be done about this? And given that we have jalt and JSTF already, is there any mileage in suggesting a third OpenType justification approach?