code wiki / _hdl_build / nx_font_outline.nx

nx_font_outline.nx source

↩ module page · 98 lines · 5259 B

1// nx_font_outline.nx -- R1 of the sovereign-font ladder: the glyph OUTLINE MODEL in the exact TrueType glyf 2// layout (contour endPts[] + on-curve points px[]/py[] in FUnits, 1000-EM, y-up), authored as clean geometric 3// letters designed IN-HOUSE (sovereign, no glyph copied). This is the data R2 (nx_font_ttf_emit) serializes into 4// a real .ttf. A gate validates every glyph is glyf-ready (endPts monotonic, each contour >=3 pts, points in 5// int16 range, bbox sane) with a negative control. Glyphs: .notdef, space, H, I, T (renders "HI"/"HIT"/"THI"). 6// license_tier: ORIGINAL expect_exit: 0 7import "nx_syscalls.nx" 8const K_MAGIC_99999: i64 = 99999 9const K_MAGIC_16000: i64 = 16000 10 11func sw(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 12func sn(v: i64) -> i64 { let bb: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m;sys_write(1,"-" as *u8,1)} let t: *u8=sys_mmap(28); var k: i64=0; if m==0{t[0]=48 as u8;k=1} while m>0{t[k]=(48+(m%10)) as u8;m=m/10;k=k+1} var i: i64=0; while i<k{bb[i]=t[k-1-i];i=i+1} sys_write(1,bb,k); return 0 } 13 14// each fill_* writes contour endpoints ep[], points px[]/py[], and meta[0]=numContours meta[1]=numPoints. 15func fill_notdef(ep: *i64, px: *i64, py: *i64, meta: *i64) -> i64 { 16 px[0]=80; py[0]=0; px[1]=520; py[1]=0; px[2]=520; py[2]=700; px[3]=80; py[3]=700 17 ep[0]=3; meta[0]=1; meta[1]=4; return 0 18} 19func fill_space(ep: *i64, px: *i64, py: *i64, meta: *i64) -> i64 { meta[0]=0; meta[1]=0; return 0 } 20func fill_H(ep: *i64, px: *i64, py: *i64, meta: *i64) -> i64 { 21 px[0]=130; py[0]=0; px[1]=290; py[1]=0; px[2]=290; py[2]=700; px[3]=130; py[3]=700 // left bar 22 px[4]=440; py[4]=0; px[5]=600; py[5]=0; px[6]=600; py[6]=700; px[7]=440; py[7]=700 // right bar 23 px[8]=290; py[8]=290; px[9]=440; py[9]=290; px[10]=440;py[10]=410;px[11]=290;py[11]=410 // mid bar 24 ep[0]=3; ep[1]=7; ep[2]=11; meta[0]=3; meta[1]=12; return 0 25} 26func fill_I(ep: *i64, px: *i64, py: *i64, meta: *i64) -> i64 { 27 px[0]=250; py[0]=0; px[1]=400; py[1]=0; px[2]=400; py[2]=700; px[3]=250; py[3]=700 28 ep[0]=3; meta[0]=1; meta[1]=4; return 0 29} 30func fill_T(ep: *i64, px: *i64, py: *i64, meta: *i64) -> i64 { 31 px[0]=60; py[0]=560; px[1]=660; py[1]=560; px[2]=660; py[2]=700; px[3]=60; py[3]=700 // top bar 32 px[4]=290; py[4]=0; px[5]=430; py[5]=0; px[6]=430; py[6]=560; px[7]=290; py[7]=560 // stem 33 ep[0]=3; ep[1]=7; meta[0]=2; meta[1]=8; return 0 34} 35 36// validate one glyph is glyf-ready. returns 1 ok / 0 bad. prints a line. 37func validate(name: *u8, ep: *i64, px: *i64, py: *i64, meta: *i64) -> i64 { 38 let nc: i64 = meta[0] 39 let np: i64 = meta[1] 40 sw(" " as *u8); sw(name); sw(": contours=" as *u8); sn(nc); sw(" points=" as *u8); sn(np) 41 if nc==0 { 42 if np==0 { sw(" (empty glyph, advance-only) OK\n" as *u8); return 1 } 43 sw(" BAD (0 contours but points)\n" as *u8); return 0 44 } 45 var ok: i64 = 1 46 if ep[nc-1]+1 != np { ok=0 } 47 var prev: i64 = 0-1 48 var i: i64 = 0 49 while i<nc { 50 let cend: i64 = ep[i] 51 if cend <= prev { ok=0 } 52 if cend - prev < 3 { ok=0 } 53 prev = cend 54 i=i+1 55 } 56 var minx: i64=K_MAGIC_99999; var maxx: i64=0-K_MAGIC_99999; var miny: i64=K_MAGIC_99999; var maxy: i64=0-K_MAGIC_99999 57 i=0 58 while i<np { 59 if px[i]<minx { minx=px[i] } 60 if px[i]>maxx { maxx=px[i] } 61 if py[i]<miny { miny=py[i] } 62 if py[i]>maxy { maxy=py[i] } 63 if px[i]<0-K_MAGIC_16000 { ok=0 } 64 if px[i]>K_MAGIC_16000 { ok=0 } 65 i=i+1 66 } 67 sw(" bbox[" as *u8); sn(minx); sw("," as *u8); sn(miny); sw(" " as *u8); sn(maxx); sw("," as *u8); sn(maxy); sw("]" as *u8) 68 if ok==1 { sw(" glyf-ready OK\n" as *u8); return 1 } 69 sw(" BAD\n" as *u8); return 0 70} 71 72func main() -> i64 { 73 let ep: *i64 = sys_mmap(64) as *i64 74 let px: *i64 = sys_mmap(512) as *i64 75 let py: *i64 = sys_mmap(512) as *i64 76 let meta: *i64 = sys_mmap(16) as *i64 77 var pass: i64 = 0 78 var total: i64 = 0 79 80 sw("=== nx_font_outline R1 -- sovereign glyph OUTLINE model (glyf-ready, 1000-EM, in-house designs) ===\n" as *u8) 81 fill_notdef(ep,px,py,meta); pass = pass + validate(".notdef" as *u8, ep,px,py,meta); total=total+1 82 fill_space(ep,px,py,meta); pass = pass + validate("space " as *u8, ep,px,py,meta); total=total+1 83 fill_H(ep,px,py,meta); pass = pass + validate("H " as *u8, ep,px,py,meta); total=total+1 84 fill_I(ep,px,py,meta); pass = pass + validate("I " as *u8, ep,px,py,meta); total=total+1 85 fill_T(ep,px,py,meta); pass = pass + validate("T " as *u8, ep,px,py,meta); total=total+1 86 87 // NEG-CONTROL: a malformed glyph (a contour with only 2 points) MUST be caught 88 px[0]=0;py[0]=0; px[1]=100;py[1]=0 89 ep[0]=1; meta[0]=1; meta[1]=2 90 let neg: i64 = validate("NEG-bad" as *u8, ep,px,py,meta) 91 92 sw("--- " as *u8); sn(pass); sw(" / " as *u8); sn(total); sw(" glyphs glyf-ready; neg-control caught=" as *u8) 93 if neg==0 { sw("YES\n" as *u8) } else { sw("NO\n" as *u8) } 94 if pass==total { if neg==0 { sw("VERDICT: GREEN (glyph outline model is glyf-ready; feeds R2 TTF emitter)\n" as *u8); sys_exit(0) } } 95 sw("VERDICT: RED\n" as *u8) 96 sys_exit(1) 97 return 1 98}