nx_paint_box_borders_test.nx source
↩ module page · 260 lines · 10076 B
1// nx_paint_box_borders_test.nx -- smoke for the 4-side border
2// painter. Builds a box at (5, 5, 22, 22) with four borders of
3// distinct widths and colors:
4// top: 2px red (#ff0000)
5// right: 3px green (#00ff00)
6// bottom: 4px blue (#0000ff)
7// left: 1px white (#ffffff)
8// Paints into a 32x32 framebuffer, verifies pixels.
9
10import "nx_syscalls.nx"
11import "nx_css_tokenize.nx"
12import "nx_css_apply.nx"
13import "nx_css_color_decode.nx"
14import "nx_css_dimension_to_px.nx"
15import "nx_layout_box.nx"
16import "nx_paint_solid_rect.nx"
17import "nx_paint_box_borders.nx"
18
19func _put_byte(buf: *u8, i: i64, v: i64) -> i64 {
20 buf[i] = v as u8
21 return 0
22}
23
24func main() -> i64 {
25 // Build a property-name table in its own buffer (192 bytes).
26 let table_buf: *u8 = (sys_mmap(192)) as *u8
27 let table: *BorderPropTable = (sys_mmap(NX_BORDER_PROP_TABLE_BYTES as nx_size)) as *BorderPropTable
28 nx_border_prop_table_init(table, table_buf)
29
30 // The cascade source needs to byte-equal the table's property
31 // names for the byte-equal compare to succeed. Easiest: REUSE
32 // the same buffer for the cascade's property name bytes too.
33 // Append value bytes (numbers / hex / unit) in the same buffer
34 // starting at offset 192.
35 //
36 // (table_buf is 192 bytes already; we'll allocate a larger
37 // composite buffer that contains BOTH the table AND the value
38 // strings.)
39 let cascade_buf: *u8 = (sys_mmap(256)) as *u8
40 // Copy table bytes into cascade_buf so the cascade can point at
41 // the same property name bytes.
42 var i: i64 = 0
43 while i < 192 {
44 cascade_buf[i] = table_buf[i]
45 i = i + 1
46 }
47
48 // Re-init the table to point into cascade_buf (so it and the
49 // cascade share the same buffer; byte-equal trivially passes).
50 nx_border_prop_table_init(table, cascade_buf)
51
52 // Append value bytes starting at offset 192:
53 // [192..193] "2" bt_width
54 // [194..195] "3" br_width
55 // [196..197] "4" bb_width
56 // [198..199] "1" bl_width
57 // [200..201] "px" unit
58 // [202..207] "ff0000" red bt_color
59 // [208..213] "00ff00" green br_color
60 // [214..219] "0000ff" blue bb_color
61 // [220..225] "ffffff" white bl_color
62 _put_byte(cascade_buf, 192, 50) // "2"
63 _put_byte(cascade_buf, 194, 51) // "3"
64 _put_byte(cascade_buf, 196, 52) // "4"
65 _put_byte(cascade_buf, 198, 49) // "1"
66 _put_byte(cascade_buf, 200, 112) // "p"
67 _put_byte(cascade_buf, 201, 120) // "x"
68 // "ff0000"
69 _put_byte(cascade_buf, 202, 102) _put_byte(cascade_buf, 203, 102)
70 _put_byte(cascade_buf, 204, 48) _put_byte(cascade_buf, 205, 48)
71 _put_byte(cascade_buf, 206, 48) _put_byte(cascade_buf, 207, 48)
72 // "00ff00"
73 _put_byte(cascade_buf, 208, 48) _put_byte(cascade_buf, 209, 48)
74 _put_byte(cascade_buf, 210, 102) _put_byte(cascade_buf, 211, 102)
75 _put_byte(cascade_buf, 212, 48) _put_byte(cascade_buf, 213, 48)
76 // "0000ff"
77 _put_byte(cascade_buf, 214, 48) _put_byte(cascade_buf, 215, 48)
78 _put_byte(cascade_buf, 216, 48) _put_byte(cascade_buf, 217, 48)
79 _put_byte(cascade_buf, 218, 102) _put_byte(cascade_buf, 219, 102)
80 // "ffffff"
81 _put_byte(cascade_buf, 220, 102) _put_byte(cascade_buf, 221, 102)
82 _put_byte(cascade_buf, 222, 102) _put_byte(cascade_buf, 223, 102)
83 _put_byte(cascade_buf, 224, 102) _put_byte(cascade_buf, 225, 102)
84
85 // Build cascade: 8 declarations on element 0.
86 let n_computed: i64 = 8
87 let computed: *CssComputedDecl = (sys_mmap((n_computed * NX_CSS_COMPUTED_DECL_BYTES) as nx_size)) as *CssComputedDecl
88
89 let c0: *CssComputedDecl = computed
90 c0.element_idx = 0
91 c0.prop_off = table.bt_width_off
92 c0.prop_len = table.bt_width_len
93 c0.val_kind = NX_CSS_VAL_DIMENSION
94 c0.val_off = 192
95 c0.val_len = 1
96 c0.unit_off = 200
97 c0.unit_len = 2
98
99 let c1: *CssComputedDecl = (computed as *u8 + (1 as nx_size) * (NX_CSS_COMPUTED_DECL_BYTES as nx_size)) as *CssComputedDecl
100 c1.element_idx = 0
101 c1.prop_off = table.br_width_off
102 c1.prop_len = table.br_width_len
103 c1.val_kind = NX_CSS_VAL_DIMENSION
104 c1.val_off = 194
105 c1.val_len = 1
106 c1.unit_off = 200
107 c1.unit_len = 2
108
109 let c2: *CssComputedDecl = (computed as *u8 + (2 as nx_size) * (NX_CSS_COMPUTED_DECL_BYTES as nx_size)) as *CssComputedDecl
110 c2.element_idx = 0
111 c2.prop_off = table.bb_width_off
112 c2.prop_len = table.bb_width_len
113 c2.val_kind = NX_CSS_VAL_DIMENSION
114 c2.val_off = 196
115 c2.val_len = 1
116 c2.unit_off = 200
117 c2.unit_len = 2
118
119 let c3: *CssComputedDecl = (computed as *u8 + (3 as nx_size) * (NX_CSS_COMPUTED_DECL_BYTES as nx_size)) as *CssComputedDecl
120 c3.element_idx = 0
121 c3.prop_off = table.bl_width_off
122 c3.prop_len = table.bl_width_len
123 c3.val_kind = NX_CSS_VAL_DIMENSION
124 c3.val_off = 198
125 c3.val_len = 1
126 c3.unit_off = 200
127 c3.unit_len = 2
128
129 let c4: *CssComputedDecl = (computed as *u8 + (4 as nx_size) * (NX_CSS_COMPUTED_DECL_BYTES as nx_size)) as *CssComputedDecl
130 c4.element_idx = 0
131 c4.prop_off = table.bt_color_off
132 c4.prop_len = table.bt_color_len
133 c4.val_kind = NX_CSS_VAL_HEXCOLOR
134 c4.val_off = 202
135 c4.val_len = 6
136
137 let c5: *CssComputedDecl = (computed as *u8 + (5 as nx_size) * (NX_CSS_COMPUTED_DECL_BYTES as nx_size)) as *CssComputedDecl
138 c5.element_idx = 0
139 c5.prop_off = table.br_color_off
140 c5.prop_len = table.br_color_len
141 c5.val_kind = NX_CSS_VAL_HEXCOLOR
142 c5.val_off = 208
143 c5.val_len = 6
144
145 let c6: *CssComputedDecl = (computed as *u8 + (6 as nx_size) * (NX_CSS_COMPUTED_DECL_BYTES as nx_size)) as *CssComputedDecl
146 c6.element_idx = 0
147 c6.prop_off = table.bb_color_off
148 c6.prop_len = table.bb_color_len
149 c6.val_kind = NX_CSS_VAL_HEXCOLOR
150 c6.val_off = 214
151 c6.val_len = 6
152
153 let c7: *CssComputedDecl = (computed as *u8 + (7 as nx_size) * (NX_CSS_COMPUTED_DECL_BYTES as nx_size)) as *CssComputedDecl
154 c7.element_idx = 0
155 c7.prop_off = table.bl_color_off
156 c7.prop_len = table.bl_color_len
157 c7.val_kind = NX_CSS_VAL_HEXCOLOR
158 c7.val_off = 220
159 c7.val_len = 6
160
161 // Resolve context.
162 let resolve: *CssResolveCtx = (sys_mmap(NX_CSS_RESOLVE_CTX_BYTES as nx_size)) as *CssResolveCtx
163 resolve.root_font_size_px = 16
164 resolve.parent_font_size_px = 16
165 resolve.parent_dimension_px = 100
166
167 // Build a single LayoutBox at (5, 5, 22, 22).
168 let boxes: *LayoutBox = (sys_mmap((4 * NX_LAYOUT_BOX_BYTES) as nx_size)) as *LayoutBox
169 let b: *LayoutBox = boxes
170 b.kind = NX_LAYOUT_BOX_BLOCK
171 b.parent_idx = -1
172 b.first_child_idx = -1
173 b.next_sibling_idx = -1
174 b.x = 5
175 b.y = 5
176 b.w = 22
177 b.h = 22
178
179 // Framebuffer.
180 let fb_pixels: *u8 = (sys_mmap((32 * 32 * 4) as nx_size)) as *u8
181 let fb: *Framebuffer = (sys_mmap(NX_FRAMEBUFFER_BYTES as nx_size)) as *Framebuffer
182 nx_framebuffer_init(fb, fb_pixels, 32, 32)
183 nx_framebuffer_clear(fb)
184
185 // Paint borders.
186 let total: i64 = nx_paint_box_borders(fb, b, computed, n_computed,
187 cascade_buf, table, 0, resolve)
188
189 // Paint counts (per side, with corner overlap):
190 // top: 22 x 2 = 44
191 // left: 1 x 22 = 22
192 // right: 3 x 22 = 66
193 // bottom: 22 x 4 = 88
194 // sum = 220
195 if total != 220 { return 1 }
196
197 let probe: *CssColor = (sys_mmap(NX_CSS_COLOR_BYTES as nx_size)) as *CssColor
198
199 // Top border at y=5, h=2 -> rows 5 and 6 should be red. Test
200 // a pixel in the middle of the top strip.
201 nx_framebuffer_get_pixel(fb, 15, 5, probe)
202 if probe.r != 255 { return 10 }
203 if probe.g != 0 { return 11 }
204 nx_framebuffer_get_pixel(fb, 15, 6, probe)
205 if probe.r != 255 { return 12 }
206
207 // Just below top border (y=7) should be untouched (zero).
208 // BUT this column may be covered by left/right; pick a column
209 // in the middle (x=15) which neither left (x=5) nor right
210 // (x=24..26) covers. The middle should be unpainted at y=7.
211 nx_framebuffer_get_pixel(fb, 15, 7, probe)
212 if probe.r != 0 { return 13 }
213 if probe.g != 0 { return 14 }
214 if probe.a != 0 { return 15 }
215
216 // Right border: br_w=3 -> right edge at x = 5 + 22 - 3 = 24.
217 // Columns 24, 25, 26 should be green; column 23 should NOT be.
218 nx_framebuffer_get_pixel(fb, 24, 15, probe)
219 if probe.g != 255 { return 20 }
220 if probe.r != 0 { return 21 }
221 nx_framebuffer_get_pixel(fb, 26, 15, probe)
222 if probe.g != 255 { return 22 }
223 nx_framebuffer_get_pixel(fb, 23, 15, probe)
224 if probe.r != 0 { return 23 }
225 if probe.g != 0 { return 24 }
226
227 // Bottom border: bb_w=4 -> bottom edge at y = 5 + 22 - 4 = 23.
228 // Rows 23, 24, 25, 26 should be blue (in the middle, x=15).
229 nx_framebuffer_get_pixel(fb, 15, 23, probe)
230 if probe.b != 255 { return 30 }
231 if probe.r != 0 { return 31 }
232 nx_framebuffer_get_pixel(fb, 15, 26, probe)
233 if probe.b != 255 { return 32 }
234 // Row 22 should NOT be blue at x=15.
235 nx_framebuffer_get_pixel(fb, 15, 22, probe)
236 if probe.b != 0 { return 33 }
237 if probe.r != 0 { return 34 }
238
239 // Left border: bl_w=1 -> column 5. Pixel (5, 15) should be white.
240 nx_framebuffer_get_pixel(fb, 5, 15, probe)
241 if probe.r != 255 { return 40 }
242 if probe.g != 255 { return 41 }
243 if probe.b != 255 { return 42 }
244 // Column 6 should NOT be white (in the middle vertically).
245 nx_framebuffer_get_pixel(fb, 6, 15, probe)
246 if probe.r != 0 { return 43 }
247
248 // Corner pixel (5, 5): top border paints first then left. Left
249 // border at x=5 fills h=22 starting at y=5, so y=5 column 5 is
250 // last-overwritten to white. But top border paints first and
251 // covers the same pixel with red. Then left paints over with
252 // white. (Paint order in code: top -> left -> right -> bottom,
253 // so left wins over top at (5, 5).)
254 nx_framebuffer_get_pixel(fb, 5, 5, probe)
255 if probe.r != 255 { return 50 }
256 if probe.g != 255 { return 51 }
257 if probe.b != 255 { return 52 }
258
259 return 0
260}