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