File: make-static-fonts.py

package info (click to toggle)
fonts-cantarell 0.303.1-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 17,760 kB
  • sloc: python: 859; makefile: 9; sh: 1
file content (92 lines) | stat: -rw-r--r-- 2,881 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
#!/bin/env python3

import argparse
import multiprocessing
import subprocess
from pathlib import Path

import cffsubr
import fontTools.ttLib
import fontTools.designspaceLib
import ufo2ft

import instantiator

try:
    import pathops
    have_pathops = True
except ImportError:
    have_pathops = False

def generate_and_write_autohinted_instance(
    instantiator: instantiator.Instantiator,
    instance_descriptor: fontTools.designspaceLib.InstanceDescriptor,
    output_dir: Path,
    psautohint: str,
):
    # 3. Generate instance UFO.
    instance = instantiator.generate_instance(instance_descriptor)
    file_stem = f"{instance.info.familyName}-{instance.info.styleName}".replace(" ", "")

    # 3.5. Optionally write instance UFO to disk, for debugging.
    # instance.save(output_dir / f"{file_stem}.ufo", overwrite=True)

    # 4. Compile and write instance OTF to disk. Do not optimize, because we have to
    # do it again after autohinting.
    instance_font = ufo2ft.compileOTF(
        instance,
        removeOverlaps=True,
        overlapsBackend="pathops" if have_pathops else "booleanOperations",
        inplace=True,
        useProductionNames=True,
        optimizeCFF=ufo2ft.CFFOptimization.NONE,
    )
    output_path = output_dir / f"{file_stem}.otf"
    instance_font.save(output_path)

    # 5. Run psautohint on it.
    subprocess.run([psautohint, str(output_path)])

    # 6. Subroutinize (compress) it
    instance_font = fontTools.ttLib.TTFont(output_path)
    cffsubr.subroutinize(instance_font).save(output_path)


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument(
        "designspace_path", type=Path, help="The path to the Designspace file."
    )
    parser.add_argument("psautohint", type=str, help="The path to psautohint.")
    parser.add_argument("output_dir", type=Path, help="The output directory.")
    args = parser.parse_args()

    # 1. Load Designspace and filter out instances that are marked as non-exportable.
    designspace = fontTools.designspaceLib.DesignSpaceDocument.fromfile(
        args.designspace_path
    )
    designspace.instances = [
        s
        for s in designspace.instances
        if s.lib.get("com.schriftgestaltung.export", True)
    ]

    # 2. Prepare masters.
    generator = instantiator.Instantiator.from_designspace(
        designspace, round_geometry=True
    )

    # (Fork one process per instance)
    processes = []
    pool = multiprocessing.Pool(processes=multiprocessing.cpu_count())
    for instance in designspace.instances:
        processes.append(
            pool.apply_async(
                generate_and_write_autohinted_instance,
                args=(generator, instance, args.output_dir, args.psautohint),
            )
        )
    pool.close()
    pool.join()
    for process in processes:
        process.get()  # Catch exceptions.