I found a few correctness issues in the font-generation pipeline. They look distinct from #92 (alpha threshold) and #83/#82 (FontForge missing).
1. --family does not set the font’s internal family name
In handwrite/svgtottf.py set_properties() (around lines 47–55):
family = self.metadata.get("family", None) or fontname
self.font.familyname = fontname # uses --filename, not --family
--family is written into SFNT names when sfnt_names exists (lines 64–67), but self.font.familyname always uses fontname (--filename / config). Installed fonts then show the wrong family in font pickers.
Fix: self.font.familyname = family, and keep fontname / fullname consistent with the SFNT names.
2. FontForge and potrace failures are ignored
svgtottf.py lines 28–41: subprocess.run(...) with no check=True and no return-code check. If ffpython/fontforge fails, the CLI can still exit 0 with no .ttf.
pngtosvg.py line 48: same for potrace.
Fix: subprocess.run(..., check=True, capture_output=True) and surface stderr. You already raise PotraceNotFound when the binary is missing; a failed conversion should be just as visible.
3. Missing sfnt_names in a custom config → KeyError
Lines 64–68 guard updates to sfnt_names, but line 70 always does:
self.config["sfnt_names"]["UniqueID"] = ...
A minimal config without sfnt_names crashes.
Fix: self.config.setdefault("sfnt_names", {}) before writing UniqueID.
4. Temp directory leaked on failure
handwrite/cli.py converters() (lines 17–37) creates tempfile.mkdtemp() when --directory is omitted, and only rmtrees it if run() succeeds. Any exception in SHEETtoPNG / PNGtoSVG / SVGtoTTF leaves the temp dir behind.
Fix: try/finally around run().
Also, output_directory is never makedirs’d; a missing output path fails late inside FontForge.
Happy to open a PR if you want.
I found a few correctness issues in the font-generation pipeline. They look distinct from #92 (alpha threshold) and #83/#82 (FontForge missing).
1.
--familydoes not set the font’s internal family nameIn
handwrite/svgtottf.pyset_properties()(around lines 47–55):--familyis written into SFNT names whensfnt_namesexists (lines 64–67), butself.font.familynamealways usesfontname(--filename/ config). Installed fonts then show the wrong family in font pickers.Fix:
self.font.familyname = family, and keepfontname/fullnameconsistent with the SFNT names.2. FontForge and potrace failures are ignored
svgtottf.pylines 28–41:subprocess.run(...)with nocheck=Trueand no return-code check. Ifffpython/fontforgefails, the CLI can still exit 0 with no.ttf.pngtosvg.pyline 48: same forpotrace.Fix:
subprocess.run(..., check=True, capture_output=True)and surface stderr. You already raisePotraceNotFoundwhen the binary is missing; a failed conversion should be just as visible.3. Missing
sfnt_namesin a custom config →KeyErrorLines 64–68 guard updates to
sfnt_names, but line 70 always does:A minimal config without
sfnt_namescrashes.Fix:
self.config.setdefault("sfnt_names", {})before writingUniqueID.4. Temp directory leaked on failure
handwrite/cli.pyconverters()(lines 17–37) createstempfile.mkdtemp()when--directoryis omitted, and onlyrmtrees it ifrun()succeeds. Any exception in SHEETtoPNG / PNGtoSVG / SVGtoTTF leaves the temp dir behind.Fix:
try/finallyaroundrun().Also,
output_directoryis nevermakedirs’d; a missing output path fails late inside FontForge.Happy to open a PR if you want.