S__i_l_l.py 3.1 KB

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