classes for glyph lists for OT functions (a programming question)

AlexanderKatt's picture


I use the "calt" function for character substitution, and I have a lot of similar glyph lists which are sometimes hard do maintain.

For example, I have:
sub m' [s a c e o] by m.alt;
sub n' [s a c e o] by n.alt;
sub x' [s a c e o] by x.alt;

My question is can I define a glyph list that I can use for every instance?

Can I say:

my list_s = [s a c e o];
sub m' [list_s] by m.alt;
sub n' [list_s] by m.alt;
sub x' [list_s] by m.alt;

So I if I want to add a character to that list I have to do it in one place, instead of, say 10

gargoyle's picture

It sounds like you want to replace inline classes (glyph lists) with predefined classes. Your pseudo-code is already close, just ditch the 'my' and use the prefix '@'...

@list_s = [s a c e o];
sub m' @s by m.alt;
# etc.

In order for the class to work across features (not just for calt), the definition should be made globally, i.e. in the lower section of FontLab's OpenType panel, or in the Classes panel, or somewhere near the top of an external features file.

It's also possible to nest classes, so if you needed to add an additional glyph to the predefined class for a particular rule, you could do something like...

sub m' [@s u] by m.alt;

...which would include 'u' in the class for just that rule.

eigi's picture

You can simplify the feature code more by intesive use of classes:

feature xxxx {
  @source  = [m n x];
  @target  = [m.alt m.alt m.alt];
  @context = [s a c e o];

  sub @source' @context by @target;
} xxxx;

AlexanderKatt's picture

Thanks both of you.

And what programming language is this using? Is there a comprehensive manual?

agisaak's picture

AFDKO syntax is described at

I'd actually recommend you *not* think of this as a programming language, per se, but rather simply as the syntax for specifying the structure of OpenType tables. When I first started coding OpenType features I ran into a bunch of problems which were caused by viewing it as a programming language and assuming that lookups behave similar to functions, which is in various respects a poor analogy.

For example, consider the following hypothetical piece of code:

lookup A {
} A;

lookup B {
} B;

feature xxxx {
    lookup A;
    lookup B;
} xxxx;

feature yyyy {
    lookup B;
    lookup A;
} yyyy;

In this example, feature xxxx and yyyy *must* behave identically because lookups, unlike functions, are not called. Rather, they exist within the GSUB table in a particular order and will either be processed by the application or not. This order is determined by the order in which lookups are declared rather than the order which they are referred to in the features. Thus, B will operate on the output of A even in feature yyyy where they are mentioned in reverse order.

Programs operate over data. OpenType tables, on the other hand, are static data which is processed by a text engine.


Té Rowan's picture

@AlexanderKatt - Think yacc and you're close.

Syndicate content Syndicate content