ftCLI / FoundryTools-CLI

A collection of command line tools to inspect, manipulate and convert font files
https://ftcli.github.io/FoundryTools-CLI/
MIT License
82 stars 4 forks source link

Feature request: ftcli converter otc2otf (like afdko’s) #120

Closed vitorsr closed 1 week ago

vitorsr commented 10 months ago

It would be helpful to have a robust OpenType Collection unpacker with an option to keep original timestamps.

ftCLI commented 10 months ago

ftcli converter ttc2sfnt can do it:

Usage: ftcli converter ttc2sfnt [OPTIONS] INPUT_PATH

  Extracts each font from a TTC file, and saves it as a TTF or OTF file.

Options:
  -out, --output-dir DIRECTORY  Specify the directory where output files are
                                to be saved. If the directory doesn't exist,
                                will be created. If output_dir is not
                                specified, files will be saved to the same
                                folder.
  --recalc-timestamp            Keep the original font 'modified' timestamp
                                (head.modified) or set it to current time. By
                                default, original timestamp is kept.
  --no-overwrite                Overwrite existing files or save them to a new
                                file (numbers are appended at the end of file
                                name). By default, files are overwritten.
  --help                        Show this message and exit.
vitorsr commented 10 months ago

Thanks, I somehow completely missed that!

Currently, afdko does not clean up tables merged across fonts, it is possible to add functionality to do so?

ftCLI commented 10 months ago

Could you provide an example with a font and the desired output?

vitorsr commented 9 months ago

Thanks. Sorry for taking so long to reply.

Well, in the early days of OpenType it was common to bundle variations with TTC files by including all glyphs on a same shared glyf table and having differing GlyphOrder (using fontTools terminology). This is especially common in early CJK fonts but also for other kinds of variations that either were instanced in order to be used by uncapable desktop programs or ended up becoming OpenType features.

As an example,

$ otc2otf -r mingliub.ttc
Input font: mingliub.ttc

Font 0: MingLiU-ExtB.ttf
    tag     checksum    length    offset
    ----  ----------  --------  --------
    GSUB  0x2F553F5D        76       936
    OS/2  0x60AAD706        96      1012
    cmap  0xCD25555E       636      1108
    cvt   0x00000000         8      1744
    fpgm  0xF40DDF13        17      1752
    gasp  0x00370009        16      1772
    glyf  0xBEE9F9D1  36351466      1788
    head  0xF2E8EA3C        54  36353256
    hhea  0x07FF04CD        36  36353312
    hmtx  0x1932F34C     99400  36353348
    loca  0xF92849E4    196988  36452748
    maxp  0xC8810451        32  36649736
    meta  0xA4D9F009        63  36649768
    name  0xAB66C055      1757  36649832
    post  0xFFB691F2        32  36651592
    prep  0x6286EE0A        19  36651624
    vhea  0x06020202        36  36651644
    vmtx  0x180C1E74     98494  36651680

Font 1: PMingLiU-ExtB.ttf
    tag     checksum    length    offset
    ----  ----------  --------  --------
    GSUB  - shared -
    OS/2  - shared -
    cmap  0xD5F7719E       636  36750176
    cvt   - shared -
    fpgm  - shared -
    gasp  - shared -
    glyf  - shared -
    head  0xF2E8EA4F        54  36750812
    hhea  - shared -
    hmtx  - shared -
    loca  - shared -
    maxp  - shared -
    meta  0x4F91A32D        60  36750868
    name  0x10FE1B80      1762  36750928
    post  - shared -
    prep  - shared -
    vhea  - shared -
    vmtx  - shared -

Font 2: Ming-Lt-HKSCS-ExtB.ttf
    tag     checksum    length    offset
    ----  ----------  --------  --------
    GSUB  - shared -
    OS/2  - shared -
    cmap  0x008DD163     31740  36752692
    cvt   - shared -
    fpgm  - shared -
    gasp  - shared -
    glyf  - shared -
    head  0xF2E8EA64        54  36784432
    hhea  - shared -
    hmtx  - shared -
    loca  - shared -
    maxp  - shared -
    meta  0x5EFE18E6        69  36784488
    name  0x017A975D      1841  36784560
    post  - shared -
    prep  - shared -
    vhea  - shared -
    vmtx  - shared -

The “issue” is having a large number of unused glyphs taking up a substantial amount of space.

It would be desirable to optionally perform some (destructive) cleaning up after splitting to remove unreachable glyphs.

This could be separate from the conversion itself and part of a set of commands focused on optimization.

There’s a related thread on afdko’s issue tracker on the problem of merging: https://github.com/adobe-type-tools/afdko/issues/66

ftCLI commented 9 months ago

Thanks! Got it now. Probably such a tool could go under ftcli utils, or maybe could be a --cleanup option of ttc2sfnt. It won't be fast, I'm rewriting the CLI from scratch, but I'll post here the result.

vitorsr commented 9 months ago

There’s no rush!

On a personal note, I really enjoyed this project and the general idea of having a CLI suite of minimally invasive “touch-ups” without having to resort to manually editing TTX XML, writing and accumulating single-use scripts, or dealing with the idiosyncrasies of importing and exporting binary fonts in particular editors. I hope I can make some time to contribute and be of help soon.

ftCLI commented 1 week ago

I've added a command to remove unreachable glyphs (it uses fonttools subset). Since the subsetting is a bit slow process, I prefer to keep it as a separate command.

vitorsr commented 1 week ago

Many thanks, @ftCLI!

I meant to send this way earlier - fontbakery has an unreachable glyphs check [1]. I think it could still be useful to add to a test.

[1] https://github.com/fonttools/fontbakery/blob/v0.12.10/Lib/fontbakery/checks/universal/glyphset.py#L93-L266

ftCLI commented 1 week ago

Many thanks, @ftCLI!

I meant to send this way earlier - fontbakery has an unreachable glyphs check [1]. I think it could still be useful to add to a test.

[1] https://github.com/fonttools/fontbakery/blob/v0.12.10/Lib/fontbakery/checks/universal/glyphset.py#L93-L266

Sure! I'll try to figure out how to add a test for this.

Anyway, I tested this command with fontbakery and the warning for unreachable glyphs is solved.