71 lines
1.8 KiB
Python
71 lines
1.8 KiB
Python
import os
|
|
|
|
import svgwrite
|
|
from svgwrite.path import Path
|
|
|
|
from local_dataclasses import Glyph, Metadata
|
|
|
|
base = 16
|
|
cap = -16
|
|
svg_size = 1024
|
|
guard = 12
|
|
|
|
|
|
def generate(glyph: Glyph, metadata: Metadata):
|
|
print(f"Generating character '{metadata.character}' for font {metadata.font_name}")
|
|
|
|
font_path = os.path.join(os.getcwd(), 'svgs', metadata.font_name)
|
|
|
|
left_side_bearing, right_side_bearing = _calculate_bearings(glyph)
|
|
svg_filename = f'ascii{str(metadata.ascii_value)}_l{left_side_bearing}_r{right_side_bearing}.svg'
|
|
|
|
dwg = svgwrite.Drawing(
|
|
os.path.join(font_path, svg_filename),
|
|
viewBox=f"0 0 {svg_size} {svg_size}"
|
|
)
|
|
|
|
points = []
|
|
|
|
for coordinate in glyph.coordinates:
|
|
if coordinate:
|
|
x, y = coordinate
|
|
x = _map_to_svg(x)
|
|
y = _map_to_svg(y)
|
|
points.append((x, y))
|
|
else:
|
|
if points:
|
|
_add_path(dwg, points)
|
|
points = []
|
|
|
|
if points:
|
|
_add_path(dwg, points)
|
|
|
|
dwg.save()
|
|
|
|
|
|
def _add_path(dwg, points):
|
|
if not points:
|
|
return
|
|
|
|
p = Path()
|
|
p.push(f"M {points[0][0]} {points[0][1]}")
|
|
for x, y in points[1:]:
|
|
p.push(f"L {x} {y}")
|
|
dwg.add(p)
|
|
|
|
|
|
def _calculate_bearings(glyph: Glyph):
|
|
if glyph.coordinates:
|
|
leftmost_point = _map_to_svg(min(coordinate[0] for coordinate in glyph.coordinates if coordinate))
|
|
rightmost_point = _map_to_svg(max(coordinate[0] for coordinate in glyph.coordinates if coordinate))
|
|
else:
|
|
leftmost_point = rightmost_point = _map_to_svg(0)
|
|
|
|
left_side_bearing = leftmost_point - _map_to_svg(glyph.left)
|
|
right_side_bearing = _map_to_svg(glyph.right) - rightmost_point
|
|
return left_side_bearing, right_side_bearing
|
|
|
|
|
|
def _map_to_svg(x):
|
|
return x * (svg_size - 2 * guard) / (base - cap) + svg_size / 2
|