%PDF- %PDF-
Direktori : /usr/lib/calibre/calibre/utils/fonts/sfnt/ |
Current File : //usr/lib/calibre/calibre/utils/fonts/sfnt/kern.py |
#!/usr/bin/env python3 __license__ = 'GPL v3' __copyright__ = '2012, Kovid Goyal <kovid at kovidgoyal.net>' __docformat__ = 'restructuredtext en' from struct import unpack_from, calcsize, pack, error as struct_error from calibre.utils.fonts.sfnt import (UnknownTable, FixedProperty, max_power_of_two) from calibre.utils.fonts.sfnt.errors import UnsupportedFont class KernTable(UnknownTable): version = FixedProperty('_version') def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._version, self.num_tables = unpack_from(b'>HH', self.raw) if self._version == 1 and len(self.raw) >= 8: self._version, self.num_tables = unpack_from(b'>LL', self.raw) self.headerfmt = b'>HH' if self._version == 0 else b'>LL' def restrict_to_glyphs(self, glyph_ids): if self._version not in {0, 0x10000}: raise UnsupportedFont('kern table has version: %x'%self._version) offset = 4 if (self._version == 0) else 8 tables = [] for i in range(self.num_tables): if self._version == 0: version, length, coverage = unpack_from(b'>3H', self.raw, offset) table_format = version else: length, coverage = unpack_from(b'>LH', self.raw, offset) table_format = coverage & 0xff raw = self.raw[offset:offset+length] if table_format == 0: raw = self.restrict_format_0(raw, glyph_ids) if not raw: continue tables.append(raw) offset += length self.raw = pack(self.headerfmt, self._version, len(tables)) + b''.join(tables) def restrict_format_0(self, raw, glyph_ids): if self._version == 0: version, length, coverage, npairs = unpack_from(b'>4H', raw) headerfmt = b'>3H' else: length, coverage, tuple_index, npairs = unpack_from(b'>L3H', raw) headerfmt = b'>L2H' offset = calcsize(headerfmt + b'4H') entries = [] entrysz = calcsize(b'>2Hh') for i in range(npairs): try: left, right, value = unpack_from(b'>2Hh', raw, offset) except struct_error: offset = len(raw) break # Buggy kern table if left in glyph_ids and right in glyph_ids: entries.append(pack(b'>2Hh', left, right, value)) offset += entrysz if offset != len(raw): raise UnsupportedFont('This font has extra data at the end of' ' a Format 0 kern subtable') npairs = len(entries) if npairs == 0: return b'' entry_selector = max_power_of_two(npairs) search_range = (2 ** entry_selector) * 6 range_shift = (npairs - (2 ** entry_selector)) * 6 entries = b''.join(entries) length = calcsize(headerfmt + b'4H') + len(entries) if self._version == 0: header = pack(headerfmt, version, length, coverage) else: header = pack(headerfmt, length, coverage, tuple_index) return header + pack(b'>4H', npairs, search_range, entry_selector, range_shift) + entries