Trouble with Contextual Swashes

Hi there,

I've created a font that has 3 character variations using calt (which works fine) and includes a set of 3 swash variations per character as well. The issue I'm having is I also want to include start and end swashes for select letters (a, e, i, o, r). I set up my code as such and it works perfectly fine in FontLab when I test it but when I try in Illustrator, only the start_swsh works. The end of the word remains normal.

feature swsh {
ignore sub @ALL @letter1' @ALL;
ignore sub @ALL @letter2' @ALL;
ignore sub @ALL @letter3' @ALL;
sub @letter1' @ALL by @start_swsh;
sub @letter2' @ALL by @start_swsh;
sub @letter3' @ALL by @start_swsh;
sub @ALL @letter1' by @end_swsh1;
sub @ALL @letter2' by @end_swsh1;
sub @ALL @letter3' by @end_swsh1;
sub @swsh1' by @swsh2;
} swsh;

I've been reading a lot of forums about it, and have seen people say you need to have different lookups for the start and the end, but I don't understand the code (when I type in 'lookup ____' I don't know if I'm suppose to have _____ somewhere else that it's looking up, or how that works, and the FontLab manual doesn't go into detail about this.)

I'm at my wits end with this, any help would be greatly appreciated.

Stephen Rapp's picture

What is in your @ALL class? If your end swash is in there and you told it to ignore that above that's one problem.

kimmyk's picture

I removed them, so it has every character in the font except the start and end swashes but it's still only working for the start_swsh (basically... no change.)

Any other thoughts?

Mark Simonson's picture

Try doing it like this (inside your calt feature):

lookup beginnings {
# ignore sub + sub code here
} beginnings;

lookup endings {
# ignore sub + sub code here
} endings;

kimmyk's picture

Wouldn't that make it so that every time contextual alternatives were turned on, the start and end swashes would appear? I only want them to appear when swashes are turned on.

kimmyk's picture

I tried it, and as I thought, the start swash appeared when contextual alternatives were turned on. The end swash still doesn't work :/

Mark Simonson's picture

Sorry, I meant in your contextual swash feature, not calt.

kimmyk's picture

Gotcha, thanks. I'm still having the same issue. It makes no sense and it's driving me nuts! Below is a screen shot of how it appears in FontLab, and the second image is how it looks in Illustrator. Even if I delete the start_swsh altogether and just have the end_swsh it doesn't work. When I delete the ignore part of the end_swsh then it works but on every letter that has an end swash, even in the middle of a word. I'm thinking the problem must be in the ignore part of the feature?

Here is the code as it stands, where @ALL is every character in the font minus the start and end swashes. Because I have 3 versions of each character, I need to sub all three by @start_swsh (hence @letter1 @letter2 and @letter3)

feature cswh {
lookup beginnings {
ignore sub @ALL @letter1';
ignore sub @ALL @letter2';
ignore sub @ALL @letter3';
sub @letter1' @ALL by @start_swsh;
sub @letter2' @ALL by @start_swsh;
sub @letter3' @ALL by @start_swsh;
} beginnings;

lookup endings {
ignore sub @letter1' @ALL;
ignore sub @letter2' @ALL;
ignore sub @letter3' @ALL;
sub @ALL @letter1' by @end_swsh;
sub @ALL @letter2' by @end_swsh;
sub @ALL @letter3' by @end_swsh;
} endings;
} cswh;

Mark Simonson's picture

Hm. Pretty sure this will work: take out @ALL from all the "sub" statements.

Like this:

sub @letter1' by @start_swsh;

not this:

sub @letter1' @ALL by @start_swsh;

(Note: It's really tricky to debug something like this without seeing how the font is set up and how the classes are set up. Contextual stuff can be confusing. Also, I usually try to use more descriptive names for my classes to avoid confusing myself. "@letter1" doesn't mean anything to me so it's hard to tell what you're trying to do. I would use a name like @non_start_swash1 or @non_swash1 or something like that, that tells you exactly what's going on.)

kimmyk's picture

Thanks for the note, I will be better with my naming of classes. I removed the @ALL, but it didn't do anything. I think the problem has to be in the ignore part because nothing changes until I delete it, at which point all end swashes appear in the word (see image).

Mark Simonson's picture

That's because nothing is preventing the substitutions to take place. The function of the "ignore" statement is to filter out cases in which you don't want the substitution(s) that follow(s) to take place. If the "ignore" statement finds a match, the rest of the lookup is ignored. If the "ignore" statement doesn't find a match, then the rest of the lookup is executed and the substitutions take place.

Part of the trick to writing features like this is to figure out exactly what you want to filter out and only what you want to filter out. From what I can see, you're filtering out cases in which @ALL precedes or follows @letter1, @letter2, or @letter3. Not knowing what's in these classes makes it impossible to tell exactly what's going on.

kimmyk's picture

Okay, I have end swashes for a c e i o r s t u v w. Since I have assigned three variations to each letter, I have to have three letter classes:

letter1 [a c e i o r s t u v w]
letter2 [a.1 c.1 e.1 i.1 o.1 r.1 s.1 t.1 u.2 v.1 w.1]
letter3 [a.2 c.2 e.2 i.2 o.2 r.2 s.2 t.2 u.2 v.2 w.2]

For the start and end swashes I only have 1 option per letter, so no matter which variation (1, 2 or 3) is typed it will always become the same start or end swash.

start_swsh [a.swsh2 c e.swsh2 i o.swsh3 r s.swsh1 t u v.swsh3 w.swsh2]
end_swsh [a.swsh1 c.swsh2 e.swsh1 i.swsh1 o.swsh2 r.swsh1 s.swsh2 t.swsh1 u.swsh2 v.swsh2 w.swsh3]

The @ALL class includes every since character in the font. My thinking was basically to find a way to say 'substitute characters in the class letter1, letter2 and letter3 by end swash only at the end of a line.' I figured out that removing the space from the @ALL class, it fixed the problem for a single word, but if there are multiple words in a line all of the start and end swashes appear before and after every word, instead of at the start and end of a line.

See screenshot for how it looks now, and how I would like it to look (I manually took out the swashes in this one)

Mark Simonson's picture

A couple things:

It's not possible to test for the start or end of a line of text in OpenType, which means there's no way to automatically get want you want.

Since you have several glyphs in your @letterx classes that are not represented in your @start_swsh class, it would probably be better to keep the starting and ending classes separate, not just the the swash starting and ending glyphs, also the ones you're matching. Like this:

nonstart_letter1 [a e o s v w]
nonstart_letter2 [a.1 e.1 o.1 s.1 v.1 w.1]
nonstart_letter3 [a.2 e.2 o.2 s.2 v.2 w.2]
start_swsh [a.swsh2 e.swsh2 o.swsh3 s.swsh1 v.swsh3 w.swsh2]

nonend_letter1 [a c e i o r s t u v w]
nonend_letter2 [a.1 c.1 e.1 i.1 o.1 r.1 s.1 t.1 u.2 v.1 w.1]
nonend_letter3 [a.2 c.2 e.2 i.2 o.2 r.2 s.2 t.2 u.2 v.2 w.2]
end_swsh [a.swsh1 c.swsh2 e.swsh1 i.swsh1 o.swsh2 r.swsh1 s.swsh2 t.swsh1 u.swsh2 v.swsh2 w.swsh3]

This way, you avoid the probably unexpected effect of some of your swash variants getting converted to plain letters when cswh is invoked.

Finally, in your @ALL class, I would only include characters that are expected to be used in words, unless you think it would be good to have starting and ending swashes on passwords or other random strings.

JanekZ's picture

"It's not possible to test for the start or end of a line of text in OpenType"
Thats true, but you can substitute first letter in the line:

In the font I made the glyphs .init (these upside down)
languagesystem latn dflt;
languagesystem DFLT dflt;
@all=[a-z A-Z ];
@all.init=[a.init-z.init A.init-Z.init ];
@all.i.sp=[a-z A-Z a.init-z.init A.init-Z.init space period comma ];

lookup calt1 {
sub @all' by @all.init ;
} calt1;

lookup calt2 {
sub @all.i.sp @all.init' by @all ;
} calt2;

feature calt {
lookup calt1;
lookup calt2;
} calt;

Thomas Phinney's picture

That’s great, and what I sometimes recommend.

Note that sadly some OpenType layout engines break context at spaces and other word-endings, which will defeat such attempts. :( One can argue that such engines are just basically broken, but some of Adobe’s layout engines work this way, among others.

JanekZ's picture

sadly FireFox (at least 22) too...
"what I sometimes recommend" - I did not know about it and made this feature by trials and errors.
I upgraded FireFox (32.0.3, win XP) and the calt works as needed if the line breaks: enter or shift-enter are set manually.

Syndicate content Syndicate content