mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
auto merge of #1278 : saneyuki/servo/rm_box, r=pcwalton
This commit is contained in:
commit
37f9427b6c
5 changed files with 150 additions and 174 deletions
|
@ -127,12 +127,10 @@ impl BlockFlow {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut model_ref = base.model.mutate();
|
top_offset = clearance + base.margin.top + base.border.top + base.padding.top;
|
||||||
let model = &mut model_ref.ptr;
|
|
||||||
top_offset = clearance + model.margin.top + model.border.top + model.padding.top;
|
|
||||||
cur_y = cur_y + top_offset;
|
cur_y = cur_y + top_offset;
|
||||||
bottom_offset = model.margin.bottom + model.border.bottom + model.padding.bottom;
|
bottom_offset = base.margin.bottom + base.border.bottom + base.padding.bottom;
|
||||||
left_offset = model.offset();
|
left_offset = base.offset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if inorder {
|
if inorder {
|
||||||
|
@ -160,17 +158,15 @@ impl BlockFlow {
|
||||||
let mut first_in_flow = true;
|
let mut first_in_flow = true;
|
||||||
for &box in self.box.iter() {
|
for &box in self.box.iter() {
|
||||||
let base = box.base();
|
let base = box.base();
|
||||||
let mut model_ref = base.model.mutate();
|
if !self.is_root && base.border.top == Au::new(0) && base.padding.top == Au::new(0) {
|
||||||
let model = &mut model_ref.ptr;
|
collapsible = base.margin.top;
|
||||||
if !self.is_root && model.border.top == Au::new(0) && model.padding.top == Au::new(0) {
|
|
||||||
collapsible = model.margin.top;
|
|
||||||
top_margin_collapsible = true;
|
top_margin_collapsible = true;
|
||||||
}
|
}
|
||||||
if !self.is_root && model.border.bottom == Au::new(0) && model.padding.bottom == Au::new(0) {
|
if !self.is_root && base.border.bottom == Au::new(0) && base.padding.bottom == Au::new(0) {
|
||||||
bottom_margin_collapsible = true;
|
bottom_margin_collapsible = true;
|
||||||
}
|
}
|
||||||
margin_top = model.margin.top;
|
margin_top = base.margin.top;
|
||||||
margin_bottom = model.margin.bottom;
|
margin_bottom = base.margin.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
for kid in self.base.child_iter() {
|
for kid in self.base.child_iter() {
|
||||||
|
@ -220,23 +216,22 @@ impl BlockFlow {
|
||||||
|
|
||||||
let mut noncontent_height = Au::new(0);
|
let mut noncontent_height = Au::new(0);
|
||||||
for box in self.box.iter() {
|
for box in self.box.iter() {
|
||||||
let base = box.base();
|
let base = box.mut_base();
|
||||||
let mut model_ref = base.model.mutate();
|
|
||||||
let mut position_ref = base.position.mutate();
|
let mut position_ref = base.position.mutate();
|
||||||
let (model, position) = (&mut model_ref.ptr, &mut position_ref.ptr);
|
let position = &mut position_ref.ptr;
|
||||||
|
|
||||||
// The associated box is the border box of this flow.
|
// The associated box is the border box of this flow.
|
||||||
model.margin.top = margin_top;
|
base.margin.top = margin_top;
|
||||||
model.margin.bottom = margin_bottom;
|
base.margin.bottom = margin_bottom;
|
||||||
|
|
||||||
position.origin.y = clearance + model.margin.top;
|
position.origin.y = clearance + base.margin.top;
|
||||||
|
|
||||||
noncontent_height = model.padding.top + model.padding.bottom + model.border.top +
|
noncontent_height = base.padding.top + base.padding.bottom + base.border.top +
|
||||||
model.border.bottom;
|
base.border.bottom;
|
||||||
position.size.height = height + noncontent_height;
|
position.size.height = height + noncontent_height;
|
||||||
|
|
||||||
noncontent_height = noncontent_height + clearance + model.margin.top +
|
noncontent_height = noncontent_height + clearance + base.margin.top +
|
||||||
model.margin.bottom;
|
base.margin.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.base.position.size.height = height + noncontent_height;
|
self.base.position.size.height = height + noncontent_height;
|
||||||
|
@ -257,18 +252,18 @@ impl BlockFlow {
|
||||||
-> bool {
|
-> bool {
|
||||||
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 model = box.base().model.get();
|
let base = box.base();
|
||||||
model.margin.left + model.border.left + model.padding.left
|
base.margin.left + base.border.left + base.padding.left
|
||||||
};
|
};
|
||||||
let y = self.base.abs_position.y + do self.box.map_default(Au::new(0)) |box| {
|
let y = self.base.abs_position.y + do self.box.map_default(Au::new(0)) |box| {
|
||||||
let model = box.base().model.get();
|
let base = box.base();
|
||||||
model.margin.top + model.border.top + model.padding.top
|
base.margin.top + base.border.top + base.padding.top
|
||||||
};
|
};
|
||||||
let w = self.base.position.size.width - do self.box.map_default(Au::new(0)) |box| {
|
let w = self.base.position.size.width - do self.box.map_default(Au::new(0)) |box| {
|
||||||
box.base().model.get().noncontent_width()
|
box.base().noncontent_width()
|
||||||
};
|
};
|
||||||
let h = self.base.position.size.height - do self.box.map_default(Au::new(0)) |box| {
|
let h = self.base.position.size.height - do self.box.map_default(Au::new(0)) |box| {
|
||||||
box.base().model.get().noncontent_height()
|
box.base().noncontent_height()
|
||||||
};
|
};
|
||||||
do self.base.node.with_mut_iframe_element |iframe_element| {
|
do self.base.node.with_mut_iframe_element |iframe_element| {
|
||||||
iframe_element.size.get_mut_ref().set_rect(Rect(Point2D(to_frac_px(x) as f32,
|
iframe_element.size.get_mut_ref().set_rect(Rect(Point2D(to_frac_px(x) as f32,
|
||||||
|
@ -339,9 +334,10 @@ impl FlowContext for BlockFlow {
|
||||||
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() {
|
||||||
{
|
{
|
||||||
// Can compute border width here since it doesn't depend on anything.
|
let mut_base = box.mut_base();
|
||||||
let base = box.base();
|
let base = box.base();
|
||||||
base.model.mutate().ptr.compute_borders(base.style())
|
// Can compute border width here since it doesn't depend on anything.
|
||||||
|
mut_base.compute_borders(base.style())
|
||||||
}
|
}
|
||||||
|
|
||||||
let (this_minimum_width, this_preferred_width) = box.minimum_and_preferred_widths();
|
let (this_minimum_width, this_preferred_width) = box.minimum_and_preferred_widths();
|
||||||
|
@ -374,16 +370,14 @@ impl FlowContext for BlockFlow {
|
||||||
let mut x_offset = Au::new(0);
|
let mut x_offset = Au::new(0);
|
||||||
|
|
||||||
for &box in self.box.iter() {
|
for &box in self.box.iter() {
|
||||||
let base = box.base();
|
let base = box.mut_base();
|
||||||
let style = base.style();
|
let style = base.style();
|
||||||
let mut model_ref = base.model.mutate();
|
|
||||||
let model = &mut model_ref.ptr;
|
|
||||||
|
|
||||||
// Can compute padding here since we know containing block width.
|
// Can compute padding here since we know containing block width.
|
||||||
model.compute_padding(style, remaining_width);
|
base.compute_padding(style, remaining_width);
|
||||||
|
|
||||||
// Margins are 0 right now so model.noncontent_width() is just borders + padding.
|
// Margins are 0 right now so base.noncontent_width() is just borders + padding.
|
||||||
let available_width = remaining_width - model.noncontent_width();
|
let available_width = remaining_width - base.noncontent_width();
|
||||||
|
|
||||||
// Top and bottom margins for blocks are 0 if auto.
|
// Top and bottom margins for blocks are 0 if auto.
|
||||||
let margin_top = MaybeAuto::from_style(style.Margin.margin_top,
|
let margin_top = MaybeAuto::from_style(style.Margin.margin_top,
|
||||||
|
@ -426,19 +420,19 @@ impl FlowContext for BlockFlow {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
model.margin.top = margin_top;
|
base.margin.top = margin_top;
|
||||||
model.margin.right = margin_right;
|
base.margin.right = margin_right;
|
||||||
model.margin.bottom = margin_bottom;
|
base.margin.bottom = margin_bottom;
|
||||||
model.margin.left = margin_left;
|
base.margin.left = margin_left;
|
||||||
|
|
||||||
x_offset = model.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();
|
let position_ref = base.position.mutate();
|
||||||
position_ref.ptr.origin.x = model.margin.left;
|
position_ref.ptr.origin.x = base.margin.left;
|
||||||
let padding_and_borders = model.padding.left + model.padding.right +
|
let padding_and_borders = base.padding.left + base.padding.right +
|
||||||
model.border.left + model.border.right;
|
base.border.left + base.border.right;
|
||||||
position_ref.ptr.size.width = remaining_width + padding_and_borders;
|
position_ref.ptr.size.width = remaining_width + padding_and_borders;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -482,26 +476,24 @@ impl FlowContext for BlockFlow {
|
||||||
collapsible: &mut Au) {
|
collapsible: &mut Au) {
|
||||||
for &box in self.box.iter() {
|
for &box in self.box.iter() {
|
||||||
let base = box.base();
|
let base = box.base();
|
||||||
let mut model_ref = base.model.mutate();
|
|
||||||
let model = &mut model_ref.ptr;
|
|
||||||
|
|
||||||
// The top margin collapses with its first in-flow block-level child's
|
// The top margin collapses with its first in-flow block-level child's
|
||||||
// top margin if the parent has no top border, no top padding.
|
// top margin if the parent has no top border, no top padding.
|
||||||
if *first_in_flow && top_margin_collapsible {
|
if *first_in_flow && top_margin_collapsible {
|
||||||
// If top-margin of parent is less than top-margin of its first child,
|
// If top-margin of parent is less than top-margin of its first child,
|
||||||
// the parent box goes down until its top is aligned with the child.
|
// the parent box goes down until its top is aligned with the child.
|
||||||
if *margin_top < model.margin.top {
|
if *margin_top < base.margin.top {
|
||||||
// TODO: The position of child floats should be updated and this
|
// TODO: The position of child floats should be updated and this
|
||||||
// would influence clearance as well. See #725
|
// would influence clearance as well. See #725
|
||||||
let extra_margin = model.margin.top - *margin_top;
|
let extra_margin = base.margin.top - *margin_top;
|
||||||
*top_offset = *top_offset + extra_margin;
|
*top_offset = *top_offset + extra_margin;
|
||||||
*margin_top = model.margin.top;
|
*margin_top = base.margin.top;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// The bottom margin of an in-flow block-level element collapses
|
// The bottom margin of an in-flow block-level element collapses
|
||||||
// with the top margin of its next in-flow block-level sibling.
|
// with the top margin of its next in-flow block-level sibling.
|
||||||
*collapsing = geometry::min(model.margin.top, *collapsible);
|
*collapsing = geometry::min(base.margin.top, *collapsible);
|
||||||
*collapsible = model.margin.bottom;
|
*collapsible = base.margin.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
*first_in_flow = false;
|
*first_in_flow = false;
|
||||||
|
|
|
@ -28,12 +28,12 @@ use std::unstable::raw::Box;
|
||||||
use style::ComputedValues;
|
use style::ComputedValues;
|
||||||
use style::computed_values::{
|
use style::computed_values::{
|
||||||
border_style, clear, float, font_family, font_style, line_height,
|
border_style, clear, float, font_family, font_style, line_height,
|
||||||
position, text_align, text_decoration, vertical_align};
|
position, text_align, text_decoration, vertical_align, LengthOrPercentage};
|
||||||
|
|
||||||
use css::node_style::StyledNode;
|
use css::node_style::StyledNode;
|
||||||
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData, ToGfxColor};
|
use layout::display_list_builder::{DisplayListBuilder, ExtraDisplayListData, ToGfxColor};
|
||||||
use layout::float_context::{ClearType, ClearLeft, ClearRight, ClearBoth};
|
use layout::float_context::{ClearType, ClearLeft, ClearRight, ClearBoth};
|
||||||
use layout::model::{BoxModel, MaybeAuto};
|
use layout::model::{MaybeAuto, specified};
|
||||||
|
|
||||||
/// Boxes (`struct Box`) are the leaves of the layout tree. They cannot position themselves. In
|
/// Boxes (`struct Box`) are the leaves of the layout tree. They cannot position themselves. In
|
||||||
/// general, boxes do not have a simple correspondence with CSS boxes in the specification:
|
/// general, boxes do not have a simple correspondence with CSS boxes in the specification:
|
||||||
|
@ -119,6 +119,8 @@ impl Clone for @RenderBox {
|
||||||
pub trait RenderBoxUtils {
|
pub trait RenderBoxUtils {
|
||||||
fn base<'a>(&'a self) -> &'a RenderBoxBase;
|
fn base<'a>(&'a self) -> &'a RenderBoxBase;
|
||||||
|
|
||||||
|
fn mut_base<'a>(&'a self) -> &'a mut RenderBoxBase;
|
||||||
|
|
||||||
/// Returns true if this element is replaced content. This is true for images, form elements,
|
/// Returns true if this element is replaced content. This is true for images, form elements,
|
||||||
/// and so on.
|
/// and so on.
|
||||||
fn is_replaced(&self) -> bool;
|
fn is_replaced(&self) -> bool;
|
||||||
|
@ -172,6 +174,7 @@ pub trait RenderBoxUtils {
|
||||||
|
|
||||||
pub trait RenderBoxRefUtils<'self> {
|
pub trait RenderBoxRefUtils<'self> {
|
||||||
fn base(self) -> &'self RenderBoxBase;
|
fn base(self) -> &'self RenderBoxBase;
|
||||||
|
fn mut_base(self) -> &'self mut RenderBoxBase;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A box that represents a generic render box.
|
/// A box that represents a generic render box.
|
||||||
|
@ -618,13 +621,22 @@ pub struct RenderBoxBase {
|
||||||
/// The position of this box relative to its owning flow.
|
/// The position of this box relative to its owning flow.
|
||||||
position: Slot<Rect<Au>>,
|
position: Slot<Rect<Au>>,
|
||||||
|
|
||||||
/// The core parameters (border, padding, margin) used by the box model.
|
|
||||||
model: Slot<BoxModel>,
|
|
||||||
|
|
||||||
/// A debug ID.
|
/// A debug ID.
|
||||||
///
|
///
|
||||||
/// TODO(#87) Make this only present in debug builds.
|
/// TODO(#87) Make this only present in debug builds.
|
||||||
id: int
|
id: int,
|
||||||
|
|
||||||
|
/// the border of the content box.
|
||||||
|
border: SideOffsets2D<Au>,
|
||||||
|
|
||||||
|
/// the padding of the content box.
|
||||||
|
padding: SideOffsets2D<Au>,
|
||||||
|
|
||||||
|
/// the margin of the content box.
|
||||||
|
margin: SideOffsets2D<Au>,
|
||||||
|
|
||||||
|
/// The width of the content box.
|
||||||
|
content_box_width: Au,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderBoxBase {
|
impl RenderBoxBase {
|
||||||
|
@ -634,8 +646,11 @@ impl RenderBoxBase {
|
||||||
RenderBoxBase {
|
RenderBoxBase {
|
||||||
node: node,
|
node: node,
|
||||||
position: Slot::init(Au::zero_rect()),
|
position: Slot::init(Au::zero_rect()),
|
||||||
model: Slot::init(Zero::zero()),
|
|
||||||
id: id,
|
id: id,
|
||||||
|
border: Zero::zero(),
|
||||||
|
padding: Zero::zero(),
|
||||||
|
margin: Zero::zero(),
|
||||||
|
content_box_width: Zero::zero(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -655,13 +670,11 @@ impl RenderBoxBase {
|
||||||
let margin_right = MaybeAuto::from_style(style.Margin.margin_right,
|
let margin_right = MaybeAuto::from_style(style.Margin.margin_right,
|
||||||
Au::new(0)).specified_or_zero();
|
Au::new(0)).specified_or_zero();
|
||||||
|
|
||||||
let mut model_ref = self.model.mutate();
|
let padding_left = self.compute_padding_length(style.Padding.padding_left, Au::new(0));
|
||||||
let model = &mut model_ref.ptr;
|
let padding_right = self.compute_padding_length(style.Padding.padding_right, Au::new(0));
|
||||||
let padding_left = model.compute_padding_length(style.Padding.padding_left, Au::new(0));
|
|
||||||
let padding_right = model.compute_padding_length(style.Padding.padding_right, Au::new(0));
|
|
||||||
|
|
||||||
width + margin_left + margin_right + padding_left + padding_right + model.border.left +
|
width + margin_left + margin_right + padding_left + padding_right + self.border.left +
|
||||||
model.border.right
|
self.border.right
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn calculate_line_height(&self, font_size: Au) -> Au {
|
pub fn calculate_line_height(&self, font_size: Au) -> Au {
|
||||||
|
@ -672,23 +685,50 @@ impl RenderBoxBase {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compute_padding(&self, containing_block_width: Au) {
|
/// Populates the box model border parameters from the given computed style.
|
||||||
self.model.mutate().ptr.compute_padding(self.node.style(), containing_block_width);
|
pub fn compute_borders(&mut self, style: &ComputedValues) {
|
||||||
|
self.border.top = style.Border.border_top_width;
|
||||||
|
self.border.right = style.Border.border_right_width;
|
||||||
|
self.border.bottom = style.Border.border_bottom_width;
|
||||||
|
self.border.left = style.Border.border_left_width;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_noncontent_width(&self) -> Au {
|
/// Populates the box model padding parameters from the given computed style.
|
||||||
let model_ref = self.model.mutate();
|
pub fn compute_padding(&mut self, style: &ComputedValues, containing_block_width: Au) {
|
||||||
model_ref.ptr.border.left + model_ref.ptr.padding.left + model_ref.ptr.border.right +
|
self.padding.top = self.compute_padding_length(style.Padding.padding_top,
|
||||||
model_ref.ptr.padding.right
|
containing_block_width);
|
||||||
|
self.padding.right = self.compute_padding_length(style.Padding.padding_right,
|
||||||
|
containing_block_width);
|
||||||
|
self.padding.bottom = self.compute_padding_length(style.Padding.padding_bottom,
|
||||||
|
containing_block_width);
|
||||||
|
self.padding.left = self.compute_padding_length(style.Padding.padding_left,
|
||||||
|
containing_block_width);
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn compute_padding_length(&self, padding: LengthOrPercentage, content_box_width: Au) -> Au {
|
||||||
|
specified(padding, content_box_width)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn noncontent_width(&self) -> Au {
|
||||||
|
let left = self.margin.left + self.border.left + self.padding.left;
|
||||||
|
let right = self.margin.right + self.border.right + self.padding.right;
|
||||||
|
left + right
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn noncontent_height(&self) -> Au {
|
||||||
|
let top = self.margin.top + self.border.top + self.padding.top;
|
||||||
|
let bottom = self.margin.bottom + self.border.bottom + self.padding.bottom;
|
||||||
|
top + bottom
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The box formed by the content edge as defined in CSS 2.1 § 8.1. Coordinates are relative to
|
/// The box formed by the content edge as defined in CSS 2.1 § 8.1. Coordinates are relative to
|
||||||
/// the owning flow.
|
/// the owning flow.
|
||||||
pub fn content_box(&self) -> Rect<Au> {
|
pub fn content_box(&self) -> Rect<Au> {
|
||||||
let (position, model) = (self.position.get(), self.model.get());
|
let position = self.position.get();
|
||||||
let origin = Point2D(position.origin.x + model.border.left + model.padding.left,
|
let origin = Point2D(position.origin.x + self.border.left + self.padding.left,
|
||||||
position.origin.y);
|
position.origin.y);
|
||||||
let size = Size2D(position.size.width - self.get_noncontent_width(), position.size.height);
|
let noncontent_width = self.border.left + self.padding.left + self.border.right + self.padding.right;
|
||||||
|
let size = Size2D(position.size.width - noncontent_width, position.size.height);
|
||||||
Rect(origin, size)
|
Rect(origin, size)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -824,6 +864,10 @@ impl RenderBoxBase {
|
||||||
get_propagated_text_decoration(self.nearest_ancestor_element())
|
get_propagated_text_decoration(self.nearest_ancestor_element())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn offset(&self) -> Au {
|
||||||
|
self.margin.left + self.border.left + self.padding.left
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RenderBoxUtils for @RenderBox {
|
impl RenderBoxUtils for @RenderBox {
|
||||||
|
@ -835,6 +879,13 @@ impl RenderBoxUtils for @RenderBox {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mut_base<'a>(&'a self) -> &'a mut RenderBoxBase {
|
||||||
|
unsafe {
|
||||||
|
let (_, box_ptr): (uint, *Box<RenderBoxBase>) = cast::transmute(*self);
|
||||||
|
cast::transmute_mut(&(*box_ptr).data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn is_replaced(&self) -> bool {
|
fn is_replaced(&self) -> bool {
|
||||||
self.class() == ImageRenderBoxClass
|
self.class() == ImageRenderBoxClass
|
||||||
}
|
}
|
||||||
|
@ -894,7 +945,7 @@ impl RenderBoxUtils for @RenderBox {
|
||||||
abs_bounds: &Rect<Au>) {
|
abs_bounds: &Rect<Au>) {
|
||||||
// Fast path.
|
// Fast path.
|
||||||
let base = self.base();
|
let base = self.base();
|
||||||
let border = base.model.get().border;
|
let border = base.border;
|
||||||
if border.is_zero() {
|
if border.is_zero() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -1115,5 +1166,13 @@ impl<'self> RenderBoxRefUtils<'self> for &'self RenderBox {
|
||||||
cast::transmute(box_ptr)
|
cast::transmute(box_ptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn mut_base(self) -> &'self mut RenderBoxBase {
|
||||||
|
unsafe {
|
||||||
|
let (_, box_ptr): (uint, *mut RenderBoxBase) = cast::transmute(self);
|
||||||
|
cast::transmute(box_ptr)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,8 +127,7 @@ impl FlowContext for FloatFlow {
|
||||||
|
|
||||||
for box in self.box.iter() {
|
for box in self.box.iter() {
|
||||||
{
|
{
|
||||||
let base = box.base();
|
box.mut_base().compute_borders(box.base().style());
|
||||||
base.model.mutate().ptr.compute_borders(base.style());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let (this_minimum_width, this_preferred_width) = box.minimum_and_preferred_widths();
|
let (this_minimum_width, this_preferred_width) = box.minimum_and_preferred_widths();
|
||||||
|
@ -153,13 +152,13 @@ impl FlowContext for FloatFlow {
|
||||||
|
|
||||||
for &box in self.box.iter() {
|
for &box in self.box.iter() {
|
||||||
let base = box.base();
|
let base = box.base();
|
||||||
|
let mut_base = box.mut_base();
|
||||||
let style = base.style();
|
let style = base.style();
|
||||||
let mut position_ref = base.position.mutate();
|
let mut position_ref = base.position.mutate();
|
||||||
let mut model_ref = base.model.mutate();
|
let position = &mut position_ref.ptr;
|
||||||
let (position, model) = (&mut position_ref.ptr, &mut model_ref.ptr);
|
|
||||||
|
|
||||||
// Can compute padding here since we know containing block width.
|
// Can compute padding here since we know containing block width.
|
||||||
model.compute_padding(style, remaining_width);
|
mut_base.compute_padding(style, remaining_width);
|
||||||
|
|
||||||
// Margins for floats are 0 if auto.
|
// Margins for floats are 0 if auto.
|
||||||
let margin_top = MaybeAuto::from_style(style.Margin.margin_top,
|
let margin_top = MaybeAuto::from_style(style.Margin.margin_top,
|
||||||
|
@ -180,19 +179,19 @@ impl FlowContext for FloatFlow {
|
||||||
remaining_width).specified_or_default(shrink_to_fit);
|
remaining_width).specified_or_default(shrink_to_fit);
|
||||||
debug!("assign_widths_float -- width: {}", width);
|
debug!("assign_widths_float -- width: {}", width);
|
||||||
|
|
||||||
model.margin.top = margin_top;
|
mut_base.margin.top = margin_top;
|
||||||
model.margin.right = margin_right;
|
mut_base.margin.right = margin_right;
|
||||||
model.margin.bottom = margin_bottom;
|
mut_base.margin.bottom = margin_bottom;
|
||||||
model.margin.left = margin_left;
|
mut_base.margin.left = margin_left;
|
||||||
|
|
||||||
x_offset = model.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.
|
||||||
position.origin.x = model.margin.left;
|
position.origin.x = base.margin.left;
|
||||||
|
|
||||||
let padding_and_borders = model.padding.left + model.padding.right +
|
let padding_and_borders = base.padding.left + base.padding.right +
|
||||||
model.border.left + model.border.right;
|
base.border.left + base.border.right;
|
||||||
position.size.width = remaining_width + padding_and_borders;
|
position.size.width = remaining_width + padding_and_borders;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -231,12 +230,11 @@ impl FlowContext for FloatFlow {
|
||||||
Some(clear) => self.base.floats_in.clearance(clear),
|
Some(clear) => self.base.floats_in.clearance(clear),
|
||||||
};
|
};
|
||||||
|
|
||||||
let model = base.model.get();
|
let noncontent_width = base.padding.left + base.padding.right + base.border.left +
|
||||||
let noncontent_width = model.padding.left + model.padding.right + model.border.left +
|
base.border.right;
|
||||||
model.border.right;
|
|
||||||
|
|
||||||
full_noncontent_width = noncontent_width + model.margin.left + model.margin.right;
|
full_noncontent_width = noncontent_width + base.margin.left + base.margin.right;
|
||||||
margin_height = model.margin.top + model.margin.bottom;
|
margin_height = base.margin.top + base.margin.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
let info = PlacementInfo {
|
let info = PlacementInfo {
|
||||||
|
@ -270,9 +268,7 @@ impl FlowContext for FloatFlow {
|
||||||
|
|
||||||
for &box in self.box.iter() {
|
for &box in self.box.iter() {
|
||||||
let base = box.base();
|
let base = box.base();
|
||||||
let model_ref = base.model.borrow();
|
top_offset = base.margin.top + base.border.top + base.padding.top;
|
||||||
top_offset = model_ref.ptr.margin.top + model_ref.ptr.border.top +
|
|
||||||
model_ref.ptr.padding.top;
|
|
||||||
cur_y = cur_y + top_offset;
|
cur_y = cur_y + top_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,15 +283,14 @@ impl FlowContext for FloatFlow {
|
||||||
let mut noncontent_height;
|
let mut noncontent_height;
|
||||||
for box in self.box.iter() {
|
for box in self.box.iter() {
|
||||||
let base = box.base();
|
let base = box.base();
|
||||||
let mut model_ref = base.model.mutate();
|
|
||||||
let mut position_ref = base.position.mutate();
|
let mut position_ref = base.position.mutate();
|
||||||
let (model, position) = (&mut model_ref.ptr, &mut position_ref.ptr);
|
let position = &mut position_ref.ptr;
|
||||||
|
|
||||||
// The associated box is the border box of this flow.
|
// The associated box is the border box of this flow.
|
||||||
position.origin.y = model.margin.top;
|
position.origin.y = base.margin.top;
|
||||||
|
|
||||||
noncontent_height = model.padding.top + model.padding.bottom + model.border.top +
|
noncontent_height = base.padding.top + base.padding.bottom + base.border.top +
|
||||||
model.border.bottom;
|
base.border.bottom;
|
||||||
|
|
||||||
//TODO(eatkinson): compute heights properly using the 'height' property.
|
//TODO(eatkinson): compute heights properly using the 'height' property.
|
||||||
let height_prop = MaybeAuto::from_style(base.style().Box.height,
|
let height_prop = MaybeAuto::from_style(base.style().Box.height,
|
||||||
|
|
|
@ -681,10 +681,10 @@ impl FlowContext for InlineFlow {
|
||||||
let mut top;
|
let mut top;
|
||||||
let mut bottom;
|
let mut bottom;
|
||||||
{
|
{
|
||||||
let model = image_box.base.model.get();
|
let base = &image_box.base;
|
||||||
top = model.border.top + model.padding.top + model.margin.top;
|
top = base.border.top + base.padding.top + base.margin.top;
|
||||||
bottom = model.border.bottom + model.padding.bottom +
|
bottom = base.border.bottom + base.padding.bottom +
|
||||||
model.margin.bottom;
|
base.margin.bottom;
|
||||||
}
|
}
|
||||||
|
|
||||||
let noncontent_height = top + bottom;
|
let noncontent_height = top + bottom;
|
||||||
|
|
|
@ -4,22 +4,9 @@
|
||||||
|
|
||||||
//! Borders, padding, and margins.
|
//! Borders, padding, and margins.
|
||||||
|
|
||||||
use std::num::Zero;
|
|
||||||
use geom::side_offsets::SideOffsets2D;
|
|
||||||
use servo_util::geometry::Au;
|
use servo_util::geometry::Au;
|
||||||
use style::ComputedValues;
|
|
||||||
use computed = style::computed_values;
|
use computed = style::computed_values;
|
||||||
|
|
||||||
/// Encapsulates the borders, padding, and margins, which we collectively call the "box model".
|
|
||||||
#[deriving(Clone)]
|
|
||||||
pub struct BoxModel {
|
|
||||||
border: SideOffsets2D<Au>,
|
|
||||||
padding: SideOffsets2D<Au>,
|
|
||||||
margin: SideOffsets2D<Au>,
|
|
||||||
/// The width of the content box.
|
|
||||||
content_box_width: Au,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Useful helper data type when computing values for blocks and positioned elements.
|
/// Useful helper data type when computing values for blocks and positioned elements.
|
||||||
pub enum MaybeAuto {
|
pub enum MaybeAuto {
|
||||||
Auto,
|
Auto,
|
||||||
|
@ -51,63 +38,6 @@ impl MaybeAuto {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Zero for BoxModel {
|
|
||||||
fn zero() -> BoxModel {
|
|
||||||
BoxModel {
|
|
||||||
border: Zero::zero(),
|
|
||||||
padding: Zero::zero(),
|
|
||||||
margin: Zero::zero(),
|
|
||||||
content_box_width: Zero::zero(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn is_zero(&self) -> bool {
|
|
||||||
self.padding.is_zero() && self.border.is_zero() && self.margin.is_zero()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl BoxModel {
|
|
||||||
/// Populates the box model border parameters from the given computed style.
|
|
||||||
pub fn compute_borders(&mut self, style: &ComputedValues) {
|
|
||||||
self.border.top = style.Border.border_top_width;
|
|
||||||
self.border.right = style.Border.border_right_width;
|
|
||||||
self.border.bottom = style.Border.border_bottom_width;
|
|
||||||
self.border.left = style.Border.border_left_width;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Populates the box model padding parameters from the given computed style.
|
|
||||||
pub fn compute_padding(&mut self, style: &ComputedValues, containing_width: Au) {
|
|
||||||
self.padding.top = self.compute_padding_length(style.Padding.padding_top,
|
|
||||||
containing_width);
|
|
||||||
self.padding.right = self.compute_padding_length(style.Padding.padding_right,
|
|
||||||
containing_width);
|
|
||||||
self.padding.bottom = self.compute_padding_length(style.Padding.padding_bottom,
|
|
||||||
containing_width);
|
|
||||||
self.padding.left = self.compute_padding_length(style.Padding.padding_left,
|
|
||||||
containing_width);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn noncontent_width(&self) -> Au {
|
|
||||||
let left = self.margin.left + self.border.left + self.padding.left;
|
|
||||||
let right = self.margin.right + self.border.right + self.padding.right;
|
|
||||||
left + right
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn noncontent_height(&self) -> Au {
|
|
||||||
let top = self.margin.top + self.border.top + self.padding.top;
|
|
||||||
let bottom = self.margin.bottom + self.border.bottom + self.padding.bottom;
|
|
||||||
top + bottom
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn offset(&self) -> Au {
|
|
||||||
self.margin.left + self.border.left + self.padding.left
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn compute_padding_length(&self, padding: computed::LengthOrPercentage, content_box_width: Au) -> Au {
|
|
||||||
specified(padding, content_box_width)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn specified_or_none(length: computed::LengthOrPercentageOrNone, containing_length: Au) -> Option<Au> {
|
pub fn specified_or_none(length: computed::LengthOrPercentageOrNone, containing_length: Au) -> Option<Au> {
|
||||||
match length {
|
match length {
|
||||||
computed::LPN_None => None,
|
computed::LPN_None => None,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue