Add right floats and fix bug where max_y was not being set

This commit is contained in:
Eric Atkinson 2013-06-25 16:19:08 -07:00
parent 11873117a1
commit 650bd65460
4 changed files with 38 additions and 21 deletions

View file

@ -24,7 +24,8 @@ use newcss::values::{CSSDisplayTableRowGroup, CSSDisplayTableHeaderGroup, CSSDis
use newcss::values::{CSSDisplayTableRow, CSSDisplayTableColumnGroup, CSSDisplayTableColumn}; use newcss::values::{CSSDisplayTableRow, CSSDisplayTableColumnGroup, CSSDisplayTableColumn};
use newcss::values::{CSSDisplayTableCell, CSSDisplayTableCaption}; use newcss::values::{CSSDisplayTableCell, CSSDisplayTableCaption};
use newcss::values::{CSSDisplayNone}; use newcss::values::{CSSDisplayNone};
use newcss::values::{CSSFloatNone}; use newcss::values::{CSSFloatNone, CSSFloatLeft, CSSFloatRight};
use layout::float_context::{FloatLeft, FloatRight};
use script::dom::element::*; use script::dom::element::*;
use script::dom::node::{AbstractNode, CommentNodeTypeId, DoctypeNodeTypeId}; use script::dom::node::{AbstractNode, CommentNodeTypeId, DoctypeNodeTypeId};
use script::dom::node::{ElementNodeTypeId, LayoutView, TextNodeTypeId}; use script::dom::node::{ElementNodeTypeId, LayoutView, TextNodeTypeId};
@ -370,17 +371,18 @@ impl LayoutTreeBuilder {
// determine whether to float left or right. // determine whether to float left or right.
let is_float = if (node.is_element()) { let is_float = if (node.is_element()) {
match node.style().float() { match node.style().float() {
CSSFloatNone => false, CSSFloatNone => None,
_ => true CSSFloatLeft => Some(FloatLeft),
CSSFloatRight => Some(FloatRight)
} }
} else { } else {
false None
}; };
let new_generator = match (display, parent_generator.flow, sibling_flow) { let new_generator = match (display, parent_generator.flow, sibling_flow) {
(CSSDisplayBlock, BlockFlow(_), _) if is_float => { (CSSDisplayBlock, BlockFlow(_), _) if !is_float.is_none() => {
self.create_child_generator(node, parent_generator, Flow_Float) self.create_child_generator(node, parent_generator, Flow_Float(is_float.get()))
} }
(CSSDisplayBlock, BlockFlow(info), _) => match (info.is_root, node.parent_node()) { (CSSDisplayBlock, BlockFlow(info), _) => match (info.is_root, node.parent_node()) {
@ -574,13 +576,13 @@ impl LayoutTreeBuilder {
pub fn make_flow(&mut self, ty: FlowContextType, node: AbstractNode<LayoutView>) -> FlowContext { pub fn make_flow(&mut self, ty: FlowContextType, node: AbstractNode<LayoutView>) -> FlowContext {
let info = FlowData::new(self.next_flow_id(), node); let info = FlowData::new(self.next_flow_id(), node);
let result = match ty { let result = match ty {
Flow_Absolute => AbsoluteFlow(@mut info), Flow_Absolute => AbsoluteFlow(@mut info),
Flow_Block => BlockFlow(@mut BlockFlowData::new(info)), Flow_Block => BlockFlow(@mut BlockFlowData::new(info)),
Flow_Float => FloatFlow(@mut FloatFlowData::new(info)), Flow_Float(f_type) => FloatFlow(@mut FloatFlowData::new(info, f_type)),
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 => BlockFlow(@mut BlockFlowData::new_root(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());
result result

View file

@ -8,7 +8,7 @@ use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
use layout::display_list_builder::{FlowDisplayListBuilderMethods}; use layout::display_list_builder::{FlowDisplayListBuilderMethods};
use layout::flow::{FloatFlow, FlowData}; use layout::flow::{FloatFlow, FlowData};
use layout::model::{MaybeAuto}; use layout::model::{MaybeAuto};
use layout::float_context::{FloatContext, PlacementInfo, FloatLeft}; use layout::float_context::{FloatContext, PlacementInfo, FloatLeft, FloatType};
use std::cell::Cell; use std::cell::Cell;
use geom::point::Point2D; use geom::point::Point2D;
@ -27,21 +27,25 @@ pub struct FloatFlowData {
containing_width: Au, containing_width: Au,
/// Parent clobbers our position, so store it separately /// Offset relative to where the parent tried to position this flow
rel_pos: Point2D<Au>, rel_pos: Point2D<Au>,
/// Left or right?
float_type: FloatType,
/// Index into the box list for inline floats /// Index into the box list for inline floats
index: Option<uint>, index: Option<uint>,
} }
impl FloatFlowData { impl FloatFlowData {
pub fn new(common: FlowData) -> FloatFlowData { pub fn new(common: FlowData, float_type: FloatType) -> FloatFlowData {
FloatFlowData { FloatFlowData {
common: common, common: common,
containing_width: Au(0), containing_width: Au(0),
box: None, box: None,
index: None, index: None,
float_type: float_type,
rel_pos: Point2D(Au(0), Au(0)), rel_pos: Point2D(Au(0), Au(0)),
} }
} }
@ -210,7 +214,7 @@ impl FloatFlowData {
height: height, height: height,
ceiling: Au(0), ceiling: Au(0),
max_width: self.containing_width, max_width: self.containing_width,
f_type: FloatLeft, f_type: self.float_type,
}; };
// Place the float and return the FloatContext back to the parent flow. // Place the float and return the FloatContext back to the parent flow.

View file

@ -225,6 +225,7 @@ impl FloatContextBase{
f_type: info.f_type f_type: info.f_type
}; };
self.float_data[self.floats_used] = Some(new_float); self.float_data[self.floats_used] = Some(new_float);
self.max_y = max(self.max_y, new_float.bounds.origin.y);
self.floats_used += 1; self.floats_used += 1;
} }
@ -240,16 +241,26 @@ impl FloatContextBase{
let maybe_location = self.available_rect(float_y, info.height, info.max_width); let maybe_location = self.available_rect(float_y, info.height, info.max_width);
debug!("place_float: Got available rect: %? for y-pos: %?", maybe_location, float_y); debug!("place_float: Got available rect: %? for y-pos: %?", maybe_location, float_y);
match maybe_location { match maybe_location {
// If there are no floats blocking us, return the current location // If there are no floats blocking us, return the current location
// TODO(eatknson): integrate with overflow // TODO(eatknson): integrate with overflow
None => return Point2D(Au(0), float_y), None => return match info.f_type {
FloatLeft => Point2D(Au(0), float_y),
FloatRight => Point2D(info.max_width - info.width, float_y)
},
Some(rect) => { Some(rect) => {
assert!(rect.origin.y + rect.size.height != float_y, assert!(rect.origin.y + rect.size.height != float_y,
"Non-terminating float placement"); "Non-terminating float placement");
// Place here if there is enough room // Place here if there is enough room
if (rect.size.width >= info.width) { if (rect.size.width >= info.width) {
return Point2D(rect.origin.x, float_y); return match info.f_type {
FloatLeft => Point2D(rect.origin.x, float_y),
FloatRight => {
Point2D(rect.origin.x + rect.size.width - info.width, float_y)
}
};
} }
// Try to place at the next-lowest location. // Try to place at the next-lowest location.

View file

@ -31,7 +31,7 @@ use layout::box::RenderBox;
use layout::context::LayoutContext; use layout::context::LayoutContext;
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData}; use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData};
use layout::inline::{InlineFlowData}; use layout::inline::{InlineFlowData};
use layout::float_context::{FloatContext, Invalid}; use layout::float_context::{FloatContext, Invalid, FloatType};
use std::cell::Cell; use std::cell::Cell;
use std::uint; use std::uint;
@ -56,7 +56,7 @@ pub enum FlowContext {
pub enum FlowContextType { pub enum FlowContextType {
Flow_Absolute, Flow_Absolute,
Flow_Block, Flow_Block,
Flow_Float, Flow_Float(FloatType),
Flow_InlineBlock, Flow_InlineBlock,
Flow_Inline, Flow_Inline,
Flow_Root, Flow_Root,