mirror of
https://github.com/servo/servo.git
synced 2025-08-09 15:35:34 +01:00
Add right floats and fix bug where max_y was not being set
This commit is contained in:
parent
11873117a1
commit
650bd65460
4 changed files with 38 additions and 21 deletions
|
@ -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
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue