Created
November 7, 2025 23:24
-
-
Save DallenB4/6a602040791ade1b84953b4b666f2ce7 to your computer and use it in GitHub Desktop.
Patch U+F8FF of a TrueType font with an SVG. Make sure your entire SVG is made of paths.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| from fontTools.ttLib import TTFont | |
| from fontTools.pens.ttGlyphPen import TTGlyphPen | |
| from fontTools.pens.cu2quPen import Cu2QuPen | |
| from fontTools.pens.transformPen import TransformPen | |
| from fontTools.pens.boundsPen import BoundsPen | |
| from fontTools.misc.transform import Transform | |
| from fontTools.svgLib import SVGPath | |
| def patch_svg_into_font(svg_path, input_ttf, output_ttf, max_err=0.02): | |
| glyph_name = "uniF8FF" | |
| font = TTFont(input_ttf) | |
| # Font metrics | |
| upem = font["head"].unitsPerEm | |
| ascent = font["hhea"].ascent | |
| descent = font["hhea"].descent | |
| vbox_height = ascent - descent | |
| # Determine glyph advance width | |
| hmtx = font["hmtx"].metrics | |
| if glyph_name in hmtx: | |
| advanceWidth, _ = hmtx[glyph_name] | |
| else: | |
| first = font.getGlyphOrder()[0] | |
| advanceWidth = hmtx.get(first, (upem, 0))[0] | |
| tt_pen = TTGlyphPen(None) | |
| cu2qu = Cu2QuPen(tt_pen, max_err) | |
| svg = SVGPath(svg_path) | |
| svg.draw(cu2qu) | |
| glyph_raw = tt_pen.glyph() | |
| bpen = BoundsPen(None) | |
| glyph_raw.draw(bpen, None) | |
| xMin, yMin, xMax, yMax = bpen.bounds | |
| raw_w = xMax - xMin | |
| raw_h = yMax - yMin | |
| sx = advanceWidth / raw_w | |
| sy = vbox_height / raw_h | |
| scale = min(sx, sy) | |
| target_cx = advanceWidth / 2 | |
| target_cy = (ascent + descent) / 2 | |
| glyph_cx = (xMin + xMax) / 2 | |
| glyph_cy = (yMin + yMax) / 2 | |
| dx = target_cx - scale * glyph_cx | |
| dy = target_cy + scale * glyph_cy | |
| tt_pen2 = TTGlyphPen(None) | |
| cu2qu2 = Cu2QuPen(tt_pen2, max_err) | |
| transform = Transform(scale, 0, 0, -scale, dx, dy) | |
| tpen = TransformPen(cu2qu2, transform) | |
| svg = SVGPath(svg_path) | |
| svg.draw(tpen) | |
| glyph = tt_pen2.glyph() | |
| order = font.getGlyphOrder() | |
| if glyph_name not in order: | |
| order = order + [glyph_name] | |
| font.setGlyphOrder(order) | |
| font["glyf"][glyph_name] = glyph | |
| lsb = int(round((advanceWidth - raw_w * scale) / 2)) | |
| font["hmtx"].metrics[glyph_name] = (int(round(advanceWidth)), lsb) | |
| font.save(output_ttf) | |
| print(f"Saved {output_ttf}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment