code wiki / _hdl_build / nx_browser_darkmode_gate.nx

nx_browser_darkmode_gate.nx source

↩ module page · 130 lines · 6987 B

1// nx_browser_darkmode_gate.nx -- DARK MODE (the "OLED look" the operator framed the visual push around), 2// a UX-census ADMIT flipped by BUILD + evidence. Renders the SAME bench page through the real core in LIGHT 3// (dark_mode=0) and DARK (dark_mode=1); proves: (T1) the light page is majority-LIGHT; (T2) the dark page is 4// majority-DARK -- the theme actually FLIPPED (CAN-FAIL control: if the flag did nothing the two renders would 5// be identical and this fails); (T3) dark page still has LIGHT TEXT ink (readable, not an all-black void); 6// (T4) the browser chrome went dark too (coherent, not a light bar on a dark page); (T5) evidence PNGs written 7// (light + dark + a side-by-side) for the eyeball. license_tier: ORIGINAL expect_exit: 0 8import "nx_browser_render.nx" 9 10func dm_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 dm_num(v: i64) -> i64 { let b: *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{b[i]=t[k-1-i];i=i+1} sys_write(1,b,k); return 0 } 12 13const DM_W: i64 = 900 14 15func dm_render(html: *u8, hlen: i64, dark: i64, hout: *i64) -> *u8 { 16 let page: *Page = sys_mmap(NX_PAGE_BYTES) as *Page 17 page.raw = html 18 page.raw_len = hlen 19 page.dark_mode = dark // set BEFORE br_layout (it picks the default CSS) 20 br_layout(page, DM_W/2) 21 page.vec_headings = 1 22 var H: i64 = (page.page_h + NX_CHROME_H + 40) * 2 23 if H > 1400 { H = 1400 } 24 let fb: *Framebuffer = sys_mmap(NX_FRAMEBUFFER_BYTES) as *Framebuffer 25 let px: *u8 = sys_mmap(DM_W*H*4 + 64) 26 nx_framebuffer_init(fb, px, DM_W, H) 27 var url: *u8 = "nishi://reader\x00" as *u8 28 if dark == 1 { url = "nishi://reader (dark)\x00" as *u8 } 29 br_draw_fb(fb, page, DM_W/2, url, 21, 2) 30 hout[0] = H 31 return px 32} 33// count pixels darker than lum L and lighter than lum L, in the PAGE area (below the chrome) 34func dm_counts(px: *u8, W: i64, H: i64, out: *i64) -> i64 { 35 var dark: i64=0 36 var light: i64=0 37 var lightink: i64=0 38 let y0: i64 = NX_CHROME_H*2 + 4 39 var y: i64=y0 40 while y<H { 41 var x: i64=0 42 while x<W { 43 let o: i64=(y*W+x)*4 44 let lum: i64=(2126*(px[o] as i64)+7152*(px[o+1] as i64)+722*(px[o+2] as i64))/10000 45 if lum < 60 { dark=dark+1 } 46 if lum > 200 { light=light+1 } 47 if lum > 150 { if lum < 245 { lightink=lightink+1 } } // light-gray text ink (not pure white) 48 x=x+1 49 } 50 y=y+1 51 } 52 out[0]=dark; out[1]=light; out[2]=lightink 53 return 0 54} 55func dm_rgb_write(px: *u8, W: i64, H: i64, path: *u8) -> i64 { 56 let rgb: *u8 = sys_mmap(W*H*3+64) 57 var p: i64=0 58 while p<W*H { rgb[p*3]=px[p*4]; rgb[p*3+1]=px[p*4+1]; rgb[p*3+2]=px[p*4+2]; p=p+1 } 59 nx_png_write_rgb(path, rgb, W, H) 60 return 0 61} 62// chrome-bar mean luminance (top strip) -- proves the chrome darkened too 63func dm_chrome_lum(px: *u8, W: i64) -> i64 { 64 var s: i64=0 65 var n: i64=0 66 var y: i64=2 67 while y<NX_CHROME_H*2-2 { var x: i64=0; while x<W { let o: i64=(y*W+x)*4; s=s+(2126*(px[o] as i64)+7152*(px[o+1] as i64)+722*(px[o+2] as i64))/10000; n=n+1; x=x+8 } y=y+2 } 68 if n>0 { return s/n } else { return 0 } 69} 70 71func main() -> i64 { 72 dm_puts("DARK MODE gate: the OLED reader theme through the real core, with a can-fail control\n" as *u8) 73 let lp: *i64 = sys_mmap(16) as *i64 74 let html: *u8 = sys_read_file("knowledge/status/ocr_bench_page.html\x00" as *u8, lp) 75 if lp[0] <= 0 { dm_puts("darkmode: no bench page\n" as *u8); sys_exit(1); return 1 } 76 77 let hl: *i64 = sys_mmap(16) as *i64 78 let hd: *i64 = sys_mmap(16) as *i64 79 let lpx: *u8 = dm_render(html, lp[0], 0, hl) 80 let dpx: *u8 = dm_render(html, lp[0], 1, hd) 81 let lc: *i64 = sys_mmap(32) as *i64 82 let dc: *i64 = sys_mmap(32) as *i64 83 dm_counts(lpx, DM_W, hl[0], lc) 84 dm_counts(dpx, DM_W, hd[0], dc) 85 dm_puts(" light page: dark-px=" as *u8); dm_num(lc[0]); dm_puts(" light-px=" as *u8); dm_num(lc[1]); dm_puts("\n" as *u8) 86 dm_puts(" dark page: dark-px=" as *u8); dm_num(dc[0]); dm_puts(" light-px=" as *u8); dm_num(dc[1]); dm_puts(" light-ink=" as *u8); dm_num(dc[2]); dm_puts("\n" as *u8) 87 let lchrome: i64 = dm_chrome_lum(lpx, DM_W) 88 let dchrome: i64 = dm_chrome_lum(dpx, DM_W) 89 dm_puts(" chrome-bar mean lum: light=" as *u8); dm_num(lchrome); dm_puts(" dark=" as *u8); dm_num(dchrome); dm_puts("\n" as *u8) 90 91 var pass: i64=0 92 var ttl: i64=0 93 ttl=ttl+1; dm_puts(" T1 light page is majority-LIGHT (light>dark): " as *u8); if lc[1] > lc[0]*4 { pass=pass+1; dm_puts("PASS\n" as *u8) } else { dm_puts("FAIL\n" as *u8) } 94 ttl=ttl+1; dm_puts(" T2 dark page is majority-DARK (theme FLIPPED, can-fail): " as *u8); if dc[0] > dc[1]*4 { pass=pass+1; dm_puts("PASS\n" as *u8) } else { dm_puts("FAIL\n" as *u8) } 95 ttl=ttl+1; dm_puts(" T3 dark page has LIGHT TEXT ink (readable, not a void): " as *u8); if dc[2] > 2000 { pass=pass+1; dm_puts("PASS\n" as *u8) } else { dm_puts("FAIL\n" as *u8) } 96 ttl=ttl+1; dm_puts(" T4 chrome went dark too (dark bar << light bar lum): " as *u8); if dchrome < 90 { if lchrome > 180 { pass=pass+1; dm_puts("PASS\n" as *u8) } else { dm_puts("FAIL\n" as *u8) } } else { dm_puts("FAIL\n" as *u8) } 97 98 dm_rgb_write(lpx, DM_W, hl[0], "knowledge/status/darkmode_light.png\x00" as *u8) 99 dm_rgb_write(dpx, DM_W, hd[0], "knowledge/status/darkmode_dark.png\x00" as *u8) 100 // side-by-side (light left, dark right) into one PNG 101 var CH: i64 = hl[0] 102 if hd[0] < CH { CH = hd[0] } 103 let cw: i64 = DM_W*2 + 20 104 let comp: *u8 = sys_mmap(cw*CH*3 + 64) 105 var q: i64=0 106 while q<cw*CH*3 { comp[q]=30 as u8; q=q+1 } 107 var yy: i64=0 108 while yy<CH { 109 var xx: i64=0 110 while xx<DM_W { 111 let lo: i64=(yy*DM_W+xx)*4 112 let co: i64=(yy*cw+xx)*3 113 comp[co]=lpx[lo]; comp[co+1]=lpx[lo+1]; comp[co+2]=lpx[lo+2] 114 let ro: i64=(yy*cw+(xx+DM_W+20))*3 115 comp[ro]=dpx[lo]; comp[ro+1]=dpx[lo+1]; comp[ro+2]=dpx[lo+2] 116 xx=xx+1 117 } 118 yy=yy+1 119 } 120 nx_png_write_rgb("knowledge/status/darkmode_compare.png\x00" as *u8, comp, cw, CH) 121 let clp: *i64 = sys_mmap(16) as *i64 122 clp[0]=0-1 123 let cb: *u8 = sys_read_file("knowledge/status/darkmode_compare.png\x00" as *u8, clp) 124 ttl=ttl+1; dm_puts(" T5 evidence PNGs written (light+dark+compare " as *u8); dm_num(clp[0]); dm_puts("B): " as *u8) 125 if clp[0] > 5000 { pass=pass+1; dm_puts("PASS\n" as *u8) } else { dm_puts("FAIL\n" as *u8) } 126 127 dm_puts("BROWSER-DARKMODE-GATE passed " as *u8); dm_num(pass); dm_puts("/" as *u8); dm_num(ttl) 128 if pass==ttl { dm_puts(" verdict=GREEN (dark mode works; see knowledge/status/darkmode_compare.png)\n" as *u8); sys_exit(0); return 0 } 129 dm_puts(" verdict=RED\n" as *u8); sys_exit(1); return 1 130}