Skip to content

Commit

Permalink
src/utils.py:subset_fonts(): fix use of hard-coded files within /tmp.
Browse files Browse the repository at this point in the history
This can cause problems with concurrent use of PyMuPDF.

We now use tempfile.TemporaryDirectory().
  • Loading branch information
julian-smith-artifex-com committed Jun 4, 2024
1 parent d5fe5bd commit 66b9c65
Showing 1 changed file with 45 additions and 60 deletions.
105 changes: 45 additions & 60 deletions src/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5467,67 +5467,52 @@ def build_subset(buffer, unc_set, gid_set):
pymupdf.message("This method requires fontTools to be installed.")
raise
import tempfile
tmp_dir = tempfile.gettempdir()
oldfont_path = f"{tmp_dir}/oldfont.ttf"
newfont_path = f"{tmp_dir}/newfont.ttf"
uncfile_path = f"{tmp_dir}/uncfile.txt"
args = [
oldfont_path,
"--retain-gids",
f"--output-file={newfont_path}",
"--layout-features='*'",
"--passthrough-tables",
"--ignore-missing-glyphs",
"--ignore-missing-unicodes",
"--symbol-cmap",
]

# store glyph ids or unicodes as file
with open(f"{tmp_dir}/uncfile.txt", "w", encoding='utf8') as unc_file:
if 0xFFFD in unc_set: # error unicode exists -> use glyphs
args.append(f"--gids-file={uncfile_path}")
gid_set.add(189)
unc_list = list(gid_set)
for unc in unc_list:
unc_file.write("%i\n" % unc)
else:
args.append(f"--unicodes-file={uncfile_path}")
unc_set.add(255)
unc_list = list(unc_set)
for unc in unc_list:
unc_file.write("%04x\n" % unc)

# store fontbuffer as a file
with open(oldfont_path, "wb") as fontfile:
fontfile.write(buffer)
try:
os.remove(newfont_path) # remove old file
except Exception:
pass
try: # invoke fontTools subsetter
fts.main(args)
font = pymupdf.Font(fontfile=newfont_path)
new_buffer = font.buffer # subset font binary
if font.glyph_count == 0: # intercept empty font
with tempfile.TemporaryDirectory() as tmp_dir:
oldfont_path = f"{tmp_dir}/oldfont.ttf"
newfont_path = f"{tmp_dir}/newfont.ttf"
uncfile_path = f"{tmp_dir}/uncfile.txt"
args = [
oldfont_path,
"--retain-gids",
f"--output-file={newfont_path}",
"--layout-features='*'",
"--passthrough-tables",
"--ignore-missing-glyphs",
"--ignore-missing-unicodes",
"--symbol-cmap",
]

# store glyph ids or unicodes as file
with open(f"{tmp_dir}/uncfile.txt", "w", encoding='utf8') as unc_file:
if 0xFFFD in unc_set: # error unicode exists -> use glyphs
args.append(f"--gids-file={uncfile_path}")
gid_set.add(189)
unc_list = list(gid_set)
for unc in unc_list:
unc_file.write("%i\n" % unc)
else:
args.append(f"--unicodes-file={uncfile_path}")
unc_set.add(255)
unc_list = list(unc_set)
for unc in unc_list:
unc_file.write("%04x\n" % unc)

# store fontbuffer as a file
with open(oldfont_path, "wb") as fontfile:
fontfile.write(buffer)
try:
os.remove(newfont_path) # remove old file
except Exception:
pass
try: # invoke fontTools subsetter
fts.main(args)
font = pymupdf.Font(fontfile=newfont_path)
new_buffer = font.buffer # subset font binary
if font.glyph_count == 0: # intercept empty font
new_buffer = None
except Exception:
pymupdf.exception_info()
new_buffer = None
except Exception:
pymupdf.exception_info()
new_buffer = None
try:
os.remove(uncfile_path)
except Exception:
pymupdf.exception_info()
pass
try:
os.remove(oldfont_path)
except Exception:
pymupdf.exception_info()
pass
try:
os.remove(newfont_path)
except Exception:
pymupdf.exception_info()
pass
return new_buffer

def repl_fontnames(doc):
Expand Down

0 comments on commit 66b9c65

Please sign in to comment.