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}