code wiki / _hdl_build / nx_browser_find_gate.nx

nx_browser_find_gate.nx source

↩ module page · 123 lines · 6669 B

1// nx_browser_find_gate.nx -- gate for FIND-IN-PAGE (the Ctrl+F feature every browser has; UX census had 2// it as an ADMITTED gap -- this flips it, with EVIDENCE). Proves on the real bench page through the real 3// core: (T1) the term "wizards" is FOUND with the right match count; (T2) the first-match page-y is 4// returned (scroll-to target) and really is the paragraph's y; (T3) with the find active the render shows 5// HIGHLIGHT pixels (#FFE066) under the match; (T4) with no find active there are ZERO highlight pixels; 6// (T5) NEG: an absent term matches 0 and highlights NOTHING (the highlighter cannot false-fire); 7// (T6) case-insensitive ("WIZARDS" == "wizards"); (T7) EVIDENCE CLIP recorded: page -> find+highlight -> 8// scrolled-to-match, browser-playable APNG (knowledge/status/usersim_find_clip.png). 9// expect_exit: 0 license_tier: ORIGINAL 10import "nx_browser_render.nx" 11import "nx_apng_write.nx" 12 13func fg_puts(s: *u8) -> i64 { var n: i64=0; while s[n]!=(0 as u8){n=n+1} sys_write(1,s,n); return 0 } 14func fg_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 } 15 16const FG_W: i64 = 500 17const FG_H: i64 = 400 18 19// render into a fresh RGBA buffer at scroll sy; returns pixels 20func fg_frame(page: *Page, sy: i64) -> *u8 { 21 let fb: *Framebuffer = sys_mmap(NX_FRAMEBUFFER_BYTES) as *Framebuffer 22 let px: *u8 = sys_mmap(FG_W*FG_H*4 + 64) 23 nx_framebuffer_init(fb, px, FG_W, FG_H) 24 br_draw_fb_at(fb, page, FG_W, "usersim://find\x00" as *u8, 14, 1, sy) 25 return px 26} 27// count highlight-yellow pixels (255,224,102) 28func fg_hl(px: *u8) -> i64 { 29 var cnt: i64 = 0 30 var i: i64 = 0 31 while i < FG_W*FG_H { 32 if (px[i*4] as i64)==255 { if (px[i*4+1] as i64)==224 { if (px[i*4+2] as i64)==102 { cnt=cnt+1 } } } 33 i = i + 1 34 } 35 return cnt 36} 37func fg_rgb(px: *u8, rgb: *u8) -> i64 { 38 var p: i64 = 0 39 while p < FG_W*FG_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 } 40 return 0 41} 42 43func main() -> i64 { 44 fg_puts("FIND-IN-PAGE gate: search -> highlight -> scroll-to-match, on the real core, with clip evidence\n" as *u8) 45 let lp: *i64 = sys_mmap(16) as *i64 46 let html: *u8 = sys_read_file("knowledge/status/ocr_bench_page.html\x00" as *u8, lp) 47 if lp[0] <= 0 { fg_puts("find_gate: no bench page\n" as *u8); sys_exit(1); return 1 } 48 let page: *Page = sys_mmap(NX_PAGE_BYTES) as *Page 49 page.raw = html 50 page.raw_len = lp[0] 51 br_layout(page, FG_W) 52 if page.ok != 1 { fg_puts("find_gate: layout failed\n" as *u8); sys_exit(1); return 1 } 53 54 var pass: i64=0 55 var ttl: i64=0 56 57 // T1: find "wizards" (appears once in the pangram paragraph) 58 let yb: *i64 = sys_mmap(16) as *i64 59 let m1: i64 = br_find(page, "wizards\x00" as *u8, 7, yb) 60 ttl=ttl+1; fg_puts(" T1 find 'wizards': matches=" as *u8); fg_num(m1); fg_puts(" (expect 1): " as *u8) 61 if m1==1 { pass=pass+1; fg_puts("PASS\n" as *u8) } else { fg_puts("FAIL\n" as *u8) } 62 63 // T2: first-match y is a real content y (below the h1, above page_h) 64 ttl=ttl+1; fg_puts(" T2 scroll-to target y=" as *u8); fg_num(yb[0]); fg_puts(" (0 < y < page_h " as *u8); fg_num(page.page_h); fg_puts("): " as *u8) 65 if yb[0] > 0 { if yb[0] < page.page_h { pass=pass+1; fg_puts("PASS\n" as *u8) } else { fg_puts("FAIL\n" as *u8) } } else { fg_puts("FAIL\n" as *u8) } 66 67 // T3: highlight pixels present while the find is active 68 let pxa: *u8 = fg_frame(page, 0) 69 let hla: i64 = fg_hl(pxa) 70 ttl=ttl+1; fg_puts(" T3 highlight pixels with find active (got " as *u8); fg_num(hla); fg_puts(" > 100): " as *u8) 71 if hla > 100 { pass=pass+1; fg_puts("PASS\n" as *u8) } else { fg_puts("FAIL\n" as *u8) } 72 73 // T4: clearing the find removes ALL highlight 74 page.find_ptr = 0 75 page.find_len = 0 76 let pxb: *u8 = fg_frame(page, 0) 77 let hlb: i64 = fg_hl(pxb) 78 ttl=ttl+1; fg_puts(" T4 zero highlight pixels with find cleared (got " as *u8); fg_num(hlb); fg_puts("): " as *u8) 79 if hlb == 0 { pass=pass+1; fg_puts("PASS\n" as *u8) } else { fg_puts("FAIL\n" as *u8) } 80 81 // T5 NEG: absent term -> 0 matches, no highlight 82 let m2: i64 = br_find(page, "zzqx\x00" as *u8, 4, yb) 83 let pxn: *u8 = fg_frame(page, 0) 84 let hln: i64 = fg_hl(pxn) 85 ttl=ttl+1; fg_puts(" T5 NEG absent term: matches=" as *u8); fg_num(m2); fg_puts(" highlight=" as *u8); fg_num(hln); fg_puts(": " as *u8) 86 if m2==0 { if hln==0 { pass=pass+1; fg_puts("PASS\n" as *u8) } else { fg_puts("FAIL\n" as *u8) } } else { fg_puts("FAIL\n" as *u8) } 87 88 // T6: case-insensitive 89 let m3: i64 = br_find(page, "WIZARDS\x00" as *u8, 7, yb) 90 ttl=ttl+1; fg_puts(" T6 case-insensitive 'WIZARDS': matches=" as *u8); fg_num(m3); fg_puts(": " as *u8) 91 if m3==1 { pass=pass+1; fg_puts("PASS\n" as *u8) } else { fg_puts("FAIL\n" as *u8) } 92 93 // T7: EVIDENCE CLIP -- plain page, find+highlight, scrolled-to-match 94 let st: *ApngState = sys_mmap(NX_APNG_STATE_BYTES) as *ApngState 95 apng_open(st, "knowledge/status/usersim_find_clip.png\x00" as *u8, FG_W, FG_H, 3, 2, 3) 96 let rgb: *u8 = sys_mmap(FG_W*FG_H*3 + 64) 97 page.find_ptr = 0 98 page.find_len = 0 99 let f1: *u8 = fg_frame(page, 0) 100 fg_rgb(f1, rgb) 101 apng_frame(st, rgb) // frame 1: the page 102 br_find(page, "wizards\x00" as *u8, 7, yb) 103 let f2: *u8 = fg_frame(page, 0) 104 fg_rgb(f2, rgb) 105 apng_frame(st, rgb) // frame 2: highlighted 106 var sy: i64 = yb[0] - 60 107 if sy < 0 { sy = 0 } 108 let f3: *u8 = fg_frame(page, sy) 109 fg_rgb(f3, rgb) 110 apng_frame(st, rgb) // frame 3: scrolled to the match 111 apng_close(st) 112 let cl: *i64 = sys_mmap(16) as *i64 113 cl[0]=0-1 114 let cb: *u8 = sys_read_file("knowledge/status/usersim_find_clip.png\x00" as *u8, cl) 115 ttl=ttl+1; fg_puts(" T7 evidence clip recorded + animated (" as *u8); fg_num(cl[0]); fg_puts("B): " as *u8) 116 var clip_ok: i64 = 0 117 if cl[0] > 50000 { if (cb[37] as i64)==97 { if (cb[38] as i64)==99 { clip_ok=1 } } } 118 if clip_ok==1 { pass=pass+1; fg_puts("PASS\n" as *u8) } else { fg_puts("FAIL\n" as *u8) } 119 120 fg_puts("BROWSER-FIND-GATE passed " as *u8); fg_num(pass); fg_puts("/" as *u8); fg_num(ttl) 121 if pass==ttl { fg_puts(" verdict=GREEN (find-in-page works; watch knowledge/status/usersim_find_clip.png)\n" as *u8); sys_exit(0); return 0 } 122 fg_puts(" verdict=RED\n" as *u8); sys_exit(1); return 1 123}