Skip to content

Instantly share code, notes, and snippets.

@vovkasm
Created January 29, 2025 12:48
Show Gist options
  • Save vovkasm/508ecabb0459061564c263c97a90e7d8 to your computer and use it in GitHub Desktop.
Save vovkasm/508ecabb0459061564c263c97a90e7d8 to your computer and use it in GitHub Desktop.
Using fontforge to generate iconic font
# This is most important parts, not full script
import fontforge
import os
from dataclasses import dataclass
@dataclass
class CharDef:
# icon name
name: str
# path to svg relative to base_dir
path: str | None = None
# unicode code point
code: int = 0
# ...
base_dir = "" # base directory
font_path = os.path.join(base_dir, font_dir, options['font_name'] + '.ttf')
# font_em - size of em in points (we have 1024)
# font_design_size - size of svgs (for ex 24)
design_px = options['font_em'] / options['font_design_size']
font = fontforge.font()
font.encoding = 'UnicodeFull'
# design size in pica points
font.design_size = options['font_design_size']
font.em = options['font_em']
font.ascent = options['font_ascent'] # for icons = 1024
font.descent = options['font_descent'] # for icons = 0
font.fontname = options['font_name']
font.familyname = options['font_name']
font.fullname = options['font_name']
font.copyright = options['copyright']
# Add valid space glyph to avoid "unknown character" box on IE11
glyph = font.createChar(32)
glyph.width = 200
def createGlyph(name, char_def):
code = char_def.code
source = char_def.path
full_source_path = os.path.join(base_dir, source)
frag, ext = os.path.splitext(full_source_path)
if ext == '.svg':
glyph = font.createChar(code, name)
glyph.importOutlines(full_source_path)
glyph.width = options['font_em']
width = glyph.width - glyph.left_side_bearing - glyph.right_side_bearing
aligned_to_pixel_grid = (width % design_px == 0)
if (aligned_to_pixel_grid):
shift = glyph.left_side_bearing % design_px
glyph.left_side_bearing = glyph.left_side_bearing - shift
glyph.right_side_bearing = glyph.right_side_bearing + shift
# all_our_chars is a list of CharDef objects
for name in all_our_chars:
createGlyph(name, chars[name])
# font_path - path to ttf file
font.generate(font_path)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment