code wiki / _hdl_build / nx_render_wiki_bmp.nx
nx_render_wiki_bmp.nx source
↩ module page · 138 lines · 6444 B
1// nx_render_wiki_bmp.nx -- render a REAL fetched Wikipedia page to a viewable BMP image, end-to-end
2// through the sovereign browser pipeline: read knowledge/fetched/wiki_web_dev.html -> nx_layout_from_dom
3// -> nx_layout_block (geometry) -> nx_paint_walk_layout (pixels) -> 24-bit BMP (openable on Windows).
4// Composes the gated layout/paint organs + the nx_bmp format; no gcc/V8/Chrome.
5import "nx_syscalls.nx"
6import "nx_css_tokenize.nx"
7import "nx_css_apply.nx"
8import "nx_css_color_decode.nx"
9import "nx_layout_box.nx"
10import "nx_layout_from_dom.nx"
11import "nx_layout_block.nx"
12import "nx_paint_solid_rect.nx"
13import "nx_paint_text.nx"
14import "nx_font_bitmap_5x7.nx"
15import "nx_paint_walk_layout.nx"
16const K_MAGIC_16384: i64 = 16384
17const K_MAGIC_2400: i64 = 2400
18
19func wb_u32(fd: i64, v: i64) -> i64 {
20 let b: *u8 = sys_mmap(4)
21 b[0]=(v & 255) as u8; b[1]=((v>>8)&255) as u8; b[2]=((v>>16)&255) as u8; b[3]=((v>>24)&255) as u8
22 sys_write(fd, b, 4); return 0
23}
24func wb_u16(fd: i64, v: i64) -> i64 {
25 let b: *u8 = sys_mmap(2)
26 b[0]=(v & 255) as u8; b[1]=((v>>8)&255) as u8
27 sys_write(fd, b, 2); return 0
28}
29// write the framebuffer as a 24-bit BMP (bottom-up, BGR), reading pixels via the public get_pixel.
30func wb_save(path: *u8, fb: *Framebuffer, w: i64, h: i64) -> i64 {
31 let row3: i64 = w * 3
32 let pad: i64 = (4 - (row3 % 4)) % 4
33 let rowstride: i64 = row3 + pad
34 let datasize: i64 = rowstride * h
35 let fd: i64 = sys_openat_wr(path, 420)
36 if fd < 0 { return 0 - 1 }
37 sys_write(fd, "BM\x00" as *u8, 2)
38 wb_u32(fd, 54 + datasize); wb_u32(fd, 0); wb_u32(fd, 54)
39 wb_u32(fd, 40); wb_u32(fd, w); wb_u32(fd, h); wb_u16(fd, 1); wb_u16(fd, 24)
40 wb_u32(fd, 0); wb_u32(fd, datasize); wb_u32(fd, 0); wb_u32(fd, 0); wb_u32(fd, 0); wb_u32(fd, 0)
41 let rowbuf: *u8 = sys_mmap(rowstride + 4)
42 let px: *CssColor = (sys_mmap(NX_CSS_COLOR_BYTES as nx_size)) as *CssColor
43 var y: i64 = h - 1
44 while y >= 0 {
45 var x: i64 = 0
46 while x < w {
47 nx_framebuffer_get_pixel(fb, x, y, px)
48 if px.a == 0 {
49 rowbuf[x*3] = 255 as u8; rowbuf[x*3+1] = 255 as u8; rowbuf[x*3+2] = 255 as u8 // unpainted -> white page
50 } else {
51 rowbuf[x*3] = px.b as u8
52 rowbuf[x*3+1] = px.g as u8
53 rowbuf[x*3+2] = px.r as u8
54 }
55 x = x + 1
56 }
57 var p: i64 = 0
58 while p < pad { rowbuf[row3 + p] = 0 as u8; p = p + 1 }
59 sys_write(fd, rowbuf, rowstride)
60 y = y - 1
61 }
62 sys_close(fd)
63 return 0
64}
65
66func main() -> i64 {
67 // ---- read the REAL fetched Wikipedia page ----
68 let path: *u8 = "knowledge/fetched/wiki_web_dev.html\x00"
69 let len_p: *i64 = sys_mmap(16) as *i64
70 let html: *u8 = sys_read_file(path, len_p)
71 let html_len: i64 = *len_p
72 if html_len <= 0 { sys_write(2, "no wiki html\n" as *u8, 12); return 1 }
73
74 let VW: i64 = 800 // viewport / image width
75 // ---- HTML -> layout box tree (Wikipedia is big -> roomy arena) ----
76 let boxes: *LayoutBox = (sys_mmap(NX_LAYOUT_BOX_BYTES * K_MAGIC_16384 + 16)) as *LayoutBox
77 let tree: *LayoutTree = (sys_mmap(64)) as *LayoutTree
78 nx_layout_tree_init(tree, boxes, K_MAGIC_16384)
79 let stk: *LayoutFromDomStack = (sys_mmap(NX_LAYOUT_FROM_DOM_STACK_BYTES + 8)) as *LayoutFromDomStack
80 let stk_idx: *i64 = (sys_mmap(8 * 128)) as *i64
81 nx_layout_from_dom_stack_init(stk, stk_idx, 128)
82 if nx_layout_from_dom(html, html_len, tree, stk) != 0 { sys_write(2, "layout-from-dom FAIL\n" as *u8, 20); return 2 }
83
84 // ---- block layout: pixel geometry (empty CSS cascade -> default block flow) ----
85 let prop_buf: *u8 = sys_mmap(256)
86 let ltable: *LayoutPropTable = (sys_mmap(NX_LAYOUT_PROP_TABLE_BYTES)) as *LayoutPropTable
87 nx_layout_prop_table_init(ltable, prop_buf)
88 let resolve: *CssResolveCtx = (sys_mmap(NX_CSS_RESOLVE_CTX_BYTES)) as *CssResolveCtx
89 resolve.root_font_size_px = 16
90 resolve.parent_font_size_px = 16
91 resolve.parent_dimension_px = VW
92 let lctx: *LayoutCtx = (sys_mmap(NX_LAYOUT_CTX_BYTES)) as *LayoutCtx
93 nx_layout_ctx_init(lctx, tree, 0 as *CssComputedDecl, 0, html, VW, resolve)
94 let page_h: i64 = nx_layout_block_layout(lctx, ltable, 0)
95
96 // image height = laid-out page height, clamped so the BMP stays sane
97 var VH: i64 = page_h
98 if VH < 64 { VH = 64 }
99 if VH > K_MAGIC_2400 { VH = K_MAGIC_2400 }
100
101 // ---- framebuffer + paint ----
102 let fb_pixels: *u8 = (sys_mmap((VW * VH * 4) as nx_size)) as *u8
103 let fb: *Framebuffer = (sys_mmap(NX_FRAMEBUFFER_BYTES as nx_size)) as *Framebuffer
104 nx_framebuffer_init(fb, fb_pixels, VW, VH)
105 nx_framebuffer_clear(fb)
106 let ptable_buf: *u8 = (sys_mmap(64)) as *u8
107 let ptable: *PaintPropTable = (sys_mmap(NX_PAINT_PROP_TABLE_BYTES as nx_size)) as *PaintPropTable
108 nx_paint_prop_table_init(ptable, ptable_buf)
109 let pctx: *PaintCtx = (sys_mmap(NX_PAINT_CTX_BYTES as nx_size)) as *PaintCtx
110 nx_paint_ctx_init(pctx, fb, tree, 0 as *CssComputedDecl, 0, html, ptable)
111 let ink: *CssColor = (sys_mmap(NX_CSS_COLOR_BYTES as nx_size)) as *CssColor
112 ink.r = 0; ink.g = 0; ink.b = 0; ink.a = 255
113 nx_paint_ctx_set_text(pctx, html, ink)
114 let painted: i64 = nx_paint_walk_layout(pctx, 0)
115 sys_write(1, "painted pixels = " as *u8, 17)
116 let pb: *u8 = sys_mmap(20); var pk: i64 = 0; var pm: i64 = painted
117 if pm == 0 { pb[0]=48; pk=1 }
118 while pm > 0 { pb[pk] = (48 + (pm % 10)) as u8; pm = pm / 10; pk = pk + 1 }
119 var po: i64 = 0; let pob: *u8 = sys_mmap(20)
120 while po < pk { pob[po] = pb[pk-1-po]; po = po + 1 }
121 sys_write(1, pob, pk); sys_write(1, "\n" as *u8, 1)
122
123 // ---- save the rendered page as a viewable BMP ----
124 let outp: *u8 = "knowledge/status/wiki_render.bmp\x00"
125 wb_save(outp, fb, VW, VH)
126
127 // report
128 sys_write(1, "rendered knowledge/fetched/wiki_web_dev.html -> knowledge/status/wiki_render.bmp (" as *u8, 82)
129 wb_u16(1, VW); sys_write(1, "x" as *u8, 1); wb_u16(1, VH); sys_write(1, ", boxes=" as *u8, 8)
130 let nb: i64 = tree.count
131 let dbuf: *u8 = sys_mmap(16); var k: i64 = 0; var m: i64 = nb
132 if m == 0 { dbuf[0]=48; k=1 }
133 while m > 0 { dbuf[k] = (48 + (m % 10)) as u8; m = m / 10; k = k + 1 }
134 var o: i64 = 0; let ob: *u8 = sys_mmap(16)
135 while o < k { ob[o] = dbuf[k-1-o]; o = o + 1 }
136 sys_write(1, ob, k); sys_write(1, ")\n" as *u8, 2)
137 return 0
138}