代码之家  ›  专栏  ›  技术社区  ›  Jossef Harush Kadouri

提取ttf字体连字映射

  •  1
  • Jossef Harush Kadouri  · 技术社区  · 7 年前

    我有一个存在 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
    ...
    

    image

    0 回复  |  直到 7 年前
        1
  •  2
  •   Jossef Harush Kadouri    7 年前

    如前所述 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}`);
        });
    });