code wiki / _hdl_build / nx_aatext_proof.nx

nx_aatext_proof.nx source

↩ module page · 108 lines · 4421 B

1// nx_aatext_proof.nx -- prove GRAYSCALE-AA text from the full-ASCII 8x8 font via coverage supersampling, 2// vs the current 1-bit blocky render. Same string, 3 rows: 8px 1:1, 16px blocky, 16px coverage-AA. If the 3// AA row reads clearly smoother, this is the drop-in quality jump for the browser (full ASCII, no new font). 4import "nx_syscalls.nx" 5import "nx_font8x8.nx" 6import "nx_png_write.nx" 7 8func slen(s: *u8) -> i64 { var n: i64 = 0; while s[n] != (0 as u8) { n = n + 1 } return n } 9 10// alpha-blend ink (r,g,b) onto the RGBA buffer at (x,y) with coverage a (0..255) 11func blend(px: *u8, W: i64, H: i64, x: i64, y: i64, r: i64, g: i64, b: i64, a: i64) -> i64 { 12 if x < 0 { return 0 } 13 if x >= W { return 0 } 14 if y < 0 { return 0 } 15 if y >= H { return 0 } 16 let o: i64 = (y * W + x) * 4 17 let ia: i64 = 255 - a 18 px[o+0] = (((px[o+0] & 0xff) * ia) + (r * a)) / 255 19 px[o+1] = (((px[o+1] & 0xff) * ia) + (g * a)) / 255 20 px[o+2] = (((px[o+2] & 0xff) * ia) + (b * a)) / 255 21 px[o+3] = 255 as u8 22 return 0 23} 24 25// 1-bit blocky: each 8x8 font pixel -> blk x blk solid block (the current br_paint_text2x style) 26func draw_blocky(px: *u8, W: i64, H: i64, ft8: *u8, x: i64, y: i64, s: *u8, n: i64, blk: i64, r: i64, g: i64, b: i64) -> i64 { 27 var i: i64 = 0 28 while i < n { 29 let ch: i64 = s[i] & 0xff 30 let cx: i64 = x + i * 9 * blk 31 if ch >= 0x20 { if ch <= 0x7E { 32 let go: i64 = (ch - 0x20) * 8 33 var row: i64 = 0 34 while row < 8 { 35 let bits: i64 = ft8[go + row] & 0xff 36 var col: i64 = 0 37 while col < 8 { 38 if ((bits >> col) & 1) == 1 { 39 var yy: i64 = 0 40 while yy < blk { var xx: i64 = 0; while xx < blk { blend(px, W, H, cx + col*blk + xx, y + row*blk + yy, r, g, b, 255); xx = xx + 1 } yy = yy + 1 } 41 } 42 col = col + 1 43 } 44 row = row + 1 45 } 46 } } 47 i = i + 1 48 } 49 return 0 50} 51 52// coverage-AA: render each 8x8 glyph at `psz` px with SSxSS supersampling -> grayscale coverage -> blend 53func draw_aa(px: *u8, W: i64, H: i64, ft8: *u8, x: i64, y: i64, s: *u8, n: i64, psz: i64, adv: i64, r: i64, g: i64, b: i64) -> i64 { 54 let SS: i64 = 4 55 var i: i64 = 0 56 while i < n { 57 let ch: i64 = s[i] & 0xff 58 let cx: i64 = x + i * adv 59 if ch >= 0x20 { if ch <= 0x7E { 60 let go: i64 = (ch - 0x20) * 8 61 var ty: i64 = 0 62 while ty < psz { 63 var tx: i64 = 0 64 while tx < psz { 65 var cov: i64 = 0 66 var sy: i64 = 0 67 while sy < SS { 68 var sx: i64 = 0 69 while sx < SS { 70 let subx: i64 = tx * SS + sx 71 let suby: i64 = ty * SS + sy 72 let srcx: i64 = (subx * 8) / (psz * SS) 73 let srcy: i64 = (suby * 8) / (psz * SS) 74 let bits: i64 = ft8[go + srcy] & 0xff 75 if ((bits >> srcx) & 1) == 1 { cov = cov + 1 } 76 sx = sx + 1 77 } 78 sy = sy + 1 79 } 80 if cov > 0 { blend(px, W, H, cx + tx, y + ty, r, g, b, (cov * 255) / (SS * SS)) } 81 tx = tx + 1 82 } 83 ty = ty + 1 84 } 85 } } 86 i = i + 1 87 } 88 return 0 89} 90 91func main() -> i64 { 92 let W: i64 = 900 93 let H: i64 = 220 94 let px: *u8 = sys_mmap(W * H * 4) 95 var i: i64 = 0 96 while i < W * H * 4 { px[i] = 255 as u8; i = i + 1 } 97 let ft8: *u8 = font8x8_table() 98 let s: *u8 = "The quick brown fox -- Nishi Browser 2026 s-class\x00" as *u8 99 let n: i64 = slen(s) 100 draw_blocky(px, W, H, ft8, 12, 20, s, n, 1, 20, 20, 24) // row 1: 8px 1:1 (current small render) 101 draw_blocky(px, W, H, ft8, 12, 80, s, n, 2, 20, 20, 24) // row 2: 16px blocky 102 draw_aa(px, W, H, ft8, 12, 150, s, n, 16, 18, 20, 20, 24) // row 3: 16px coverage-AA 103 let rgb: *u8 = sys_mmap(W * H * 3) 104 var j: i64 = 0 105 while j < W * H { rgb[j*3+0] = px[j*4+0]; rgb[j*3+1] = px[j*4+1]; rgb[j*3+2] = px[j*4+2]; j = j + 1 } 106 nx_png_write_rgb("_offc/aatext.png\x00" as *u8, rgb, W, H) 107 return 0 108}