123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104 |
- from fontTools.misc import sstruct
- from fontTools.misc.textTools import bytesjoin, strjoin, readHex
- from fontTools.ttLib import TTLibError
- from . import DefaultTable
- # Apple's documentation of 'meta':
- # https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6meta.html
- META_HEADER_FORMAT = """
- > # big endian
- version: L
- flags: L
- dataOffset: L
- numDataMaps: L
- """
- DATA_MAP_FORMAT = """
- > # big endian
- tag: 4s
- dataOffset: L
- dataLength: L
- """
- class table__m_e_t_a(DefaultTable.DefaultTable):
- def __init__(self, tag=None):
- DefaultTable.DefaultTable.__init__(self, tag)
- self.data = {}
- def decompile(self, data, ttFont):
- headerSize = sstruct.calcsize(META_HEADER_FORMAT)
- header = sstruct.unpack(META_HEADER_FORMAT, data[0:headerSize])
- if header["version"] != 1:
- raise TTLibError("unsupported 'meta' version %d" % header["version"])
- dataMapSize = sstruct.calcsize(DATA_MAP_FORMAT)
- for i in range(header["numDataMaps"]):
- dataMapOffset = headerSize + i * dataMapSize
- dataMap = sstruct.unpack(
- DATA_MAP_FORMAT, data[dataMapOffset : dataMapOffset + dataMapSize]
- )
- tag = dataMap["tag"]
- offset = dataMap["dataOffset"]
- self.data[tag] = data[offset : offset + dataMap["dataLength"]]
- if tag in ["dlng", "slng"]:
- self.data[tag] = self.data[tag].decode("utf-8")
- def compile(self, ttFont):
- keys = sorted(self.data.keys())
- headerSize = sstruct.calcsize(META_HEADER_FORMAT)
- dataOffset = headerSize + len(keys) * sstruct.calcsize(DATA_MAP_FORMAT)
- header = sstruct.pack(
- META_HEADER_FORMAT,
- {
- "version": 1,
- "flags": 0,
- "dataOffset": dataOffset,
- "numDataMaps": len(keys),
- },
- )
- dataMaps = []
- dataBlocks = []
- for tag in keys:
- if tag in ["dlng", "slng"]:
- data = self.data[tag].encode("utf-8")
- else:
- data = self.data[tag]
- dataMaps.append(
- sstruct.pack(
- DATA_MAP_FORMAT,
- {"tag": tag, "dataOffset": dataOffset, "dataLength": len(data)},
- )
- )
- dataBlocks.append(data)
- dataOffset += len(data)
- return bytesjoin([header] + dataMaps + dataBlocks)
- def toXML(self, writer, ttFont):
- for tag in sorted(self.data.keys()):
- if tag in ["dlng", "slng"]:
- writer.begintag("text", tag=tag)
- writer.newline()
- writer.write(self.data[tag])
- writer.newline()
- writer.endtag("text")
- writer.newline()
- else:
- writer.begintag("hexdata", tag=tag)
- writer.newline()
- data = self.data[tag]
- if min(data) >= 0x20 and max(data) <= 0x7E:
- writer.comment("ascii: " + data.decode("ascii"))
- writer.newline()
- writer.dumphex(data)
- writer.endtag("hexdata")
- writer.newline()
- def fromXML(self, name, attrs, content, ttFont):
- if name == "hexdata":
- self.data[attrs["tag"]] = readHex(content)
- elif name == "text" and attrs["tag"] in ["dlng", "slng"]:
- self.data[attrs["tag"]] = strjoin(content).strip()
- else:
- raise TTLibError("can't handle '%s' element" % name)
|