Need help with calt features



As you can see the combination “nxxn” works fine but in “oxxn” the second “x” is wrong.
Funnily, with “s” everything works as it should, even though I don’t think I did anything different there.
Any ideas what I might have done wrong?


Please share the OpenType code in your calt feature


Here it is!

lookup IsolForms {
	ignore sub @isolDef' @AllLetters, @AllLetters @isolDef';
	sub @isolDef' by @isolSub;
} IsolForms;

lookup InitForms {
	ignore sub @AllLetters @initDef';
	sub @initDef' by @initSub;
} InitForms;

lookup InitForms2 {
	sub @Uppercase @initDef' by @initSub;
} InitForms2;

lookup InitForms3 {
	sub @DisconnectedLowercase @initDef' by @initSub;
} InitForms3;

lookup FinaForms {
	ignore sub @finaDef' @AllLetters;
	sub @finaDef' by @finaSub;
} FinaForms;

lookup Finaforms2 {
	sub @finaDef' @Uppercase by @finaSub;
} Finaforms2;


This appears to be code for word-initial, word-final and isolated glyphs, but isn’t your problem with word-internal glyphs?


What do you mean by word-internal glyphs?


Oh, wait. I think I understand now.

When you’re going through the sequence n x x n, first the renderer deals with a sequence n x, subsituting, say, x.connectedonleft for x. Then the next sequence is x.connectedonleft x, and you don’t want a substitution there, and you’re (correctly) not getting one.

In the sequence o x x o, I suppose o is not in @DisconnectedLowercase, so you get no substitution of x. So the next sequence dealt with is x x, and if x is in @DisconnectedLowercase you’ll get the substitution of the second x–which you don’t want.

Am I understanding the situation correctly now?


What I don’t understand is also why this doesn’t happen with “s”.
“o” is in @DisconnectedLowercase.
Let me show you what else is there.

b eng eth f f_j.liga g gbreve gcommaaccent gdotaccent j ldot o oacute ocircumflex odieresis ograve ohungarumlaut omacron oslash otilde p q s sacute scaron scedilla scommaaccent s.init s.isol sacute.init scaron.init scommaaccent.init v w wacute wcircumflex wdieresis wgrave x y yacute ydieresis ycircumflex ygrave z zacute zcaron zdotaccent z.init zacute.init zcaron.init zdotaccent.init


Forgot to mention… when typing axxo this doesn’t happen and I get the right x (the not connected one).


So these glyphs are in @DisconnectedLowercase: o x

And these are not: a n

In the sequence o x x o the renderer will first encounter the pair o x and, applying your InitForms3 lookup, will make it (say) o x.alt.

Then the renderer moves along not to x x but to x.alt x. Since x.alt is not in @DisconnectedLowercase, InitForms3 will not make a substitution for the second x. But all the other lookups are also consulted for x.alt x. So a lot depends on what is in @AllLetters, @isolDef and @initDef. For example, if x.alt is not in @AllLetters and x is in @initDef, a substitution will be made for the second x by your InitForms lookup.

More abstractly, remember that given a sequence

1 2 3 4

The renderer will (a) deal with 1 2, sorting through the lookups till it finds one that applies, then will (b) deal with 2 3 as modified by (a), then deal with 3 4 as modified by (a) and (b), and so on.

I can’t be sure how these considerations apply without seeing all your classes, but it seems to me that everything depends on what’s in those classes.


Thanks a ton for your time and explanation! You are absolutely right.
I just had to add x.init to @DisconnectedLowercase. It’s solved now :slight_smile:


That’s great! Very glad to help. (I actually love writing feature code, believe it or not.)


That’s great! I would love to be more fluent in writing code, but then I make these stupid mistakes :smiley: