Skip to content

Commit

Permalink
font-patcher: Enable lowestRecPPEM fix in TTCs
Browse files Browse the repository at this point in the history
[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
  40138be  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 <[email protected]>
  • Loading branch information
Finii committed Sep 23, 2022
1 parent e8a17c7 commit 7c5c838
Showing 1 changed file with 37 additions and 15 deletions.
52 changes: 37 additions & 15 deletions font-patcher
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,26 @@ class TableHEADWriter:
checksum = (checksum + extra) & 0xFFFFFFFF
return checksum

def find_head_table(self):
def find_head_table(self, idx):
""" 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()
self.f.seek(3*2, 1)

Expand All @@ -102,7 +119,7 @@ class TableHEADWriter:
self.tab_length = self.getlong()
if tab_name == b'head':
return
raise Exception('No HEAD table found')
raise Exception('No HEAD table found in font idx {}'.format(idx))

def goto(self, where):
""" Go to a named location in the file or to the specified index """
Expand Down Expand Up @@ -146,7 +163,7 @@ class TableHEADWriter:
self.modified = False
self.f = open(filename, 'r+b')

self.find_head_table()
self.find_head_table(0)

self.flags = self.getshort('flags')
self.lowppem = self.getshort('lowestRecPPEM')
Expand Down Expand Up @@ -266,15 +283,19 @@ class font_patcher:
try:
source_font = TableHEADWriter(self.args.font)
dest_font = TableHEADWriter(outfile)
if source_font.flags & 0x08 == 0 and dest_font.flags & 0x08 != 0:
print("Changing flags from 0x{:X} to 0x{:X}".format(dest_font.flags, dest_font.flags & ~0x08))
dest_font.putshort(dest_font.flags & ~0x08, 'flags') # clear 'ppem_to_int'
if source_font.lowppem != dest_font.lowppem:
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()
for idx in range(source_font.num_fonts):
print("{}: Tweaking {}/{}".format(projectName, idx + 1, source_font.num_fonts))
source_font.find_head_table(idx)
dest_font.find_head_table(idx)
if source_font.flags & 0x08 == 0 and dest_font.flags & 0x08 != 0:
print("Changing flags from 0x{:X} to 0x{:X}".format(dest_font.flags, dest_font.flags & ~0x08))
dest_font.putshort(dest_font.flags & ~0x08, 'flags') # clear 'ppem_to_int'
if source_font.lowppem != dest_font.lowppem:
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:
print("Can not handle font flags ({})".format(repr(error)))
finally:
Expand Down Expand Up @@ -1292,8 +1313,9 @@ def main():
patcher = font_patcher(args)

sourceFonts = []
for subfont in fontforge.fontsInFile(args.font):
print("\n{}: Processing {}".format(projectName, subfont))
all_fonts = fontforge.fontsInFile(args.font)
for i, subfont in enumerate(all_fonts):
print("\n{}: Processing {} ({}/{})".format(projectName, subfont, i + 1, len(all_fonts)))
try:
sourceFonts.append(fontforge.open("{}({})".format(args.font, subfont), 1)) # 1 = ("fstypepermitted",))
except Exception:
Expand Down

0 comments on commit 7c5c838

Please sign in to comment.