nx_browser_render_own_test.nx source
↩ module page · 106 lines · 3753 B
1// nx_browser_render_own_test.nx -- Phase-5 render row: take the HTML
2// the browser fetched from OUR OWN site over sovereign HTTPS
3// (/tmp/nishi_own.html, produced by nx_browser_own_site_live_test)
4// and prove the render pipeline on it:
5//
6// 1. nx_html_to_text extracts readable text -> must contain
7// "Nishi Family" (the real h1) and be non-trivial
8// 2. the extracted text paints into an RGBA framebuffer via the
9// 5x7 bitmap font -> framebuffer must be NON-BLANK
10// 3. ASCII raster saved to /tmp/nishi_own_render.txt (visible proof)
11//
12// HONEST SCOPE: this renders the page's TEXT through the paint
13// substrate. Full CSS-cascade layout of arbitrary real-world pages
14// (style blocks, viewport meta) is the NEXT rung -- flagged, not
15// claimed. Compose-by-file with the fetch test keeps each gate row
16// single-responsibility.
17//
18// expect_exit: 0
19// license_tier: ORIGINAL
20
21import "nx_syscalls.nx"
22import "nx_html_to_text.nx"
23import "nx_css_color_decode.nx"
24import "nx_paint_solid_rect.nx"
25import "nx_paint_text.nx"
26import "nx_paint_fb_ascii_dump.nx"
27
28// Find needle (NUL-terminated) in hay[0..hay_len); 1 if present.
29func ro_contains(hay: *u8, hay_len: i64, needle: *u8) -> i64 {
30 var nlen: i64 = 0
31 while needle[nlen] != (0 as u8) { nlen = nlen + 1 }
32 if nlen == 0 { return 1 }
33 var i: i64 = 0
34 while i + nlen <= hay_len {
35 var j: i64 = 0
36 var ok: i64 = 1
37 while j < nlen {
38 if hay[i + j] != needle[j] { ok = 0; j = nlen }
39 j = j + 1
40 }
41 if ok == 1 { return 1 }
42 i = i + 1
43 }
44 return 0
45}
46
47func main() -> i64 {
48 // ---- 1. Load the fetched page ----
49 let lenp: *i64 = sys_mmap(16) as *i64
50 let html: *u8 = sys_read_file("/tmp/nishi_own.html\x00", lenp)
51 let html_len: i64 = lenp[0]
52 if html as i64 == 0 { return 10 }
53 if html_len < 64 { return 11 }
54
55 // ---- 2. Extract text ----
56 let text: *u8 = sys_mmap(65536)
57 let text_len: i64 = nx_html_to_text(html, html_len, text, 65536)
58 if text_len < 16 { return 20 }
59 if ro_contains(text, text_len, "Nishi Family\x00") != 1 { return 21 }
60
61 // ---- 3. Paint first line of text into a framebuffer ----
62 // 80 cols x 16 rows of 6x8 cells = 480x128 px.
63 let fb_raw: *u8 = sys_mmap(NX_FRAMEBUFFER_BYTES)
64 let fb: *Framebuffer = fb_raw as *Framebuffer
65 let w: i64 = 480
66 let h: i64 = 128
67 let pixels: *u8 = sys_mmap(w * h * 4)
68 nx_framebuffer_init(fb, pixels, w, h)
69 nx_framebuffer_clear(fb)
70
71 // Take up to 76 chars of the first non-empty text line.
72 let line: *u8 = sys_mmap(128)
73 var li: i64 = 0
74 var ti: i64 = 0
75 while ti < text_len {
76 let c: i64 = text[ti] & 0xff
77 if c == 10 { if li > 0 { ti = text_len } }
78 if ti < text_len {
79 if c >= 32 { if li < 76 { line[li] = c as u8; li = li + 1 } }
80 ti = ti + 1
81 }
82 }
83 if li < 4 { return 30 }
84 line[li] = 0 as u8
85 let white: *CssColor = (sys_mmap(NX_CSS_COLOR_BYTES)) as *CssColor
86 white.r = 255; white.g = 255; white.b = 255; white.a = 255
87 nx_paint_text(fb, 4, 4, line, li, white)
88
89 // ---- 4. Non-blank assertion + visible artifact ----
90 var lit: i64 = 0
91 var pi: i64 = 0
92 let total_px: i64 = w * h
93 while pi < total_px {
94 if (pixels[pi * 4] & 0xff) > 128 { lit = lit + 1 }
95 pi = pi + 1
96 }
97 if lit < 16 { return 40 } // a real glyph row lights >= dozens
98
99 let dump_cap: i64 = (w + 1) * h
100 let dump: *u8 = sys_mmap(dump_cap)
101 let dn: i64 = nx_paint_fb_ascii_dump(fb, dump, dump_cap)
102 if dn <= 0 { return 41 }
103 let ofd: i64 = sys_openat_wr("/tmp/nishi_own_render.txt\x00", 0x1A4)
104 if ofd > 0 { sys_write(ofd, dump, dn); sys_close(ofd) }
105 return 0
106}