Coding: Deactivating ligatures in the superscript feature

Hello Typedrawers,
this is my first post, so beforehand I want to thank you all for the tremendous amount of information that can be found here.

I'm a graphic designer and over the last months I developed a script typeface. My approach was quite straightforward, I didn't want the typeface to be overly realistic and complex, all I wanted was to eliminate basic redundancies. I chose to replace letters A-Z and figures 0-9 with custom ligatures via the "liga" feature, in case they were repeated right next to each other. So if "99" is typed, it gets replaced by "99 ligature".

Everything works to my liking, but after adding superscript figures I ran into this problem: As the "liga" feature replaces double figures (eg "99" with the "99 ligature"), these figures are not affected when activating the "sups" feature. Of course the "liga" feature could be turned off manually in the layout program, but that doesn't feel like a professional solution.



Being absolutely no coding-guy, I tried to break the ligatures apart in the "sups" code before exchanging them with the superscript figures like this:

feature sups {
sub nine_nine by nine nine;
sub @figures by @figuresSuperscript;
} sups;

This works in the Fontlab preview, but not in Indesign.

So what I want is: When the "sups" feature gets activated, all figure-ligatures should be eliminated and replaced by the superscript figures (nine_nine -> ninesuperior ninesuperior), without having to turn off the "liga" feature.

What would be a nice way to achieve this? Thanks!

Comments

  • I love it when solutions are that simple. Thanks a lot, @Robin Mientjes, the magic works.
  • On why your code

    feature sups {
    sub nine_nine by nine nine;
    sub @figures by @figuresSuperscript;
    } sups;

    does not work: always keep in mind a subtable is processed only once, and the first match exits. Thus, since nine_nine matches, that next rule is never executed. This is similar to having ligatures /f_f and /f_f_i in the right order (FYI, there /f_f_i must come first, OR you must have an explicit new table that changes /f_f /i into /f_f_i, which is computationally far less efficient).

    So, theoretically you could have tried adding a new subtable after the /nine_nine but on close inspection it seems that your first rule doesn't even fire... (your sups+liga still shows the liga form). As Robin's fix works, there must be something in InDesign that prevents this, although I cannot come up with any good reason.
  • Thomas PhinneyThomas Phinney Posts: 1,635

    So, theoretically you could have tried adding a new subtable after the /nine_nine but on close inspection it seems that your first rule doesn't even fire... (your sups+liga still shows the liga form). As Robin's fix works, there must be something in InDesign that prevents this, although I cannot come up with any good reason.
    I don’t know if it is still true, but long ago, the core text engine used by InDesign made some assumptions about kinds of layout needed for different OT features. That definitely included thinking that some features would be done by GSUB rather than GPOS. It might have also included not having a many-to-one substitution done by the 'sups' feature—expecting that to be a one-to-one substitution only. I don’t explicitly recall this, but it seems... familiar... and is a similar kind of thinking.

    If my suspicion were correct, the same code might work fine in a non-Adobe app. Could try it in a web browser or something.

    @Robin Mientjes What version of InDesign were you running, btw?
  • Thanks Theunis and Thomas for further examination. I just tested my sups feature in Illustrator and Libre Office, and you are right - it doesn't work there. So it must be something Indesign does - I tested in CS6. I'll modify my code.
  • Isn’t it also a thing to group your lookups? So if you have a many-to-one, it’s smart to have that be a different lookup than a one-to-many or a one-to-one. That might be breaking the code.

    As for Theunis’s tests, it seems that the old rule of “f_f_i before f_i” isn’t valid anymore – it works either way, as the lookup is parsed as a whole, not line by line. It just means keeping your lookups straight – in general a healthy habit.

    But smarter people can correct me on this, please.
  • Robin: it's actually "ffi" before "ff", not "fi".

  • As for Theunis’s tests, it seems that the old rule of “f_f_i before f_i” isn’t valid anymore – it works either way, as the lookup is parsed as a whole, not line by line. It just means keeping your lookups straight – in general a healthy habit.
    Actually I believe what's going on here is that AFDKO automatically reorders ligature substitutions at compile time.

    https://adobe-type-tools.github.io/afdko/OpenTypeFeatureFileSpecification.html#5.d
  • @André G. Isaak That says the ‘implementation software’ – I don’t think the AFDKO is meant by that, but rather text layout software. I think maybe @Roel Nieskens mentioned some time ago that the order didn’t matter, but I can’t find it right now.
  • The text isn't very clear on this — the reason I am taking this to mean the ADFKO is that in the example it gives it says both orders would produce an identical representation in the font which would suggest it is talking about a compiler rather than layout software. I could, of course, be wrong.
  • @André G. Isaak That says the ‘implementation software’ – I don’t think the AFDKO is meant by that, but rather text layout software. I think maybe @Roel Nieskens mentioned some time ago that the order didn’t matter, but I can’t find it right now.
    ‘implementation software’ usually means AFDKO’s makeotf in that spec, and I believe that AFDKO does re-order the substitutions. No layout engine does such re-ordering, to the best of my knowledge.
  • They mean the AFDKO, as layout engines should not reorder. FontCreator automatically re-orders ligatures if needed.

    Also note that the order of features is not significant, but the order of lookups. In the above sample code the order of the lookups is determined by the order of the features, but that is not always true, as for example a lookup can be reused in other features.

    To make it more confusing, some shaping engines always process specific features and their lookups in a pre-defined order. For example the Universal Shaping Engine, used by Microsoft, will always first process lookups in the liga feature, then the lookups in sups. So if you are looking for consistent behaviour, I would not place sups before liga.

    One last thing, one-to-many and many-to-one will never end up in the same lookup.

    Hope this helps.
Sign In or Register to comment.