DAY 13
1
Software Development

## 瀏覽器引擎處理版面佈局的簡易版（三）

LayoutBox 算出 layout 的初始函數，針對自己是那種型別來開始，這個專案中目前只實作 block。

``````// implimpl<'a> LayoutBox<'a>

/// Lay out a box and its descendants.
fn layout(&mut self, containing_block: Dimensions) {
match self.box_type {
BlockNode(_) => self.layout_block(containing_block),
InlineNode(_) | AnonymousBlock => {} // TODO
}
}
``````

``````<A hieght = 100>
<a heught = 200>
</A>
``````

``````<B width = 100>
<b width = 70>
<c width = 40>
</B>
``````

`B` 的的寬度是 100，雖然 `b``c` 加起來超過了，但他的寬度依舊是 100。

``````fn layout_block(&mut self, containing_block: Dimensions) {
// 子受父的寬度影響
self.calculate_block_width(containing_block);

// 決定這個 box 的位置
self.calculate_block_position(containing_block);

// 把底下的子算一下
self.layout_block_children();

// 父的高度受子影響，所以要等子算完才得到父
self.calculate_block_height();
}
``````

``````// Calculate the width of a block-level non-replaced element in normal flow.
// Sets the horizontal margin/padding/border dimensions, and the `width`.
fn calculate_block_width(&mut self, containing_block: Dimensions) {
...
}
``````

``````fn layout_block_children(&mut self) {
// 將 `self.dimensions.height` 設為全部內容加起來的總高度
let d = &mut self.dimensions;
for child in &mut self.children {
child.layout(*d);
// 把所有子元素的高度相加
d.content.height = d.content.height + child.dimensions.margin_box().height;
}
}
``````

``````    /// Height of a block-level non-replaced element in normal flow with overflow visible.
fn calculate_block_height(&mut self) {
// If the height is set to an explicit length, use that exact length.
// Otherwise, just keep the value set by `layout_block_children`.
if let Some(Length(h, Px)) = self.get_style_node().value("height") {
self.dimensions.content.height = h;
}
}
``````

``````    fn calculate_block_position(&mut self, containing_block: Dimensions) {
let style = self.get_style_node();
let d = &mut self.dimensions;

// margin, border, and padding have initial value 0.
let zero = Length(0.0, Px);

// If margin-top or margin-bottom is `auto`, the used value is zero.
d.margin.top = style.lookup("margin-top", "margin", &zero).to_px();
d.margin.bottom = style.lookup("margin-bottom", "margin", &zero).to_px();

d.border.top = style.lookup("border-top-width", "border-width", &zero).to_px();
d.border.bottom = style.lookup("border-bottom-width", "border-width", &zero).to_px();

d.content.x = containing_block.content.x +

// Position the box below all the previous boxes in the container.
d.content.y = containing_block.content.height + containing_block.content.y +
}
``````

## 劉安齊

### 1 則留言

0
Chris
iT邦新手 5 級 ‧ 2018-02-10 13:02:12

「在 auto 模式下， normal flow 處理 block 的時候，有一套演算法來想辦法勁量讓子元素符合父。」

1. 「在 auto 模式下」指的是 width: auto? 還是 overflow: auto?
2. 「勁」量，應該是「盡」量？

「盡」才對
overflow: auto 喔！