def test_transform_monospaced_sidebearings(self, ttFont): hmtxTable = WOFF2HmtxTable() metrics = ttFont["hmtx"].metrics hmtxTable.metrics = metrics # force one of the monospaced glyphs at the end of hmtx table to have # its xMin different from its left sidebearing (50) ttFont["glyf"]["one"].xMin = metrics["one"][1] + 1 data = hmtxTable.transform(ttFont) assert data == ( b"\x01" # 00000001 | bits 1 unset: explicit monospaced sidebearings # advanceWidthArray b'\x01\xf4' # .notdef: 500 b'\x02X' # space: 600 b'\x02&' # A: 550 b'\x00\x00' # acutecomb: 0 b'\x02&' # Aacute: 550 b'\x01\xf4' # zero: 500 # leftSideBearingArray b'\x002' # one: 50 (xMin: 51) b'\x00(' # two: 40 )
def test_reconstruct_flags_reserved_bits(self): hmtxTable = WOFF2HmtxTable() with pytest.raises( ttLib.TTLibError, match="Bits 2-7 of 'hmtx' flags are reserved" ): hmtxTable.reconstruct(b"\xFF", ttFont=None)
def test_transform_proportional_sidebearings(self, ttFont): hmtxTable = WOFF2HmtxTable() metrics = ttFont["hmtx"].metrics # force one of the proportional glyphs to have its left sidebearing be # different from its xMin (40) metrics["A"] = (550, 39) hmtxTable.metrics = metrics assert ttFont["glyf"]["A"].xMin != metrics["A"][1] data = hmtxTable.transform(ttFont) assert data == ( b"\x02" # 00000010 | bits 0 unset: explicit proportional sidebearings # advanceWidthArray b'\x01\xf4' # .notdef: 500 b'\x02X' # space: 600 b'\x02&' # A: 550 b'\x00\x00' # acutecomb: 0 b'\x02&' # Aacute: 550 b'\x01\xf4' # zero: 500 # lsbArray b'\x002' # .notdef: 50 b'\x00\x00' # space: 0 b"\x00'" # A: 39 (xMin: 40) b'\xff\xd8' # acutecomb: -40 b'\x00(' # Aacute: 40 b'\x00\x1e' # zero: 30 )
def test_reconstruct_too_much_data(self, ttFont): ttFont["hhea"].numberOfHMetrics = 2 data = b'\x03\x01\xf4\x02X\x02&' hmtxTable = WOFF2HmtxTable() with pytest.raises(ttLib.TTLibError, match="too much 'hmtx' table data"): hmtxTable.reconstruct(data, ttFont)
def test_reconstruct_monospaced_sidebearings(self, ttFont): hmtxTable = WOFF2HmtxTable() data = ( b"\x01" # 00000001 | bits 1 unset: explicit monospaced sidebearings # advanceWidthArray b'\x01\xf4' # .notdef: 500 b'\x02X' # space: 600 b'\x02&' # A: 550 b'\x00\x00' # acutecomb: 0 b'\x02&' # Aacute: 550 b'\x01\xf4' # zero: 500 # leftSideBearingArray b'\x003' # one: 51 (xMin: 50) b'\x00(' # two: 40 ) hmtxTable.reconstruct(data, ttFont) assert hmtxTable.metrics == { ".notdef": (500, 50), "space": (600, 0), "A": (550, 40), "acutecomb": (0, -40), "Aacute": (550, 40), "zero": (500, 30), "one": (500, 51), "two": (500, 40), } assert ttFont["glyf"]["one"].xMin == 50
def test_reconstruct_no_sidebearings(self, ttFont): hmtxTable = WOFF2HmtxTable() data = ( b"\x03" # 00000011 | bits 0 and 1 are set (no sidebearings arrays) # advanceWidthArray b'\x01\xf4' # .notdef: 500 b'\x02X' # space: 600 b'\x02&' # A: 550 b'\x00\x00' # acutecomb: 0 b'\x02&' # Aacute: 550 b'\x01\xf4' # zero: 500 ) hmtxTable.reconstruct(data, ttFont) assert hmtxTable.metrics == { ".notdef": (500, 50), "space": (600, 0), "A": (550, 40), "acutecomb": (0, -40), "Aacute": (550, 40), "zero": (500, 30), "one": (500, 50), "two": (500, 40), }
def test_transform_not_applicable(self, ttFont): hmtxTable = WOFF2HmtxTable() metrics = ttFont["hmtx"].metrics # force both a proportional and monospaced glyph to have sidebearings # different from the respective xMin coordinates metrics["A"] = (550, 39) metrics["one"] = (500, 51) hmtxTable.metrics = metrics # 'None' signals to fall back using untransformed hmtx table data assert hmtxTable.transform(ttFont) is None
def test_transform_no_sidebearings(self, ttFont): hmtxTable = WOFF2HmtxTable() hmtxTable.metrics = ttFont["hmtx"].metrics data = hmtxTable.transform(ttFont) assert data == ( b"\x03" # 00000011 | bits 0 and 1 are set (no sidebearings arrays) # advanceWidthArray b'\x01\xf4' # .notdef: 500 b'\x02X' # space: 600 b'\x02&' # A: 550 b'\x00\x00' # acutecomb: 0 b'\x02&' # Aacute: 550 b'\x01\xf4' # zero: 500 )
def test_reconstruct_proportional_sidebearings(self, ttFont): hmtxTable = WOFF2HmtxTable() data = ( b"\x02" # 00000010 | bits 0 unset: explicit proportional sidebearings # advanceWidthArray b'\x01\xf4' # .notdef: 500 b'\x02X' # space: 600 b'\x02&' # A: 550 b'\x00\x00' # acutecomb: 0 b'\x02&' # Aacute: 550 b'\x01\xf4' # zero: 500 # lsbArray b'\x002' # .notdef: 50 b'\x00\x00' # space: 0 b"\x00'" # A: 39 (xMin: 40) b'\xff\xd8' # acutecomb: -40 b'\x00(' # Aacute: 40 b'\x00\x1e' # zero: 30 ) hmtxTable.reconstruct(data, ttFont) assert hmtxTable.metrics == { ".notdef": (500, 50), "space": (600, 0), "A": (550, 39), "acutecomb": (0, -40), "Aacute": (550, 40), "zero": (500, 30), "one": (500, 50), "two": (500, 40), } assert ttFont["glyf"]["A"].xMin == 40
def test_reconstruct_flags_required_bits(self): hmtxTable = WOFF2HmtxTable() with pytest.raises(ttLib.TTLibError, match="either bits 0 or 1 .* must set"): hmtxTable.reconstruct(b"\x00", ttFont=None)