Opentype Newbie - guidance

Hi, I’ve recently started using the open type features in Font Creator
I am trying to understand what each things does in the editor
E.g., can someone maybe explain to me what the following example does? (and what the purpose of each section is)
Or, at least point me somewhere that I can learn this from
Also, can codepoints be used instead of names?

Thanks,
David

class @KernClass78 [w wgrave wacute wcircumflex];

script latn {
   feature Kerning;
}

feature Kerning kern {
   lookup PairAdjustment1;
}

lookup PairAdjustment1 {
   lookupflags IgnoreMarks;

   subtable "Subtable 1" {
     pos A v <-38> <0>;
     pos A question <-68> <0>;
     pos @KernClass78 A <8> <0>;
   }
}

The beauty of the Visual OpenType Designer is that you don’t really need to understand how the code works, though it doesn’t hurt to have some idea:

  1. class @KernClass78 [w wgrave wacute wcircumflex]; This is a list of letters that are all treated the same
  2. script latn {feature Kerning;} This is the kerning feature defined for the Latin script
  3. feature Kerning kern {lookup PairAdjustment1;} This is the lookup to be used by the kerning feature
  4. lookup PairAdjustment1 {lookupflags IgnoreMarks;

subtable “Subtable 1” {
pos A v <-38> <0>; This reduces the advance width of “A” by 38 funits before “v”
pos A question <-68> <0>; This reduces the advance width of “A” by 68 funits before ?
pos @KernClass78 A <8> <0>; This increases the advance width of w, wgrave, wacute ,wcircumflex before “A” by 8 funits
}
}

If you simply add kerning classes and kerning pairs to your fonts, Autokern will calculate the pairs for you.

Using Kerning Classes

@Bhikkhu - Thanks!

The reason why I am trying to understand the code is because I have a project in mind:
I currently work in a program that a provides its custom kerning settings. I’ve invested several hundred hours into those kerning settings and I would love to be able to port them over.
Since I have programming experience, I am trying to see if it’s possible to the porting through script

Regarding your explanation - ok, now I understand classes and I understand the pos ‘command’ as these are similar to the settings I have now. However, I still don’t understand:

  1. What is the script function for? And what is meant by “latin script”?
  2. What is the feature function for?
  3. Why is a lookup function needed? Why can’t there just be stand-alone search lines? (I’m not asking because I want it to be that way, I’m just trying to understand better)
  4. Why are the lookups placed in a subtable function? Is there any special meaning of these 3 being grouped together?
  5. Is it possible to glyph codepoints in classes instead of glyph names?
  6. Is it possible to use a longer pos command? I.e., I want to change character A and B only when they appear in succession with C and D.
    E.g. whenever the letters ABCD are in succession, change kerning of D - but nothing else should change
  7. In the pos statement, I see there are 2 angle brackets with values - are those for x and y? And are they both always necessary even though the value is zero?

Thanks for your help - very much appreciated!
Looking forward to hear more!
David

  1. What is the script function for? And what is meant by “latin script”? Script Tags
  2. What is the feature function for? Feature Tags
  3. Why is a lookup function needed? Why are the lookups placed in a subtable function? Without a lookup table no pairs would be kerned.
  4. Is it possible to glyph codepoints in classes instead of glyph names? Some glyphs may be unmapped, so will have no code-points (e.g. Small Capitals), but they can be kerned if glyph names are used.
  5. Is it possible to use a longer pos command? For this you will need to create a contextual substitution.
  6. In the pos statement, I see there are 2 angle brackets with values - are those for x and y? And are they both always necessary even though the value is zero? I think so.

I’m not sure if this is a documented feature, but yes it is possible:

This line

  pos A v <-38>;

asuming the “A” has 0x41 (thus 65 decimal) as codepoint, can be replaced with

  pos uni41 v <-38>;

Likewise (but even less recommended) you can use the glyph index, so if A is the fourth glyph:

  pos 4 v <-38>;

You can even mix glyph names with code points, and glyph indexes in a class definition:

  class @KernClass78 [uni77 450 wacute wcircumflex];

Just keep in mind, the script code will be compiled, so when you reopen the code editor all codepoints and glyph indexes will be replaced with glyph names.

More information about glyph positioning can be found in the manual:
OpenType Layout Features - Pos

Thanks guys!
@Bhikkhu: Thanks for the links and the answers! However, I still have a few things unclear:

  1. Regarding lookup function, what I mean to ask is can the lookups (or better said, the pos commands) be inserted directly into the feature function, or does it have to be in a lookup function? I.e., is the lookup function for “organizational” purposes, or is this essential to the functionality?
  2. Similarly, regarding the subTable - do the pos commands have to be in the subtable, or can they be in the lookup function itself
  3. If it doesn’t have to be in a subTable, so what are subTables used for?
  4. Can you explain - or show an example of what a contextual substitution is?

@Erwin:

  • Thanks so much for the elaborate description! Very well explained.
    Also, thanks for the warning about the compiling - good to know

Thanks,
David

It is essential to put them in lookups.

They can be in the lookup, but only if you don’t need more than one table; FontCreator will then take care of the correct internal OpenType Layout Feature data.

You can for example use the first subtable to define several exceptions:

pos T edieresis <-10>;

Then use another sub table to make more easy to maintain (and usually class based) kerning like

class @T [T Tcedilla Tcaron Tbar];
class @e [e egrave eacute ecircumflex edieresis ebreve edotaccent ecaron];

pos @T @e <-20>;

in this example the pair T edieresis will have a kerning value -10

The others will use -20

Yes. See:

This should get you started:

script DFLT {
  feature Kerning;
}

class @KernClassT [T];
class @KernClassedieresis [edieresis];
class @KernClass1 [T Tcedilla Tcaron Tbar];
class @KernClass2 [e egrave eacute ecircumflex edieresis ebreve edotaccent ecaron];
class @KernClassC [C];
class @KernClassD [D];

feature Kerning kern {
  lookup ChainedContextPositioning1;
  lookup PairAdjustment1;
}

lookup ChainedContextPositioning1 {
  context (B A) C (D E);
  sub 0 PairAdjustment2;
}

lookup PairAdjustment1 {
  subtable "Subtable 1" {
    pos @KernClassT @KernClassedieresis <-10> <0>;
  }
  subtable "Subtable 2" {
    pos @KernClass1 @KernClass2 <-20> <0>;
  }
}

lookup PairAdjustment2 {
  pos @KernClassC @KernClassD <-700> <0>;
}

Note: In context (B A) C (D E); the A and B are switched for some reason. I think this is a flaw on our side, so I’ll look into it!

Thanks Erwin!

  1. Regarding the subtables, what exactly is causing pair T edieresis to have a kerning value -10?
    Is it because it’s in it’s own table and is therefore excluded? or is it because whatever is previous wins?
    (In other words, what would happen if that subtable was second?)
  2. Regarding your example of contextual substitution - that’s great! Thanks!
    Just a few questions:
  3. Why is AB and DE in parenthesis?
  4. What is the ‘sub’ command? and what is the 0 that follows
  5. Part of question A, what does “PairAdjustment2” get applied to?

Thanks a lot!
David

As sson as a match is found, then processing of next pairs will stop.

It is just the notation.

In this case sub is just a keyword (for substitution tables).

The sequence index, usually 0, indicates where the operation will occur in the input glyph sequence.

In this example, the middle input class (sequence index 1) is processed by SingleSubstitution1.
SequenceIndex.png

When you type “ABCDE” the kerning will be applied to CD.

We’ve just released another update in which we changed the order of the Backtrack, so now it shows more in line with Input and Lookahead.

Another thing that is important when defining a chaining context, is the fact the substitution table will only be applied to the input, so in order to make a pair adjustment work, you need (at least) two input items:

So this will not work:
chainedcontextwrong.png
And this will apply the kerning pair for “C D”:
chainedcontextgood.png