mirror of
https://github.com/servo/servo.git
synced 2025-06-19 14:48:59 +01:00
Remove 'FloatFlow'
Removes 'FloatFlow' in favor of FloatBlockFlow, which is cointained inside BlockFlow in a 'has-a' relationship. This avoids a bunch of duplicated code. This patch is for: https://github.com/mozilla/servo/issues/1281
This commit is contained in:
parent
a0c6075b4d
commit
ac45d70a4a
5 changed files with 321 additions and 412 deletions
|
@ -10,7 +10,7 @@ use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
|
||||||
use layout::flow::{BlockFlowClass, FlowClass, Flow, FlowData, ImmutableFlowUtils};
|
use layout::flow::{BlockFlowClass, FlowClass, Flow, FlowData, ImmutableFlowUtils};
|
||||||
use layout::flow;
|
use layout::flow;
|
||||||
use layout::model::{MaybeAuto, Specified, Auto, specified_or_none, specified};
|
use layout::model::{MaybeAuto, Specified, Auto, specified_or_none, specified};
|
||||||
use layout::float_context::{FloatContext, Invalid};
|
use layout::float_context::{FloatContext, PlacementInfo, Invalid, FloatType};
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use geom::point::Point2D;
|
use geom::point::Point2D;
|
||||||
|
@ -20,6 +20,34 @@ use gfx::display_list::DisplayList;
|
||||||
use servo_util::geometry::{Au, to_frac_px};
|
use servo_util::geometry::{Au, to_frac_px};
|
||||||
use servo_util::geometry;
|
use servo_util::geometry;
|
||||||
|
|
||||||
|
pub struct FloatedBlockInfo {
|
||||||
|
containing_width: Au,
|
||||||
|
|
||||||
|
/// Offset relative to where the parent tried to position this flow
|
||||||
|
rel_pos: Point2D<Au>,
|
||||||
|
|
||||||
|
/// Index into the box list for inline floats
|
||||||
|
index: Option<uint>,
|
||||||
|
|
||||||
|
/// Number of floated children
|
||||||
|
floated_children: uint,
|
||||||
|
|
||||||
|
/// Left or right?
|
||||||
|
float_type: FloatType
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FloatedBlockInfo {
|
||||||
|
pub fn new(float_type: FloatType) -> FloatedBlockInfo {
|
||||||
|
FloatedBlockInfo {
|
||||||
|
containing_width: Au(0),
|
||||||
|
rel_pos: Point2D(Au(0), Au(0)),
|
||||||
|
index: None,
|
||||||
|
floated_children: 0,
|
||||||
|
float_type: float_type
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct BlockFlow {
|
pub struct BlockFlow {
|
||||||
/// Data common to all flows.
|
/// Data common to all flows.
|
||||||
base: FlowData,
|
base: FlowData,
|
||||||
|
@ -28,7 +56,10 @@ pub struct BlockFlow {
|
||||||
box: Option<@RenderBox>,
|
box: Option<@RenderBox>,
|
||||||
|
|
||||||
/// Whether this block flow is the root flow.
|
/// Whether this block flow is the root flow.
|
||||||
is_root: bool
|
is_root: bool,
|
||||||
|
|
||||||
|
// Additional floating flow members.
|
||||||
|
float: Option<~FloatedBlockInfo>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockFlow {
|
impl BlockFlow {
|
||||||
|
@ -36,7 +67,8 @@ impl BlockFlow {
|
||||||
BlockFlow {
|
BlockFlow {
|
||||||
base: base,
|
base: base,
|
||||||
box: None,
|
box: None,
|
||||||
is_root: false
|
is_root: false,
|
||||||
|
float: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +76,17 @@ impl BlockFlow {
|
||||||
BlockFlow {
|
BlockFlow {
|
||||||
base: base,
|
base: base,
|
||||||
box: Some(box),
|
box: Some(box),
|
||||||
is_root: false
|
is_root: false,
|
||||||
|
float: None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn float_from_box(base: FlowData, float_type: FloatType, box: @RenderBox) -> BlockFlow {
|
||||||
|
BlockFlow {
|
||||||
|
base: base,
|
||||||
|
box: Some(box),
|
||||||
|
is_root: false,
|
||||||
|
float: Some(~FloatedBlockInfo::new(float_type))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,15 +94,30 @@ impl BlockFlow {
|
||||||
BlockFlow {
|
BlockFlow {
|
||||||
base: base,
|
base: base,
|
||||||
box: None,
|
box: None,
|
||||||
is_root: true
|
is_root: true,
|
||||||
|
float: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_float(base: FlowData, float_type: FloatType) -> BlockFlow {
|
||||||
|
BlockFlow {
|
||||||
|
base: base,
|
||||||
|
box: None,
|
||||||
|
is_root: false,
|
||||||
|
float: Some(~FloatedBlockInfo::new(float_type))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_float(&self) -> bool {
|
||||||
|
self.float.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn teardown(&mut self) {
|
pub fn teardown(&mut self) {
|
||||||
for box in self.box.iter() {
|
for box in self.box.iter() {
|
||||||
box.teardown();
|
box.teardown();
|
||||||
}
|
}
|
||||||
self.box = None;
|
self.box = None;
|
||||||
|
self.float = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes left and right margins and width based on CSS 2.1 section 10.3.3.
|
/// Computes left and right margins and width based on CSS 2.1 section 10.3.3.
|
||||||
|
@ -115,6 +172,63 @@ impl BlockFlow {
|
||||||
(width_Au, left_margin_Au, right_margin_Au)
|
(width_Au, left_margin_Au, right_margin_Au)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn compute_block_margins(&self, box: @RenderBox, remaining_width: Au, available_width: Au) -> (Au, Au, Au) {
|
||||||
|
let base = box.base();
|
||||||
|
let style = base.style();
|
||||||
|
|
||||||
|
let (width, maybe_margin_left, maybe_margin_right) =
|
||||||
|
(MaybeAuto::from_style(style.Box.width, remaining_width),
|
||||||
|
MaybeAuto::from_style(style.Margin.margin_left, remaining_width),
|
||||||
|
MaybeAuto::from_style(style.Margin.margin_right, remaining_width));
|
||||||
|
|
||||||
|
let (width, margin_left, margin_right) = self.compute_horiz(width,
|
||||||
|
maybe_margin_left,
|
||||||
|
maybe_margin_right,
|
||||||
|
available_width);
|
||||||
|
|
||||||
|
// If the tentative used width is greater than 'max-width', width should be recalculated,
|
||||||
|
// but this time using the computed value of 'max-width' as the computed value for 'width'.
|
||||||
|
let (width, margin_left, margin_right) = {
|
||||||
|
match specified_or_none(style.Box.max_width, remaining_width) {
|
||||||
|
Some(value) if value < width => self.compute_horiz(Specified(value),
|
||||||
|
maybe_margin_left,
|
||||||
|
maybe_margin_right,
|
||||||
|
available_width),
|
||||||
|
_ => (width, margin_left, margin_right)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// If the resulting width is smaller than 'min-width', width should be recalculated,
|
||||||
|
// but this time using the value of 'min-width' as the computed value for 'width'.
|
||||||
|
let (width, margin_left, margin_right) = {
|
||||||
|
let computed_min_width = specified(style.Box.min_width, remaining_width);
|
||||||
|
if computed_min_width > width {
|
||||||
|
self.compute_horiz(Specified(computed_min_width),
|
||||||
|
maybe_margin_left,
|
||||||
|
maybe_margin_right,
|
||||||
|
available_width)
|
||||||
|
} else {
|
||||||
|
(width, margin_left, margin_right)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (width, margin_left, margin_right);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn compute_float_margins(&self, box: @RenderBox, remaining_width: Au) -> (Au, Au, Au) {
|
||||||
|
let style = box.base().style();
|
||||||
|
let margin_left = MaybeAuto::from_style(style.Margin.margin_left,
|
||||||
|
remaining_width).specified_or_zero();
|
||||||
|
let margin_right = MaybeAuto::from_style(style.Margin.margin_right,
|
||||||
|
remaining_width).specified_or_zero();
|
||||||
|
let shrink_to_fit = geometry::min(self.base.pref_width,
|
||||||
|
geometry::max(self.base.min_width, remaining_width));
|
||||||
|
let width = MaybeAuto::from_style(style.Box.width,
|
||||||
|
remaining_width).specified_or_default(shrink_to_fit);
|
||||||
|
debug!("assign_widths_float -- width: {}", width);
|
||||||
|
return (width, margin_left, margin_right);
|
||||||
|
}
|
||||||
|
|
||||||
// inline(always) because this is only ever called by in-order or non-in-order top-level
|
// inline(always) because this is only ever called by in-order or non-in-order top-level
|
||||||
// methods
|
// methods
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
|
@ -252,12 +366,104 @@ impl BlockFlow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn assign_height_float_inorder(&mut self) {
|
||||||
|
// assign_height_float was already called by the traversal function
|
||||||
|
// so this is well-defined
|
||||||
|
|
||||||
|
let mut height = Au(0);
|
||||||
|
let mut clearance = Au(0);
|
||||||
|
let mut full_noncontent_width = Au(0);
|
||||||
|
let mut margin_height = Au(0);
|
||||||
|
|
||||||
|
for box in self.box.iter() {
|
||||||
|
let base = box.base();
|
||||||
|
height = base.position.borrow().ptr.size.height;
|
||||||
|
clearance = match base.clear() {
|
||||||
|
None => Au(0),
|
||||||
|
Some(clear) => self.base.floats_in.clearance(clear),
|
||||||
|
};
|
||||||
|
|
||||||
|
let noncontent_width = base.padding.left + base.padding.right + base.border.left +
|
||||||
|
base.border.right;
|
||||||
|
|
||||||
|
full_noncontent_width = noncontent_width + base.margin.left + base.margin.right;
|
||||||
|
margin_height = base.margin.top + base.margin.bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
let info = PlacementInfo {
|
||||||
|
width: self.base.position.size.width + full_noncontent_width,
|
||||||
|
height: height + margin_height,
|
||||||
|
ceiling: clearance,
|
||||||
|
max_width: self.float.get_ref().containing_width,
|
||||||
|
f_type: self.float.get_ref().float_type,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Place the float and return the FloatContext back to the parent flow.
|
||||||
|
// After, grab the position and use that to set our position.
|
||||||
|
self.base.floats_out = self.base.floats_in.add_float(&info);
|
||||||
|
self.float.get_mut_ref().rel_pos = self.base.floats_out.last_float_pos();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn assign_height_float(&mut self, ctx: &mut LayoutContext) {
|
||||||
|
// Now that we've determined our height, propagate that out.
|
||||||
|
let has_inorder_children = self.base.num_floats > 0;
|
||||||
|
if has_inorder_children {
|
||||||
|
let mut float_ctx = FloatContext::new(self.float.get_ref().floated_children);
|
||||||
|
for kid in self.base.child_iter() {
|
||||||
|
flow::mut_base(*kid).floats_in = float_ctx.clone();
|
||||||
|
kid.assign_height_inorder(ctx);
|
||||||
|
float_ctx = flow::mut_base(*kid).floats_out.clone();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut cur_y = Au(0);
|
||||||
|
let mut top_offset = Au(0);
|
||||||
|
|
||||||
|
for &box in self.box.iter() {
|
||||||
|
let base = box.base();
|
||||||
|
top_offset = base.margin.top + base.border.top + base.padding.top;
|
||||||
|
cur_y = cur_y + top_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
for kid in self.base.child_iter() {
|
||||||
|
let child_base = flow::mut_base(*kid);
|
||||||
|
child_base.position.origin.y = cur_y;
|
||||||
|
cur_y = cur_y + child_base.position.size.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut height = cur_y - top_offset;
|
||||||
|
|
||||||
|
let mut noncontent_height;
|
||||||
|
let box = self.box.as_ref().unwrap();
|
||||||
|
let base = box.base();
|
||||||
|
let mut position_ref = base.position.mutate();
|
||||||
|
let position = &mut position_ref.ptr;
|
||||||
|
|
||||||
|
// The associated box is the border box of this flow.
|
||||||
|
position.origin.y = base.margin.top;
|
||||||
|
|
||||||
|
noncontent_height = base.padding.top + base.padding.bottom + base.border.top +
|
||||||
|
base.border.bottom;
|
||||||
|
|
||||||
|
//TODO(eatkinson): compute heights properly using the 'height' property.
|
||||||
|
let height_prop = MaybeAuto::from_style(base.style().Box.height,
|
||||||
|
Au::new(0)).specified_or_zero();
|
||||||
|
|
||||||
|
height = geometry::max(height, height_prop) + noncontent_height;
|
||||||
|
debug!("assign_height_float -- height: {}", height);
|
||||||
|
|
||||||
|
position.size.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn build_display_list_block<E:ExtraDisplayListData>(
|
pub fn build_display_list_block<E:ExtraDisplayListData>(
|
||||||
&mut self,
|
&mut self,
|
||||||
builder: &DisplayListBuilder,
|
builder: &DisplayListBuilder,
|
||||||
dirty: &Rect<Au>,
|
dirty: &Rect<Au>,
|
||||||
list: &Cell<DisplayList<E>>)
|
list: &Cell<DisplayList<E>>)
|
||||||
-> bool {
|
-> bool {
|
||||||
|
if self.is_float() {
|
||||||
|
return self.build_display_list_float(builder, dirty, list);
|
||||||
|
}
|
||||||
|
|
||||||
if self.base.node.is_iframe_element() {
|
if self.base.node.is_iframe_element() {
|
||||||
let x = self.base.abs_position.x + do self.box.map_default(Au::new(0)) |box| {
|
let x = self.base.abs_position.x + do self.box.map_default(Au::new(0)) |box| {
|
||||||
let base = box.base();
|
let base = box.base();
|
||||||
|
@ -302,6 +508,39 @@ impl BlockFlow {
|
||||||
|
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn build_display_list_float<E:ExtraDisplayListData>(&mut self,
|
||||||
|
builder: &DisplayListBuilder,
|
||||||
|
dirty: &Rect<Au>,
|
||||||
|
list: &Cell<DisplayList<E>>)
|
||||||
|
-> bool {
|
||||||
|
//TODO: implement iframe size messaging
|
||||||
|
if self.base.node.is_iframe_element() {
|
||||||
|
error!("float iframe size messaging not implemented yet");
|
||||||
|
}
|
||||||
|
let abs_rect = Rect(self.base.abs_position, self.base.position.size);
|
||||||
|
if !abs_rect.intersects(dirty) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
let offset = self.base.abs_position + self.float.get_ref().rel_pos;
|
||||||
|
// add box that starts block context
|
||||||
|
for box in self.box.iter() {
|
||||||
|
box.build_display_list(builder, dirty, &offset, list)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO: handle any out-of-flow elements
|
||||||
|
|
||||||
|
// go deeper into the flow tree
|
||||||
|
for child in self.base.child_iter() {
|
||||||
|
let child_base = flow::mut_base(*child);
|
||||||
|
child_base.abs_position = offset + child_base.position.origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Flow for BlockFlow {
|
impl Flow for BlockFlow {
|
||||||
|
@ -334,10 +573,16 @@ impl Flow for BlockFlow {
|
||||||
let child_base = flow::mut_base(*child_ctx);
|
let child_base = flow::mut_base(*child_ctx);
|
||||||
min_width = geometry::max(min_width, child_base.min_width);
|
min_width = geometry::max(min_width, child_base.min_width);
|
||||||
pref_width = geometry::max(pref_width, child_base.pref_width);
|
pref_width = geometry::max(pref_width, child_base.pref_width);
|
||||||
|
|
||||||
num_floats = num_floats + child_base.num_floats;
|
num_floats = num_floats + child_base.num_floats;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.is_float() {
|
||||||
|
self.base.num_floats = 1;
|
||||||
|
self.float.get_mut_ref().floated_children = num_floats;
|
||||||
|
} else {
|
||||||
|
self.base.num_floats = num_floats;
|
||||||
|
}
|
||||||
|
|
||||||
/* 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. */
|
||||||
for box in self.box.iter() {
|
for box in self.box.iter() {
|
||||||
|
@ -355,16 +600,20 @@ impl Flow for BlockFlow {
|
||||||
|
|
||||||
self.base.min_width = min_width;
|
self.base.min_width = min_width;
|
||||||
self.base.pref_width = pref_width;
|
self.base.pref_width = pref_width;
|
||||||
self.base.num_floats = num_floats;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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
|
||||||
/// on this context, the context has had its width set by the parent context.
|
/// on this context, the context has had its width set by the parent context.
|
||||||
///
|
///
|
||||||
/// 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(&mut self, ctx: &mut LayoutContext) {
|
fn assign_widths(&mut self, ctx: &mut LayoutContext) {
|
||||||
debug!("assign_widths_block: assigning width for flow {}", self.base.id);
|
if self.is_float() {
|
||||||
|
debug!("assign_widths_float: assigning width for flow {}", self.base.id);
|
||||||
|
} else {
|
||||||
|
debug!("assign_widths_block: assigning width for flow {}", self.base.id);
|
||||||
|
}
|
||||||
|
|
||||||
if self.is_root {
|
if self.is_root {
|
||||||
debug!("Setting root position");
|
debug!("Setting root position");
|
||||||
self.base.position.origin = Au::zero_point();
|
self.base.position.origin = Au::zero_point();
|
||||||
|
@ -377,12 +626,19 @@ impl Flow for BlockFlow {
|
||||||
let mut remaining_width = self.base.position.size.width;
|
let mut remaining_width = self.base.position.size.width;
|
||||||
let mut x_offset = Au::new(0);
|
let mut x_offset = Au::new(0);
|
||||||
|
|
||||||
|
if self.is_float() {
|
||||||
|
// Parent usually sets this, but floats are never inorder
|
||||||
|
self.base.is_inorder = false;
|
||||||
|
}
|
||||||
|
|
||||||
for &box in self.box.iter() {
|
for &box in self.box.iter() {
|
||||||
let base = box.mut_base();
|
let base = box.base();
|
||||||
|
let mut_base = box.mut_base();
|
||||||
let style = base.style();
|
let style = base.style();
|
||||||
|
let mut_position = &mut base.position.mutate().ptr;
|
||||||
|
|
||||||
// Can compute padding here since we know containing block width.
|
// Can compute padding here since we know containing block width.
|
||||||
base.compute_padding(style, remaining_width);
|
mut_base.compute_padding(style, remaining_width);
|
||||||
|
|
||||||
// Margins are 0 right now so base.noncontent_width() is just borders + padding.
|
// Margins are 0 right now so base.noncontent_width() is just borders + padding.
|
||||||
let available_width = remaining_width - base.noncontent_width();
|
let available_width = remaining_width - base.noncontent_width();
|
||||||
|
@ -393,58 +649,38 @@ impl Flow for BlockFlow {
|
||||||
let margin_bottom = MaybeAuto::from_style(style.Margin.margin_bottom,
|
let margin_bottom = MaybeAuto::from_style(style.Margin.margin_bottom,
|
||||||
remaining_width).specified_or_zero();
|
remaining_width).specified_or_zero();
|
||||||
|
|
||||||
let (width, maybe_margin_left, maybe_margin_right) =
|
let (width, margin_left, margin_right) = if self.is_float() {
|
||||||
(MaybeAuto::from_style(style.Box.width, remaining_width),
|
self.compute_float_margins(box, remaining_width)
|
||||||
MaybeAuto::from_style(style.Margin.margin_left, remaining_width),
|
} else {
|
||||||
MaybeAuto::from_style(style.Margin.margin_right, remaining_width));
|
self.compute_block_margins(box, remaining_width, available_width)
|
||||||
|
|
||||||
let (width, margin_left, margin_right) = self.compute_horiz(width,
|
|
||||||
maybe_margin_left,
|
|
||||||
maybe_margin_right,
|
|
||||||
available_width);
|
|
||||||
|
|
||||||
// If the tentative used width is greater than 'max-width', width should be recalculated,
|
|
||||||
// but this time using the computed value of 'max-width' as the computed value for 'width'.
|
|
||||||
let (width, margin_left, margin_right) = {
|
|
||||||
match specified_or_none(style.Box.max_width, remaining_width) {
|
|
||||||
Some(value) if value < width => self.compute_horiz(Specified(value),
|
|
||||||
maybe_margin_left,
|
|
||||||
maybe_margin_right,
|
|
||||||
available_width),
|
|
||||||
_ => (width, margin_left, margin_right)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// If the resulting width is smaller than 'min-width', width should be recalculated,
|
|
||||||
// but this time using the value of 'min-width' as the computed value for 'width'.
|
|
||||||
let (width, margin_left, margin_right) = {
|
|
||||||
let computed_min_width = specified(style.Box.min_width, remaining_width);
|
|
||||||
if computed_min_width > width {
|
|
||||||
self.compute_horiz(Specified(computed_min_width),
|
|
||||||
maybe_margin_left,
|
|
||||||
maybe_margin_right,
|
|
||||||
available_width)
|
|
||||||
} else {
|
|
||||||
(width, margin_left, margin_right)
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
base.margin.top = margin_top;
|
mut_base.margin.top = margin_top;
|
||||||
base.margin.right = margin_right;
|
mut_base.margin.right = margin_right;
|
||||||
base.margin.bottom = margin_bottom;
|
mut_base.margin.bottom = margin_bottom;
|
||||||
base.margin.left = margin_left;
|
mut_base.margin.left = margin_left;
|
||||||
|
|
||||||
x_offset = base.offset();
|
x_offset = base.offset();
|
||||||
remaining_width = width;
|
remaining_width = width;
|
||||||
|
|
||||||
//The associated box is the border box of this flow
|
//The associated box is the border box of this flow
|
||||||
let position_ref = base.position.mutate();
|
mut_position.origin.x = base.margin.left;
|
||||||
position_ref.ptr.origin.x = base.margin.left;
|
|
||||||
let padding_and_borders = base.padding.left + base.padding.right +
|
let padding_and_borders = base.padding.left + base.padding.right +
|
||||||
base.border.left + base.border.right;
|
base.border.left + base.border.right;
|
||||||
position_ref.ptr.size.width = remaining_width + padding_and_borders;
|
mut_position.size.width = remaining_width + padding_and_borders;
|
||||||
}
|
}
|
||||||
|
|
||||||
let has_inorder_children = self.base.is_inorder || self.base.num_floats > 0;
|
if self.is_float() {
|
||||||
|
self.base.position.size.width = remaining_width;
|
||||||
|
}
|
||||||
|
|
||||||
|
let has_inorder_children = if self.is_float() {
|
||||||
|
self.base.num_floats > 0
|
||||||
|
} else {
|
||||||
|
self.base.is_inorder || self.base.num_floats > 0
|
||||||
|
};
|
||||||
|
|
||||||
for kid in self.base.child_iter() {
|
for kid in self.base.child_iter() {
|
||||||
assert!(kid.starts_block_flow() || kid.starts_inline_flow());
|
assert!(kid.starts_block_flow() || kid.starts_inline_flow());
|
||||||
|
|
||||||
|
@ -460,19 +696,29 @@ impl Flow for BlockFlow {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assign_height_inorder(&mut self, ctx: &mut LayoutContext) {
|
fn assign_height_inorder(&mut self, ctx: &mut LayoutContext) {
|
||||||
debug!("assign_height_inorder: assigning height for block {}", self.base.id);
|
if self.is_float() {
|
||||||
self.assign_height_block_base(ctx, true);
|
debug!("assign_height_inorder_float: assigning height for float {}", self.base.id);
|
||||||
|
self.assign_height_float_inorder();
|
||||||
|
} else {
|
||||||
|
debug!("assign_height_inorder: assigning height for block {}", self.base.id);
|
||||||
|
self.assign_height_block_base(ctx, true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assign_height(&mut self, ctx: &mut LayoutContext) {
|
fn assign_height(&mut self, ctx: &mut LayoutContext) {
|
||||||
debug!("assign_height: assigning height for block {}", self.base.id);
|
if self.is_float() {
|
||||||
// This is the only case in which a block flow can start an inorder
|
debug!("assign_height_float: assigning height for float {}", self.base.id);
|
||||||
// subtraversal.
|
self.assign_height_float(ctx);
|
||||||
if self.is_root && self.base.num_floats > 0 {
|
} else {
|
||||||
self.assign_height_inorder(ctx);
|
debug!("assign_height: assigning height for block {}", self.base.id);
|
||||||
return;
|
// This is the only case in which a block flow can start an inorder
|
||||||
|
// subtraversal.
|
||||||
|
if self.is_root && self.base.num_floats > 0 {
|
||||||
|
self.assign_height_inorder(ctx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.assign_height_block_base(ctx, false);
|
||||||
}
|
}
|
||||||
self.assign_height_block_base(ctx, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collapse_margins(&mut self,
|
fn collapse_margins(&mut self,
|
||||||
|
@ -482,6 +728,12 @@ impl Flow for BlockFlow {
|
||||||
top_offset: &mut Au,
|
top_offset: &mut Au,
|
||||||
collapsing: &mut Au,
|
collapsing: &mut Au,
|
||||||
collapsible: &mut Au) {
|
collapsible: &mut Au) {
|
||||||
|
if self.is_float() {
|
||||||
|
// Margins between a floated box and any other box do not collapse.
|
||||||
|
*collapsing = Au::new(0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for &box in self.box.iter() {
|
for &box in self.box.iter() {
|
||||||
let base = box.base();
|
let base = box.base();
|
||||||
|
|
||||||
|
@ -515,7 +767,7 @@ impl Flow for BlockFlow {
|
||||||
if self.is_root {
|
if self.is_root {
|
||||||
~"BlockFlow(root)"
|
~"BlockFlow(root)"
|
||||||
} else {
|
} else {
|
||||||
let txt = ~"BlockFlow: ";
|
let txt = if self.is_float() { ~"FloatFlow: " } else { ~"BlockFlow: " };
|
||||||
txt.append(match self.box {
|
txt.append(match self.box {
|
||||||
Some(rb) => {
|
Some(rb) => {
|
||||||
rb.debug_str()
|
rb.debug_str()
|
||||||
|
|
|
@ -25,7 +25,6 @@ use layout::block::BlockFlow;
|
||||||
use layout::box::{GenericRenderBox, ImageRenderBox, RenderBox, RenderBoxBase};
|
use layout::box::{GenericRenderBox, ImageRenderBox, RenderBox, RenderBoxBase};
|
||||||
use layout::box::{UnscannedTextRenderBox};
|
use layout::box::{UnscannedTextRenderBox};
|
||||||
use layout::context::LayoutContext;
|
use layout::context::LayoutContext;
|
||||||
use layout::float::FloatFlow;
|
|
||||||
use layout::float_context::FloatType;
|
use layout::float_context::FloatType;
|
||||||
use layout::flow::{Flow, FlowData, MutableFlowUtils};
|
use layout::flow::{Flow, FlowData, MutableFlowUtils};
|
||||||
use layout::inline::InlineFlow;
|
use layout::inline::InlineFlow;
|
||||||
|
@ -360,13 +359,13 @@ impl<'self> FlowConstructor<'self> {
|
||||||
flow
|
flow
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds the flow for a node with `float: {left|right}`. This yields a `FloatFlow` with a
|
/// Builds the flow for a node with `float: {left|right}`. This yields a float `BlockFlow` with
|
||||||
/// `BlockFlow` underneath it.
|
/// a `BlockFlow` underneath it.
|
||||||
fn build_flow_for_floated_block(&self, node: AbstractNode<LayoutView>, float_type: FloatType)
|
fn build_flow_for_floated_block(&self, node: AbstractNode<LayoutView>, float_type: FloatType)
|
||||||
-> ~Flow: {
|
-> ~Flow: {
|
||||||
let base = FlowData::new(self.next_flow_id(), node);
|
let base = FlowData::new(self.next_flow_id(), node);
|
||||||
let box = self.build_box_for_node(node);
|
let box = self.build_box_for_node(node);
|
||||||
let mut flow = ~FloatFlow::from_box(base, float_type, box) as ~Flow:;
|
let mut flow = ~BlockFlow::float_from_box(base, float_type, box) as ~Flow:;
|
||||||
self.build_children_of_block_flow(&mut flow, node);
|
self.build_children_of_block_flow(&mut flow, node);
|
||||||
flow
|
flow
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,333 +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 layout::box::{RenderBox, RenderBoxUtils};
|
|
||||||
use layout::context::LayoutContext;
|
|
||||||
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
|
|
||||||
use layout::flow::{FloatFlowClass, FlowClass, Flow, FlowData};
|
|
||||||
use layout::flow;
|
|
||||||
use layout::model::{MaybeAuto};
|
|
||||||
use layout::float_context::{FloatContext, PlacementInfo, FloatType};
|
|
||||||
|
|
||||||
use std::cell::Cell;
|
|
||||||
use geom::point::Point2D;
|
|
||||||
use geom::rect::Rect;
|
|
||||||
use gfx::display_list::DisplayList;
|
|
||||||
use servo_util::geometry::Au;
|
|
||||||
use servo_util::geometry;
|
|
||||||
|
|
||||||
pub struct FloatFlow {
|
|
||||||
/// Data common to all flows.
|
|
||||||
base: FlowData,
|
|
||||||
|
|
||||||
/// The associated render box.
|
|
||||||
box: Option<@RenderBox>,
|
|
||||||
|
|
||||||
containing_width: Au,
|
|
||||||
|
|
||||||
/// Offset relative to where the parent tried to position this flow
|
|
||||||
rel_pos: Point2D<Au>,
|
|
||||||
|
|
||||||
/// Left or right?
|
|
||||||
float_type: FloatType,
|
|
||||||
|
|
||||||
/// Index into the box list for inline floats
|
|
||||||
index: Option<uint>,
|
|
||||||
|
|
||||||
/// Number of floated children
|
|
||||||
floated_children: uint,
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
impl FloatFlow {
|
|
||||||
pub fn new(base: FlowData, float_type: FloatType) -> FloatFlow {
|
|
||||||
FloatFlow {
|
|
||||||
base: base,
|
|
||||||
containing_width: Au(0),
|
|
||||||
box: None,
|
|
||||||
index: None,
|
|
||||||
float_type: float_type,
|
|
||||||
rel_pos: Point2D(Au(0), Au(0)),
|
|
||||||
floated_children: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn from_box(base: FlowData, float_type: FloatType, box: @RenderBox) -> FloatFlow {
|
|
||||||
FloatFlow {
|
|
||||||
base: base,
|
|
||||||
containing_width: Au(0),
|
|
||||||
box: Some(box),
|
|
||||||
index: None,
|
|
||||||
float_type: float_type,
|
|
||||||
rel_pos: Point2D(Au(0), Au(0)),
|
|
||||||
floated_children: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn teardown(&mut self) {
|
|
||||||
for box in self.box.iter() {
|
|
||||||
box.teardown();
|
|
||||||
}
|
|
||||||
self.box = None;
|
|
||||||
self.index = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn build_display_list_float<E:ExtraDisplayListData>(&mut self,
|
|
||||||
builder: &DisplayListBuilder,
|
|
||||||
dirty: &Rect<Au>,
|
|
||||||
list: &Cell<DisplayList<E>>)
|
|
||||||
-> bool {
|
|
||||||
//TODO: implement iframe size messaging
|
|
||||||
if self.base.node.is_iframe_element() {
|
|
||||||
error!("float iframe size messaging not implemented yet");
|
|
||||||
}
|
|
||||||
let abs_rect = Rect(self.base.abs_position, self.base.position.size);
|
|
||||||
if !abs_rect.intersects(dirty) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
let offset = self.base.abs_position + self.rel_pos;
|
|
||||||
// add box that starts block context
|
|
||||||
for box in self.box.iter() {
|
|
||||||
box.build_display_list(builder, dirty, &offset, list)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: handle any out-of-flow elements
|
|
||||||
|
|
||||||
// go deeper into the flow tree
|
|
||||||
for child in self.base.child_iter() {
|
|
||||||
let child_base = flow::mut_base(*child);
|
|
||||||
child_base.abs_position = offset + child_base.position.origin;
|
|
||||||
}
|
|
||||||
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn debug_str(&self) -> ~str {
|
|
||||||
~"FloatFlow"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Flow for FloatFlow {
|
|
||||||
fn class(&self) -> FlowClass {
|
|
||||||
FloatFlowClass
|
|
||||||
}
|
|
||||||
|
|
||||||
fn as_float<'a>(&'a mut self) -> &'a mut FloatFlow {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
|
|
||||||
fn bubble_widths(&mut self, _: &mut LayoutContext) {
|
|
||||||
let mut min_width = Au(0);
|
|
||||||
let mut pref_width = Au(0);
|
|
||||||
let mut num_floats = 0;
|
|
||||||
|
|
||||||
for child_ctx in self.base.child_iter() {
|
|
||||||
//assert!(child_ctx.starts_block_flow() || child_ctx.starts_inline_flow());
|
|
||||||
|
|
||||||
let child_base = flow::mut_base(*child_ctx);
|
|
||||||
min_width = geometry::max(min_width, child_base.min_width);
|
|
||||||
pref_width = geometry::max(pref_width, child_base.pref_width);
|
|
||||||
num_floats = num_floats + child_base.num_floats;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.base.num_floats = 1;
|
|
||||||
self.floated_children = num_floats;
|
|
||||||
|
|
||||||
for box in self.box.iter() {
|
|
||||||
{
|
|
||||||
box.mut_base().compute_borders(box.base().style());
|
|
||||||
}
|
|
||||||
|
|
||||||
let (this_minimum_width, this_preferred_width) = box.minimum_and_preferred_widths();
|
|
||||||
min_width = min_width + this_minimum_width;
|
|
||||||
pref_width = pref_width + this_preferred_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.base.min_width = min_width;
|
|
||||||
self.base.pref_width = pref_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn assign_widths(&mut self, _: &mut LayoutContext) {
|
|
||||||
debug!("assign_widths_float: assigning width for flow {}", self.base.id);
|
|
||||||
// position.size.width is set by parent even though we don't know
|
|
||||||
// position.origin yet.
|
|
||||||
let mut remaining_width = self.base.position.size.width;
|
|
||||||
self.containing_width = remaining_width;
|
|
||||||
let mut x_offset = Au(0);
|
|
||||||
|
|
||||||
// Parent usually sets this, but floats are never inorder
|
|
||||||
self.base.is_inorder = false;
|
|
||||||
|
|
||||||
for &box in self.box.iter() {
|
|
||||||
let base = box.base();
|
|
||||||
let mut_base = box.mut_base();
|
|
||||||
let style = base.style();
|
|
||||||
let mut position_ref = base.position.mutate();
|
|
||||||
let position = &mut position_ref.ptr;
|
|
||||||
|
|
||||||
// Can compute padding here since we know containing block width.
|
|
||||||
mut_base.compute_padding(style, remaining_width);
|
|
||||||
|
|
||||||
// Margins for floats are 0 if auto.
|
|
||||||
let margin_top = MaybeAuto::from_style(style.Margin.margin_top,
|
|
||||||
remaining_width).specified_or_zero();
|
|
||||||
let margin_bottom = MaybeAuto::from_style(style.Margin.margin_bottom,
|
|
||||||
remaining_width).specified_or_zero();
|
|
||||||
let margin_left = MaybeAuto::from_style(style.Margin.margin_left,
|
|
||||||
remaining_width).specified_or_zero();
|
|
||||||
let margin_right = MaybeAuto::from_style(style.Margin.margin_right,
|
|
||||||
remaining_width).specified_or_zero();
|
|
||||||
|
|
||||||
|
|
||||||
let shrink_to_fit = geometry::min(self.base.pref_width,
|
|
||||||
geometry::max(self.base.min_width, remaining_width));
|
|
||||||
|
|
||||||
|
|
||||||
let width = MaybeAuto::from_style(style.Box.width,
|
|
||||||
remaining_width).specified_or_default(shrink_to_fit);
|
|
||||||
debug!("assign_widths_float -- width: {}", width);
|
|
||||||
|
|
||||||
mut_base.margin.top = margin_top;
|
|
||||||
mut_base.margin.right = margin_right;
|
|
||||||
mut_base.margin.bottom = margin_bottom;
|
|
||||||
mut_base.margin.left = margin_left;
|
|
||||||
|
|
||||||
x_offset = base.offset();
|
|
||||||
remaining_width = width;
|
|
||||||
|
|
||||||
// The associated box is the border box of this flow.
|
|
||||||
position.origin.x = base.margin.left;
|
|
||||||
|
|
||||||
let padding_and_borders = base.padding.left + base.padding.right +
|
|
||||||
base.border.left + base.border.right;
|
|
||||||
position.size.width = remaining_width + padding_and_borders;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.base.position.size.width = remaining_width;
|
|
||||||
|
|
||||||
let has_inorder_children = self.base.num_floats > 0;
|
|
||||||
for kid in self.base.child_iter() {
|
|
||||||
//assert!(kid.starts_block_flow() || kid.starts_inline_flow());
|
|
||||||
|
|
||||||
let child_base = flow::mut_base(*kid);
|
|
||||||
child_base.position.origin.x = x_offset;
|
|
||||||
child_base.position.size.width = remaining_width;
|
|
||||||
child_base.is_inorder = has_inorder_children;
|
|
||||||
|
|
||||||
if !child_base.is_inorder {
|
|
||||||
child_base.floats_in = FloatContext::new(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn assign_height_inorder(&mut self, _: &mut LayoutContext) {
|
|
||||||
debug!("assign_height_inorder_float: assigning height for float {}", self.base.id);
|
|
||||||
// assign_height_float was already called by the traversal function
|
|
||||||
// so this is well-defined
|
|
||||||
|
|
||||||
let mut height = Au(0);
|
|
||||||
let mut clearance = Au(0);
|
|
||||||
let mut full_noncontent_width = Au(0);
|
|
||||||
let mut margin_height = Au(0);
|
|
||||||
|
|
||||||
for box in self.box.iter() {
|
|
||||||
let base = box.base();
|
|
||||||
height = base.position.borrow().ptr.size.height;
|
|
||||||
clearance = match base.clear() {
|
|
||||||
None => Au(0),
|
|
||||||
Some(clear) => self.base.floats_in.clearance(clear),
|
|
||||||
};
|
|
||||||
|
|
||||||
let noncontent_width = base.padding.left + base.padding.right + base.border.left +
|
|
||||||
base.border.right;
|
|
||||||
|
|
||||||
full_noncontent_width = noncontent_width + base.margin.left + base.margin.right;
|
|
||||||
margin_height = base.margin.top + base.margin.bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
let info = PlacementInfo {
|
|
||||||
width: self.base.position.size.width + full_noncontent_width,
|
|
||||||
height: height + margin_height,
|
|
||||||
ceiling: clearance,
|
|
||||||
max_width: self.containing_width,
|
|
||||||
f_type: self.float_type,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Place the float and return the FloatContext back to the parent flow.
|
|
||||||
// After, grab the position and use that to set our position.
|
|
||||||
self.base.floats_out = self.base.floats_in.add_float(&info);
|
|
||||||
self.rel_pos = self.base.floats_out.last_float_pos();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn assign_height(&mut self, ctx: &mut LayoutContext) {
|
|
||||||
// Now that we've determined our height, propagate that out.
|
|
||||||
let has_inorder_children = self.base.num_floats > 0;
|
|
||||||
if has_inorder_children {
|
|
||||||
let mut float_ctx = FloatContext::new(self.floated_children);
|
|
||||||
for kid in self.base.child_iter() {
|
|
||||||
flow::mut_base(*kid).floats_in = float_ctx.clone();
|
|
||||||
kid.assign_height_inorder(ctx);
|
|
||||||
float_ctx = flow::mut_base(*kid).floats_out.clone();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
debug!("assign_height_float: assigning height for float {}", self.base.id);
|
|
||||||
let mut cur_y = Au(0);
|
|
||||||
let mut top_offset = Au(0);
|
|
||||||
|
|
||||||
for &box in self.box.iter() {
|
|
||||||
let base = box.base();
|
|
||||||
top_offset = base.margin.top + base.border.top + base.padding.top;
|
|
||||||
cur_y = cur_y + top_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
for kid in self.base.child_iter() {
|
|
||||||
let child_base = flow::mut_base(*kid);
|
|
||||||
child_base.position.origin.y = cur_y;
|
|
||||||
cur_y = cur_y + child_base.position.size.height;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut height = cur_y - top_offset;
|
|
||||||
|
|
||||||
let mut noncontent_height;
|
|
||||||
let box = self.box.as_ref().unwrap();
|
|
||||||
let base = box.base();
|
|
||||||
let mut position_ref = base.position.mutate();
|
|
||||||
let position = &mut position_ref.ptr;
|
|
||||||
|
|
||||||
// The associated box is the border box of this flow.
|
|
||||||
position.origin.y = base.margin.top;
|
|
||||||
|
|
||||||
noncontent_height = base.padding.top + base.padding.bottom + base.border.top +
|
|
||||||
base.border.bottom;
|
|
||||||
|
|
||||||
//TODO(eatkinson): compute heights properly using the 'height' property.
|
|
||||||
let height_prop = MaybeAuto::from_style(base.style().Box.height,
|
|
||||||
Au::new(0)).specified_or_zero();
|
|
||||||
|
|
||||||
height = geometry::max(height, height_prop) + noncontent_height;
|
|
||||||
debug!("assign_height_float -- height: {}", height);
|
|
||||||
|
|
||||||
position.size.height = height;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
fn collapse_margins(&mut self,
|
|
||||||
_: bool,
|
|
||||||
_: &mut bool,
|
|
||||||
_: &mut Au,
|
|
||||||
_: &mut Au,
|
|
||||||
collapsing: &mut Au,
|
|
||||||
_: &mut Au) {
|
|
||||||
// Margins between a floated box and any other box do not collapse.
|
|
||||||
*collapsing = Au::new(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn debug_str(&self) -> ~str {
|
|
||||||
~"FloatFlow"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -29,7 +29,6 @@ use css::node_style::StyledNode;
|
||||||
use layout::block::BlockFlow;
|
use layout::block::BlockFlow;
|
||||||
use layout::box::RenderBox;
|
use layout::box::RenderBox;
|
||||||
use layout::context::LayoutContext;
|
use layout::context::LayoutContext;
|
||||||
use layout::float::FloatFlow;
|
|
||||||
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
|
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
|
||||||
use layout::float_context::{FloatContext, Invalid};
|
use layout::float_context::{FloatContext, Invalid};
|
||||||
use layout::incremental::RestyleDamage;
|
use layout::incremental::RestyleDamage;
|
||||||
|
@ -74,11 +73,6 @@ pub trait Flow {
|
||||||
fail!("called as_inline() on a non-inline flow")
|
fail!("called as_inline() on a non-inline flow")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If this is a float flow, returns the underlying object. Fails otherwise.
|
|
||||||
fn as_float<'a>(&'a mut self) -> &'a mut FloatFlow {
|
|
||||||
fail!("called as_float() on a non-float flow")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Main methods
|
// Main methods
|
||||||
|
|
||||||
/// Pass 1 of reflow: computes minimum and preferred widths.
|
/// Pass 1 of reflow: computes minimum and preferred widths.
|
||||||
|
@ -217,7 +211,6 @@ pub trait MutableFlowUtils {
|
||||||
pub enum FlowClass {
|
pub enum FlowClass {
|
||||||
AbsoluteFlowClass,
|
AbsoluteFlowClass,
|
||||||
BlockFlowClass,
|
BlockFlowClass,
|
||||||
FloatFlowClass,
|
|
||||||
InlineBlockFlowClass,
|
InlineBlockFlowClass,
|
||||||
InlineFlowClass,
|
InlineFlowClass,
|
||||||
TableFlowClass,
|
TableFlowClass,
|
||||||
|
@ -395,7 +388,7 @@ impl<'self> ImmutableFlowUtils for &'self Flow {
|
||||||
/// Returns true if this flow is a block or a float flow.
|
/// Returns true if this flow is a block or a float flow.
|
||||||
fn is_block_like(self) -> bool {
|
fn is_block_like(self) -> bool {
|
||||||
match self.class() {
|
match self.class() {
|
||||||
BlockFlowClass | FloatFlowClass => true,
|
BlockFlowClass => true,
|
||||||
AbsoluteFlowClass | InlineBlockFlowClass | InlineFlowClass | TableFlowClass => false,
|
AbsoluteFlowClass | InlineBlockFlowClass | InlineFlowClass | TableFlowClass => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -408,7 +401,7 @@ impl<'self> ImmutableFlowUtils for &'self Flow {
|
||||||
/// Returns true if this flow is a block flow, an inline-block flow, or a float flow.
|
/// Returns true if this flow is a block flow, an inline-block flow, or a float flow.
|
||||||
fn starts_block_flow(self) -> bool {
|
fn starts_block_flow(self) -> bool {
|
||||||
match self.class() {
|
match self.class() {
|
||||||
BlockFlowClass | InlineBlockFlowClass | FloatFlowClass => true,
|
BlockFlowClass | InlineBlockFlowClass => true,
|
||||||
AbsoluteFlowClass | InlineFlowClass | TableFlowClass => false,
|
AbsoluteFlowClass | InlineFlowClass | TableFlowClass => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -417,7 +410,7 @@ impl<'self> ImmutableFlowUtils for &'self Flow {
|
||||||
fn starts_inline_flow(self) -> bool {
|
fn starts_inline_flow(self) -> bool {
|
||||||
match self.class() {
|
match self.class() {
|
||||||
InlineFlowClass => true,
|
InlineFlowClass => true,
|
||||||
AbsoluteFlowClass | BlockFlowClass | FloatFlowClass | InlineBlockFlowClass |
|
AbsoluteFlowClass | BlockFlowClass | InlineBlockFlowClass |
|
||||||
TableFlowClass => false,
|
TableFlowClass => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -525,7 +518,6 @@ impl<'self> MutableFlowUtils for &'self mut Flow {
|
||||||
match self.class() {
|
match self.class() {
|
||||||
BlockFlowClass => self.as_block().build_display_list_block(builder, dirty, list),
|
BlockFlowClass => self.as_block().build_display_list_block(builder, dirty, list),
|
||||||
InlineFlowClass => self.as_inline().build_display_list_inline(builder, dirty, list),
|
InlineFlowClass => self.as_inline().build_display_list_inline(builder, dirty, list),
|
||||||
FloatFlowClass => self.as_float().build_display_list_float(builder, dirty, list),
|
|
||||||
_ => fail!("Tried to build_display_list_recurse of flow: {:?}", self),
|
_ => fail!("Tried to build_display_list_recurse of flow: {:?}", self),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,6 @@ pub mod layout {
|
||||||
pub mod context;
|
pub mod context;
|
||||||
pub mod display_list_builder;
|
pub mod display_list_builder;
|
||||||
pub mod float_context;
|
pub mod float_context;
|
||||||
pub mod float;
|
|
||||||
pub mod flow;
|
pub mod flow;
|
||||||
pub mod layout_task;
|
pub mod layout_task;
|
||||||
pub mod inline;
|
pub mod inline;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue