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}