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}