You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Implement the core layout engine: given a styled DOM tree and viewport dimensions, produce a LayoutTree with precise geometry (position and size) for every box. Covers block formatting context, inline formatting context, and CSS positioned layout.
Prerequisites
Step 4 (style resolution — computed styles for every node)
crates/ie-layout/src/text_measure.rs — new file, TextMeasure trait
Implementation
Expanded types (lib.rs)
LayoutBox:
pubstructLayoutBox{pubnode_id:Option<NodeId>,// None for anonymous boxespubbox_type:BoxType,pubstyle:ComputedStyle,pubcontent_rect:Rect,pubpadding:EdgeSizes,pubborder:EdgeSizes,pubmargin:EdgeSizes,pubchildren:Vec<usize>,// indices into LayoutTree arena}pubenumBoxType{Block,Inline,InlineBlock,Anonymous,Text(String)}pubstructEdgeSizes{pubtop:f32,pubright:f32,pubbottom:f32,publeft:f32}
LayoutTree: arena of LayoutBox (Vec<LayoutBox> indexed by usize)
Parent: #19
Goal
Implement the core layout engine: given a styled DOM tree and viewport dimensions, produce a
LayoutTreewith precise geometry (position and size) for every box. Covers block formatting context, inline formatting context, and CSS positioned layout.Prerequisites
File Changes
crates/ie-layout/src/lib.rs— restructure, expand LayoutTree/LayoutBox typescrates/ie-layout/src/box_generation.rs— new filecrates/ie-layout/src/block.rs— new filecrates/ie-layout/src/inline.rs— new filecrates/ie-layout/src/positioned.rs— new filecrates/ie-layout/src/text_measure.rs— new file, TextMeasure traitImplementation
Expanded types (
lib.rs)LayoutBox:LayoutTree: arena ofLayoutBox(Vec<LayoutBox>indexed by usize)layout(doc: &Document, styles: &[ComputedStyle], viewport: Rect, text_measure: &dyn TextMeasure) -> LayoutTreeTextMeasure trait (
text_measure.rs)MockTextMeasurethat returnswidth = text.len() * 8.0,height = style.font_sizeBox generation (
box_generation.rs)display: none→ skip (no box)display: block→ BlockBoxdisplay: inline→ InlineBoxdisplay: inline-block→ InlineBlockBoxdisplay: flex→ FlexBox (handled in Step 7, generate as Block for now)padding,border,marginfromComputedStyleintoEdgeSizesBlock formatting context (
block.rs)fn layout_block(box_idx: usize, tree: &mut LayoutTree, containing_width: f32, text_measure: &dyn TextMeasure):widthis auto:width = containing_width - margin_left - margin_right - padding_left - padding_right - border_left - border_rightwidthis specified: use itmargin-leftandmargin-rightare both auto: center the box (split remaining space)min-width/max-widthclampingy = previous_bottom)heightis auto: sum of children heights. If specified: use it. Handlemin-height/max-height.Inline formatting context (
inline.rs)fn layout_inline(box_idx: usize, tree: &mut LayoutTree, containing_width: f32, text_measure: &dyn TextMeasure):text_measure.measure()containing_width, break to next linewhite-space: normal→ collapse whitespace, allow wrappingwhite-space: nowrap→ collapse whitespace, no wrappingwhite-space: pre→ preserve whitespace, no wrappingwhite-space: pre-wrap→ preserve whitespace, allow wrappingPositioned layout (
positioned.rs)position: static— default, normal flowposition: relative— lay out in normal flow, then offset bytop/left/right/bottomposition: absolute:position != static)top/left/right/bottomagainst that ancestor's padding boxposition: fixed— like absolute but relative to viewportz-indexfor paint ordering (consumed by ie-render in Step 6)position != static && z-index != autocreate stacking contextsopacity < 1also creates a stacking contextTests
All tests use
MockTextMeasure(8px per character, height = font-size).Block layout tests
width: 200px→ content_rect.width = 200width: 200px; margin: 0 auto→ centered in 800px viewportmargin-bottom: 20pxandmargin-top: 30px→ gap is 30px (not 50px)box-sizing: border-box: width includes padding+bordermin-width/max-widthclampingInline layout tests
white-space: nowrap→ no wrapping regardless of container widthtext-align: center→ line content centeredPositioned layout tests
position: relative; top: 10px; left: 20px→ offset from normal positionposition: absolute→ removed from flow, siblings not affectedposition: absolutewith nearest positioned ancestor → positioned relative to that ancestorposition: fixed→ positioned relative to viewport rectAcceptance Criteria
cargo test -p ie-layout— all tests passcargo clippy -p ie-layout -- -D warnings— no warnings