Add get_name, get_full_name, get_glyph_index, and glyph_count functions
This commit is contained in:
parent
61aef094df
commit
0f0711ef2b
@ -445,7 +445,10 @@ def parse_cmap_subtable(f: BinaryIO, platformID: PlatformID) -> CmapSubtable:
|
||||
|
||||
assert False, format
|
||||
|
||||
class EncodingID(ABE): pass
|
||||
class EncodingID(ABE):
|
||||
@abstractmethod
|
||||
def get_code_point(self, char: str) -> Optional[int]:
|
||||
assert False, f"Unimplemented: get_code_point for {repr(self)}"
|
||||
|
||||
class UnicodeEncodingID(EncodingID, Enum):
|
||||
Unicode_1_0 = 0
|
||||
@ -456,6 +459,14 @@ class UnicodeEncodingID(EncodingID, Enum):
|
||||
UnicodeVariationSequences = 5
|
||||
UnicodeFull = 6
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self._name_
|
||||
|
||||
def get_code_point(self, char: str) -> int | None:
|
||||
return ord(char) # TODO: Actually validate that the codepoint is within range of these different versions of Unicode Encoding
|
||||
match self:
|
||||
case _: assert False, self
|
||||
|
||||
class MacintoshEncodingID(EncodingID, Enum):
|
||||
Roman = 0
|
||||
|
||||
@ -477,6 +488,15 @@ class WindowsEncodingID(EncodingID, Enum):
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self._name_
|
||||
|
||||
def get_code_point(self, char: str) -> int | None:
|
||||
match self:
|
||||
case self.UnicodeBMP:
|
||||
code_point = ord(char)
|
||||
if 0 <= code_point <= 0xFFFF: return code_point
|
||||
return None
|
||||
case self.UnicodeFull: return ord(char)
|
||||
case _: assert False, self
|
||||
|
||||
@dataclass
|
||||
class CustomEncodingID(EncodingID):
|
||||
@ -6261,3 +6281,44 @@ def parse_open_font_file(f: BinaryIO) -> OpenFontFile:
|
||||
def open_font_file(file_path: str) -> OpenFontFile: # as in `open (verb) font file (noun)`, not OpenFontFile
|
||||
with open(file_path, 'rb') as f:
|
||||
return parse_open_font_file(f)
|
||||
|
||||
def get_name(font: OpenFontFile, nameID: NameID) -> str:
|
||||
assert isinstance(font.naming_table, NameTable_Format_0)
|
||||
|
||||
for nameRecord in font.naming_table.nameRecord:
|
||||
if nameRecord.nameID == nameID:
|
||||
return nameRecord.string
|
||||
|
||||
assert False, f"Name not found: {nameID}"
|
||||
|
||||
def get_full_name(font: OpenFontFile) -> str:
|
||||
return get_name(font, PredefinedNameID.FULL_NAME)
|
||||
|
||||
def get_glyph_index(font: OpenFontFile, char: str) -> int:
|
||||
for encoding_record in font.character_to_glyph_mapping.encodingRecords:
|
||||
code_point = encoding_record.encodingID.get_code_point(char)
|
||||
if code_point is not None:
|
||||
match encoding_record.subtable:
|
||||
case CmapSubtable_Format_4(
|
||||
segCountX2=segCountX2,
|
||||
endCode=end_code,
|
||||
startCode=start_code,
|
||||
idDelta=id_delta,
|
||||
idRangeOffset=id_range_offset,
|
||||
glyphIdArray=glyph_id_array):
|
||||
for i, (start, end) in enumerate(zip(start_code, end_code)):
|
||||
if start <= code_point <= end:
|
||||
if start == end == 0xFFFF: return 0
|
||||
if id_range_offset[i] == 0: return (id_delta[i]+code_point)%0xFFFF
|
||||
index = glyph_id_array[code_point-start+id_range_offset[i]//2+i-segCountX2//2]
|
||||
if index == 0: return 0
|
||||
return (index+id_delta[i])%0xFFFF
|
||||
case CmapSubtable_Format_12(groups=groups):
|
||||
for group in groups:
|
||||
if group.startCharCode <= code_point <= group.endCharCode:
|
||||
assert False, (group, code_point)
|
||||
case _: assert False, encoding_record.subtable.__class__
|
||||
return 0
|
||||
|
||||
def glyph_count(font: OpenFontFile) -> int:
|
||||
return font.maximum_profile.numGlyphs
|
Loading…
Reference in New Issue
Block a user