Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Kent Lew

About

Username
Kent Lew
Joined
Visits
1,864
Last Active
Roles
Member, Type Person
Points
541
Invited by
Admin James Puckett
Posts
513
  • Re: Multiple contextual alternates in sequence, based on proximity?

    Regarding floating lookup blocks: Generally, lookups [groups of rules] are compiled in the same order as the feature blocks in which they are declared. And typically, this is how you want it (and why you pay attention to the order of your feature blocks).

    However, sometimes there are multiple feature interactions where, when two features are activated at the same time, you want some rules in a downstream feature to take precedence over rules in the upstream feature — but not *all* rules (otherwise, you’d just reorder the features, right?).

    If you declare a lookup block on its own, outside of a feature block, it gets compiled in the order in which it actually appears, regardless of the order of the feature block(s) that it gets registered to. (Last I checked, this is an advanced subtlety that Tal doesn’t explain in his excellent OpenType Cookbook primer.)

    Here are some hastily composed, abstract examples.

    In the following example, you have two features with two sets of substitutions, both for x and y.
    feature ss01 {
    sub x by x.001;
    sub y by y.001;
    } ss01;

    feature ss02 {
    sub x by x.002;
    sub y by y.002;
    } ss02;
    Pretty standard. If both Stylistic Set 1 and 2 are active at the same time, then the .001 alternates will be rendered.

    But suppose that, when both Sets are active, you would want the y.002 to be displayed but the x.001 to still take precedence? The solution is to declare the y.002 substitution as a lookup outside a feature block and before the ss01 feature.
    lookup y2 {
    sub y by y.002;
    } y2;

    feature ss01 {
    sub x by x.001;
    sub y by y.001;
    } ss01;

    feature ss02 {
    sub x by x.002;
    lookup y2;
    } ss02;
    In this case, the y.002 substitution is still deployed by the ss02 feature, but the lookup itself is compiled ahead of the ss01 feature lookups. So, when both features are active simultaneously, the y.002 substitution is found first and gets implemented, despite the ordering of the features (which still determines how x gets handled).

    This advanced technique is usually only necessary when dealing with complex multi-feature and cross-feature interactions.

    I’m not sure this will be necessary in your case, since it seems like you’re talking about everything happening within just a single liga (or calt) feature.