mirror of
https://github.com/servo/servo.git
synced 2025-08-04 21:20:23 +01:00
Merge RootFlow into BlockFlow
This commit is contained in:
parent
b69a1e1ebd
commit
c0d8836e06
5 changed files with 77 additions and 229 deletions
|
@ -7,7 +7,7 @@
|
||||||
use layout::box::{RenderBox};
|
use layout::box::{RenderBox};
|
||||||
use layout::context::LayoutContext;
|
use layout::context::LayoutContext;
|
||||||
use layout::display_list_builder::{DisplayListBuilder, FlowDisplayListBuilderMethods};
|
use layout::display_list_builder::{DisplayListBuilder, FlowDisplayListBuilderMethods};
|
||||||
use layout::flow::{BlockFlow, FlowContext, FlowData, InlineBlockFlow, RootFlow};
|
use layout::flow::{BlockFlow, FlowContext, FlowData, InlineBlockFlow};
|
||||||
use layout::inline::InlineLayout;
|
use layout::inline::InlineLayout;
|
||||||
|
|
||||||
use au = gfx::geometry;
|
use au = gfx::geometry;
|
||||||
|
@ -23,7 +23,10 @@ pub struct BlockFlowData {
|
||||||
common: FlowData,
|
common: FlowData,
|
||||||
|
|
||||||
/// The associated render box.
|
/// The associated render box.
|
||||||
box: Option<RenderBox>
|
box: Option<RenderBox>,
|
||||||
|
|
||||||
|
/// Whether this block flow is the root flow.
|
||||||
|
is_root: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockFlowData {
|
impl BlockFlowData {
|
||||||
|
@ -31,53 +34,41 @@ impl BlockFlowData {
|
||||||
BlockFlowData {
|
BlockFlowData {
|
||||||
common: common,
|
common: common,
|
||||||
box: None,
|
box: None,
|
||||||
|
is_root: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_root(common: FlowData) -> BlockFlowData {
|
||||||
|
BlockFlowData {
|
||||||
|
common: common,
|
||||||
|
box: None,
|
||||||
|
is_root: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// NB: These are part of FlowContext, not part of BlockFlowData, because the root flow calls these
|
|
||||||
/// as well. It is not clear to me whether this needs to be the case, or whether `RootFlow` can be
|
|
||||||
/// merged into this.
|
|
||||||
pub trait BlockLayout {
|
pub trait BlockLayout {
|
||||||
|
fn starts_root_flow(&self) -> bool;
|
||||||
fn starts_block_flow(&self) -> bool;
|
fn starts_block_flow(&self) -> bool;
|
||||||
fn with_block_box(&self, &fn(box: RenderBox) -> ()) -> ();
|
|
||||||
|
|
||||||
fn bubble_widths_block(&self, ctx: &LayoutContext);
|
|
||||||
fn assign_widths_block(&self, ctx: &LayoutContext);
|
|
||||||
fn assign_height_block(&self, ctx: &LayoutContext);
|
|
||||||
fn build_display_list_block(&self,
|
|
||||||
a: &DisplayListBuilder,
|
|
||||||
b: &Rect<Au>,
|
|
||||||
c: &Point2D<Au>,
|
|
||||||
d: &Cell<DisplayList>);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockLayout for FlowContext {
|
impl BlockLayout for FlowContext {
|
||||||
fn starts_block_flow(&self) -> bool {
|
fn starts_root_flow(&self) -> bool {
|
||||||
match *self {
|
match *self {
|
||||||
RootFlow(*) | BlockFlow(*) | InlineBlockFlow(*) => true,
|
BlockFlow(info) => info.is_root,
|
||||||
_ => false
|
_ => false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the current flow's corresponding block box, if it exists, and do something with it.
|
fn starts_block_flow(&self) -> bool {
|
||||||
/// This works on both BlockFlow and RootFlow, since they are mostly the same.
|
|
||||||
fn with_block_box(&self, callback: &fn(box: RenderBox) -> ()) -> () {
|
|
||||||
match *self {
|
match *self {
|
||||||
BlockFlow(*) => {
|
BlockFlow(*) | InlineBlockFlow(*) => true,
|
||||||
for self.block().box.each |&b| {
|
_ => false
|
||||||
callback(b);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
RootFlow(*) => {
|
|
||||||
for self.root().box.each |&b| {
|
|
||||||
callback(b);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => fail!(fmt!("Tried to do something with_block_box(), but this is a %?", self))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BlockFlowData {
|
||||||
/* Recursively (bottom-up) determine the context's preferred and
|
/* Recursively (bottom-up) determine the context's preferred and
|
||||||
minimum widths. When called on this context, all child contexts
|
minimum widths. When called on this context, all child contexts
|
||||||
have had their min/pref widths set. This function must decide
|
have had their min/pref widths set. This function must decide
|
||||||
|
@ -87,14 +78,12 @@ impl BlockLayout for FlowContext {
|
||||||
/* TODO: floats */
|
/* TODO: floats */
|
||||||
/* TODO: absolute contexts */
|
/* TODO: absolute contexts */
|
||||||
/* TODO: inline-blocks */
|
/* TODO: inline-blocks */
|
||||||
fn bubble_widths_block(&self, ctx: &LayoutContext) {
|
pub fn bubble_widths_block(@mut self, ctx: &LayoutContext) {
|
||||||
assert!(self.starts_block_flow());
|
|
||||||
|
|
||||||
let mut min_width = Au(0);
|
let mut min_width = Au(0);
|
||||||
let mut pref_width = Au(0);
|
let mut pref_width = Au(0);
|
||||||
|
|
||||||
/* find max width from child block contexts */
|
/* find max width from child block contexts */
|
||||||
for self.each_child |child_ctx| {
|
for BlockFlow(self).each_child |child_ctx| {
|
||||||
assert!(child_ctx.starts_block_flow() || child_ctx.starts_inline_flow());
|
assert!(child_ctx.starts_block_flow() || child_ctx.starts_inline_flow());
|
||||||
|
|
||||||
do child_ctx.with_imm_node |child_node| {
|
do child_ctx.with_imm_node |child_node| {
|
||||||
|
@ -105,15 +94,13 @@ impl BlockLayout for FlowContext {
|
||||||
|
|
||||||
/* if not an anonymous block context, add in block box's widths.
|
/* if not an anonymous block context, add in block box's widths.
|
||||||
these widths will not include child elements, just padding etc. */
|
these widths will not include child elements, just padding etc. */
|
||||||
do self.with_block_box |box| {
|
self.box.map(|&box| {
|
||||||
min_width = min_width.add(&box.get_min_width(ctx));
|
min_width = min_width.add(&box.get_min_width(ctx));
|
||||||
pref_width = pref_width.add(&box.get_pref_width(ctx));
|
pref_width = pref_width.add(&box.get_pref_width(ctx));
|
||||||
}
|
});
|
||||||
|
|
||||||
do self.with_mut_node |this_node| {
|
self.common.min_width = min_width;
|
||||||
this_node.min_width = min_width;
|
self.common.pref_width = pref_width;
|
||||||
this_node.pref_width = pref_width;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Recursively (top-down) determines the actual width of child contexts and boxes. When called
|
/// Recursively (top-down) determines the actual width of child contexts and boxes. When called
|
||||||
|
@ -121,23 +108,26 @@ impl BlockLayout for FlowContext {
|
||||||
///
|
///
|
||||||
/// Dual boxes consume some width first, and the remainder is assigned to all child (block)
|
/// Dual boxes consume some width first, and the remainder is assigned to all child (block)
|
||||||
/// contexts.
|
/// contexts.
|
||||||
fn assign_widths_block(&self, _: &LayoutContext) {
|
pub fn assign_widths_block(@mut self, ctx: &LayoutContext) {
|
||||||
assert!(self.starts_block_flow());
|
if self.is_root {
|
||||||
|
self.common.position.origin = Au::zero_point();
|
||||||
|
self.common.position.size.width = ctx.screen_size.size.width;
|
||||||
|
}
|
||||||
|
|
||||||
let mut remaining_width = self.with_imm_node(|this| this.position.size.width);
|
let mut remaining_width = self.common.position.size.width;
|
||||||
let left_used = Au(0);
|
let left_used = Au(0);
|
||||||
|
|
||||||
// Let the box consume some width. It will return the amount remaining for its children.
|
// Let the box consume some width. It will return the amount remaining for its children.
|
||||||
do self.with_block_box |box| {
|
self.box.map(|&box| {
|
||||||
do box.with_mut_base |base| {
|
do box.with_mut_base |base| {
|
||||||
base.position.size.width = remaining_width;
|
base.position.size.width = remaining_width;
|
||||||
|
|
||||||
let (left_used, right_used) = box.get_used_width();
|
let (left_used, right_used) = box.get_used_width();
|
||||||
remaining_width -= left_used.add(&right_used);
|
remaining_width -= left_used.add(&right_used);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
for self.each_child |kid| {
|
for BlockFlow(self).each_child |kid| {
|
||||||
assert!(kid.starts_block_flow() || kid.starts_inline_flow());
|
assert!(kid.starts_block_flow() || kid.starts_inline_flow());
|
||||||
|
|
||||||
do kid.with_mut_node |child_node| {
|
do kid.with_mut_node |child_node| {
|
||||||
|
@ -147,51 +137,50 @@ impl BlockLayout for FlowContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assign_height_block(&self, _ctx: &LayoutContext) {
|
pub fn assign_height_block(@mut self, ctx: &LayoutContext) {
|
||||||
assert!(self.starts_block_flow());
|
|
||||||
|
|
||||||
let mut cur_y = Au(0);
|
let mut cur_y = Au(0);
|
||||||
|
|
||||||
for self.each_child |kid| {
|
for BlockFlow(self).each_child |kid| {
|
||||||
do kid.with_mut_node |child_node| {
|
do kid.with_mut_node |child_node| {
|
||||||
child_node.position.origin.y = cur_y;
|
child_node.position.origin.y = cur_y;
|
||||||
cur_y += child_node.position.size.height;
|
cur_y += child_node.position.size.height;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
do self.with_mut_node |this_node| {
|
let height = if self.is_root { Au::max(ctx.screen_size.size.height, cur_y) }
|
||||||
this_node.position.size.height = cur_y;
|
else { cur_y };
|
||||||
}
|
|
||||||
|
self.common.position.size.height = height;
|
||||||
|
|
||||||
let _used_top = Au(0);
|
let _used_top = Au(0);
|
||||||
let _used_bot = Au(0);
|
let _used_bot = Au(0);
|
||||||
|
|
||||||
do self.with_block_box |box| {
|
self.box.map(|&box| {
|
||||||
do box.with_mut_base |base| {
|
do box.with_mut_base |base| {
|
||||||
base.position.origin.y = Au(0);
|
base.position.origin.y = Au(0);
|
||||||
base.position.size.height = cur_y;
|
base.position.size.height = height;
|
||||||
let (_used_top, _used_bot) = box.get_used_height();
|
let (_used_top, _used_bot) = box.get_used_height();
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_display_list_block(&self,
|
pub fn build_display_list_block(@mut self,
|
||||||
builder: &DisplayListBuilder,
|
builder: &DisplayListBuilder,
|
||||||
dirty: &Rect<Au>,
|
dirty: &Rect<Au>,
|
||||||
offset: &Point2D<Au>,
|
offset: &Point2D<Au>,
|
||||||
list: &Cell<DisplayList>) {
|
list: &Cell<DisplayList>) {
|
||||||
assert!(self.starts_block_flow());
|
|
||||||
|
|
||||||
// add box that starts block context
|
// add box that starts block context
|
||||||
do self.with_block_box |box| {
|
self.box.map(|&box| {
|
||||||
box.build_display_list(builder, dirty, offset, list)
|
box.build_display_list(builder, dirty, offset, list)
|
||||||
}
|
});
|
||||||
|
|
||||||
|
|
||||||
// TODO: handle any out-of-flow elements
|
// TODO: handle any out-of-flow elements
|
||||||
|
|
||||||
// go deeper into the flow tree
|
// go deeper into the flow tree
|
||||||
for self.each_child |child| {
|
let flow = BlockFlow(self);
|
||||||
self.build_display_list_for_child(builder, child, dirty, offset, list)
|
for flow.each_child |child| {
|
||||||
|
flow.build_display_list_for_child(builder, child, dirty, offset, list)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,9 +15,8 @@ use layout::context::LayoutContext;
|
||||||
use layout::debug::{BoxedMutDebugMethods, DebugMethods};
|
use layout::debug::{BoxedMutDebugMethods, DebugMethods};
|
||||||
use layout::flow::{AbsoluteFlow, BlockFlow, FloatFlow, Flow_Absolute, Flow_Block, Flow_Float};
|
use layout::flow::{AbsoluteFlow, BlockFlow, FloatFlow, Flow_Absolute, Flow_Block, Flow_Float};
|
||||||
use layout::flow::{Flow_Inline, Flow_InlineBlock, Flow_Root, Flow_Table, FlowContext};
|
use layout::flow::{Flow_Inline, Flow_InlineBlock, Flow_Root, Flow_Table, FlowContext};
|
||||||
use layout::flow::{FlowContextType, FlowData, InlineBlockFlow, InlineFlow, RootFlow, TableFlow};
|
use layout::flow::{FlowContextType, FlowData, InlineBlockFlow, InlineFlow, TableFlow};
|
||||||
use layout::inline::{InlineFlowData, InlineLayout};
|
use layout::inline::{InlineFlowData, InlineLayout};
|
||||||
use layout::root::RootFlowData;
|
|
||||||
|
|
||||||
use newcss::values::{CSSDisplay, CSSDisplayBlock, CSSDisplayInline, CSSDisplayInlineBlock};
|
use newcss::values::{CSSDisplay, CSSDisplayBlock, CSSDisplayInline, CSSDisplayInlineBlock};
|
||||||
use newcss::values::{CSSDisplayNone};
|
use newcss::values::{CSSDisplayNone};
|
||||||
|
@ -153,18 +152,6 @@ impl BoxGenerator {
|
||||||
assert!(block.box.is_none());
|
assert!(block.box.is_none());
|
||||||
block.box = Some(new_box);
|
block.box = Some(new_box);
|
||||||
},
|
},
|
||||||
RootFlow(root) => {
|
|
||||||
debug!("BoxGenerator[f%d]: point c", root.common.id);
|
|
||||||
let new_box = builder.make_box(ctx, box_type, node, self.flow);
|
|
||||||
debug!("BoxGenerator[f%d]: (node is: %s)", root.common.id, node.debug_str());
|
|
||||||
debug!("BoxGenerator[f%d]: attaching box[b%d] to root flow (node: %s)",
|
|
||||||
root.common.id,
|
|
||||||
new_box.id(),
|
|
||||||
node.debug_str());
|
|
||||||
|
|
||||||
assert!(root.box.is_none());
|
|
||||||
root.box = Some(new_box);
|
|
||||||
},
|
|
||||||
_ => warn!("push_node() not implemented for flow f%d", self.flow.id()),
|
_ => warn!("push_node() not implemented for flow f%d", self.flow.id()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,7 +182,7 @@ impl BoxGenerator {
|
||||||
debug!("BoxGenerator: adding element range=%?", node_range);
|
debug!("BoxGenerator: adding element range=%?", node_range);
|
||||||
inline.elems.add_mapping(node, &node_range);
|
inline.elems.add_mapping(node, &node_range);
|
||||||
},
|
},
|
||||||
BlockFlow(*) | RootFlow(*) => assert!(self.range_stack.len() == 0),
|
BlockFlow(*) => assert!(self.range_stack.len() == 0),
|
||||||
_ => warn!("pop_node() not implemented for flow %?", self.flow.id()),
|
_ => warn!("pop_node() not implemented for flow %?", self.flow.id()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -279,18 +266,16 @@ impl BuilderContext {
|
||||||
};
|
};
|
||||||
|
|
||||||
let containing_context = match (simulated_display, self.default_collector.flow) {
|
let containing_context = match (simulated_display, self.default_collector.flow) {
|
||||||
(CSSDisplayBlock, RootFlow(*)) => {
|
(CSSDisplayBlock, BlockFlow(info)) => match (info.is_root, node.parent_node()) {
|
||||||
// If this is the root node, then use the root flow's
|
// If this is the root node, then use the root flow's
|
||||||
// context. Otherwise, make a child block context.
|
// context. Otherwise, make a child block context.
|
||||||
match node.parent_node() {
|
(true, Some(_)) => { self.create_child_flow_of_type(Flow_Block, builder, node) }
|
||||||
Some(_) => { self.create_child_flow_of_type(Flow_Block, builder, node) }
|
(true, None) => { self.clone() }
|
||||||
None => { self.clone() },
|
(false, _) => {
|
||||||
|
self.clear_inline_collector();
|
||||||
|
self.create_child_flow_of_type(Flow_Block, builder, node)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(CSSDisplayBlock, BlockFlow(*)) => {
|
|
||||||
self.clear_inline_collector();
|
|
||||||
self.create_child_flow_of_type(Flow_Block, builder, node)
|
|
||||||
},
|
|
||||||
(CSSDisplayInline, InlineFlow(*)) => self.clone(),
|
(CSSDisplayInline, InlineFlow(*)) => self.clone(),
|
||||||
(CSSDisplayInlineBlock, InlineFlow(*)) => self.clone(),
|
(CSSDisplayInlineBlock, InlineFlow(*)) => self.clone(),
|
||||||
(CSSDisplayInline, BlockFlow(*)) => self.get_inline_collector(builder, node),
|
(CSSDisplayInline, BlockFlow(*)) => self.get_inline_collector(builder, node),
|
||||||
|
@ -453,7 +438,7 @@ pub impl LayoutTreeBuilder {
|
||||||
Flow_Float => FloatFlow(@mut info),
|
Flow_Float => FloatFlow(@mut info),
|
||||||
Flow_InlineBlock => InlineBlockFlow(@mut info),
|
Flow_InlineBlock => InlineBlockFlow(@mut info),
|
||||||
Flow_Inline => InlineFlow(@mut InlineFlowData::new(info)),
|
Flow_Inline => InlineFlow(@mut InlineFlowData::new(info)),
|
||||||
Flow_Root => RootFlow(@mut RootFlowData::new(info)),
|
Flow_Root => BlockFlow(@mut BlockFlowData::new_root(info)),
|
||||||
Flow_Table => TableFlow(@mut info),
|
Flow_Table => TableFlow(@mut info),
|
||||||
};
|
};
|
||||||
debug!("LayoutTreeBuilder: created flow: %s", result.debug_str());
|
debug!("LayoutTreeBuilder: created flow: %s", result.debug_str());
|
||||||
|
|
|
@ -17,24 +17,21 @@
|
||||||
/// * `BlockFlow`: A flow that establishes a block context. It has several child flows, each of
|
/// * `BlockFlow`: A flow that establishes a block context. It has several child flows, each of
|
||||||
/// which are positioned according to block formatting context rules (CSS block boxes). Block
|
/// which are positioned according to block formatting context rules (CSS block boxes). Block
|
||||||
/// flows also contain a single `GenericBox` to represent their rendered borders, padding, etc.
|
/// flows also contain a single `GenericBox` to represent their rendered borders, padding, etc.
|
||||||
/// (In the future, this render box may be folded into `BlockFlow` to save space.)
|
/// (In the future, this render box may be folded into `BlockFlow` to save space.) The BlockFlow
|
||||||
|
/// at the root of the tree has special behavior: it stretches to the boundaries of the viewport.
|
||||||
///
|
///
|
||||||
/// * `InlineFlow`: A flow that establishes an inline context. It has a flat list of child
|
/// * `InlineFlow`: A flow that establishes an inline context. It has a flat list of child
|
||||||
/// boxes/flows that are subject to inline layout and line breaking and structs to represent
|
/// boxes/flows that are subject to inline layout and line breaking and structs to represent
|
||||||
/// line breaks and mapping to CSS boxes, for the purpose of handling `getClientRects()` and
|
/// line breaks and mapping to CSS boxes, for the purpose of handling `getClientRects()` and
|
||||||
/// similar methods.
|
/// similar methods.
|
||||||
///
|
|
||||||
/// * `RootFlow`: The flow at the root of the tree. This flow behaves like a `BlockFlow`, except
|
|
||||||
/// that stretches to the boundaries of the viewport.
|
|
||||||
|
|
||||||
use dom::node::AbstractNode;
|
use dom::node::AbstractNode;
|
||||||
use layout::block::{BlockFlowData, BlockLayout};
|
use layout::block::{BlockFlowData};
|
||||||
use layout::box::RenderBox;
|
use layout::box::RenderBox;
|
||||||
use layout::context::LayoutContext;
|
use layout::context::LayoutContext;
|
||||||
use layout::debug::DebugMethods;
|
use layout::debug::DebugMethods;
|
||||||
use layout::display_list_builder::DisplayListBuilder;
|
use layout::display_list_builder::DisplayListBuilder;
|
||||||
use layout::inline::{InlineFlowData};
|
use layout::inline::{InlineFlowData};
|
||||||
use layout::root::{RootFlowData};
|
|
||||||
|
|
||||||
use core::cell::Cell;
|
use core::cell::Cell;
|
||||||
use geom::point::Point2D;
|
use geom::point::Point2D;
|
||||||
|
@ -51,7 +48,6 @@ pub enum FlowContext {
|
||||||
FloatFlow(@mut FlowData),
|
FloatFlow(@mut FlowData),
|
||||||
InlineBlockFlow(@mut FlowData),
|
InlineBlockFlow(@mut FlowData),
|
||||||
InlineFlow(@mut InlineFlowData),
|
InlineFlow(@mut InlineFlowData),
|
||||||
RootFlow(@mut RootFlowData),
|
|
||||||
TableFlow(@mut FlowData),
|
TableFlow(@mut FlowData),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,10 +79,7 @@ impl TreeNodeRef<FlowData> for FlowContext {
|
||||||
InlineFlow(info) => {
|
InlineFlow(info) => {
|
||||||
callback(&info.common)
|
callback(&info.common)
|
||||||
}
|
}
|
||||||
RootFlow(info) => {
|
TableFlow(info) => callback(info)
|
||||||
callback(&info.common)
|
|
||||||
}
|
|
||||||
TableFlow(info) => callback(info),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn with_mut_node<R>(&self, callback: &fn(&mut FlowData) -> R) -> R {
|
fn with_mut_node<R>(&self, callback: &fn(&mut FlowData) -> R) -> R {
|
||||||
|
@ -100,9 +93,6 @@ impl TreeNodeRef<FlowData> for FlowContext {
|
||||||
InlineFlow(info) => {
|
InlineFlow(info) => {
|
||||||
callback(&mut info.common)
|
callback(&mut info.common)
|
||||||
}
|
}
|
||||||
RootFlow(info) => {
|
|
||||||
callback(&mut info.common)
|
|
||||||
}
|
|
||||||
TableFlow(info) => callback(info),
|
TableFlow(info) => callback(info),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -227,36 +217,33 @@ impl<'self> FlowContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn root(&self) -> @mut RootFlowData {
|
pub fn root(&self) -> @mut BlockFlowData {
|
||||||
match *self {
|
match *self {
|
||||||
RootFlow(info) => info,
|
BlockFlow(info) if info.is_root => info,
|
||||||
_ => fail!(fmt!("Tried to access root data of non-root: f%d", self.id()))
|
_ => fail!(fmt!("Tried to access root block data of non-root: f%d", self.id()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bubble_widths(&self, ctx: &mut LayoutContext) {
|
pub fn bubble_widths(&self, ctx: &mut LayoutContext) {
|
||||||
match *self {
|
match *self {
|
||||||
BlockFlow(*) => self.bubble_widths_block(ctx),
|
BlockFlow(info) => info.bubble_widths_block(ctx),
|
||||||
InlineFlow(info) => info.bubble_widths_inline(ctx),
|
InlineFlow(info) => info.bubble_widths_inline(ctx),
|
||||||
RootFlow(info) => info.bubble_widths_root(ctx),
|
|
||||||
_ => fail!(fmt!("Tried to bubble_widths of flow: f%d", self.id()))
|
_ => fail!(fmt!("Tried to bubble_widths of flow: f%d", self.id()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assign_widths(&self, ctx: &mut LayoutContext) {
|
pub fn assign_widths(&self, ctx: &mut LayoutContext) {
|
||||||
match *self {
|
match *self {
|
||||||
BlockFlow(*) => self.assign_widths_block(ctx),
|
BlockFlow(info) => info.assign_widths_block(ctx),
|
||||||
InlineFlow(info) => info.assign_widths_inline(ctx),
|
InlineFlow(info) => info.assign_widths_inline(ctx),
|
||||||
RootFlow(info) => info.assign_widths_root(ctx),
|
|
||||||
_ => fail!(fmt!("Tried to assign_widths of flow: f%d", self.id()))
|
_ => fail!(fmt!("Tried to assign_widths of flow: f%d", self.id()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn assign_height(&self, ctx: &mut LayoutContext) {
|
pub fn assign_height(&self, ctx: &mut LayoutContext) {
|
||||||
match *self {
|
match *self {
|
||||||
BlockFlow(*) => self.assign_height_block(ctx),
|
BlockFlow(info) => info.assign_height_block(ctx),
|
||||||
InlineFlow(info) => info.assign_height_inline(ctx),
|
InlineFlow(info) => info.assign_height_inline(ctx),
|
||||||
RootFlow(info) => info.assign_height_root(ctx),
|
|
||||||
_ => fail!(fmt!("Tried to assign_height of flow: f%d", self.id()))
|
_ => fail!(fmt!("Tried to assign_height of flow: f%d", self.id()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -271,8 +258,7 @@ impl<'self> FlowContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
match *self {
|
match *self {
|
||||||
RootFlow(info) => info.build_display_list_root(builder, dirty, offset, list),
|
BlockFlow(info) => info.build_display_list_block(builder, dirty, offset, list),
|
||||||
BlockFlow(*) => self.build_display_list_block(builder, dirty, offset, list),
|
|
||||||
InlineFlow(info) => info.build_display_list_inline(builder, dirty, offset, list),
|
InlineFlow(info) => info.build_display_list_inline(builder, dirty, offset, list),
|
||||||
_ => fail!(fmt!("Tried to build_display_list_recurse of flow: %?", self))
|
_ => fail!(fmt!("Tried to build_display_list_recurse of flow: %?", self))
|
||||||
}
|
}
|
||||||
|
@ -281,12 +267,6 @@ impl<'self> FlowContext {
|
||||||
// Actual methods that do not require much flow-specific logic
|
// Actual methods that do not require much flow-specific logic
|
||||||
pub fn foldl_all_boxes<B:Copy>(&self, seed: B, cb: &fn(a: B, b: RenderBox) -> B) -> B {
|
pub fn foldl_all_boxes<B:Copy>(&self, seed: B, cb: &fn(a: B, b: RenderBox) -> B) -> B {
|
||||||
match *self {
|
match *self {
|
||||||
RootFlow(root) => {
|
|
||||||
let root = &mut *root;
|
|
||||||
do root.box.map_default(seed) |box| {
|
|
||||||
cb(seed, *box)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BlockFlow(block) => {
|
BlockFlow(block) => {
|
||||||
let block = &mut *block;
|
let block = &mut *block;
|
||||||
do block.box.map_default(seed) |box| {
|
do block.box.map_default(seed) |box| {
|
||||||
|
@ -319,14 +299,6 @@ impl<'self> FlowContext {
|
||||||
|
|
||||||
pub fn iter_all_boxes(&self, cb: &fn(RenderBox) -> bool) {
|
pub fn iter_all_boxes(&self, cb: &fn(RenderBox) -> bool) {
|
||||||
match *self {
|
match *self {
|
||||||
RootFlow(root) => {
|
|
||||||
let root = &mut *root;
|
|
||||||
for root.box.each |box| {
|
|
||||||
if !cb(*box) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
BlockFlow(block) => {
|
BlockFlow(block) => {
|
||||||
let block = &mut *block;
|
let block = &mut *block;
|
||||||
for block.box.each |box| {
|
for block.box.each |box| {
|
||||||
|
@ -394,12 +366,6 @@ impl DebugMethods for FlowContext {
|
||||||
None => ~"BlockFlow",
|
None => ~"BlockFlow",
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
RootFlow(root) => {
|
|
||||||
match root.box {
|
|
||||||
Some(box) => fmt!("RootFlow(box=b%d)", box.id()),
|
|
||||||
None => ~"RootFlow",
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => ~"(Unknown flow)"
|
_ => ~"(Unknown flow)"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,91 +0,0 @@
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
use core::cell::Cell;
|
|
||||||
use geom::point::Point2D;
|
|
||||||
use geom::rect::Rect;
|
|
||||||
use gfx::display_list::DisplayList;
|
|
||||||
use gfx::geometry::Au;
|
|
||||||
use layout::block::BlockLayout;
|
|
||||||
use layout::box::RenderBox;
|
|
||||||
use layout::context::LayoutContext;
|
|
||||||
use layout::flow::{FlowContext, FlowData, RootFlow};
|
|
||||||
use layout::display_list_builder::DisplayListBuilder;
|
|
||||||
|
|
||||||
use servo_util::tree::{TreeNodeRef, TreeUtils};
|
|
||||||
|
|
||||||
pub struct RootFlowData {
|
|
||||||
/// Data common to all flows.
|
|
||||||
common: FlowData,
|
|
||||||
|
|
||||||
/// The render box at the root of the tree.
|
|
||||||
box: Option<RenderBox>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RootFlowData {
|
|
||||||
pub fn new(common: FlowData) -> RootFlowData {
|
|
||||||
RootFlowData {
|
|
||||||
common: common,
|
|
||||||
box: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait RootLayout {
|
|
||||||
fn starts_root_flow(&self) -> bool;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RootLayout for FlowContext {
|
|
||||||
fn starts_root_flow(&self) -> bool {
|
|
||||||
match *self {
|
|
||||||
RootFlow(*) => true,
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RootFlowData {
|
|
||||||
/// Defer to the block algorithm.
|
|
||||||
pub fn bubble_widths_root(@mut self, ctx: &LayoutContext) {
|
|
||||||
RootFlow(self).bubble_widths_block(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn assign_widths_root(@mut self, ctx: &LayoutContext) {
|
|
||||||
self.common.position.origin = Au::zero_point();
|
|
||||||
self.common.position.size.width = ctx.screen_size.size.width;
|
|
||||||
|
|
||||||
RootFlow(self).assign_widths_block(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn assign_height_root(@mut self, ctx: &LayoutContext) {
|
|
||||||
// this is essentially the same as assign_height_block(), except
|
|
||||||
// the root adjusts self height to at least cover the viewport.
|
|
||||||
let mut cur_y = Au(0);
|
|
||||||
|
|
||||||
for RootFlow(self).each_child |child_flow| {
|
|
||||||
do child_flow.with_mut_node |child_node| {
|
|
||||||
child_node.position.origin.y = cur_y;
|
|
||||||
cur_y += child_node.position.size.height;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.common.position.size.height = Au::max(ctx.screen_size.size.height, cur_y);
|
|
||||||
|
|
||||||
do RootFlow(self).with_block_box |box| {
|
|
||||||
do box.with_mut_base |base| {
|
|
||||||
base.position.origin.y = Au(0);
|
|
||||||
base.position.size.height = Au::max(ctx.screen_size.size.height, cur_y);
|
|
||||||
let (_used_top, _used_bot) = box.get_used_height();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build_display_list_root(@mut self,
|
|
||||||
builder: &DisplayListBuilder,
|
|
||||||
dirty: &Rect<Au>,
|
|
||||||
offset: &Point2D<Au>,
|
|
||||||
list: &Cell<DisplayList>) {
|
|
||||||
RootFlow(self).build_display_list_block(builder, dirty, offset, list);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -111,7 +111,6 @@ pub mod layout {
|
||||||
pub mod flow;
|
pub mod flow;
|
||||||
pub mod layout_task;
|
pub mod layout_task;
|
||||||
pub mod inline;
|
pub mod inline;
|
||||||
pub mod root;
|
|
||||||
pub mod text;
|
pub mod text;
|
||||||
mod aux;
|
mod aux;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue