code wiki / (root) / nx_paint_box_borders_test.nx

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}