aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/fonttools/fontTools/varLib/hvar.py
blob: d243f9aa8ceb6150b2dea7a99cea7d4d686dee52 (plain) (blame)
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
from fontTools.misc.roundTools import noRound
from fontTools.ttLib import TTFont, newTable
from fontTools.ttLib.tables import otTables as ot
from fontTools.ttLib.tables.otBase import OTTableWriter
from fontTools.varLib import HVAR_FIELDS, VVAR_FIELDS, _add_VHVAR
from fontTools.varLib import builder, models, varStore
from fontTools.misc.fixedTools import fixedToFloat as fi2fl
from fontTools.misc.cliTools import makeOutputFileName
from functools import partial
import logging

log = logging.getLogger("fontTools.varLib.avar")


def _get_advance_metrics(font, axisTags, tableFields):
    # There's two ways we can go from here:
    # 1. For each glyph, at each master peak, compute the value of the
    #    advance width at that peak.  Then pass these all to a VariationModel
    #    builder to compute back the deltas.
    # 2. For each master peak, pull out the deltas of the advance width directly,
    #    and feed these to the VarStoreBuilder, forgoing the remoding step.
    # We'll go with the second option, as it's simpler, faster, and more direct.
    gvar = font["gvar"]
    vhAdvanceDeltasAndSupports = {}
    glyphOrder = font.getGlyphOrder()
    phantomIndex = tableFields.phantomIndex
    for glyphName in glyphOrder:
        supports = []
        deltas = []
        variations = gvar.variations.get(glyphName, [])

        for tv in variations:
            supports.append(tv.axes)
            phantoms = tv.coordinates[-4:]
            phantoms = phantoms[phantomIndex * 2 : phantomIndex * 2 + 2]
            assert len(phantoms) == 2
            phantoms[0] = phantoms[0][phantomIndex] if phantoms[0] is not None else 0
            phantoms[1] = phantoms[1][phantomIndex] if phantoms[1] is not None else 0
            deltas.append(phantoms[1] - phantoms[0])

        vhAdvanceDeltasAndSupports[glyphName] = (deltas, supports)

    vOrigDeltasAndSupports = None  # TODO

    return vhAdvanceDeltasAndSupports, vOrigDeltasAndSupports


def add_HVAR(font):
    if "HVAR" in font:
        del font["HVAR"]
    axisTags = [axis.axisTag for axis in font["fvar"].axes]
    getAdvanceMetrics = partial(_get_advance_metrics, font, axisTags, HVAR_FIELDS)
    _add_VHVAR(font, axisTags, HVAR_FIELDS, getAdvanceMetrics)


def add_VVAR(font):
    if "VVAR" in font:
        del font["VVAR"]
    getAdvanceMetrics = partial(_get_advance_metrics, font, axisTags, HVAR_FIELDS)
    axisTags = [axis.axisTag for axis in font["fvar"].axes]
    _add_VHVAR(font, axisTags, VVAR_FIELDS, getAdvanceMetrics)


def main(args=None):
    """Add `HVAR` table to variable font."""

    if args is None:
        import sys

        args = sys.argv[1:]

    from fontTools import configLogger
    from fontTools.designspaceLib import DesignSpaceDocument
    import argparse

    parser = argparse.ArgumentParser(
        "fonttools varLib.hvar",
        description="Add `HVAR` table from to variable font.",
    )
    parser.add_argument("font", metavar="varfont.ttf", help="Variable-font file.")
    parser.add_argument(
        "-o",
        "--output-file",
        type=str,
        help="Output font file name.",
    )

    options = parser.parse_args(args)

    configLogger(level="WARNING")

    font = TTFont(options.font)
    if not "fvar" in font:
        log.error("Not a variable font.")
        return 1

    add_HVAR(font)
    if "vmtx" in font:
        add_VVAR(font)

    if options.output_file is None:
        outfile = makeOutputFileName(options.font, overWrite=True, suffix=".hvar")
    else:
        outfile = options.output_file
    if outfile:
        log.info("Saving %s", outfile)
        font.save(outfile)


if __name__ == "__main__":
    import sys

    sys.exit(main())