【问题标题】:Extracting ttf font ligature mappings提取 ttf 字体连字映射
【发布时间】:2019-02-16 09:45:17
【问题描述】:

我有一个现有的ttf font,我希望将所有连字映射提取到此表单中:

{
    "calendar_today": "E935",
    "calendar_view_day": "E936",
    ...
}

我在这个脚本中使用fontkit

const fontkit = require('fontkit');
let font = fontkit.openSync('./MaterialIcons-Regular.ttf');
let lookupList = font.GSUB.lookupList.toArray();
let lookupListIndexes = font.GSUB.featureList[0].feature.lookupListIndexes;

lookupListIndexes.forEach(index => {
    let subTable = lookupList[index].subTables[0];
    let ligatureSets = subTable.ligatureSets.toArray();

    ligatureSets.forEach(ligatureSet => {
        ligatureSet.forEach(ligature => {
            let character = font.stringsForGlyph(ligature.glyph)[0];
            let characterCode = character.charCodeAt(0).toString(16).toUpperCase();

            let ligatureText = ligature
                .components
                .map(x => font.stringsForGlyph(x)[0])
                .join('');

            console.log(`${ligatureText} -> ${characterCode}`);
        });
    });
});

但是,我没有得到完整的连字名称。输出:

...
alendar_today -> E935
rop_portrait -> E3C5
ontact_phone -> E0CF
ontrol_point -> E3BA
hevron_right -> E5CC
...

我做错了什么?通过 FontForge 的分析来看,字体的 Ligature 名称没有丢失任何字符。

【问题讨论】:

    标签: javascript fonts ligature


    【解决方案1】:

    here所述,第一个字符是根据覆盖范围记录计算的。

    首先,计算前导字符

    let leadingCharacters = [];
    subTable.coverage.rangeRecords.forEach((coverage) => {
        for (let i = coverage.start; i <= coverage.end; i++) {
            let character = font.stringsForGlyph(i)[0];
            leadingCharacters.push(character);
        }
    });
    

    然后,通过子表的索引访问这些字符

    let ligatureSets = subTable.ligatureSets.toArray();
    ligatureSets.forEach((ligatureSet, ligatureSetIndex) => {
    
        let leadingCharacter = leadingCharacters[ligatureSetIndex];
    
        ligatureSet.forEach(ligature => {
            let character = font.stringsForGlyph(ligature.glyph)[0];
            let characterCode = character.charCodeAt(0).toString(16).toUpperCase();
    
            let ligatureText = ligature
                .components
                .map(x => font.stringsForGlyph(x)[0])
                .join('');
    
            ligatureText = leadingCharacter + ligatureText;
    
            console.log(`${ligatureText} -> ${characterCode}`);
        });
    });
    

    【讨论】:

      猜你喜欢
      • 2020-10-08
      • 2021-11-16
      • 2011-01-01
      • 2013-05-01
      • 2016-01-20
      • 2013-03-05
      • 2011-07-15
      • 2016-12-12
      • 1970-01-01
      相关资源
      最近更新 更多