code wiki / (root) / nx_layout_block_test.nx

nx_layout_block_test.nx source

↩ module page · 143 lines · 5404 B

1// nx_layout_block_test.nx -- smoke for the Phase-3 block-layout 2// primitive. Builds a 2-box tree (root + child) with explicit cascade 3// declarations on the child (width 100px, height 50px, margin-top 20px, 4// padding-top 10px), runs the normal-flow layout pass, asserts each 5// box's (x, y, w, h). 6// 7// Layout math (Phase 3 content-box subset): 8// root: x=0, y=0, w=viewport(800), h=80 9// (no own padding; content_h = children_h = child's outer_h) 10// child: x=0 (parent's content x), y=20 (margin-top), 11// w=100 (explicit), h=60 (padding-top 10 + content 50) 12// child outer_h = mt(20) + h(60) + mb(0) = 80 13 14import "nx_syscalls.nx" 15import "nx_css_tokenize.nx" 16import "nx_css_parse.nx" 17import "nx_css_selector_match.nx" 18import "nx_css_apply.nx" 19import "nx_css_number_parse.nx" 20import "nx_css_dimension_to_px.nx" 21import "nx_layout_box.nx" 22import "nx_layout_block.nx" 23 24func _put_byte(buf: *u8, i: i64, v: i64) -> i64 { 25 buf[i] = v as u8 26 return 0 27} 28 29func main() -> i64 { 30 // Single shared source buffer. The first 64 bytes hold the 31 // canonical property names (written by nx_layout_prop_table_init). 32 // We append numeric/unit byte strings starting at offset 64. 33 let buf: *u8 = (sys_mmap(256)) as *u8 34 35 let table: *LayoutPropTable = (sys_mmap(NX_LAYOUT_PROP_TABLE_BYTES as nx_size)) as *LayoutPropTable 36 nx_layout_prop_table_init(table, buf) 37 38 // Layout for value strings in the SAME buffer (so cascade decls 39 // can point into it): 40 // [64..66] "100" width value 41 // [67..68] "20" margin-top value 42 // [69..70] "10" padding-top value 43 // [71..72] "50" height value 44 // [73..74] "px" unit 45 _put_byte(buf, 64, 49) // '1' 46 _put_byte(buf, 65, 48) // '0' 47 _put_byte(buf, 66, 48) // '0' 48 _put_byte(buf, 67, 50) // '2' 49 _put_byte(buf, 68, 48) // '0' 50 _put_byte(buf, 69, 49) // '1' 51 _put_byte(buf, 70, 48) // '0' 52 _put_byte(buf, 71, 53) // '5' 53 _put_byte(buf, 72, 48) // '0' 54 _put_byte(buf, 73, 112) // 'p' 55 _put_byte(buf, 74, 120) // 'x' 56 57 // Build cascade: 4 declarations on element 1 (the child). 58 let n_computed: i64 = 4 59 let computed: *CssComputedDecl = (sys_mmap((n_computed * NX_CSS_COMPUTED_DECL_BYTES) as nx_size)) as *CssComputedDecl 60 61 // decl 0: child width:100px 62 let c0: *CssComputedDecl = computed 63 c0.element_idx = 1 64 c0.prop_off = table.width_off 65 c0.prop_len = table.width_len 66 c0.val_kind = NX_CSS_VAL_DIMENSION 67 c0.val_off = 64 68 c0.val_len = 3 69 c0.unit_off = 73 70 c0.unit_len = 2 71 72 // decl 1: child height:50px 73 let c1: *CssComputedDecl = (computed as *u8 + (1 as nx_size) * (NX_CSS_COMPUTED_DECL_BYTES as nx_size)) as *CssComputedDecl 74 c1.element_idx = 1 75 c1.prop_off = table.height_off 76 c1.prop_len = table.height_len 77 c1.val_kind = NX_CSS_VAL_DIMENSION 78 c1.val_off = 71 79 c1.val_len = 2 80 c1.unit_off = 73 81 c1.unit_len = 2 82 83 // decl 2: child margin-top:20px 84 let c2: *CssComputedDecl = (computed as *u8 + (2 as nx_size) * (NX_CSS_COMPUTED_DECL_BYTES as nx_size)) as *CssComputedDecl 85 c2.element_idx = 1 86 c2.prop_off = table.margin_top_off 87 c2.prop_len = table.margin_top_len 88 c2.val_kind = NX_CSS_VAL_DIMENSION 89 c2.val_off = 67 90 c2.val_len = 2 91 c2.unit_off = 73 92 c2.unit_len = 2 93 94 // decl 3: child padding-top:10px 95 let c3: *CssComputedDecl = (computed as *u8 + (3 as nx_size) * (NX_CSS_COMPUTED_DECL_BYTES as nx_size)) as *CssComputedDecl 96 c3.element_idx = 1 97 c3.prop_off = table.padding_top_off 98 c3.prop_len = table.padding_top_len 99 c3.val_kind = NX_CSS_VAL_DIMENSION 100 c3.val_off = 69 101 c3.val_len = 2 102 c3.unit_off = 73 103 c3.unit_len = 2 104 105 // Resolve context for em/rem/% (none used here). 106 let resolve: *CssResolveCtx = (sys_mmap(NX_CSS_RESOLVE_CTX_BYTES as nx_size)) as *CssResolveCtx 107 resolve.root_font_size_px = 16 108 resolve.parent_font_size_px = 16 109 resolve.parent_dimension_px = 800 110 111 // Build 2-box tree. 112 let max_boxes: i64 = 4 113 let boxes: *LayoutBox = (sys_mmap((max_boxes * NX_LAYOUT_BOX_BYTES) as nx_size)) as *LayoutBox 114 let tree: *LayoutTree = (sys_mmap(NX_LAYOUT_TREE_BYTES as nx_size)) as *LayoutTree 115 nx_layout_tree_init(tree, boxes, max_boxes) 116 117 let root_idx: i64 = nx_layout_box_append(tree, NX_LAYOUT_BOX_BLOCK, 0) 118 let child_idx: i64 = nx_layout_box_append(tree, NX_LAYOUT_BOX_BLOCK, 1) 119 nx_layout_box_attach_child(tree, root_idx, child_idx) 120 121 // Run layout. 122 let ctx: *LayoutCtx = (sys_mmap(NX_LAYOUT_CTX_BYTES as nx_size)) as *LayoutCtx 123 nx_layout_ctx_init(ctx, tree, computed, n_computed, buf, 800, resolve) 124 125 let outer_h: i64 = nx_layout_block_layout(ctx, table, root_idx) 126 if outer_h != 80 { return 1 } 127 128 // Verify root geometry. 129 let root: *LayoutBox = boxes 130 if root.x != 0 { return 10 } 131 if root.y != 0 { return 11 } 132 if root.w != 800 { return 12 } 133 if root.h != 80 { return 13 } 134 135 // Verify child geometry. 136 let child: *LayoutBox = (boxes as *u8 + (1 as nx_size) * (NX_LAYOUT_BOX_BYTES as nx_size)) as *LayoutBox 137 if child.x != 0 { return 20 } 138 if child.y != 20 { return 21 } 139 if child.w != 100 { return 22 } 140 if child.h != 60 { return 23 } 141 142 return 0 143}