Problem with making lining figures in FontLab 7

Eryk Kosinski
Eryk Kosinski Posts: 72
edited August 2021 in Font Technology
I am a beginner user of FontLab 7 and got into learning lining figures recently. I have a problem with creating proportional oldstyle figures. I am using onum and pnum features. I managed to do oldstyle figures and proportional ones but unable to do proportional oldstyle figures.        

Comments

  • John Hudson
    John Hudson Posts: 3,126
    edited August 2021
    In OpenType Layout, you need to think what is the order of the substitution lookups, and what is the state of the output from previous lookups that provides the input for the current lookup. This will determine what substitutions you need to put into the lookup in order to achieve your desired result.

    In FontLab 7—and other tools based on the Adobe AFDKO system—there are two ways you can control the order of lookups.

    1. Write all your substitution lookup code in the prefix section of the features panel, give the lookups names, and then reference those names in the (arbitrarily) ordered features below. If you do it this way, then the order of the lookups in the prefix determines the order in which they are applied.

    2. Write your substitution lookup code directly in the features, and drag and drop the features into the order you want them applied.



    I prefer method (1), because I am often working on complex fonts that require interleaving of lookups from different features, but if you are making a fairly typical Latin font, you can probably use method (2), which is that most people do.

    So...

    I am presuming your default numerals are lining tabular, i.e. those are the numerals that are mapped directly to the Unicode character codepoints. [This is the most common default numeral form in fonts for legacy reasons.]

    In my fonts, I use these suffixes to identify different variant numeral types (but you can use whatever suffixes you like):

    .LP = lining proportional
    .OT = oldstyle tabular
    .OP = oldstyle proportional

    (also .ST and .SP if the font contains smallcap numerals, and .LT is the lining tabular numerals are not the default, as in the illustration above).

    You can use whatever order of substitutions you like, so long as you are aware of the order and the output and input at each stage. Since the default style is a lining tabular numeral, let’s presume that the first lookup will retain the lining style, but make it proportional, so the pnum feature lookup will be ordered first. Using /zero/ as an example (and method (2) above):

    feature pnum {
    sub zero by zero.LP
    ...
    } pnum;

    Now you have two numeral styles available to subsequent lookups: the default LT numerals and the pnum LP numerals. This means that both need to be included as inputs in the oldstyle numerals feature:

    feature onum {
    sub zero by zero.OT
    ...
    sub zero.LP by zero.OP
    ...
    } onum;

    Obviously, if you order the onum feature lookup before the pnum feature lookup, then you would have different inputs.

    Note that you only need to map the resulting state of previous output—either default numerals or result of previous feature lookups—in the current lookup. So using the example above, your font doesn’t need a tnum feature at all, because the default form is tabular and you are processing pnum before onum.

    I see a lot of font feature code in which people map every variant to every other variant in lots of features, but that just bloats the code and the GSUB table, because many of those substitutions will never be applied. If you think about the code in terms of stages and outputs and inputs, you can write efficient feature code that only includes the substitutions that will actually be applied.

  • John Hudson
    John Hudson Posts: 3,126
    BTW, the FontLab 7 forum is a good place to ask this sort of question.
  • Ori Ben-Dor
    Ori Ben-Dor Posts: 386
    edited August 2021
    [Accidentally saved comment?]
  • John Hudson
    John Hudson Posts: 3,126
    [Does anyone know how to tag text segments as code in TypeDrawers posts and have linebreaks preserved?]
  • There are 2 bits of information, or "axes": proportional/tabular & lining/oldstyle.
    Hence there are 4 possible combinations: proportional-lining, proportional-oldstyle, tabular-lining, & tabular-oldstyle.

    There are also 4 relevant OpenType features: pnum, tnum, lnum, & onum.

    But these 4 features do NOT correspond to the 4 combinations. Rather, each feature corresponds to a value on one of the axes.
    For instance, onum corresponds to oldstyle, but it has no bearing on the proportional/tabular axis.

    You can force a certain combination by having two features work together, i.e., a two-step substitution.
    For instance, if you want proportional-oldstyle, you'd use pnum & onum (remember that features are applied in the same order in which they're defined, so if pnum is defined before onum, you need pnum to substitute default figures with proportional ones and then onum to substitute proportional ones with proportional-oldstyle ones).

    ---

    In practice, I'd create 4 OpenType classes, one for each value on one of the axes. Each class would contain BOTH VERSIONS, with respect to the other axis, of each glyph.
    For instance, onum would contain both one.onum (proportional-oldstyle) & one.otnum (tabular-oldstyle). And then the onum feature, for instance, would substitute lnum with onum.

    I've created a very simple FL7 file that demonstrates that, but apparently you can't attach files in this category :(
    I'll try to send it to you privately.
  • Apparently you can't attach files to private messages either.
    Let's try this way:
    https://anonfiles.com/Z8Rec0Beu5/nums_vfc
    (Open the file in FL7 and look at the classes & features in the Classes & Features panels.)
  • @John Hudson [pasting text into a code block works; “Einsetzen” is “Paste”]


  • I've now read @John Hudson's comment. He's right that my approach "bloats" the code, but it's easier on the coder & more adaptable (everything is symmetrical, so you don't need to worry about feature order, and changing the default set later won't require updating the code).
  • There are 2 bits of information, or "axes": proportional/tabular & lining/oldstyle.
    Hence there are 4 possible combinations: proportional-lining, proportional-oldstyle, tabular-lining, & tabular-oldstyle.

    There are also 4 relevant OpenType features: pnum, tnum, lnum, & onum.

    But these 4 features do NOT correspond to the 4 combinations. Rather, each feature corresponds to a value on one of the axes.
    For instance, onum corresponds to oldstyle, but it has no bearing on the proportional/tabular axis.

    You can force a certain combination by having two features work together, i.e., a two-step substitution.
    For instance, if you want proportional-oldstyle, you'd use pnum & onum (remember that features are applied in the same order in which they're defined, so if pnum is defined before onum, you need pnum to substitute default figures with proportional ones and then onum to substitute proportional ones with proportional-oldstyle ones).

    ---

    In practice, I'd create 4 OpenType classes, one for each value on one of the axes. Each class would contain BOTH VERSIONS, with respect to the other axis, of each glyph.
    For instance, onum would contain both one.onum (proportional-oldstyle) & one.otnum (tabular-oldstyle). And then the onum feature, for instance, would substitute lnum with onum.

    I've created a very simple FL7 file that demonstrates that, but apparently you can't attach files in this category :(
    I'll try to send it to you privately.

    I have done it your way from the file you have sent me. Everything works perfectly. Thank you.