vhea.py 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. import struct
  2. from lxml.etree import Element
  3. from data import VFixed
  4. from transform.bytes import outputTableBytes
  5. class vhea:
  6. """
  7. Class representing a vhea table.
  8. """
  9. def __init__(self, m):
  10. metrics = m['metrics']
  11. self.version = VFixed('1.0')
  12. self.ascent = metrics['vertAscent']
  13. self.descent = metrics['vertDescent']
  14. self.lineGap = 0 # hard-coded based on best practices
  15. self.advanceHeightMax = metrics['height']
  16. self.minTopSideBearing = 0
  17. self.minBottomSideBearing = 0
  18. self.yMaxExtent = metrics['height']
  19. # carets should be this ratio for emoji fonts.
  20. self.caretSlopeRise = 1
  21. self.caretSlopeRun = 0
  22. self.caretOffset = 0
  23. # reserved, hardcoded; meant to be 0.
  24. # yes, the numbers are different from hhea. That's meant to be the case.
  25. self.reserved1 = 0
  26. self.reserved2 = 0
  27. self.reserved3 = 0
  28. self.reserved4 = 0
  29. self.metricDataFormat = 0 # hardcoded, meant to be 0.
  30. self.numOfLongVerMetrics = 0 # TODO: try to actually generate this based on the actual number of vmetrics that exist.
  31. def toTTX(self):
  32. """
  33. Compiles table to TTX.
  34. """
  35. vhea = Element("vhea")
  36. vhea.append(Element("tableVersion", {'value': self.version.toHexStr() }))
  37. vhea.append(Element("ascent", {'value': str(self.ascent) }))
  38. vhea.append(Element("descent", {'value': str(self.descent) }))
  39. vhea.append(Element("lineGap", {'value': str(self.lineGap) }))
  40. vhea.append(Element("advanceHeightMax", {'value': str(self.advanceHeightMax) }))
  41. vhea.append(Element("minTopSideBearing", {'value': str(self.minTopSideBearing) }))
  42. vhea.append(Element("minBottomSideBearing", {'value': str(self.minBottomSideBearing) }))
  43. vhea.append(Element("yMaxExtent", {'value': str(self.yMaxExtent) }))
  44. vhea.append(Element("caretSlopeRise", {'value': str(self.caretSlopeRise) }))
  45. vhea.append(Element("caretSlopeRun", {'value': str(self.caretSlopeRun) }))
  46. vhea.append(Element("caretOffset", {'value': str(self.caretOffset) }))
  47. vhea.append(Element("reserved1", {'value': str(self.reserved1) }))
  48. vhea.append(Element("reserved2", {'value': str(self.reserved2) }))
  49. vhea.append(Element("reserved3", {'value': str(self.reserved3) }))
  50. vhea.append(Element("reserved4", {'value': str(self.reserved4) }))
  51. vhea.append(Element("metricDataFormat", {'value': str(self.metricDataFormat) }))
  52. vhea.append(Element("numberOfHMetrics", {'value': str(self.numOfLongVerMetrics) }))
  53. return vhea
  54. def toBytes(self):
  55. vhea = struct.pack(">ihhhhhhhhhhhhhhhH"
  56. , int(self.version) # Fixed (Int32)
  57. , self.ascent # Int16
  58. , self.descent # Int16
  59. , self.lineGap # Int16
  60. , self.advanceHeightMax # Int16
  61. , self.minTopSideBearing # Int16
  62. , self.minBottomSideBearing # Int16
  63. , self.yMaxExtent # Int16
  64. , self.caretSlopeRise # Int16
  65. , self.caretSlopeRun # Int16
  66. , self.caretOffset # Int16
  67. , self.reserved1 # Int16
  68. , self.reserved2 # Int16
  69. , self.reserved3 # Int16
  70. , self.reserved4 # Int16
  71. , self.metricDataFormat # Int16
  72. , self.numOfLongVerMetrics # UInt16
  73. )
  74. return outputTableBytes(vhea)