code wiki / _hdl_build / nx_ui_contrast.nx

nx_ui_contrast.nx source

↩ module page · 99 lines · 5238 B

1// nx_ui_contrast.nx -- QUANTITATIVE layer of the judging system: MEASURED WCAG contrast (not technique presence). 2// Extracts --nx-color-ink / --nx-color-bg from each emitted page's :root and computes the ACCURATE WCAG 2.x 3// contrast ratio via nx_brand_guard (fx_pow sRGB gamma, matches the WCAG reference). AA>=4.50:1, AAA>=7.00:1. 4// Composes nx_brand_guard (-> its nx_syscalls layer; no nx_syscalls_x86_64 dup). Helpers uc_*-prefixed to avoid 5// any collision with the brand_guard/brand_tokens/fx import chain. In _hdl_build/ beside nx_brand_guard so the 6// import resolves. license_tier: ORIGINAL expect_exit: 0 7import "nx_brand_guard.nx" 8const K_MAGIC_262144: i64 = 262144 9 10func uc_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8) { n=n+1 } sys_write(1,s,n); return 0 } 11func uc_num(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-(m/10)*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 } 12func uc_len(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8) { n=n+1 } return n } 13 14func uc_find(hay: *u8, n: i64, pat: *u8) -> i64 { 15 let pl: i64 = uc_len(pat) 16 if pl==0 { return 0-1 } 17 var i: i64=0 18 while i+pl<=n { 19 var j: i64=0; var ok: i64=1 20 while j<pl { if hay[i+j]!=pat[j] { ok=0; j=pl } else { j=j+1 } } 21 if ok==1 { return i } 22 i=i+1 23 } 24 return 0-1 25} 26func uc_slurp(path: *u8, buf: *u8, cap: i64) -> i64 { 27 let fd: i64 = sys_openat_rd(path) 28 if fd < 0 { return 0 } 29 var total: i64 = 0 30 var nrd: i64 = sys_read(fd, buf, cap) 31 while nrd > 0 { total = total + nrd; if total >= cap { nrd = 0 } else { nrd = sys_read(fd, ((buf as i64)+total) as *u8, cap-total) } } 32 sys_close(fd) 33 return total 34} 35func uc_ext(buf: *u8, n: i64, key: *u8, out: *u8) -> i64 { 36 let p: i64 = uc_find(buf, n, key) 37 if p < 0 { out[0]=0 as u8; return 0 } 38 var i: i64 = p + uc_len(key) 39 var gg: i64 = 1 40 while gg==1 { if i<n { if buf[i]==(32 as u8) { i=i+1 } else { gg=0 } } else { gg=0 } } 41 var o: i64 = 0 42 gg = 1 43 while gg==1 { 44 if i>=n { gg=0 } 45 else { 46 let c: i64 = buf[i] as i64 47 if c==59 { gg=0 } else { if c==32 { gg=0 } else { if c==125 { gg=0 } else { out[o]=buf[i]; o=o+1; i=i+1 } } } 48 } 49 } 50 out[o]=0 as u8 51 if out[0]==(35 as u8) { return 1 } 52 return 0 53} 54func uc_white(h: *u8) -> i64 { h[0]=35 as u8; h[1]=102 as u8; h[2]=102 as u8; h[3]=102 as u8; h[4]=102 as u8; h[5]=102 as u8; h[6]=102 as u8; h[7]=0 as u8; return 0 } 55 56func uc_grade(name: *u8, path: *u8, buf: *u8, cap: i64, tot: *i64) -> i64 { 57 let n: i64 = uc_slurp(path, buf, cap) 58 uc_puts(" " as *u8); uc_puts(name); uc_puts(": " as *u8) 59 if n<=0 { uc_puts("(missing)\n" as *u8); return 0 } 60 let ink: *u8 = sys_mmap(16) 61 let bg: *u8 = sys_mmap(16) 62 uc_ext(buf, n, "--nx-color-ink:" as *u8, ink) 63 let hb: i64 = uc_ext(buf, n, "--nx-color-bg:" as *u8, bg) 64 if hb==0 { uc_white(bg) } 65 if ink[0]!=(35 as u8) { uc_puts("(no ink token)\n" as *u8); return 0 } 66 let c: i64 = bg_contrast_hex_x100(ink, bg) 67 uc_puts("ink " as *u8); uc_puts(ink); uc_puts(" on bg " as *u8); uc_puts(bg); uc_puts(" = " as *u8) 68 if c<0 { uc_puts("parse-fail\n" as *u8); return 0 } 69 let f: i64 = c - (c/100)*100 70 uc_num(c/100); uc_puts("." as *u8) 71 if f<10 { uc_puts("0" as *u8) } 72 uc_num(f); uc_puts(":1 " as *u8) 73 tot[1]=tot[1]+1 74 if c>=700 { uc_puts("AAA (exceeds a11y floor)\n" as *u8); tot[0]=tot[0]+1 } else { if c>=450 { uc_puts("AA\n" as *u8); tot[0]=tot[0]+1 } else { uc_puts("BELOW AA -- FAIL\n" as *u8) } } 75 return 0 76} 77 78func main() -> i64 { 79 let cap: i64 = K_MAGIC_262144 80 let buf: *u8 = sys_mmap(cap) 81 let tot: *i64 = sys_mmap(16) as *i64 82 tot[0]=0; tot[1]=0 83 uc_puts("=== nx_ui_contrast -- MEASURED WCAG contrast (accurate fx_pow, via nx_brand_guard) ===\n" as *u8) 84 uc_puts("real benchmark: ink vs bg from each page's :root. AA>=4.50:1, AAA>=7.00:1. Quality, not presence.\n" as *u8) 85 uc_grade("award " as *u8, "web_assets/lds_award.html" as *u8, buf, cap, tot) 86 uc_grade("connect " as *u8, "web_assets/lds_connect.html" as *u8, buf, cap, tot) 87 uc_grade("youth " as *u8, "web_assets/lds_youth.html" as *u8, buf, cap, tot) 88 uc_grade("reconnect" as *u8, "web_assets/lds_reconnect.html" as *u8, buf, cap, tot) 89 uc_grade("games " as *u8, "web_assets/games.html" as *u8, buf, cap, tot) 90 uc_grade("wiki " as *u8, "knowledge/wiki_pages/feedback-additive-not-guards.html" as *u8, buf, cap, tot) 91 uc_puts("--- " as *u8); uc_num(tot[0]); uc_puts(" / " as *u8); uc_num(tot[1]); uc_puts(" pages meet >= AA contrast (measured) ---\n" as *u8) 92 let nc: i64 = bg_contrast_hex_x100("#8a8a8a" as *u8, "#9a9a9a" as *u8) 93 let nf: i64 = nc - (nc/100)*100 94 uc_puts(" NEG-CONTROL #8a8a8a on #9a9a9a = " as *u8); uc_num(nc/100); uc_puts("." as *u8) 95 if nf<10 { uc_puts("0" as *u8) } 96 uc_num(nf); uc_puts(":1 -> " as *u8) 97 if nc<450 { uc_puts("correctly BELOW AA (math discriminates)\n" as *u8) } else { uc_puts("FAIL (math too lenient)\n" as *u8) } 98 return 0 99}