font.ttf 3.000: all five cabinet atlases (adds Simplified Chinese and Korean) #32

Merged
Yonokid merged 6 commits from GanYiZhong/YataiDONNijiiro:font-all-atlases into main 2026-09-15 17:46:19 +02:00
4 changed files with 10 additions and 5 deletions
Showing only changes of commit 7ba7e142ae - Show all commits

No files matched your search

Binary file not shown.
Binary file not shown.
Binary file not shown.
+10 -5
View File
@@ -44,7 +44,7 @@ def _trace(job):
return cp, int(round(w * scale)), None # blank: advance only
big = np.array(Image.fromarray(a).resize((w * UPSCALE, h * UPSCALE), Image.BICUBIC)) < 128 # potracer: True = white
path = potrace.Bitmap(big).trace(turdsize=4,
alphamax=1.0, opticurve=True, opttolerance=0.5)
alphamax=1.0, opticurve=True, opttolerance=0.2)
k = scale / UPSCALE
def P(p): return (p.x * k, (baseline_px * UPSCALE - p.y) * k)
contours = []
@@ -62,13 +62,18 @@ def main():
ap = argparse.ArgumentParser()
ap.add_argument('atlas_dir'); ap.add_argument('out')
ap.add_argument('--order', default='jp,tw,cn,kr,en')
ap.add_argument('--han-order', default='', help='separate priority for CJK ideographs (U+2E80-9FFF, F900-FAFF, 20000+); --order then applies to everything else')
ap.add_argument('--jobs', type=int, default=max(1, os.cpu_count() - 4))
ap.add_argument('--limit', type=int, default=0, help='debug: glyphs per atlas')
args = ap.parse_args()
langs = args.order.split(',')
han_langs = args.han_order.split(',') if args.han_order else langs
def is_han(cp): return 0x2E80 <= cp <= 0x9FFF or 0xF900 <= cp <= 0xFAFF or cp >= 0x20000
def rank(lang, cp): return (han_langs if is_han(cp) else langs).index(lang) if lang in (han_langs if is_han(cp) else langs) else 99
taken = {} # cp -> (advance, contours or None, lang)
for lang in langs:
all_langs = list(dict.fromkeys(langs + han_langs))
for lang in all_langs:
t0 = time.time()
glyphs, attr = parse_xml(os.path.join(args.atlas_dir, f'{lang}_64.xml'))
im = Image.open(os.path.join(args.atlas_dir, f'{lang}_64.dds'))
@@ -89,7 +94,7 @@ def main():
alpha_path = os.path.join(args.atlas_dir, f'_{lang}_alpha.npy')
np.save(alpha_path, A)
jobs = [(cp, u, v, w, h, scale, baseline_px) for cp, (u, v, w, h) in sorted(glyphs.items())
if cp not in taken or taken[cp][1] is None and cp not in (0x20, 0x3000, 0xA0)]
if (cp not in taken or taken[cp][1] is None and cp not in (0x20, 0x3000, 0xA0) or rank(lang, cp) < rank(taken[cp][2], cp))]
if args.limit: jobs = jobs[:args.limit]
got = 0
with Pool(args.jobs, initializer=_init, initargs=(alpha_path,)) as pool:
@@ -98,7 +103,7 @@ def main():
if cp in (0x20, 0x3000, 0xA0) and cp not in taken:
taken[cp] = (adv, None, lang)
continue
if cp in taken and taken[cp][1] is not None: continue
if cp in taken and taken[cp][1] is not None and rank(lang, cp) >= rank(taken[cp][2], cp): continue
taken[cp] = (adv, contours, lang); got += 1
os.remove(alpha_path)
print(f'{lang}_64: fontPoint {attr["fontPoint"]} scale {scale:.2f} baseline {baseline_px:.1f}px '
@@ -117,7 +122,7 @@ def main():
adv, contours, _ = taken[cp]
pen = TTGlyphPen(None)
if contours:
qpen = Cu2QuPen(pen, max_err=2.0, reverse_direction=False)
qpen = Cu2QuPen(pen, max_err=1.0, reverse_direction=False)
for segs in contours:
for s in segs:
if s[0] == 'M': qpen.moveTo(s[1])