Pomax / lib-font

This library adds a new Font() object to the JavaScript toolbox, similar to new Image() for images

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Ligatures w/ Athena Ruby

RoelN opened this issue · comments

Trying to get the glyphArray for Athena Ruby doesn't work.

Test code:

import { Font } from "./Font.js";

const font = new Font("athena ruby");
// font.src = "/Users/roel/Desktop/Fonts/Bungee-Regular.ttf";
// font.src = `./fonts/Recursive_VF_1.064.ttf`;
// font.src = `./fonts/MehrNastaliqWeb-Regular.ttf`;
font.src = `./fonts/AthenaRuby_b018.ttf`;

font.onload = (evt) => {
  let font = evt.detail.font;

  const { cmap, name, GSUB } = font.opentype.tables;

  let scripts = GSUB.getSupportedScripts();

  scripts.forEach((script) => {
    let langsys = GSUB.getSupportedLangSys(script);

    langsys.forEach((lang) => {
      let langSysTable = GSUB.getLangSysTable(script, lang);
      let features = GSUB.getFeatures(langSysTable);
      let featureCount = features.length;

      features.forEach((feature) => {
        const lookupIDs = feature.lookupListIndices;

        lookupIDs.forEach((id) => {
          const lookup = GSUB.getLookup(id);

          if (lookup.lookupType === 4) {
            lookup.subtableOffsets.forEach((_, i) => {
              const subtable = lookup.getSubTable(i);
              const coverage = subtable.getCoverageTable();

              console.log(coverage); // Does not contain glyphArray
            });
          }
        });
      });
    });
  });
};

Example output for the console.log:

...
CoverageTable {
  coverageFormat: 2,
  rangeCount: 3,
  rangeRecords: [
    CoverageRangeRecord {
      startGlyphID: 325,
      endGlyphID: 325,
      startCoverageIndex: 0
    },
    CoverageRangeRecord {
      startGlyphID: 327,
      endGlyphID: 327,
      startCoverageIndex: 1
    },
    CoverageRangeRecord {
      startGlyphID: 337,
      endGlyphID: 337,
      startCoverageIndex: 2
    }
  ]
}
...

This confuses me a little :-) In the above loop, the console.log happens 12 times. The font has 5 lookup type 4 tables (<LookupType value="4"/> in a dumped .ttx file). Spec says "The subtable has one format: LigatureSubstFormat1". Or am I wrongly assuming coverageFormat points to that?

commented

CoverageFormat 1 has a glyphArray that is literally just a list of glyph ids, whereas CoverageFormat 2 encodes which glyphs are covered by using the same kind of segments that cmap 4 uses (see https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2#coverage-format-2). It calls them "rangeRecords", but just as it's possible (if really silly) for cmap 4 to have segments with the same start and end codes, rangeRecords can be set for only a single glyphid (which is what we see in your log result).

Also note that coverage tables do not point to lookups, it's the other way around: a lookup defines what should happen, for a set of characters. The "what should happen" part is covered by the lookup's subtables, and the "what it applies to" is documented separated by each subtable. One lookup can have multiple subtables, and one subtable can have multiple coverage tables, so 5 lookups leading to 12 coverage tables is entirely possible.