dlig feature help

Michael JarboeMichael Jarboe Posts: 265
edited October 2015 in Technique and Theory
I'm doing this discretionary ligature feature where the substitusion part looks like this so that it works with lowercase, sentence case or uppercase. I wanted to make an OpenType class, but that won't work for ligatures, right? I'm just typing all this out by hand, just wondering if there's a way to condense the code at all.

Almost forgot to add this is an all caps font so as to why all resolve as an uppercase ligature.

    sub a b by AB;
    sub A b by AB;
    sub A B by AB;
    sub aacute b by AacuteB;
    sub Aacute b by AacuteB;
    sub Aacute B by AacuteB;
    sub acircumflex b by AcircumflexB;
    sub Acircumflex b by AcircumflexB;
    sub Acircumflex B by AcircumflexB;
    sub adieresis b by AdieresisB;
    sub Adieresis b by AdieresisB;
    sub Adieresis B by AdieresisB;
    sub amacron b by AmacronB;
    sub Amacron b by AmacronB;
    sub Amacron B by AmacronB;
    sub abreve b by AbreveB;
    sub Abreve b by AbreveB;
    sub Abreve B by AbreveB;
    sub aogonek b by AogonekB;
    sub Aogonek b by AogonekB;
    sub Aogonek B by AogonekB;


  • Write a python script that creates the code from lists of glyphs. If you don't know how just message me your email and I'll send something you can modify and run in dropbox.
  • I will just also note that the convention for ligature names is to separate the components with an underscore character. So "Abreve_B" instead of "AbreveB" and so on. 
  • Thomas, I think initially I had the glyphs named like that, but then I was thinking it looked cleaner to not have an underscore separation, and I figured /AE and /OE aren't separated (even though they're different than the ligatures I'm creating, this is from a from a purely visual 'splitting hairs' point of view, lol) so I took out all the underscores.

    Once I did that I noticed that a few glyphs like /LE and /LF are already appointed in unicode so I had to keep them as /L_E and /L_F. So now that you've mentioned the convention I'll switch back, and all of these dligs will be consistent in the way they're named.

    So by convention, should all 'f' ligatures be separated by an underscore? I feel like I've seen them named with and without.
  • Chris LozosChris Lozos Posts: 1,427
    Yes, f_f_l
  • /ae and /a_e are quite different things. The former are not just a ligature, they have a distinct meaning and shape. The later are two letters next to each other. 
  • So by convention, should all 'f' ligatures be separated by an underscore? I feel like I've seen them named with and without.

    There is some legacy in the Unicode FB00–FB06 range. One can find the FB00–FB04 ligatures in the Adobe Glyph List still, but these were later omitted in the Adobe Glyph List For New Fonts (AGLFN). In the intro of the AGLFN 1.5 one can read: ‘"ffi" is also omitted, as the AGL maps this to the Alphabetic Presentation Forms Area value FB03, rather than decomposing it to the three-value Unicode sequence 0066,0066,0069.’

  • Kent LewKent Lew Posts: 905
    It looks like you are working with an all-caps design where the capitals and lowercase share the same form and you want a single ligature glyph to result from any combination of the corresponding UC or lc.

    In which case, you can use a format like this:
    sub [A a] [B b] by A_B;
    sub [Aacute aacute] [B b] by Aacute_B;

    And yes, this is a prime candidate for generating via Python script. If you name your ligatures according to the convention, with an underscore separating the two components, it’s pretty straightforward to generate from just a list of the ligature glyph names themselves.

    for gname in ligList:
    g1, g2 = gname.split('_')
    print "sub [%s %s] [%s %s] by %s;" % (g1, g1.lower(), g2, g2.lower(), gname)

  • Thanks Kent, but where/how do I define the ligature list? I'm looking into some Python tutorials now.
  • Okay, I think I figured it out I just hit the Lists part of Adam Twardoch's Basics of Python scripting, got a preliminary list working in the macro and it's working once brought into the OT feature code as well. Thanks again! This will be much better than writing it all out by hand in TextEdit.
  • Kent LewKent Lew Posts: 905
    Sorry, I assumed some Python knowledge/experience.

    If you’re working in RoboFont, you can just work off a selection in the Font window, in place of a ligList variable, by replacing the first line above with the following:

    f = CurrentFont()

    for gname in f.selection:
    then pick up from before at the indent. Something similar should work for either FontLab or Glyphs, with perhaps some minor app-specific adjustment for getting the selection. Of course, your selection then needs to be comprised of ligatures named in the expected format, or you’ll get an error.

  • I’ve posted some relevant code to Github. https://github.com/DunwichType/mixer

    It’s called mixer. It builds text files of permutations by mixing lists together.
  • Kent are the bracketed glyphs within your top code example decompiled at some point once written into the final .otf file? I have my final code it worked fine, but I noticed in one instance of a .vfb OpenType panel the dlig feature had the brackets removed and what is represented in the brackets was broken down into individual lines of code for each glyph. Just curious, I thought that was interesting. I think I had imported a .otf into FontLab and saw that the dlig code was different from the initial code that used your bracketed form, if that makes sense.
  • Kent LewKent Lew Posts: 905
    The bracketed format is a convenience feature of the Adobe syntax. This all gets compiled into GSUB tables according to the proper structure based upon the GSUB type, which is inherent in the particulars of Adobe syntax.

    In this case, yes, when you compile the font, these bracketed glyphs get enumerated into all relevant combinations which are then structured into GSUB Type 4 [ligature] lookups.

    If you crack such a font back into an editor, then these tables will very likely be reinterpreted as separate rules, no longer exhibiting the shortcut convenience of the bracketed format.

    In your original post, you asked if there were a way to “condense the code at all.” The bracketed format condenses the instructions. In this case, there are multiple ways in Adobe syntax to express the same set of instructions.

    The compiled code itself is what it is.


  • Excellent, thanks Ken!
Sign In or Register to comment.