_c_v_a_r.py 3.2 KB

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