mirror of
https://github.com/ryanoasis/nerd-fonts.git
synced 2024-09-19 09:51:48 +02:00
font-patcher: Enable lowestRecPPEM fix in TTCs
[why]
The font flags and PPEM fix does not work with font collection files,
because it does not know how to handle them. It assumes a ttf or otf
font with the specified table structure.
The fix (for single font files) has been introduced with commit
40138bee9
font-patcher: Handle lowestRecPPEM
[how]
Check if the file is of type 'ttcf', and if so fast forward to the given
single font index into the collection.
This can be rather slow...
Signed-off-by: Fini Jastrow <ulf.fini.jastrow@desy.de>
This commit is contained in:
parent
e8a17c71bf
commit
7c5c838122
1 changed files with 37 additions and 15 deletions
52
font-patcher
52
font-patcher
|
@ -88,9 +88,26 @@ class TableHEADWriter:
|
||||||
checksum = (checksum + extra) & 0xFFFFFFFF
|
checksum = (checksum + extra) & 0xFFFFFFFF
|
||||||
return checksum
|
return checksum
|
||||||
|
|
||||||
def find_head_table(self):
|
def find_head_table(self, idx):
|
||||||
""" Search all tables for the HEAD table and store its metadata """
|
""" Search all tables for the HEAD table and store its metadata """
|
||||||
self.f.seek(4)
|
# Use font with index idx if this is a font collection file
|
||||||
|
self.f.seek(0, 0)
|
||||||
|
tag = self.f.read(4)
|
||||||
|
if tag == b'ttcf':
|
||||||
|
self.f.seek(2*2, 1)
|
||||||
|
self.num_fonts = self.getlong()
|
||||||
|
if (idx >= self.num_fonts):
|
||||||
|
raise Exception('Trying to access subfont index {} but have only {} fonts'.format(idx, num_fonts))
|
||||||
|
for _ in range(idx + 1):
|
||||||
|
offset = self.getlong()
|
||||||
|
self.f.seek(offset, 0)
|
||||||
|
elif idx != 0:
|
||||||
|
raise Exception('Trying to access subfont but file is no collection')
|
||||||
|
else:
|
||||||
|
self.f.seek(0, 0)
|
||||||
|
self.num_fonts = 1
|
||||||
|
|
||||||
|
self.f.seek(4, 1)
|
||||||
numtables = self.getshort()
|
numtables = self.getshort()
|
||||||
self.f.seek(3*2, 1)
|
self.f.seek(3*2, 1)
|
||||||
|
|
||||||
|
@ -102,7 +119,7 @@ class TableHEADWriter:
|
||||||
self.tab_length = self.getlong()
|
self.tab_length = self.getlong()
|
||||||
if tab_name == b'head':
|
if tab_name == b'head':
|
||||||
return
|
return
|
||||||
raise Exception('No HEAD table found')
|
raise Exception('No HEAD table found in font idx {}'.format(idx))
|
||||||
|
|
||||||
def goto(self, where):
|
def goto(self, where):
|
||||||
""" Go to a named location in the file or to the specified index """
|
""" Go to a named location in the file or to the specified index """
|
||||||
|
@ -146,7 +163,7 @@ class TableHEADWriter:
|
||||||
self.modified = False
|
self.modified = False
|
||||||
self.f = open(filename, 'r+b')
|
self.f = open(filename, 'r+b')
|
||||||
|
|
||||||
self.find_head_table()
|
self.find_head_table(0)
|
||||||
|
|
||||||
self.flags = self.getshort('flags')
|
self.flags = self.getshort('flags')
|
||||||
self.lowppem = self.getshort('lowestRecPPEM')
|
self.lowppem = self.getshort('lowestRecPPEM')
|
||||||
|
@ -266,15 +283,19 @@ class font_patcher:
|
||||||
try:
|
try:
|
||||||
source_font = TableHEADWriter(self.args.font)
|
source_font = TableHEADWriter(self.args.font)
|
||||||
dest_font = TableHEADWriter(outfile)
|
dest_font = TableHEADWriter(outfile)
|
||||||
if source_font.flags & 0x08 == 0 and dest_font.flags & 0x08 != 0:
|
for idx in range(source_font.num_fonts):
|
||||||
print("Changing flags from 0x{:X} to 0x{:X}".format(dest_font.flags, dest_font.flags & ~0x08))
|
print("{}: Tweaking {}/{}".format(projectName, idx + 1, source_font.num_fonts))
|
||||||
dest_font.putshort(dest_font.flags & ~0x08, 'flags') # clear 'ppem_to_int'
|
source_font.find_head_table(idx)
|
||||||
if source_font.lowppem != dest_font.lowppem:
|
dest_font.find_head_table(idx)
|
||||||
print("Changing lowestRecPPEM from {} to {}".format(dest_font.lowppem, source_font.lowppem))
|
if source_font.flags & 0x08 == 0 and dest_font.flags & 0x08 != 0:
|
||||||
dest_font.putshort(source_font.lowppem, 'lowestRecPPEM')
|
print("Changing flags from 0x{:X} to 0x{:X}".format(dest_font.flags, dest_font.flags & ~0x08))
|
||||||
if dest_font.modified:
|
dest_font.putshort(dest_font.flags & ~0x08, 'flags') # clear 'ppem_to_int'
|
||||||
dest_font.reset_table_checksum()
|
if source_font.lowppem != dest_font.lowppem:
|
||||||
dest_font.reset_full_checksum()
|
print("Changing lowestRecPPEM from {} to {}".format(dest_font.lowppem, source_font.lowppem))
|
||||||
|
dest_font.putshort(source_font.lowppem, 'lowestRecPPEM')
|
||||||
|
if dest_font.modified:
|
||||||
|
dest_font.reset_table_checksum()
|
||||||
|
dest_font.reset_full_checksum()
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
print("Can not handle font flags ({})".format(repr(error)))
|
print("Can not handle font flags ({})".format(repr(error)))
|
||||||
finally:
|
finally:
|
||||||
|
@ -1292,8 +1313,9 @@ def main():
|
||||||
patcher = font_patcher(args)
|
patcher = font_patcher(args)
|
||||||
|
|
||||||
sourceFonts = []
|
sourceFonts = []
|
||||||
for subfont in fontforge.fontsInFile(args.font):
|
all_fonts = fontforge.fontsInFile(args.font)
|
||||||
print("\n{}: Processing {}".format(projectName, subfont))
|
for i, subfont in enumerate(all_fonts):
|
||||||
|
print("\n{}: Processing {} ({}/{})".format(projectName, subfont, i + 1, len(all_fonts)))
|
||||||
try:
|
try:
|
||||||
sourceFonts.append(fontforge.open("{}({})".format(args.font, subfont), 1)) # 1 = ("fstypepermitted",))
|
sourceFonts.append(fontforge.open("{}({})".format(args.font, subfont), 1)) # 1 = ("fstypepermitted",))
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
Loading…
Reference in a new issue