code wiki / _hdl_build / nx_vecfont_body_bench.nx

nx_vecfont_body_bench.nx source

↩ module page · 114 lines · 8212 B

1// nx_vecfont_body_bench.nx -- decide the FONT arc with a measurement, not a guess. Renders the SAME 2// lowercase phrase through the sovereign stroke-VECTOR font (nx_font -> aa_raster) at HEADLINE size and 3// at BODY size, so we can see where the vector font wins (big = smooth curves shine) vs where it may lose 4// (small = no hinting, could blur below the crisp AA bitmap). Outputs two PNGs to eyeball + OCR + AA-measure. 5// This grounds "wire the vector font for headings, keep the bitmap for body" (the hybrid) with evidence. 6// expect_exit: 0 license_tier: ORIGINAL 7import "nx_font.nx" 8import "nx_aa_raster.nx" 9import "nx_png_write.nx" 10const K_MAGIC_400000: i64 = 400000 11const K_MAGIC_40000: i64 = 40000 12const K_MAGIC_1600: i64 = 1600 13const K_MAGIC_1400: i64 = 1400 14const K_MAGIC_1100: i64 = 1100 15const K_MAGIC_1500: i64 = 1500 16const K_MAGIC_1700: i64 = 1700 17const K_MAGIC_1550: i64 = 1550 18const K_MAGIC_1050: i64 = 1050 19const K_MAGIC_1250: i64 = 1250 20const K_MAGIC_2200: i64 = 2200 21 22func vb_slen(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} return n } 23func vb_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 24func vb_num(v: i64) -> i64 { let b: *u8=sys_mmap(28); var m: i64=v; if m<0{m=0-m} 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{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 25 26// render `text` at pixel-size px into a W x H white PNG at `path` (single line, dark text). 27func vb_render(text: *u8, n: i64, px: i64, W: i64, H: i64, path: *u8) -> i64 { 28 let ss: i64 = 4 29 let S: i64 = px * ss // em scale in the supersample grid 30 // stroke output arrays (generous) 31 let xs: *i64 = sys_mmap(8*K_MAGIC_400000) as *i64 // Chaikin-smoothed glyphs -> ~20 verts/point, full phrase 32 let ys: *i64 = sys_mmap(8*K_MAGIC_400000) as *i64 33 let cstart: *i64 = sys_mmap(8*K_MAGIC_40000) as *i64 34 let clen: *i64 = sys_mmap(8*K_MAGIC_40000) as *i64 35 let np: *i64 = sys_mmap(16) as *i64; np[0]=0 36 let nc: *i64 = sys_mmap(16) as *i64; nc[0]=0 37 // gs_stroke needs trig tables (cs/sn 12 steps) -- init like nx_vecphrase_proof 38 let cs: *i64 = sys_mmap(8*20) as *i64 39 let sn: *i64 = sys_mmap(8*20) as *i64 40 font_trig_init(cs, sn) // 16-gon table (matches gs_disc joins -> no wobble) 41 // emit the string at pen (margin, top) in the SUPERSAMPLE grid 42 font_text(text, n, xs, ys, cstart, clen, np, nc, cs, sn, 20*ss, 6*ss, S) 43 // rasterize into coverage (W x H), then blit onto white 44 let cov: *u8 = sys_mmap(W*H + 16) 45 aa_render(xs, ys, cstart, clen, nc[0], cov, W, H, ss) 46 let rgb: *u8 = sys_mmap(W*H*3 + 16) 47 var i: i64 = 0 48 while i < W*H*3 { rgb[i] = 255 as u8; i = i + 1 } 49 aa_blit(rgb, W, H, 0, 0, cov, W, H, 42, 42, 51) // dark #2a2a33 50 nx_png_write_rgb(path, rgb, W, H) 51 return 0 52} 53 54func main() -> i64 { 55 vb_puts("VECFONT body bench: the stroke-vector font at headline vs body size (where does it win?)\n" as *u8) 56 let phrase: *u8 = "the quick brown fox jumps over lazy dog\x00" as *u8 57 let n: i64 = vb_slen(phrase) 58 // HEADLINE: 40px (lowercase pangram) 59 vb_render(phrase, n, 40, K_MAGIC_1600, 70, "knowledge/status/vecfont_headline.png\x00" as *u8) 60 vb_puts(" wrote vecfont_headline.png (40px)\n" as *u8) 61 // CAPS + DIGITS headline (the NEW glyphs -- must OCR-read before wiring vector headings) 62 let caps: *u8 = "The Quick Brown Fox: 42 Books, 1970 Records!\x00" as *u8 63 vb_render(caps, vb_slen(caps), 40, K_MAGIC_1600, 70, "knowledge/status/vecfont_caps.png\x00" as *u8) 64 vb_puts(" wrote vecfont_caps.png (40px caps+digits+punct)\n" as *u8) 65 // BODY: 16px (the hard case -- no hinting) 66 vb_render(phrase, n, 16, 700, 32, "knowledge/status/vecfont_body.png\x00" as *u8) 67 vb_puts(" wrote vecfont_body.png (16px)\n" as *u8) 68 // TYPE-QUALITY reference: "Render legibility" isolated at ~72px caps (empx 116) to compare vs Chrome 69 let tq: *u8 = "Render legibility\x00" as *u8 70 vb_render(tq, vb_slen(tq), 116, K_MAGIC_1400, 190, "knowledge/status/typeq_ours.png\x00" as *u8) 71 vb_puts(" wrote typeq_ours.png (type-quality ref)\n" as *u8) 72 // CURVE-SMOOTHNESS reference: a big isolated "O" (closest glyph to a circle) for contour-turning analysis 73 vb_render("O\x00" as *u8, 1, 300, 380, 400, "knowledge/status/typeq_O_ours.png\x00" as *u8) 74 vb_puts(" wrote typeq_O_ours.png (big O for smoothness)\n" as *u8) 75 // BASELINE-CONSISTENCY reference: an all-x-height word (no ascenders/descenders) so every letter's bottom 76 // is the baseline -> the variance of letter-bottoms = the "bounce" (amateur) vs consistent (professional). 77 vb_render("consensus\x00" as *u8, 9, 120, K_MAGIC_1100, 200, "knowledge/status/typeq_base_ours.png\x00" as *u8) 78 vb_puts(" wrote typeq_base_ours.png (x-height word for baseline consistency)\n" as *u8) 79 // PEN-WEIGHT reference: an isolated 'l' (one pure stem -- no neighbors, no curves, no modulation) at the 80 // SAME em as the word render -> the unconfounded pen-width measure for the weight axis. 81 vb_render("l\x00" as *u8, 1, 116, 160, 190, "knowledge/status/typeq_l_ours.png\x00" as *u8) 82 vb_puts(" wrote typeq_l_ours.png (isolated stem for pen weight)\n" as *u8) 83 // KERNING specimen: the classically-risky pairs (T/V/W/Y/A/L overhangs + punctuation) at current metrics 84 let kp: *u8 = "To Ta Ty AV AW LT TT VA Yo Fa P. r; ty\x00" as *u8 85 vb_render(kp, vb_slen(kp), 90, K_MAGIC_1500, 160, "knowledge/status/typeq_kern_pairs.png\x00" as *u8) 86 vb_puts(" wrote typeq_kern_pairs.png (risky-pair specimen)\n" as *u8) 87 // debug: big isolated V (apex construction check) 88 vb_render("V\x00" as *u8, 1, 300, 380, 400, "knowledge/status/typeq_V_dbg.png\x00" as *u8) 89 vb_puts(" wrote typeq_V_dbg.png\n" as *u8) 90 // GEOMETRIC (machine-regular) specimen -- pangram for OCR + eyeball 91 font_spec_geo(1); font_spec_mod(100); font_spec_swell(100) 92 vb_render("the quick brown fox jumps over lazy dog\x00" as *u8, 39, 40, K_MAGIC_1700, 100, "knowledge/status/geo_specimen.png\x00" as *u8) 93 vb_render("sassafras mississippi bosses\x00" as *u8, 28, 120, K_MAGIC_1600, 220, "knowledge/status/geo_s_dbg.png\x00" as *u8) // isolate the s 94 vb_render("Hamburgevons 2026 quick\x00" as *u8, 23, 64, K_MAGIC_1400, 110, "knowledge/status/geo_vs_pro.png\x00" as *u8) // MATCH pro_compare.png 64px 95 vb_render("the quick brown fox jumps over the lazy dog\x00" as *u8, 43, 16, K_MAGIC_1500, 46, "knowledge/status/geo_body16.png\x00" as *u8) 96 vb_render("the quick brown fox jumps over the lazy dog\x00" as *u8, 43, 20, K_MAGIC_1700, 56, "knowledge/status/geo_body20.png\x00" as *u8) 97 vb_render("mg magnum eggnog\x00" as *u8, 16, 150, K_MAGIC_1550, 320, "knowledge/status/geo_mg_dbg.png\x00" as *u8) // isolate m + g 98 vb_render("gauge eggnog logo\x00" as *u8, 17, 110, K_MAGIC_1500, 250, "knowledge/status/geo_g_dbg.png\x00" as *u8) // g in word context 99 font_spec_reset() 100 vb_puts(" wrote geo_specimen.png + geo_s_dbg.png\n" as *u8) 101 // ★OCR SIZE-LADDER: the same pangram at body->headline sizes so the OCR judge says how small our font 102 // stays legible vs Chrome (a professional font degrades gracefully). Ground truth in the filenames. 103 let pg: *u8 = "the quick brown fox jumps over the lazy dog\x00" as *u8 104 let pn: i64 = vb_slen(pg) 105 vb_render(pg, pn, 10, 900, 30, "knowledge/status/ladder_ours_10.png\x00" as *u8) 106 vb_render(pg, pn, 12, K_MAGIC_1050, 36, "knowledge/status/ladder_ours_12.png\x00" as *u8) 107 vb_render(pg, pn, 14, K_MAGIC_1250, 42, "knowledge/status/ladder_ours_14.png\x00" as *u8) 108 vb_render(pg, pn, 16, K_MAGIC_1400, 46, "knowledge/status/ladder_ours_16.png\x00" as *u8) 109 vb_render(pg, pn, 20, K_MAGIC_1700, 56, "knowledge/status/ladder_ours_20.png\x00" as *u8) 110 vb_render(pg, pn, 26, K_MAGIC_2200, 72, "knowledge/status/ladder_ours_26.png\x00" as *u8) 111 vb_puts(" wrote ladder_ours_{10..26}.png\n" as *u8) 112 vb_puts("VECFONT-BENCH done -- OCR + eyeball both to decide headings-vector / body-bitmap hybrid\n" as *u8) 113 return 0 114}