• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1from . import DefaultTable
2from fontTools.misc import sstruct
3from fontTools.misc.textTools import bytesjoin
4from fontTools.ttLib.tables.TupleVariation import (
5    compileTupleVariationStore,
6    decompileTupleVariationStore,
7    TupleVariation,
8)
9
10
11# https://www.microsoft.com/typography/otspec/cvar.htm
12# https://www.microsoft.com/typography/otspec/otvarcommonformats.htm
13# https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6cvar.html
14
15CVAR_HEADER_FORMAT = """
16    > # big endian
17    majorVersion:        H
18    minorVersion:        H
19    tupleVariationCount: H
20    offsetToData:        H
21"""
22
23CVAR_HEADER_SIZE = sstruct.calcsize(CVAR_HEADER_FORMAT)
24
25
26class table__c_v_a_r(DefaultTable.DefaultTable):
27    dependencies = ["cvt ", "fvar"]
28
29    def __init__(self, tag=None):
30        DefaultTable.DefaultTable.__init__(self, tag)
31        self.majorVersion, self.minorVersion = 1, 0
32        self.variations = []
33
34    def compile(self, ttFont, useSharedPoints=False):
35        tupleVariationCount, tuples, data = compileTupleVariationStore(
36            variations=[v for v in self.variations if v.hasImpact()],
37            pointCount=len(ttFont["cvt "].values),
38            axisTags=[axis.axisTag for axis in ttFont["fvar"].axes],
39            sharedTupleIndices={},
40            useSharedPoints=useSharedPoints,
41        )
42        header = {
43            "majorVersion": self.majorVersion,
44            "minorVersion": self.minorVersion,
45            "tupleVariationCount": tupleVariationCount,
46            "offsetToData": CVAR_HEADER_SIZE + len(tuples),
47        }
48        return b"".join([sstruct.pack(CVAR_HEADER_FORMAT, header), tuples, data])
49
50    def decompile(self, data, ttFont):
51        axisTags = [axis.axisTag for axis in ttFont["fvar"].axes]
52        header = {}
53        sstruct.unpack(CVAR_HEADER_FORMAT, data[0:CVAR_HEADER_SIZE], header)
54        self.majorVersion = header["majorVersion"]
55        self.minorVersion = header["minorVersion"]
56        assert self.majorVersion == 1, self.majorVersion
57        self.variations = decompileTupleVariationStore(
58            tableTag=self.tableTag,
59            axisTags=axisTags,
60            tupleVariationCount=header["tupleVariationCount"],
61            pointCount=len(ttFont["cvt "].values),
62            sharedTuples=None,
63            data=data,
64            pos=CVAR_HEADER_SIZE,
65            dataPos=header["offsetToData"],
66        )
67
68    def fromXML(self, name, attrs, content, ttFont):
69        if name == "version":
70            self.majorVersion = int(attrs.get("major", "1"))
71            self.minorVersion = int(attrs.get("minor", "0"))
72        elif name == "tuple":
73            valueCount = len(ttFont["cvt "].values)
74            var = TupleVariation({}, [None] * valueCount)
75            self.variations.append(var)
76            for tupleElement in content:
77                if isinstance(tupleElement, tuple):
78                    tupleName, tupleAttrs, tupleContent = tupleElement
79                    var.fromXML(tupleName, tupleAttrs, tupleContent)
80
81    def toXML(self, writer, ttFont):
82        axisTags = [axis.axisTag for axis in ttFont["fvar"].axes]
83        writer.simpletag("version", major=self.majorVersion, minor=self.minorVersion)
84        writer.newline()
85        for var in self.variations:
86            var.toXML(writer, axisTags)
87