S__i_l_l.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. from fontTools.misc import sstruct
  2. from fontTools.misc.fixedTools import floatToFixedToStr
  3. from fontTools.misc.textTools import safeEval
  4. from . import DefaultTable
  5. from . import grUtils
  6. import struct
  7. Sill_hdr = """
  8. >
  9. version: 16.16F
  10. """
  11. class table_S__i_l_l(DefaultTable.DefaultTable):
  12. def __init__(self, tag=None):
  13. DefaultTable.DefaultTable.__init__(self, tag)
  14. self.langs = {}
  15. def decompile(self, data, ttFont):
  16. (_, data) = sstruct.unpack2(Sill_hdr, data, self)
  17. self.version = float(floatToFixedToStr(self.version, precisionBits=16))
  18. (numLangs,) = struct.unpack(">H", data[:2])
  19. data = data[8:]
  20. maxsetting = 0
  21. langinfo = []
  22. for i in range(numLangs):
  23. (langcode, numsettings, offset) = struct.unpack(
  24. ">4sHH", data[i * 8 : (i + 1) * 8]
  25. )
  26. offset = int(offset / 8) - (numLangs + 1)
  27. langcode = langcode.replace(b"\000", b"")
  28. langinfo.append((langcode.decode("utf-8"), numsettings, offset))
  29. maxsetting = max(maxsetting, offset + numsettings)
  30. data = data[numLangs * 8 :]
  31. finfo = []
  32. for i in range(maxsetting):
  33. (fid, val, _) = struct.unpack(">LHH", data[i * 8 : (i + 1) * 8])
  34. finfo.append((fid, val))
  35. self.langs = {}
  36. for c, n, o in langinfo:
  37. self.langs[c] = []
  38. for i in range(o, o + n):
  39. self.langs[c].append(finfo[i])
  40. def compile(self, ttFont):
  41. ldat = b""
  42. fdat = b""
  43. offset = len(self.langs)
  44. for c, inf in sorted(self.langs.items()):
  45. ldat += struct.pack(">4sHH", c.encode("utf8"), len(inf), 8 * offset + 20)
  46. for fid, val in inf:
  47. fdat += struct.pack(">LHH", fid, val, 0)
  48. offset += len(inf)
  49. ldat += struct.pack(">LHH", 0x80808080, 0, 8 * offset + 20)
  50. return (
  51. sstruct.pack(Sill_hdr, self)
  52. + grUtils.bininfo(len(self.langs))
  53. + ldat
  54. + fdat
  55. )
  56. def toXML(self, writer, ttFont):
  57. writer.simpletag("version", version=self.version)
  58. writer.newline()
  59. for c, inf in sorted(self.langs.items()):
  60. writer.begintag("lang", name=c)
  61. writer.newline()
  62. for fid, val in inf:
  63. writer.simpletag("feature", fid=grUtils.num2tag(fid), val=val)
  64. writer.newline()
  65. writer.endtag("lang")
  66. writer.newline()
  67. def fromXML(self, name, attrs, content, ttFont):
  68. if name == "version":
  69. self.version = float(safeEval(attrs["version"]))
  70. elif name == "lang":
  71. c = attrs["name"]
  72. self.langs[c] = []
  73. for element in content:
  74. if not isinstance(element, tuple):
  75. continue
  76. tag, a, subcontent = element
  77. if tag == "feature":
  78. self.langs[c].append(
  79. (grUtils.tag2num(a["fid"]), int(safeEval(a["val"])))
  80. )