(Cross-posted on the OpenType list, with apologies)
I've been helping with production of a typeface, which cycles through alternate versions of its letters. The idea is that the next time the same letter shows up in a line, the font will select the next version of that letter. So essentially each letter needs to do its own independent cycling. In other words, if a user types "abbakang" they should they get a b b.1 a.1 k a.2 b.2 a.3 n g1.That is, each time a specific letter comes up, it needs to pick the next alternate, relative to the last one that came up.
I have no problem coming up with code to do this, but the problem is the code is freakin' huge. I'm wondering if there is any more efficient approach that gets the same effect? (I do know easy ways to do this if one just cycles through a different alternate where each glyph is dependent on the immediately preceding glyph. But that's not the assignment here, unfortunately.)
Of course, it may be that there is no more efficient way of doing exactly this, which would be why few if any fonts have used this style of letter cycling. :/
Here's what I have so far, in AFDKO/FontLab feature syntax. The "not_A" class contains every glyph *except* the A and its variant forms. Similarly the "not_B" class.
feature calt {
lookup AA useExtension {
sub A A' by A.1 ;
sub A.1 A' by A.2 ;
sub A.2 A' by A.3 ;
sub A.3 A' by A ;
sub A @not_A A' by A.1 ;
sub A.1 @not_A A' by A.2 ;
sub A.2 @not_A A' by A.3 ;
sub A.3 @not_A A' by A ;
sub A @not_A @not_A A' by A.1 ;
sub A.1 @not_A @not_A A' by A.2 ;
sub A.2 @not_A @not_A A' by A.3 ;
sub A.3 @not_A @not_A A' by A ;
sub A @not_A @not_A @not_A A' by A.1 ;
sub A.1 @not_A @not_A @not_A A' by A.2 ;
sub A.2 @not_A @not_A @not_A A' by A.3 ;
sub A.3 @not_A @not_A @not_A A' by A ;
sub A @not_A @not_A @not_A @not_A A' by A.1 ;
sub A.1 @not_A @not_A @not_A @not_A A' by A.2 ;
sub A.2 @not_A @not_A @not_A @not_A A' by A.3 ;
sub A.3 @not_A @not_A @not_A @not_A A' by A ;
sub A @not_A @not_A @not_A @not_A @not_A A' by A.1 ;
sub A.1 @not_A @not_A @not_A @not_A @not_A A' by A.2 ;
sub A.2 @not_A @not_A @not_A @not_A @not_A A' by A.3 ;
sub A.3 @not_A @not_A @not_A @not_A @not_A A' by A ;
... and so on with more backtracking context
} AA ;
lookup BB useExtension {
sub B B' by B.1 ;
sub B.1 B' by B.2 ;
sub B.2 B' by B.3 ;
sub B.3 B' by B ;
sub B @not_B B' by B.1 ;
sub B.1 @not_B B' by B.2 ;
sub B.2 @not_B B' by B.3 ;
sub B.3 @not_B B' by B ;
sub B @not_B @not_B B' by B.1 ;
sub B.1 @not_B @not_B B' by B.2 ;
sub B.2 @not_B @not_B B' by B.3 ;
sub B.3 @not_B @not_B B' by B ;
... and so on with more backtracking context
} BB ;
... repeat with one lookup for each letter
} calt;
Suggestions welcome!
T
P.S. Despite my use of "code" formatting, my leading spaces are getting deleted. Oh well, I imagine it's clear enough.