TTF build using fontforge

This commit is contained in:
minjaesong
2026-02-23 18:32:03 +09:00
parent 208466bbb2
commit 5e2cacd491
20 changed files with 2213 additions and 1486 deletions

91
OTFbuild/bitmap_tracer.py Normal file
View File

@@ -0,0 +1,91 @@
"""
Convert 1-bit bitmap arrays to TrueType quadratic outlines.
Each set pixel becomes part of a rectangle contour drawn clockwise.
Adjacent identical horizontal runs are merged vertically into rectangles.
Scale: x_left = col * SCALE, y_top = (BASELINE_ROW - row) * SCALE
where BASELINE_ROW = 16 (ascent in pixels).
"""
from typing import Dict, List, Tuple
import sheet_config as SC
SCALE = SC.SCALE
BASELINE_ROW = 16 # pixels from top to baseline
def trace_bitmap(bitmap, glyph_width_px):
"""
Convert a bitmap to a list of rectangle contours.
Each rectangle is ((x0, y0), (x1, y1)) in font units, where:
- (x0, y0) is bottom-left
- (x1, y1) is top-right
Returns list of (x0, y0, x1, y1) tuples representing rectangles.
"""
if not bitmap or not bitmap[0]:
return []
h = len(bitmap)
w = len(bitmap[0])
# Step 1: Find horizontal runs per row
runs = [] # list of (row, col_start, col_end)
for row in range(h):
col = 0
while col < w:
if bitmap[row][col]:
start = col
while col < w and bitmap[row][col]:
col += 1
runs.append((row, start, col))
else:
col += 1
# Step 2: Merge vertically adjacent identical runs into rectangles
rects = [] # (row_start, row_end, col_start, col_end)
used = [False] * len(runs)
for i, (row, cs, ce) in enumerate(runs):
if used[i]:
continue
# Try to extend this run downward
row_end = row + 1
j = i + 1
while j < len(runs):
r2, cs2, ce2 = runs[j]
if r2 > row_end:
break
if r2 == row_end and cs2 == cs and ce2 == ce and not used[j]:
used[j] = True
row_end = r2 + 1
j += 1
rects.append((row, row_end, cs, ce))
# Step 3: Convert to font coordinates
contours = []
for row_start, row_end, col_start, col_end in rects:
x0 = col_start * SCALE
x1 = col_end * SCALE
y_top = (BASELINE_ROW - row_start) * SCALE
y_bottom = (BASELINE_ROW - row_end) * SCALE
contours.append((x0, y_bottom, x1, y_top))
return contours
def draw_glyph_to_pen(contours, pen):
"""
Draw rectangle contours to a TTGlyphPen or similar pen.
Each rectangle is drawn as a clockwise closed contour (4 on-curve points).
"""
for x0, y0, x1, y1 in contours:
# Clockwise: bottom-left -> top-left -> top-right -> bottom-right
pen.moveTo((x0, y0))
pen.lineTo((x0, y1))
pen.lineTo((x1, y1))
pen.lineTo((x1, y0))
pen.closePath()