head.py 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import struct
  2. from lxml.etree import Element
  3. from data import BFlags, LongDateTime
  4. from transform.bytes import outputTableBytes
  5. class head:
  6. """
  7. Class representing a 'head' table.
  8. """
  9. def __init__(self, m):
  10. self.majorVersion = 1 # hard-coded, is meant to be 1.
  11. self.minorVersion = 0 # hard-coded, is meant to be 0.
  12. self.fontRevision = m['metadata']['version'] # Fixed format.
  13. self.checkSumAdjustment = 0 # hard-coded.
  14. # This needs to be set at 0 before compilation in order for a correct checksum.
  15. # During compilation, the compilers will set it to what it needs to be in the end.
  16. self.magicNumber = 0x5f0f3cf5 # hard-coded
  17. self.flags = BFlags('11010000 00000000') # hard-coded
  18. self.unitsPerEm = m['metrics']['unitsPerEm']
  19. self.created = m['metadata']['created'] # (is a LongDateTime)
  20. self.modified = LongDateTime() # is set to 'now'
  21. self.xMin = m['metrics']['xMin']
  22. self.yMin = m['metrics']['yMin']
  23. self.xMax = m['metrics']['xMax']
  24. self.yMax = m['metrics']['yMax']
  25. self.macStyle = BFlags('00000000 00000000') # hard-coded. Must agree with OS/2's fsType.
  26. self.lowestRecPPEM = m['metrics']['lowestRecPPEM']
  27. self.fontDirectionHint = 2 # depreciated; is meant to be 2.
  28. self.indexToLocFormat = 0 # This determines the format of the loca table.
  29. self.glyphDataFormat = 0 # not important, hard-coded
  30. def toTTX(self):
  31. """
  32. Compiles table to TTX.
  33. """
  34. head = Element("head")
  35. head.append(Element("tableVersion", {'value': str(self.majorVersion) + '.' + str(self.minorVersion) }))
  36. head.append(Element("fontRevision", {'value': str(self.fontRevision) })) # TTX is weird about font versioning, only accepts a basic string, so use str.
  37. head.append(Element("checkSumAdjustment", {'value': str(self.checkSumAdjustment) })) # TTX changes this at compilation, so we don't need to bother with this for this compiler.
  38. head.append(Element("magicNumber", {'value': hex(self.magicNumber) }))
  39. head.append(Element("flags", {'value': self.flags.toTTXStr() }))
  40. head.append(Element("unitsPerEm", {'value': str( self.unitsPerEm )}))
  41. head.append(Element("created", {'value': self.created.toTTXStr() }))
  42. head.append(Element("modified", {'value': self.modified.toTTXStr() })) # TTX eats the value given and creates it's own date at compilation *shrugs*
  43. head.append(Element("xMin", {'value': str(self.xMin) }))
  44. head.append(Element("yMin", {'value': str(self.yMin) }))
  45. head.append(Element("xMax", {'value': str(self.xMax) }))
  46. head.append(Element("yMax", {'value': str(self.yMax) }))
  47. head.append(Element("macStyle", {'value': self.macStyle.toTTXStr() }))
  48. head.append(Element("lowestRecPPEM", {'value': str(self.lowestRecPPEM) }))
  49. head.append(Element("fontDirectionHint", {'value': str(self.fontDirectionHint) }))
  50. head.append(Element("indexToLocFormat", {'value': str(self.indexToLocFormat) }))
  51. head.append(Element("glyphDataFormat", {'value': str(self.glyphDataFormat) }))
  52. return head
  53. def toBytes(self):
  54. head = struct.pack( '>HHiII2sHqqhhhh2sHhhh'
  55. , self.majorVersion # UInt16
  56. , self.minorVersion # UInt16
  57. , int(self.fontRevision) # Fixed (Int32 but fixed-point)
  58. , self.checkSumAdjustment # UInt32
  59. , self.magicNumber # UInt32
  60. , self.flags.toBytes() # 2 bytes/UInt16
  61. , self.unitsPerEm # UInt16
  62. , int(self.created) # LONGDATETIME (Int64)
  63. , int(self.modified) # LONGDATETIME (Int64)
  64. , self.xMin # Int16
  65. , self.yMin # Int16
  66. , self.xMax # Int16
  67. , self.yMax # Int16
  68. , self.macStyle.toBytes() # 2 bytes/UInt16
  69. , self.lowestRecPPEM # UInt16
  70. , self.fontDirectionHint # Int16
  71. , self.indexToLocFormat # Int16
  72. , self.glyphDataFormat # Int16
  73. )
  74. return outputTableBytes(head)