code wiki / (root) / nx_paint_walk_layout_test.nx

nx_paint_walk_layout_test.nx source

↩ module page · 178 lines · 6492 B

1// nx_paint_walk_layout_test.nx -- end-to-end integration smoke for 2// the bits-up rendering pipeline. Builds a layout tree by hand 3// (since nx_layout_from_dom is queued), populates a cascade with 4// background-color declarations per box, walks the tree to paint, 5// and verifies framebuffer pixels match the expected coloring. 6// 7// Tree: 8// root at (0, 0, 32, 32) with background-color: #00ff00 (green) 9// child at (4, 8, 16, 12) with background-color: #ff00ff (magenta) 10// 11// Expected rendering (document-order paint: root first, child OVER): 12// pixel (1, 1) -> green 13// pixel (10, 10) -> magenta (inside child) 14// pixel (28, 28) -> green (outside child but inside root) 15// pixel (4, 8) -> magenta (top-left of child) 16// pixel (19, 19) -> magenta (bottom-right of child = 4+15, 8+11) 17 18import "nx_syscalls.nx" 19import "nx_css_tokenize.nx" 20import "nx_css_apply.nx" 21import "nx_css_color_decode.nx" 22import "nx_layout_box.nx" 23import "nx_paint_solid_rect.nx" 24import "nx_paint_walk_layout.nx" 25 26func _put_byte(buf: *u8, i: i64, v: i64) -> i64 { 27 buf[i] = v as u8 28 return 0 29} 30 31func main() -> i64 { 32 // Shared cascade-source buffer. Layout: 33 // [0..15] "background-color" (property name -- matches paint 34 // table) 35 // [16..21] "00ff00" (green hex body) 36 // [22..27] "ff00ff" (magenta hex body) 37 let cascade_buf: *u8 = (sys_mmap(64)) as *u8 38 39 // "background-color" 40 _put_byte(cascade_buf, 0, 98) // b 41 _put_byte(cascade_buf, 1, 97) // a 42 _put_byte(cascade_buf, 2, 99) // c 43 _put_byte(cascade_buf, 3, 107) // k 44 _put_byte(cascade_buf, 4, 103) // g 45 _put_byte(cascade_buf, 5, 114) // r 46 _put_byte(cascade_buf, 6, 111) // o 47 _put_byte(cascade_buf, 7, 117) // u 48 _put_byte(cascade_buf, 8, 110) // n 49 _put_byte(cascade_buf, 9, 100) // d 50 _put_byte(cascade_buf, 10, 45) // - 51 _put_byte(cascade_buf, 11, 99) // c 52 _put_byte(cascade_buf, 12, 111) // o 53 _put_byte(cascade_buf, 13, 108) // l 54 _put_byte(cascade_buf, 14, 111) // o 55 _put_byte(cascade_buf, 15, 114) // r 56 // "00ff00" -- green 57 _put_byte(cascade_buf, 16, 48) 58 _put_byte(cascade_buf, 17, 48) 59 _put_byte(cascade_buf, 18, 102) 60 _put_byte(cascade_buf, 19, 102) 61 _put_byte(cascade_buf, 20, 48) 62 _put_byte(cascade_buf, 21, 48) 63 // "ff00ff" -- magenta 64 _put_byte(cascade_buf, 22, 102) 65 _put_byte(cascade_buf, 23, 102) 66 _put_byte(cascade_buf, 24, 48) 67 _put_byte(cascade_buf, 25, 48) 68 _put_byte(cascade_buf, 26, 102) 69 _put_byte(cascade_buf, 27, 102) 70 71 // Cascade: 2 declarations -- one per element. 72 let n_computed: i64 = 2 73 let computed: *CssComputedDecl = (sys_mmap((n_computed * NX_CSS_COMPUTED_DECL_BYTES) as nx_size)) as *CssComputedDecl 74 75 let c0: *CssComputedDecl = computed 76 c0.element_idx = 0 77 c0.prop_off = 0 78 c0.prop_len = 16 79 c0.val_kind = NX_CSS_VAL_HEXCOLOR 80 c0.val_off = 16 81 c0.val_len = 6 82 c0.unit_off = 0 83 c0.unit_len = 0 84 85 let c1: *CssComputedDecl = (computed as *u8 + (1 as nx_size) * (NX_CSS_COMPUTED_DECL_BYTES as nx_size)) as *CssComputedDecl 86 c1.element_idx = 1 87 c1.prop_off = 0 88 c1.prop_len = 16 89 c1.val_kind = NX_CSS_VAL_HEXCOLOR 90 c1.val_off = 22 91 c1.val_len = 6 92 c1.unit_off = 0 93 c1.unit_len = 0 94 95 // Build a 2-box LayoutTree with pre-assigned geometry. 96 let max_boxes: i64 = 4 97 let boxes: *LayoutBox = (sys_mmap((max_boxes * NX_LAYOUT_BOX_BYTES) as nx_size)) as *LayoutBox 98 let tree: *LayoutTree = (sys_mmap(NX_LAYOUT_TREE_BYTES as nx_size)) as *LayoutTree 99 nx_layout_tree_init(tree, boxes, max_boxes) 100 101 let root_idx: i64 = nx_layout_box_append(tree, NX_LAYOUT_BOX_BLOCK, 0) 102 let child_idx: i64 = nx_layout_box_append(tree, NX_LAYOUT_BOX_BLOCK, 1) 103 nx_layout_box_attach_child(tree, root_idx, child_idx) 104 105 let root: *LayoutBox = boxes 106 root.x = 0 107 root.y = 0 108 root.w = 32 109 root.h = 32 110 111 let child: *LayoutBox = (boxes as *u8 + (1 as nx_size) * (NX_LAYOUT_BOX_BYTES as nx_size)) as *LayoutBox 112 child.x = 4 113 child.y = 8 114 child.w = 16 115 child.h = 12 116 117 // Framebuffer: 32 x 32 RGBA. 118 let fb_pixels: *u8 = (sys_mmap((32 * 32 * 4) as nx_size)) as *u8 119 let fb: *Framebuffer = (sys_mmap(NX_FRAMEBUFFER_BYTES as nx_size)) as *Framebuffer 120 nx_framebuffer_init(fb, fb_pixels, 32, 32) 121 nx_framebuffer_clear(fb) 122 123 // Paint table buffer. 124 let table_buf: *u8 = (sys_mmap(64)) as *u8 125 let table: *PaintPropTable = (sys_mmap(NX_PAINT_PROP_TABLE_BYTES as nx_size)) as *PaintPropTable 126 nx_paint_prop_table_init(table, table_buf) 127 128 // Paint context + walk. 129 let ctx: *PaintCtx = (sys_mmap(NX_PAINT_CTX_BYTES as nx_size)) as *PaintCtx 130 nx_paint_ctx_init(ctx, fb, tree, computed, n_computed, cascade_buf, table) 131 132 let total_pixels: i64 = nx_paint_walk_layout(ctx, root_idx) 133 // root: 32 x 32 = 1024 + child: 16 x 12 = 192 = 1216 total. 134 if total_pixels != 1216 { return 1 } 135 136 let probe: *CssColor = (sys_mmap(NX_CSS_COLOR_BYTES as nx_size)) as *CssColor 137 138 // (1, 1) -- inside root, outside child -> green. 139 nx_framebuffer_get_pixel(fb, 1, 1, probe) 140 if probe.r != 0 { return 10 } 141 if probe.g != 255 { return 11 } 142 if probe.b != 0 { return 12 } 143 if probe.a != 255 { return 13 } 144 145 // (28, 28) -- inside root, outside child -> green. 146 nx_framebuffer_get_pixel(fb, 28, 28, probe) 147 if probe.r != 0 { return 20 } 148 if probe.g != 255 { return 21 } 149 if probe.b != 0 { return 22 } 150 151 // (10, 10) -- inside child -> magenta. 152 nx_framebuffer_get_pixel(fb, 10, 10, probe) 153 if probe.r != 255 { return 30 } 154 if probe.g != 0 { return 31 } 155 if probe.b != 255 { return 32 } 156 if probe.a != 255 { return 33 } 157 158 // (4, 8) -- top-left of child -> magenta. 159 nx_framebuffer_get_pixel(fb, 4, 8, probe) 160 if probe.r != 255 { return 40 } 161 if probe.b != 255 { return 41 } 162 163 // (19, 19) -- bottom-right corner of child (4+15, 8+11) -> magenta. 164 nx_framebuffer_get_pixel(fb, 19, 19, probe) 165 if probe.r != 255 { return 50 } 166 if probe.b != 255 { return 51 } 167 168 // (20, 19) -- one past child's right edge -> green again. 169 nx_framebuffer_get_pixel(fb, 20, 19, probe) 170 if probe.g != 255 { return 60 } 171 if probe.r != 0 { return 61 } 172 173 // (4, 7) -- one above child's top -> green. 174 nx_framebuffer_get_pixel(fb, 4, 7, probe) 175 if probe.g != 255 { return 70 } 176 177 return 0 178}