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}