Add /OpenFontFormat
This commit is contained in:
		
							parent
							
								
									38987a04c6
								
							
						
					
					
						commit
						9b509e6306
					
				
							
								
								
									
										2
									
								
								OpenFontFormat/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								OpenFontFormat/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
				
			|||||||
 | 
					examples
 | 
				
			||||||
 | 
					mypy.ini
 | 
				
			||||||
							
								
								
									
										5960
									
								
								OpenFontFormat/OpenFont.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5960
									
								
								OpenFontFormat/OpenFont.py
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										21
									
								
								OpenFontFormat/abcde.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								OpenFontFormat/abcde.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					class ABD:
 | 
				
			||||||
 | 
						"""
 | 
				
			||||||
 | 
						#### Abstract Base Dataclass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						This will only work on dataclasses
 | 
				
			||||||
 | 
						"""
 | 
				
			||||||
 | 
						def __post_init__(self, *args, **kwargs):
 | 
				
			||||||
 | 
							if ABD in self.__class__.__bases__ or ABD == self.__class__:
 | 
				
			||||||
 | 
								msg = f"Cannot instantiate an Abstract Base Dataclass: {self.__class__.__name__}"
 | 
				
			||||||
 | 
								raise TypeError(msg)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ABE:
 | 
				
			||||||
 | 
						"""
 | 
				
			||||||
 | 
						#### Abstract Base Enum
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						This is for classes that will have an Enum subclass them
 | 
				
			||||||
 | 
						"""
 | 
				
			||||||
 | 
						def __init__(self, *args, **kwargs):
 | 
				
			||||||
 | 
							if ABE in self.__class__.__bases__ or ABE == self:
 | 
				
			||||||
 | 
								msg = f"Cannot instantiate an Abstract Base Enum: {self.__class__.__name__}"
 | 
				
			||||||
 | 
								raise TypeError(msg)
 | 
				
			||||||
							
								
								
									
										49
									
								
								OpenFontFormat/name.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								OpenFontFormat/name.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,49 @@
 | 
				
			|||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from OpenFont import FontSpecificNameID, NameID, NameTable_Format_0, OpenFont, PredefinedNameID, TrueTypeOutlines, parse_file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def search_names(font: OpenFont, 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 print_font(font: OpenFont):
 | 
				
			||||||
 | 
						assert isinstance(font.naming_table, NameTable_Format_0)
 | 
				
			||||||
 | 
						assert isinstance(font.outlines, TrueTypeOutlines)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						name = search_names(font, PredefinedNameID.FULL_NAME)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						print(name, f"({font.maximum_profile.numGlyphs} glyphs, {font.naming_table.count} names)")
 | 
				
			||||||
 | 
						if font.font_variations:
 | 
				
			||||||
 | 
							axis_names = [search_names(font, FontSpecificNameID(axis.axisNameID)) for axis in font.font_variations.font_variations.axes]
 | 
				
			||||||
 | 
							num_instances = font.font_variations.font_variations.instanceCount
 | 
				
			||||||
 | 
							print(f"\tAxes: [{', '.join(axis_names)}] ({num_instances} instances)")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					path = "examples/"
 | 
				
			||||||
 | 
					# path = "examples/android_fonts/api_level/30"
 | 
				
			||||||
 | 
					# path = "examples/android_fonts/api_level/30/NotoNaskhArabic-Bold.ttf"
 | 
				
			||||||
 | 
					path = "examples/JetBrainsMono-2.304/"
 | 
				
			||||||
 | 
					if os.path.isfile(path):
 | 
				
			||||||
 | 
						try:
 | 
				
			||||||
 | 
							font = parse_file(path)
 | 
				
			||||||
 | 
						except AssertionError as err:
 | 
				
			||||||
 | 
							print("Failed:", path)
 | 
				
			||||||
 | 
							raise err
 | 
				
			||||||
 | 
						print_font(font)
 | 
				
			||||||
 | 
					else:
 | 
				
			||||||
 | 
						for root, dirs, files in os.walk(path):
 | 
				
			||||||
 | 
							for file in files:
 | 
				
			||||||
 | 
								_, ext = os.path.splitext(file)
 | 
				
			||||||
 | 
								match ext:
 | 
				
			||||||
 | 
									case '.ttf':
 | 
				
			||||||
 | 
										file_path = os.path.join(root, file)
 | 
				
			||||||
 | 
										try:
 | 
				
			||||||
 | 
											font = parse_file(file_path)
 | 
				
			||||||
 | 
										except AssertionError as err:
 | 
				
			||||||
 | 
											print("Failed:", file_path)
 | 
				
			||||||
 | 
											raise err
 | 
				
			||||||
 | 
										print_font(font)
 | 
				
			||||||
							
								
								
									
										26
									
								
								OpenFontFormat/read_utils.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								OpenFontFormat/read_utils.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					from typing import BinaryIO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def read_int(f: BinaryIO, number: int, signed:bool=False) -> int: return int.from_bytes(f.read(number), 'big', signed=signed)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def read_u64(f: BinaryIO) -> int: return read_int(f, 8)
 | 
				
			||||||
 | 
					def read_u32(f: BinaryIO) -> int: return read_int(f, 4)
 | 
				
			||||||
 | 
					def read_u24(f: BinaryIO) -> int: return read_int(f, 3)
 | 
				
			||||||
 | 
					def read_u16(f: BinaryIO) -> int: return read_int(f, 2)
 | 
				
			||||||
 | 
					def read_u8(f: BinaryIO) -> int: return read_int(f, 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def read_i32(f: BinaryIO) -> int: return read_int(f, 4, signed=True)
 | 
				
			||||||
 | 
					def read_i16(f: BinaryIO) -> int: return read_int(f, 2, signed=True)
 | 
				
			||||||
 | 
					def read_i8(f: BinaryIO) -> int: return read_int(f, 1, signed=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def read_utf8(f: BinaryIO, number: int) -> str: return f.read(number).decode(encoding='utf8')
 | 
				
			||||||
 | 
					def read_ascii(f: BinaryIO, number: int) -> str: return f.read(number).decode(encoding='ascii')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def read_fixed_point(f: BinaryIO, preradix_bits: int, postradix_bits:int, *, signed:bool=True) -> float:
 | 
				
			||||||
 | 
						assert (preradix_bits+postradix_bits)%8 == 0
 | 
				
			||||||
 | 
						raw = read_int(f, (preradix_bits+postradix_bits)//8, signed=signed)
 | 
				
			||||||
 | 
						return raw/(1<<(postradix_bits))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def read_pascal_string(f: BinaryIO) -> str:
 | 
				
			||||||
 | 
						string_size = read_int(f, 1)
 | 
				
			||||||
 | 
						pascal_string = read_ascii(f, string_size)
 | 
				
			||||||
 | 
						return pascal_string
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user