[OpenFontFormat] Clean up OpenFont.py
This commit is contained in:
parent
6a33053dfc
commit
33e9714d34
@ -3,8 +3,8 @@ from datetime import datetime, timedelta, timezone
|
|||||||
from enum import Enum, EnumMeta
|
from enum import Enum, EnumMeta
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from math import floor, log2
|
from math import floor, log2
|
||||||
from typing import Callable, Generic, List, Optional, Tuple, TypeVar, BinaryIO
|
from types import TracebackType
|
||||||
from typing_extensions import Self
|
from typing import Callable, Generic, List, Optional, Tuple, Type, TypeVar, BinaryIO, Self
|
||||||
|
|
||||||
from abcde import ABD, ABE
|
from abcde import ABD, ABE
|
||||||
from read_utils import read_ascii, read_fixed_point, read_i16, read_i32, read_i8, read_int, read_pascal_string, read_u16, read_u24, read_u32, read_u64, read_u8
|
from read_utils import read_ascii, read_fixed_point, read_i16, read_i32, read_i8, read_int, read_pascal_string, read_u16, read_u24, read_u32, read_u64, read_u8
|
||||||
@ -28,7 +28,7 @@ def read_long_datetime(f: BinaryIO) -> datetime:
|
|||||||
Tag_ = TypeVar('Tag_')
|
Tag_ = TypeVar('Tag_')
|
||||||
SomeTag = Callable[[str], Tag_] # If SomeTag is not an EnumMeta, it should throw a ValueError to indicate an invalid tag
|
SomeTag = Callable[[str], Tag_] # If SomeTag is not an EnumMeta, it should throw a ValueError to indicate an invalid tag
|
||||||
|
|
||||||
def parse_tag_with_conditions(f: BinaryIO, *conditions: Tuple[Callable[[str], bool], SomeTag[Tag_]], umbrellaTagCls: type | SomeTag[Tag_], strict:bool=True) -> Tag_:
|
def read_tag_with_conditions(f: BinaryIO, *conditions: Tuple[Callable[[str], bool], SomeTag[Tag_]], umbrellaTagCls: type | SomeTag[Tag_], strict:bool=True) -> Tag_:
|
||||||
tag = read_ascii(f, 4)
|
tag = read_ascii(f, 4)
|
||||||
assert not strict or all([0x20 <= ord(c) <= 0x7e for c in tag]), f"Invalid tag: {[f.seek(-4, 1), f.read(4)][1]}"
|
assert not strict or all([0x20 <= ord(c) <= 0x7e for c in tag]), f"Invalid tag: {[f.seek(-4, 1), f.read(4)][1]}"
|
||||||
for (condition, tagCls) in conditions:
|
for (condition, tagCls) in conditions:
|
||||||
@ -38,14 +38,14 @@ def parse_tag_with_conditions(f: BinaryIO, *conditions: Tuple[Callable[[str], bo
|
|||||||
else:
|
else:
|
||||||
assert False, f"Invalid {umbrellaTagCls.__name__}: '{tag}'"
|
assert False, f"Invalid {umbrellaTagCls.__name__}: '{tag}'"
|
||||||
|
|
||||||
def parse_tag_cascading(f: BinaryIO, *tagClss: SomeTag[Tag_], umbrellaTagCls: type | SomeTag[Tag_], strict:bool=True) -> Tag_:
|
def read_tag_from_tags(f: BinaryIO, *tagClss: SomeTag[Tag_], umbrellaTagCls: type | SomeTag[Tag_], strict:bool=True) -> Tag_:
|
||||||
"""
|
"""
|
||||||
This is meant to be used for when some instances of an Enum are just CC01, CC02, CC03, ...
|
This is meant to be used for when some instances of an Enum are just CC01, CC02, CC03, ...
|
||||||
"""
|
"""
|
||||||
return parse_tag_with_conditions(f, *[(lambda _: True, tagCls) for tagCls in tagClss], umbrellaTagCls=umbrellaTagCls, strict=strict)
|
return read_tag_with_conditions(f, *[(lambda _: True, tagCls) for tagCls in tagClss], umbrellaTagCls=umbrellaTagCls, strict=strict)
|
||||||
|
|
||||||
def parse_tag(f: BinaryIO, tagCls: SomeTag[Tag_], *, strict:bool=True) -> Tag_:
|
def read_tag(f: BinaryIO, tagCls: SomeTag[Tag_], *, strict:bool=True) -> Tag_:
|
||||||
return parse_tag_cascading(f, tagCls, umbrellaTagCls=tagCls, strict=strict)
|
return read_tag_from_tags(f, tagCls, umbrellaTagCls=tagCls, strict=strict)
|
||||||
|
|
||||||
ID_ = TypeVar('ID_')
|
ID_ = TypeVar('ID_')
|
||||||
SomeID = Callable[[int], ID_]
|
SomeID = Callable[[int], ID_]
|
||||||
@ -53,7 +53,7 @@ SomeID = Callable[[int], ID_]
|
|||||||
T = TypeVar('T')
|
T = TypeVar('T')
|
||||||
Parser = Callable[[BinaryIO], T]
|
Parser = Callable[[BinaryIO], T]
|
||||||
|
|
||||||
def parse_id_ranges(f: BinaryIO, *ranges: Tuple[Optional[int], SomeID[ID_]], umbrellaIdCls: SomeID[ID_], reader: Parser[int]=read_u16) -> ID_: # must be in ascending order
|
def read_id_from_ranges(f: BinaryIO, *ranges: Tuple[Optional[int], SomeID[ID_]], umbrellaIdCls: SomeID[ID_], reader: Parser[int]=read_u16) -> ID_: # must be in ascending order
|
||||||
assert len(ranges) > 0, f"Must have at least one range"
|
assert len(ranges) > 0, f"Must have at least one range"
|
||||||
id = reader(f)
|
id = reader(f)
|
||||||
for (num, idCls) in ranges:
|
for (num, idCls) in ranges:
|
||||||
@ -62,18 +62,18 @@ def parse_id_ranges(f: BinaryIO, *ranges: Tuple[Optional[int], SomeID[ID_]], umb
|
|||||||
except ValueError: pass
|
except ValueError: pass
|
||||||
assert False, f"Invalid {umbrellaIdCls.__name__}: {id}"
|
assert False, f"Invalid {umbrellaIdCls.__name__}: {id}"
|
||||||
|
|
||||||
def parse_id(f: BinaryIO, idCls: SomeID[ID_], *, reader: Parser[int]=read_u16) -> ID_:
|
def read_id(f: BinaryIO, idCls: SomeID[ID_], *, reader: Parser[int]=read_u16) -> ID_:
|
||||||
return parse_id_ranges(f, (None, idCls), umbrellaIdCls=idCls, reader=reader)
|
return read_id_from_ranges(f, (None, idCls), umbrellaIdCls=idCls, reader=reader)
|
||||||
|
|
||||||
class SaveTell:
|
class SaveTell:
|
||||||
def __init__(self, f: BinaryIO):
|
def __init__(self, f: BinaryIO):
|
||||||
self.f = f
|
self.f = f
|
||||||
|
|
||||||
def __enter__(self):
|
def __enter__(self) -> int:
|
||||||
self.tell = self.f.tell()
|
self.tell = self.f.tell()
|
||||||
return self.tell
|
return self.tell
|
||||||
|
|
||||||
def __exit__(self, exc_type, exc_value, exc_tb):
|
def __exit__(self, exc_type: Optional[Type[BaseException]], exc_value: Optional[BaseException], exc_tb: Optional[TracebackType]) -> None:
|
||||||
self.f.seek(self.tell)
|
self.f.seek(self.tell)
|
||||||
|
|
||||||
# The following `parse_at_...` functions all move the BinaryIO away from wherever it was, so use `with SaveTell(f): ...` to save the tell
|
# The following `parse_at_...` functions all move the BinaryIO away from wherever it was, so use `with SaveTell(f): ...` to save the tell
|
||||||
@ -128,8 +128,8 @@ SomeTable = TypeVar('SomeTable', bound=Table)
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class SetTable(Table, Generic[SomeTable]):
|
class SetTable(Table, Generic[SomeTable]):
|
||||||
count: int
|
tableCount: int
|
||||||
elements: List[SomeTable]
|
tables: List[SomeTable]
|
||||||
|
|
||||||
def parse_set_table(f: BinaryIO, parser: Parser[SomeTable], *, offset_reader: Parser[int]=read_u16) -> SetTable[SomeTable]:
|
def parse_set_table(f: BinaryIO, parser: Parser[SomeTable], *, offset_reader: Parser[int]=read_u16) -> SetTable[SomeTable]:
|
||||||
start_tell = f.tell()
|
start_tell = f.tell()
|
||||||
@ -237,6 +237,9 @@ class TableTag(Enum):
|
|||||||
|
|
||||||
def __str__(self) -> str: return self._value_
|
def __str__(self) -> str: return self._value_
|
||||||
|
|
||||||
|
def parse_table_tag(f: BinaryIO) -> TableTag:
|
||||||
|
return read_tag(f, TableTag)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class TableDirectoryEntry:
|
class TableDirectoryEntry:
|
||||||
tableTag: TableTag
|
tableTag: TableTag
|
||||||
@ -245,7 +248,7 @@ class TableDirectoryEntry:
|
|||||||
length: int
|
length: int
|
||||||
|
|
||||||
def parse_table_directory_entry(f: BinaryIO) -> TableDirectoryEntry:
|
def parse_table_directory_entry(f: BinaryIO) -> TableDirectoryEntry:
|
||||||
tableTag = parse_tag(f, TableTag)
|
tableTag = parse_table_tag(f)
|
||||||
checkSum = read_u32(f)
|
checkSum = read_u32(f)
|
||||||
offset = read_u32(f)
|
offset = read_u32(f)
|
||||||
length = read_u32(f)
|
length = read_u32(f)
|
||||||
@ -435,12 +438,12 @@ class CmapSubtable_Format_12(CmapSubtable):
|
|||||||
groups: List[SequentialMapGroup]
|
groups: List[SequentialMapGroup]
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class UnicodeRangeRecord:
|
class UnicodeRangeRecord(Record):
|
||||||
startUnicodeValue: int
|
startUnicodeValue: int
|
||||||
additionalCount: int
|
additionalCount: int
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return f"U+{hex(self.startUnicodeValue)[2:]:0>4}" + (f"-U+{hex(self.startUnicodeValue+self.additionalCount)[2:]:0>4}" if self.additionalCount > 0 else '')
|
return f"<U+{hex(self.startUnicodeValue)[2:]:0>4}" + (f"-U+{hex(self.startUnicodeValue+self.additionalCount)[2:]:0>4}" if self.additionalCount > 0 else '')+">"
|
||||||
|
|
||||||
def parse_unicode_range_record(f: BinaryIO) -> UnicodeRangeRecord:
|
def parse_unicode_range_record(f: BinaryIO) -> UnicodeRangeRecord:
|
||||||
startUnicodeValue = read_u24(f)
|
startUnicodeValue = read_u24(f)
|
||||||
@ -461,7 +464,7 @@ def parse_default_UVS_table(f: BinaryIO) -> DefaultUVSTable:
|
|||||||
return DefaultUVSTable(numUnicodeValueRanges, ranges)
|
return DefaultUVSTable(numUnicodeValueRanges, ranges)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class UVSMappingRecord:
|
class UVSMappingRecord(Record):
|
||||||
unicodeValue: int
|
unicodeValue: int
|
||||||
glyphID: int
|
glyphID: int
|
||||||
|
|
||||||
@ -483,7 +486,7 @@ def parse_non_default_UVS_table(f: BinaryIO) -> NonDefaultUVSTable:
|
|||||||
return NonDefaultUVSTable(numUVSMappings, uvsMappings)
|
return NonDefaultUVSTable(numUVSMappings, uvsMappings)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class VariationSelectorRecord:
|
class VariationSelectorRecord(Record):
|
||||||
varSelector: int
|
varSelector: int
|
||||||
defaultUVS: Optional[DefaultUVSTable]
|
defaultUVS: Optional[DefaultUVSTable]
|
||||||
nonDefaultUVS: Optional[NonDefaultUVSTable]
|
nonDefaultUVS: Optional[NonDefaultUVSTable]
|
||||||
@ -637,8 +640,8 @@ def encoding_ID_cls_from_platform_ID(platformID: PlatformID) -> Callable[[int],
|
|||||||
|
|
||||||
assert False, platformID
|
assert False, platformID
|
||||||
|
|
||||||
def parse_encoding_ID(f: BinaryIO, platformID: PlatformID):
|
def parse_encoding_ID(f: BinaryIO, platformID: PlatformID) -> EncodingID:
|
||||||
return parse_id(f, encoding_ID_cls_from_platform_ID(platformID))
|
return read_id(f, encoding_ID_cls_from_platform_ID(platformID))
|
||||||
|
|
||||||
def parse_string_with_encoding_ID(f: BinaryIO, length: int, encodingID: EncodingID) -> str:
|
def parse_string_with_encoding_ID(f: BinaryIO, length: int, encodingID: EncodingID) -> str:
|
||||||
bytes = f.read(length)
|
bytes = f.read(length)
|
||||||
@ -653,13 +656,13 @@ def parse_string_with_encoding_ID(f: BinaryIO, length: int, encodingID: Encoding
|
|||||||
assert False, encodingID
|
assert False, encodingID
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class EncodingRecord:
|
class EncodingRecord(Record):
|
||||||
platformID: PlatformID
|
platformID: PlatformID
|
||||||
encodingID: EncodingID
|
encodingID: EncodingID
|
||||||
subtable: CmapSubtable
|
subtable: CmapSubtable
|
||||||
|
|
||||||
def parse_encoding_record(f: BinaryIO, start_tell:int) -> EncodingRecord:
|
def parse_encoding_record(f: BinaryIO, start_tell:int) -> EncodingRecord:
|
||||||
platformID = parse_id(f, PlatformID)
|
platformID = read_id(f, PlatformID)
|
||||||
encodingID = parse_encoding_ID(f, platformID)
|
encodingID = parse_encoding_ID(f, platformID)
|
||||||
subtableOffset = read_u32(f)
|
subtableOffset = read_u32(f)
|
||||||
with SaveTell(f):
|
with SaveTell(f):
|
||||||
@ -1086,7 +1089,7 @@ def languageID_cls_from_platform_ID(platformID: PlatformID) -> Callable[[int], L
|
|||||||
assert False, platformID
|
assert False, platformID
|
||||||
|
|
||||||
def parse_language_ID(f: BinaryIO, platformID: PlatformID) -> LanguageID:
|
def parse_language_ID(f: BinaryIO, platformID: PlatformID) -> LanguageID:
|
||||||
return parse_id(f, languageID_cls_from_platform_ID(platformID))
|
return read_id(f, languageID_cls_from_platform_ID(platformID))
|
||||||
|
|
||||||
class NameID(ABE): pass
|
class NameID(ABE): pass
|
||||||
|
|
||||||
@ -1123,7 +1126,7 @@ class FontSpecificNameID(NameID):
|
|||||||
nameID: int
|
nameID: int
|
||||||
|
|
||||||
def parse_name_ID(f: BinaryIO) -> NameID:
|
def parse_name_ID(f: BinaryIO) -> NameID:
|
||||||
return parse_id_ranges(f, (255, PredefinedNameID), (32767, FontSpecificNameID), umbrellaIdCls=NameID)
|
return read_id_from_ranges(f, (255, PredefinedNameID), (32767, FontSpecificNameID), umbrellaIdCls=NameID)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class NameRecord:
|
class NameRecord:
|
||||||
@ -1135,7 +1138,7 @@ class NameRecord:
|
|||||||
string: str
|
string: str
|
||||||
|
|
||||||
def parse_name_record(f: BinaryIO, stringBytes: BinaryIO) -> NameRecord:
|
def parse_name_record(f: BinaryIO, stringBytes: BinaryIO) -> NameRecord:
|
||||||
platformID = parse_id(f, PlatformID)
|
platformID = read_id(f, PlatformID)
|
||||||
encodingID = parse_encoding_ID(f, platformID)
|
encodingID = parse_encoding_ID(f, platformID)
|
||||||
languageID = parse_language_ID(f, platformID)
|
languageID = parse_language_ID(f, platformID)
|
||||||
nameID = parse_name_ID(f)
|
nameID = parse_name_ID(f)
|
||||||
@ -1178,6 +1181,9 @@ def parse_name_table(f: BinaryIO, length: int) -> NameTable:
|
|||||||
class VendorTag:
|
class VendorTag:
|
||||||
achVendID: str
|
achVendID: str
|
||||||
|
|
||||||
|
def parse_vendor_tag(f: BinaryIO) -> VendorTag:
|
||||||
|
return read_tag(f, VendorTag, strict=False)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class OS2Table(Table, ABD):
|
class OS2Table(Table, ABD):
|
||||||
version: int
|
version: int
|
||||||
@ -1251,7 +1257,7 @@ def parse_OS2_table(f: BinaryIO) -> OS2Table:
|
|||||||
panose0, panose1, panose2, panose3, panose4, panose5, panose6, panose7, panose8, panose9 = [read_u8(f) for _ in range(10)]
|
panose0, panose1, panose2, panose3, panose4, panose5, panose6, panose7, panose8, panose9 = [read_u8(f) for _ in range(10)]
|
||||||
panose = (panose0, panose1, panose2, panose3, panose4, panose5, panose6, panose7, panose8, panose9)
|
panose = (panose0, panose1, panose2, panose3, panose4, panose5, panose6, panose7, panose8, panose9)
|
||||||
ulUnicodeRange1, ulUnicodeRange2, ulUnicodeRange3, ulUnicodeRange4 = [read_u32(f) for _ in range(4)]
|
ulUnicodeRange1, ulUnicodeRange2, ulUnicodeRange3, ulUnicodeRange4 = [read_u32(f) for _ in range(4)]
|
||||||
achVendID = parse_tag(f, VendorTag, strict=False)
|
achVendID = parse_vendor_tag(f)
|
||||||
fsSelection = read_u16(f)
|
fsSelection = read_u16(f)
|
||||||
usFirstCharIndex, usLastCharIndex = read_u16(f), read_u16(f)
|
usFirstCharIndex, usLastCharIndex = read_u16(f), read_u16(f)
|
||||||
sTypoAscender, sTypoDescender, sTypoLineGap = read_i16(f), read_i16(f), read_i16(f)
|
sTypoAscender, sTypoDescender, sTypoLineGap = read_i16(f), read_i16(f), read_i16(f)
|
||||||
@ -2470,7 +2476,7 @@ class ValidLangSysTag(LangSysTag, Enum):
|
|||||||
def __str__(self) -> str: return self._name_
|
def __str__(self) -> str: return self._name_
|
||||||
|
|
||||||
def parse_lang_sys_tag(f: BinaryIO) -> LangSysTag:
|
def parse_lang_sys_tag(f: BinaryIO) -> LangSysTag:
|
||||||
return parse_tag_cascading(f, ValidLangSysTag, MS_VOLT_Tag, umbrellaTagCls=LangSysTag)
|
return read_tag_from_tags(f, ValidLangSysTag, MS_VOLT_Tag, umbrellaTagCls=LangSysTag)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class LangSysRecord:
|
class LangSysRecord:
|
||||||
@ -2508,7 +2514,7 @@ class ScriptRecord:
|
|||||||
script: ScriptTable
|
script: ScriptTable
|
||||||
|
|
||||||
def parse_script_record(f: BinaryIO, start_tell:int) -> ScriptRecord:
|
def parse_script_record(f: BinaryIO, start_tell:int) -> ScriptRecord:
|
||||||
tag = parse_tag(f, ScriptTag)
|
tag = read_tag(f, ScriptTag)
|
||||||
scriptOffset = read_u16(f)
|
scriptOffset = read_u16(f)
|
||||||
with SaveTell(f):
|
with SaveTell(f):
|
||||||
script = parse_at_offset(f, start_tell, scriptOffset, parse_script_table)
|
script = parse_at_offset(f, start_tell, scriptOffset, parse_script_table)
|
||||||
@ -2677,7 +2683,7 @@ class MS_VOLT_Tag(CCXXTag, LangSysTag, FeatureTag):
|
|||||||
__range__ = (0, 99) # I don't know if zz00 is valid or not, but I am letting it be, so that it can be caught, because zzXX is not a valid tag for anything
|
__range__ = (0, 99) # I don't know if zz00 is valid or not, but I am letting it be, so that it can be caught, because zzXX is not a valid tag for anything
|
||||||
|
|
||||||
def parse_feature_tag(f: BinaryIO) -> FeatureTag:
|
def parse_feature_tag(f: BinaryIO) -> FeatureTag:
|
||||||
return parse_tag_cascading(f, SimpleFeatureTag, CvXXFeatureTag, SsXXFeatureTag, MS_VOLT_Tag, umbrellaTagCls=FeatureTag)
|
return read_tag_from_tags(f, SimpleFeatureTag, CvXXFeatureTag, SsXXFeatureTag, MS_VOLT_Tag, umbrellaTagCls=FeatureTag)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class FeatureParamsTable(Table, ABD): pass
|
class FeatureParamsTable(Table, ABD): pass
|
||||||
@ -2711,7 +2717,7 @@ class SizeFeatureParamsTable(FeatureParamsTable):
|
|||||||
subfamily_nameID: Optional[int]
|
subfamily_nameID: Optional[int]
|
||||||
recommended_usage_range: Optional[Tuple[int, int]]
|
recommended_usage_range: Optional[Tuple[int, int]]
|
||||||
|
|
||||||
def parse_feature_params_table(f: BinaryIO, featureTag: FeatureTag):
|
def parse_feature_params_table(f: BinaryIO, featureTag: FeatureTag) -> FeatureParamsTable:
|
||||||
match featureTag:
|
match featureTag:
|
||||||
case CvXXFeatureTag(num=_):
|
case CvXXFeatureTag(num=_):
|
||||||
format = read_u16(f)
|
format = read_u16(f)
|
||||||
@ -2840,7 +2846,7 @@ def parse_lookup_table(f: BinaryIO, _lookupType: Callable[[int], LookupType], lo
|
|||||||
|
|
||||||
start_tell = f.tell()
|
start_tell = f.tell()
|
||||||
|
|
||||||
lookupType = parse_id(f, _lookupType)
|
lookupType = read_id(f, _lookupType)
|
||||||
lookupFlag = parse_lookup_flag(f)
|
lookupFlag = parse_lookup_flag(f)
|
||||||
subTableCount = read_u16(f)
|
subTableCount = read_u16(f)
|
||||||
subTableOffsets = [read_u16(f) for _ in range(subTableCount)]
|
subTableOffsets = [read_u16(f) for _ in range(subTableCount)]
|
||||||
@ -2893,20 +2899,18 @@ def parse_condition_table(f: BinaryIO) -> ConditionTable:
|
|||||||
|
|
||||||
assert False, format
|
assert False, format
|
||||||
|
|
||||||
@dataclass
|
ConditionSetTable = SetTable[ConditionTable]
|
||||||
class ConditionSetTable(Table):
|
|
||||||
conditionCount: int
|
|
||||||
conditions: List[ConditionTable]
|
|
||||||
|
|
||||||
def parse_condition_set_table(f: BinaryIO) -> ConditionSetTable:
|
def parse_condition_set_table(f: BinaryIO) -> ConditionSetTable:
|
||||||
start_tell = f.tell()
|
return parse_set_table(f, parse_condition_table, offset_reader=read_u32)
|
||||||
|
# start_tell = f.tell()
|
||||||
|
|
||||||
conditionCount = read_u16(f)
|
# conditionCount = read_u16(f)
|
||||||
conditionOffsets = [read_u32(f) for _ in range(conditionCount)]
|
# conditionOffsets = [read_u32(f) for _ in range(conditionCount)]
|
||||||
with SaveTell(f):
|
# with SaveTell(f):
|
||||||
conditions = parse_at_offsets(f, start_tell, conditionOffsets, parse_condition_table)
|
# conditions = parse_at_offsets(f, start_tell, conditionOffsets, parse_condition_table)
|
||||||
|
|
||||||
return ConditionSetTable(conditionCount, conditions)
|
# return ConditionSetTable(conditionCount, conditions)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class FeatureTableSubstitutionRecord:
|
class FeatureTableSubstitutionRecord:
|
||||||
@ -2949,14 +2953,14 @@ def parse_feature_table_substitution_table(f: BinaryIO, featureList: FeatureList
|
|||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class FeatureVariationRecord:
|
class FeatureVariationRecord:
|
||||||
conditionSet: SetTable[ConditionTable]
|
conditionSet: ConditionSetTable
|
||||||
featureTableSubstitution: FeatureTableSubstitutionTable
|
featureTableSubstitution: FeatureTableSubstitutionTable
|
||||||
|
|
||||||
def parse_feature_variation_record(f: BinaryIO, start_tell: int, featureList: FeatureListTable) -> FeatureVariationRecord:
|
def parse_feature_variation_record(f: BinaryIO, start_tell: int, featureList: FeatureListTable) -> FeatureVariationRecord:
|
||||||
conditionSetOffset = read_u32(f)
|
conditionSetOffset = read_u32(f)
|
||||||
featureTableSubstitutionOffset = read_u32(f)
|
featureTableSubstitutionOffset = read_u32(f)
|
||||||
with SaveTell(f):
|
with SaveTell(f):
|
||||||
conditionSet = parse_at_offset(f, start_tell, conditionSetOffset, lambda f: parse_set_table(f, parse_condition_table, offset_reader=read_u32))
|
conditionSet = parse_at_offset(f, start_tell, conditionSetOffset, parse_condition_set_table)
|
||||||
featureTableSubstitution = parse_at_offset(f, start_tell, featureTableSubstitutionOffset, lambda f: parse_feature_table_substitution_table(f, featureList))
|
featureTableSubstitution = parse_at_offset(f, start_tell, featureTableSubstitutionOffset, lambda f: parse_feature_table_substitution_table(f, featureList))
|
||||||
|
|
||||||
return FeatureVariationRecord(conditionSet, featureTableSubstitution)
|
return FeatureVariationRecord(conditionSet, featureTableSubstitution)
|
||||||
@ -2997,7 +3001,7 @@ class CoverageTable_Format_1(CoverageTable):
|
|||||||
glyphArray: List[int]
|
glyphArray: List[int]
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class RangeRecord:
|
class RangeRecord(Record):
|
||||||
startGlyphID: int
|
startGlyphID: int
|
||||||
endGlyphID: int
|
endGlyphID: int
|
||||||
startCoverageIndex: int
|
startCoverageIndex: int
|
||||||
@ -3045,7 +3049,7 @@ class ClassRangeRecord:
|
|||||||
endGlyphID: int
|
endGlyphID: int
|
||||||
classValue: int
|
classValue: int
|
||||||
|
|
||||||
def parse_class_range_record(f) -> ClassRangeRecord:
|
def parse_class_range_record(f: BinaryIO) -> ClassRangeRecord:
|
||||||
startGlyphID = read_u16(f)
|
startGlyphID = read_u16(f)
|
||||||
endGlyphID = read_u16(f)
|
endGlyphID = read_u16(f)
|
||||||
classValue = read_u16(f)
|
classValue = read_u16(f)
|
||||||
@ -3087,7 +3091,7 @@ class ValueFormatFlags:
|
|||||||
def x_advance_device(self) -> bool: return (self.bytes & 0x0040)!=0
|
def x_advance_device(self) -> bool: return (self.bytes & 0x0040)!=0
|
||||||
def y_advance_device(self) -> bool: return (self.bytes & 0x0080)!=0
|
def y_advance_device(self) -> bool: return (self.bytes & 0x0080)!=0
|
||||||
|
|
||||||
def parse_value_format(f) -> ValueFormatFlags:
|
def parse_value_format(f: BinaryIO) -> ValueFormatFlags:
|
||||||
valueFormat = read_u16(f)
|
valueFormat = read_u16(f)
|
||||||
assert valueFormat & 0xFF00 == 0, "Reserved"
|
assert valueFormat & 0xFF00 == 0, "Reserved"
|
||||||
|
|
||||||
@ -3142,7 +3146,7 @@ class BaseTagListTable(Table):
|
|||||||
|
|
||||||
def parse_base_tag_list_table(f: BinaryIO) -> BaseTagListTable:
|
def parse_base_tag_list_table(f: BinaryIO) -> BaseTagListTable:
|
||||||
baseTagCount = read_u16(f)
|
baseTagCount = read_u16(f)
|
||||||
baselineTags = [parse_tag(f, BaselineTag) for _ in range(baseTagCount)]
|
baselineTags = [read_tag(f, BaselineTag) for _ in range(baseTagCount)]
|
||||||
|
|
||||||
return BaseTagListTable(baseTagCount, baselineTags)
|
return BaseTagListTable(baseTagCount, baselineTags)
|
||||||
|
|
||||||
@ -3225,7 +3229,7 @@ class BaseScriptRecord:
|
|||||||
baseScript: BaseScriptTable
|
baseScript: BaseScriptTable
|
||||||
|
|
||||||
def parse_base_script_record(f: BinaryIO, start_tell: int) -> BaseScriptRecord:
|
def parse_base_script_record(f: BinaryIO, start_tell: int) -> BaseScriptRecord:
|
||||||
baseScriptTag = parse_tag(f, ScriptTag)
|
baseScriptTag = read_tag(f, ScriptTag)
|
||||||
baseScriptOffset = read_u16(f)
|
baseScriptOffset = read_u16(f)
|
||||||
with SaveTell(f):
|
with SaveTell(f):
|
||||||
baseScript = parse_at_offset(f, start_tell, baseScriptOffset, parse_base_script_table)
|
baseScript = parse_at_offset(f, start_tell, baseScriptOffset, parse_base_script_table)
|
||||||
@ -3879,11 +3883,16 @@ def parse_chain_pos_rule_table(f: BinaryIO) -> ChainPosRuleTable:
|
|||||||
|
|
||||||
return ChainPosRuleTable(backtrackGlyphCount, backtrackSequence, inputGlyphCount, inputSequence, lookaheadGlyphCount, lookAheadSequence, posCount, posLookupRecords)
|
return ChainPosRuleTable(backtrackGlyphCount, backtrackSequence, inputGlyphCount, inputSequence, lookaheadGlyphCount, lookAheadSequence, posCount, posLookupRecords)
|
||||||
|
|
||||||
|
ChainPosRuleSetTable = SetTable[ChainPosRuleTable]
|
||||||
|
|
||||||
|
def parse_chain_pos_rule_set_table(f: BinaryIO) -> ChainPosRuleSetTable:
|
||||||
|
return parse_set_table(f, parse_chain_pos_rule_table)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ChainContextPosSubtable_Format_1(ChainContextPosSubtable):
|
class ChainContextPosSubtable_Format_1(ChainContextPosSubtable):
|
||||||
coverage: CoverageTable
|
coverage: CoverageTable
|
||||||
chainPosRuleSetCount: int
|
chainPosRuleSetCount: int
|
||||||
chainPosRuleSets: List[SetTable[ChainPosRuleTable]]
|
chainPosRuleSets: List[ChainPosRuleSetTable]
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ChainPosClassRuleTable(Table):
|
class ChainPosClassRuleTable(Table):
|
||||||
@ -3908,6 +3917,11 @@ def parse_chain_pos_class_rule_table(f: BinaryIO) -> ChainPosClassRuleTable:
|
|||||||
|
|
||||||
return ChainPosClassRuleTable(backtrackGlyphCount, backtrackSequence, inputGlyphCount, inputSequence, lookaheadGlyphCount, lookAheadSequence, posCount, posLookupRecords)
|
return ChainPosClassRuleTable(backtrackGlyphCount, backtrackSequence, inputGlyphCount, inputSequence, lookaheadGlyphCount, lookAheadSequence, posCount, posLookupRecords)
|
||||||
|
|
||||||
|
ChainPosClassRuleSetTable = SetTable[ChainPosClassRuleTable]
|
||||||
|
|
||||||
|
def parse_chain_pos_class_rule_set_table(f: BinaryIO) -> ChainPosClassRuleSetTable:
|
||||||
|
return parse_set_table(f, parse_chain_pos_class_rule_table)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ChainContextPosSubtable_Format_2(ChainContextPosSubtable):
|
class ChainContextPosSubtable_Format_2(ChainContextPosSubtable):
|
||||||
coverage: CoverageTable
|
coverage: CoverageTable
|
||||||
@ -3915,7 +3929,7 @@ class ChainContextPosSubtable_Format_2(ChainContextPosSubtable):
|
|||||||
inputClassDef: ClassDefTable
|
inputClassDef: ClassDefTable
|
||||||
lookaheadClassDef: ClassDefTable
|
lookaheadClassDef: ClassDefTable
|
||||||
chainPosClassSetCount: int
|
chainPosClassSetCount: int
|
||||||
chainPosClassSets: List[Optional[SetTable[ChainPosClassRuleTable]]]
|
chainPosClassSets: List[Optional[ChainPosClassRuleSetTable]]
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ChainContextPosSubtable_Format_3(ChainContextPosSubtable):
|
class ChainContextPosSubtable_Format_3(ChainContextPosSubtable):
|
||||||
@ -4112,7 +4126,7 @@ def parse_GPOS_lookup_subtable(f: BinaryIO, lookupType: GPOSLookupType) -> GPOSL
|
|||||||
chainPosRuleSetOffsets = [read_u16(f) for _ in range(chainPosRuleSetCount)]
|
chainPosRuleSetOffsets = [read_u16(f) for _ in range(chainPosRuleSetCount)]
|
||||||
with SaveTell(f):
|
with SaveTell(f):
|
||||||
coverage = parse_at_offset(f, start_tell, coverageOffset, parse_coverage_table)
|
coverage = parse_at_offset(f, start_tell, coverageOffset, parse_coverage_table)
|
||||||
chainPosRuleSets = parse_at_offsets(f, start_tell, chainPosRuleSetOffsets, lambda f: parse_set_table(f, parse_chain_pos_rule_table))
|
chainPosRuleSets = parse_at_offsets(f, start_tell, chainPosRuleSetOffsets, parse_chain_pos_rule_set_table)
|
||||||
|
|
||||||
return ChainContextPosSubtable_Format_1(posFormat, coverage, chainPosRuleSetCount, chainPosRuleSets)
|
return ChainContextPosSubtable_Format_1(posFormat, coverage, chainPosRuleSetCount, chainPosRuleSets)
|
||||||
case 2:
|
case 2:
|
||||||
@ -4127,7 +4141,7 @@ def parse_GPOS_lookup_subtable(f: BinaryIO, lookupType: GPOSLookupType) -> GPOSL
|
|||||||
backtrackClassDef = parse_at_offset(f, start_tell, backtrackClassDefOffset, parse_class_def_table)
|
backtrackClassDef = parse_at_offset(f, start_tell, backtrackClassDefOffset, parse_class_def_table)
|
||||||
inputClassDef = parse_at_offset(f, start_tell, inputClassDefOffset, parse_class_def_table)
|
inputClassDef = parse_at_offset(f, start_tell, inputClassDefOffset, parse_class_def_table)
|
||||||
lookaheadClassDef = parse_at_offset(f, start_tell, lookaheadClassDefOffset, parse_class_def_table)
|
lookaheadClassDef = parse_at_offset(f, start_tell, lookaheadClassDefOffset, parse_class_def_table)
|
||||||
chainPosClassSets = parse_at_optional_offsets(f, start_tell, chainPosClassSetOffsets, lambda f: parse_set_table(f, parse_chain_pos_class_rule_table))
|
chainPosClassSets = parse_at_optional_offsets(f, start_tell, chainPosClassSetOffsets, parse_chain_pos_class_rule_set_table)
|
||||||
|
|
||||||
return ChainContextPosSubtable_Format_2(posFormat, coverage, backtrackClassDef, inputClassDef, lookaheadClassDef, chainPosClassSetCount, chainPosClassSets)
|
return ChainContextPosSubtable_Format_2(posFormat, coverage, backtrackClassDef, inputClassDef, lookaheadClassDef, chainPosClassSetCount, chainPosClassSets)
|
||||||
case 3:
|
case 3:
|
||||||
@ -4156,7 +4170,7 @@ def parse_GPOS_lookup_subtable(f: BinaryIO, lookupType: GPOSLookupType) -> GPOSL
|
|||||||
|
|
||||||
match posFormat:
|
match posFormat:
|
||||||
case 1:
|
case 1:
|
||||||
extensionLookupType = parse_id(f, GPOSLookupType)
|
extensionLookupType = read_id(f, GPOSLookupType)
|
||||||
assert extensionLookupType != GPOSLookupType.ExtensionPos, f"ExtensionPos subtable cannot reference another ExtensionPos subtable"
|
assert extensionLookupType != GPOSLookupType.ExtensionPos, f"ExtensionPos subtable cannot reference another ExtensionPos subtable"
|
||||||
extensionOffset = read_u32(f)
|
extensionOffset = read_u32(f)
|
||||||
with SaveTell(f):
|
with SaveTell(f):
|
||||||
@ -4323,11 +4337,16 @@ def parse_ligature_table(f: BinaryIO) -> LigatureTable:
|
|||||||
|
|
||||||
return LigatureTable(ligatureGlyph, componentCount, componentGlyphIDs)
|
return LigatureTable(ligatureGlyph, componentCount, componentGlyphIDs)
|
||||||
|
|
||||||
|
LigatureSetTable = SetTable[LigatureTable]
|
||||||
|
|
||||||
|
def parse_ligature_set_table(f: BinaryIO) -> LigatureSetTable:
|
||||||
|
return parse_set_table(f, parse_ligature_table)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class LigatureSubstSubtable_Format_1(LigatureSubstSubtable):
|
class LigatureSubstSubtable_Format_1(LigatureSubstSubtable):
|
||||||
coverage: CoverageTable
|
coverage: CoverageTable
|
||||||
ligatureSetCount: int
|
ligatureSetCount: int
|
||||||
ligatureSets: List[SetTable[LigatureTable]]
|
ligatureSets: List[LigatureSetTable]
|
||||||
|
|
||||||
# 5
|
# 5
|
||||||
|
|
||||||
@ -4350,11 +4369,16 @@ def parse_sub_rule_table(f: BinaryIO) -> SubRuleTable:
|
|||||||
|
|
||||||
return SubRuleTable(glyphCount, substitutionCount, inputSequence, substLookupRecords)
|
return SubRuleTable(glyphCount, substitutionCount, inputSequence, substLookupRecords)
|
||||||
|
|
||||||
|
SubRuleSetTable = SetTable[SubRuleTable]
|
||||||
|
|
||||||
|
def parse_sub_rule_set_table(f: BinaryIO) -> SubRuleSetTable:
|
||||||
|
return parse_set_table(f, parse_sub_rule_table)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ContextSubstSubtable_Format_1(ContextSubstSubtable):
|
class ContextSubstSubtable_Format_1(ContextSubstSubtable):
|
||||||
coverage: CoverageTable
|
coverage: CoverageTable
|
||||||
subRuleSetCount: int
|
subRuleSetCount: int
|
||||||
subRuleSets: List[SetTable[SubRuleTable]]
|
subRuleSets: List[SubRuleSetTable]
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class SubClassRuleTable(Table):
|
class SubClassRuleTable(Table):
|
||||||
@ -4371,12 +4395,17 @@ def parse_sub_class_rule_table(f: BinaryIO) -> SubClassRuleTable:
|
|||||||
|
|
||||||
return SubClassRuleTable(glyphCount, substitutionCount, inputSequence, substLookupRecords)
|
return SubClassRuleTable(glyphCount, substitutionCount, inputSequence, substLookupRecords)
|
||||||
|
|
||||||
|
SubClassRuleSetTable = SetTable[SubClassRuleTable]
|
||||||
|
|
||||||
|
def parse_sub_class_rule_set_table(f: BinaryIO) -> SubClassRuleSetTable:
|
||||||
|
return parse_set_table(f, parse_sub_class_rule_table)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ContextSubstSubtable_Format_2(ContextSubstSubtable):
|
class ContextSubstSubtable_Format_2(ContextSubstSubtable):
|
||||||
coverage: CoverageTable
|
coverage: CoverageTable
|
||||||
classDef: ClassDefTable
|
classDef: ClassDefTable
|
||||||
subClassSetCount: int
|
subClassSetCount: int
|
||||||
subClassSets: List[Optional[SetTable[SubClassRuleTable]]]
|
subClassSets: List[Optional[SubClassRuleSetTable]]
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ContextSubstSubtable_Format_3(ContextSubstSubtable):
|
class ContextSubstSubtable_Format_3(ContextSubstSubtable):
|
||||||
@ -4417,11 +4446,16 @@ def parse_chain_sub_rule_table(f: BinaryIO) -> ChainSubRuleTable:
|
|||||||
|
|
||||||
return ChainSubRuleTable(backtrackGlyphCount, backtrackSequence, inputGlyphCount, inputSequence, lookaheadGlyphCount, lookAheadSequence, substitutionCount, substLookupRecords)
|
return ChainSubRuleTable(backtrackGlyphCount, backtrackSequence, inputGlyphCount, inputSequence, lookaheadGlyphCount, lookAheadSequence, substitutionCount, substLookupRecords)
|
||||||
|
|
||||||
|
ChainSubRuleSetTable = SetTable[ChainSubRuleTable]
|
||||||
|
|
||||||
|
def parse_chain_sub_rule_set_table(f: BinaryIO) -> ChainSubRuleSetTable:
|
||||||
|
return parse_set_table(f, parse_chain_sub_rule_table)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ChainContextSubstSubtable_Format_1(ChainContextSubstSubtable):
|
class ChainContextSubstSubtable_Format_1(ChainContextSubstSubtable):
|
||||||
coverage: CoverageTable
|
coverage: CoverageTable
|
||||||
chainSubRuleSetCount: int
|
chainSubRuleSetCount: int
|
||||||
chainSubRuleSets: List[SetTable[ChainSubRuleTable]]
|
chainSubRuleSets: List[ChainSubRuleSetTable]
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ChainSubClassRuleTable(Table):
|
class ChainSubClassRuleTable(Table):
|
||||||
@ -4449,6 +4483,11 @@ def parse_chain_sub_class_rule_table(f: BinaryIO) -> ChainSubClassRuleTable:
|
|||||||
|
|
||||||
return ChainSubClassRuleTable(backtrackGlyphCount, backtrackSequence, inputGlyphCount, inputSequence, lookaheadGlyphCount, lookAheadSequence, substitutionCount, substLookupRecords)
|
return ChainSubClassRuleTable(backtrackGlyphCount, backtrackSequence, inputGlyphCount, inputSequence, lookaheadGlyphCount, lookAheadSequence, substitutionCount, substLookupRecords)
|
||||||
|
|
||||||
|
ChainSubClassRuleSetTable = SetTable[ChainSubClassRuleTable]
|
||||||
|
|
||||||
|
def parse_chain_sub_class_rule_set_table(f: BinaryIO) -> ChainSubClassRuleSetTable:
|
||||||
|
return parse_set_table(f, parse_chain_sub_class_rule_table)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ChainContextSubstSubtable_Format_2(ChainContextSubstSubtable):
|
class ChainContextSubstSubtable_Format_2(ChainContextSubstSubtable):
|
||||||
coverage: CoverageTable
|
coverage: CoverageTable
|
||||||
@ -4456,7 +4495,7 @@ class ChainContextSubstSubtable_Format_2(ChainContextSubstSubtable):
|
|||||||
inputClassDef: ClassDefTable
|
inputClassDef: ClassDefTable
|
||||||
lookaheadClassDef: ClassDefTable
|
lookaheadClassDef: ClassDefTable
|
||||||
chainSubClassSetCount: int
|
chainSubClassSetCount: int
|
||||||
chainSubClassSets: List[Optional[SetTable[ChainSubClassRuleTable]]]
|
chainSubClassSets: List[Optional[ChainSubClassRuleSetTable]]
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class ChainContextSubstSubtable_Format_3(ChainContextSubstSubtable):
|
class ChainContextSubstSubtable_Format_3(ChainContextSubstSubtable):
|
||||||
@ -4597,7 +4636,7 @@ def parse_GSUB_lookup_subtable(f: BinaryIO, lookupType: GSUBLookupType) -> GSUBL
|
|||||||
subRuleSetOffsets = [read_u16(f) for _ in range(subRuleSetCount)]
|
subRuleSetOffsets = [read_u16(f) for _ in range(subRuleSetCount)]
|
||||||
with SaveTell(f):
|
with SaveTell(f):
|
||||||
coverage = parse_at_offset(f, start_tell, coverageOffset, parse_coverage_table)
|
coverage = parse_at_offset(f, start_tell, coverageOffset, parse_coverage_table)
|
||||||
subRuleSets = parse_at_offsets(f, start_tell, subRuleSetOffsets, lambda f: parse_set_table(f, parse_sub_rule_table))
|
subRuleSets = parse_at_offsets(f, start_tell, subRuleSetOffsets, parse_sub_rule_set_table)
|
||||||
|
|
||||||
return ContextSubstSubtable_Format_1(substFormat, coverage, subRuleSetCount, subRuleSets)
|
return ContextSubstSubtable_Format_1(substFormat, coverage, subRuleSetCount, subRuleSets)
|
||||||
case 2:
|
case 2:
|
||||||
@ -4608,7 +4647,7 @@ def parse_GSUB_lookup_subtable(f: BinaryIO, lookupType: GSUBLookupType) -> GSUBL
|
|||||||
with SaveTell(f):
|
with SaveTell(f):
|
||||||
coverage = parse_at_offset(f, start_tell, coverageOffset, parse_coverage_table)
|
coverage = parse_at_offset(f, start_tell, coverageOffset, parse_coverage_table)
|
||||||
classDef = parse_at_offset(f, start_tell, classDefOffset, parse_class_def_table)
|
classDef = parse_at_offset(f, start_tell, classDefOffset, parse_class_def_table)
|
||||||
subClassSets = parse_at_optional_offsets(f, start_tell, subClassSetOffsets, lambda f: parse_set_table(f, parse_sub_class_rule_table))
|
subClassSets = parse_at_optional_offsets(f, start_tell, subClassSetOffsets, parse_sub_class_rule_set_table)
|
||||||
|
|
||||||
return ContextSubstSubtable_Format_2(substFormat, coverage, classDef, subClassSetCount, subClassSets)
|
return ContextSubstSubtable_Format_2(substFormat, coverage, classDef, subClassSetCount, subClassSets)
|
||||||
case 3:
|
case 3:
|
||||||
@ -4636,7 +4675,7 @@ def parse_GSUB_lookup_subtable(f: BinaryIO, lookupType: GSUBLookupType) -> GSUBL
|
|||||||
chainSubRuleSetOffsets = [read_u16(f) for _ in range(chainSubRuleSetCount)]
|
chainSubRuleSetOffsets = [read_u16(f) for _ in range(chainSubRuleSetCount)]
|
||||||
with SaveTell(f):
|
with SaveTell(f):
|
||||||
coverage = parse_at_offset(f, start_tell, coverageOffset, parse_coverage_table)
|
coverage = parse_at_offset(f, start_tell, coverageOffset, parse_coverage_table)
|
||||||
chainSubRuleSets = parse_at_offsets(f, start_tell, chainSubRuleSetOffsets, lambda f: parse_set_table(f, parse_chain_sub_rule_table))
|
chainSubRuleSets = parse_at_offsets(f, start_tell, chainSubRuleSetOffsets, parse_chain_sub_rule_set_table)
|
||||||
|
|
||||||
return ChainContextSubstSubtable_Format_1(substFormat, coverage, chainSubRuleSetCount, chainSubRuleSets)
|
return ChainContextSubstSubtable_Format_1(substFormat, coverage, chainSubRuleSetCount, chainSubRuleSets)
|
||||||
case 2:
|
case 2:
|
||||||
@ -4651,7 +4690,7 @@ def parse_GSUB_lookup_subtable(f: BinaryIO, lookupType: GSUBLookupType) -> GSUBL
|
|||||||
backtrackClassDef = parse_at_offset(f, start_tell, backtrackClassDefOffset, parse_class_def_table)
|
backtrackClassDef = parse_at_offset(f, start_tell, backtrackClassDefOffset, parse_class_def_table)
|
||||||
inputClassDef = parse_at_offset(f, start_tell, inputClassDefOffset, parse_class_def_table)
|
inputClassDef = parse_at_offset(f, start_tell, inputClassDefOffset, parse_class_def_table)
|
||||||
lookaheadClassDef = parse_at_offset(f, start_tell, lookaheadClassDefOffset, parse_class_def_table)
|
lookaheadClassDef = parse_at_offset(f, start_tell, lookaheadClassDefOffset, parse_class_def_table)
|
||||||
chainSubClassSets = parse_at_optional_offsets(f, start_tell, chainSubClassSetOffsets, lambda f: parse_set_table(f, parse_chain_sub_class_rule_table))
|
chainSubClassSets = parse_at_optional_offsets(f, start_tell, chainSubClassSetOffsets, parse_chain_sub_class_rule_set_table)
|
||||||
|
|
||||||
return ChainContextSubstSubtable_Format_2(substFormat, coverage, backtrackClassDef, inputClassDef, lookaheadClassDef, chainSubClassSetCount, chainSubClassSets)
|
return ChainContextSubstSubtable_Format_2(substFormat, coverage, backtrackClassDef, inputClassDef, lookaheadClassDef, chainSubClassSetCount, chainSubClassSets)
|
||||||
case 3:
|
case 3:
|
||||||
@ -4685,7 +4724,7 @@ def parse_GSUB_lookup_subtable(f: BinaryIO, lookupType: GSUBLookupType) -> GSUBL
|
|||||||
|
|
||||||
match substFormat:
|
match substFormat:
|
||||||
case 1:
|
case 1:
|
||||||
extensionLookupType = parse_id(f, GSUBLookupType)
|
extensionLookupType = read_id(f, GSUBLookupType)
|
||||||
extensionOffset = read_u32(f)
|
extensionOffset = read_u32(f)
|
||||||
with SaveTell(f):
|
with SaveTell(f):
|
||||||
extension = parse_at_offset(f, start_tell, extensionOffset, lambda f: parse_GSUB_lookup_subtable(f, extensionLookupType))
|
extension = parse_at_offset(f, start_tell, extensionOffset, lambda f: parse_GSUB_lookup_subtable(f, extensionLookupType))
|
||||||
@ -5370,7 +5409,7 @@ def is_valid_possible_foundry_defined_axis_tag(tag: str) -> bool:
|
|||||||
return len(tag) == 4 and is_upper(tag[0]) and all(map(lambda s: is_upper(s) or is_digit(s), tag[1:]))
|
return len(tag) == 4 and is_upper(tag[0]) and all(map(lambda s: is_upper(s) or is_digit(s), tag[1:]))
|
||||||
|
|
||||||
def parse_axis_tag(f: BinaryIO) -> AxisTag:
|
def parse_axis_tag(f: BinaryIO) -> AxisTag:
|
||||||
return parse_tag_with_conditions(f, (is_valid_possible_registed_axis_tag, RegisteredAxisTag), (is_valid_possible_foundry_defined_axis_tag, FoundryDefinedAxisTag), umbrellaTagCls=AxisTag)
|
return read_tag_with_conditions(f, (is_valid_possible_registed_axis_tag, RegisteredAxisTag), (is_valid_possible_foundry_defined_axis_tag, FoundryDefinedAxisTag), umbrellaTagCls=AxisTag)
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class AxisValueMapRecord:
|
class AxisValueMapRecord:
|
||||||
|
Loading…
Reference in New Issue
Block a user