mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
layout: Unify the block-size computation for blocks and floats.
The float code was old and did not support most of CSS 2.1. So unifying the two paths both simplifies code and improves functionality. Improves the Reddit sidebar.
This commit is contained in:
parent
c2d6d8084c
commit
9f4c2de211
6 changed files with 86 additions and 140 deletions
|
@ -38,7 +38,6 @@ use gfx::display_list::{RootOfStackingContextLevel};
|
||||||
use gfx::render_task::RenderLayer;
|
use gfx::render_task::RenderLayer;
|
||||||
use servo_msg::compositor_msg::{FixedPosition, LayerId, Scrollable};
|
use servo_msg::compositor_msg::{FixedPosition, LayerId, Scrollable};
|
||||||
use servo_util::geometry::{Au, MAX_AU};
|
use servo_util::geometry::{Au, MAX_AU};
|
||||||
use servo_util::logical_geometry::WritingMode;
|
|
||||||
use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize};
|
use servo_util::logical_geometry::{LogicalPoint, LogicalRect, LogicalSize};
|
||||||
use std::cmp::{max, min};
|
use std::cmp::{max, min};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
@ -49,12 +48,14 @@ use style::computed_values::{display, float, overflow};
|
||||||
use sync::Arc;
|
use sync::Arc;
|
||||||
|
|
||||||
/// Information specific to floated blocks.
|
/// Information specific to floated blocks.
|
||||||
#[deriving(Encodable)]
|
#[deriving(Clone, Encodable)]
|
||||||
pub struct FloatedBlockInfo {
|
pub struct FloatedBlockInfo {
|
||||||
|
/// The amount of inline size that is available for the float.
|
||||||
pub containing_inline_size: Au,
|
pub containing_inline_size: Au,
|
||||||
|
|
||||||
/// Offset relative to where the parent tried to position this flow
|
/// The float ceiling, relative to `BaseFlow::position::cur_b` (i.e. the top part of the border
|
||||||
pub rel_pos: LogicalPoint<Au>,
|
/// box).
|
||||||
|
pub float_ceiling: Au,
|
||||||
|
|
||||||
/// Index into the fragment list for inline floats
|
/// Index into the fragment list for inline floats
|
||||||
pub index: Option<uint>,
|
pub index: Option<uint>,
|
||||||
|
@ -64,10 +65,10 @@ pub struct FloatedBlockInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FloatedBlockInfo {
|
impl FloatedBlockInfo {
|
||||||
pub fn new(float_kind: FloatKind, writing_mode: WritingMode) -> FloatedBlockInfo {
|
pub fn new(float_kind: FloatKind) -> FloatedBlockInfo {
|
||||||
FloatedBlockInfo {
|
FloatedBlockInfo {
|
||||||
containing_inline_size: Au(0),
|
containing_inline_size: Au(0),
|
||||||
rel_pos: LogicalPoint::new(writing_mode, Au(0), Au(0)),
|
float_ceiling: Au(0),
|
||||||
index: None,
|
index: None,
|
||||||
float_kind: float_kind,
|
float_kind: float_kind,
|
||||||
}
|
}
|
||||||
|
@ -550,7 +551,7 @@ impl BlockFlow {
|
||||||
is_root: false,
|
is_root: false,
|
||||||
static_b_offset: Au::new(0),
|
static_b_offset: Au::new(0),
|
||||||
previous_float_inline_size: None,
|
previous_float_inline_size: None,
|
||||||
float: Some(box FloatedBlockInfo::new(float_kind, base.writing_mode)),
|
float: Some(box FloatedBlockInfo::new(float_kind)),
|
||||||
base: base,
|
base: base,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -565,7 +566,7 @@ impl BlockFlow {
|
||||||
is_root: false,
|
is_root: false,
|
||||||
static_b_offset: Au::new(0),
|
static_b_offset: Au::new(0),
|
||||||
previous_float_inline_size: None,
|
previous_float_inline_size: None,
|
||||||
float: Some(box FloatedBlockInfo::new(float_kind, base.writing_mode)),
|
float: Some(box FloatedBlockInfo::new(float_kind)),
|
||||||
base: base,
|
base: base,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -813,21 +814,21 @@ impl BlockFlow {
|
||||||
|
|
||||||
/// Assign block-size for current flow.
|
/// Assign block-size for current flow.
|
||||||
///
|
///
|
||||||
/// * Collapse margins for flow's children and set in-flow child flows' y-coordinates now that
|
/// * Collapse margins for flow's children and set in-flow child flows' block offsets now that
|
||||||
/// we know their block-sizes.
|
/// we know their block-sizes.
|
||||||
/// * Calculate and set the block-size of the current flow.
|
/// * Calculate and set the block-size of the current flow.
|
||||||
/// * Calculate block-size, vertical margins, and y-coordinate for the flow's box. Ideally, this
|
/// * Calculate block-size, vertical margins, and block offset for the flow's box using CSS §
|
||||||
/// should be calculated using CSS § 10.6.7.
|
/// 10.6.7.
|
||||||
///
|
///
|
||||||
/// For absolute flows, we store the calculated content block-size for the flow. We defer the
|
/// For absolute flows, we store the calculated content block-size for the flow. We defer the
|
||||||
/// calculation of the other values until a later traversal.
|
/// calculation of the other values until a later traversal.
|
||||||
///
|
///
|
||||||
/// `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)]
|
||||||
pub fn assign_block_size_block_base<'a>(&mut self,
|
pub fn assign_block_size_block_base<'a>(&mut self,
|
||||||
layout_context: &'a LayoutContext<'a>,
|
layout_context: &'a LayoutContext<'a>,
|
||||||
margins_may_collapse: MarginsMayCollapseFlag) {
|
margins_may_collapse: MarginsMayCollapseFlag) {
|
||||||
let _scope = layout_debug_scope!("assign_block_size_block_base {:s}", self.base.debug_id());
|
let _scope = layout_debug_scope!("assign_block_size_block_base {:s}", self.base.debug_id());
|
||||||
|
|
||||||
// Our current border-box position.
|
// Our current border-box position.
|
||||||
|
@ -835,10 +836,7 @@ impl BlockFlow {
|
||||||
|
|
||||||
// Absolute positioning establishes a block formatting context. Don't propagate floats
|
// Absolute positioning establishes a block formatting context. Don't propagate floats
|
||||||
// in or out. (But do propagate them between kids.)
|
// in or out. (But do propagate them between kids.)
|
||||||
if self.is_absolutely_positioned() {
|
if self.is_absolutely_positioned() || margins_may_collapse != MarginsMayCollapse {
|
||||||
self.base.floats = Floats::new(self.fragment.style.writing_mode);
|
|
||||||
}
|
|
||||||
if margins_may_collapse != MarginsMayCollapse {
|
|
||||||
self.base.floats = Floats::new(self.fragment.style.writing_mode);
|
self.base.floats = Floats::new(self.fragment.style.writing_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -854,8 +852,9 @@ impl BlockFlow {
|
||||||
margins_may_collapse == MarginsMayCollapse &&
|
margins_may_collapse == MarginsMayCollapse &&
|
||||||
!self.is_absolutely_positioned() &&
|
!self.is_absolutely_positioned() &&
|
||||||
self.fragment.border_padding.block_start == Au(0);
|
self.fragment.border_padding.block_start == Au(0);
|
||||||
margin_collapse_info.initialize_block_start_margin(&self.fragment,
|
margin_collapse_info.initialize_block_start_margin(
|
||||||
can_collapse_block_start_margin_with_kids);
|
&self.fragment,
|
||||||
|
can_collapse_block_start_margin_with_kids);
|
||||||
|
|
||||||
// At this point, `cur_b` is at the content edge of our box. Now iterate over children.
|
// At this point, `cur_b` is at the content edge of our box. Now iterate over children.
|
||||||
let mut floats = self.base.floats.clone();
|
let mut floats = self.base.floats.clone();
|
||||||
|
@ -873,13 +872,16 @@ impl BlockFlow {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Assign block-size now for the child if it was impacted by floats and we couldn't before.
|
// Assign block-size now for the child if it was impacted by floats and we couldn't
|
||||||
|
// before.
|
||||||
flow::mut_base(kid).floats = floats.clone();
|
flow::mut_base(kid).floats = floats.clone();
|
||||||
if kid.is_float() {
|
if kid.is_float() {
|
||||||
// FIXME(pcwalton): Using `position.start.b` to mean the float ceiling is a
|
flow::mut_base(kid).position.start.b = cur_b;
|
||||||
// bit of a hack.
|
{
|
||||||
flow::mut_base(kid).position.start.b =
|
let kid_block = kid.as_block();
|
||||||
margin_collapse_info.current_float_ceiling();
|
kid_block.float.as_mut().unwrap().float_ceiling =
|
||||||
|
margin_collapse_info.current_float_ceiling();
|
||||||
|
}
|
||||||
propagate_layer_flag_from_child(&mut layers_needed_for_descendants, kid);
|
propagate_layer_flag_from_child(&mut layers_needed_for_descendants, kid);
|
||||||
|
|
||||||
let need_to_process_child_floats =
|
let need_to_process_child_floats =
|
||||||
|
@ -887,7 +889,6 @@ impl BlockFlow {
|
||||||
assert!(need_to_process_child_floats); // As it was a float itself...
|
assert!(need_to_process_child_floats); // As it was a float itself...
|
||||||
|
|
||||||
let kid_base = flow::mut_base(kid);
|
let kid_base = flow::mut_base(kid);
|
||||||
kid_base.position.start.b = cur_b;
|
|
||||||
floats = kid_base.floats.clone();
|
floats = kid_base.floats.clone();
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -928,7 +929,7 @@ impl BlockFlow {
|
||||||
flow::mut_base(kid).position.start.b = cur_b;
|
flow::mut_base(kid).position.start.b = cur_b;
|
||||||
|
|
||||||
// Now pull out the child's outgoing floats. We didn't do this immediately after the
|
// Now pull out the child's outgoing floats. We didn't do this immediately after the
|
||||||
// `assign_block-size_for_inorder_child_if_necessary` call because clearance on a block
|
// `assign_block_size_for_inorder_child_if_necessary` call because clearance on a block
|
||||||
// operates on the floats that come *in*, not the floats that go *out*.
|
// operates on the floats that come *in*, not the floats that go *out*.
|
||||||
if need_to_process_child_floats {
|
if need_to_process_child_floats {
|
||||||
floats = flow::mut_base(kid).floats.clone()
|
floats = flow::mut_base(kid).floats.clone()
|
||||||
|
@ -940,7 +941,8 @@ impl BlockFlow {
|
||||||
cur_b = cur_b + kid_base.position.size.block;
|
cur_b = cur_b + kid_base.position.size.block;
|
||||||
|
|
||||||
// Handle any (possibly collapsed) block-end margin.
|
// Handle any (possibly collapsed) block-end margin.
|
||||||
let delta = margin_collapse_info.advance_block_end_margin(&kid_base.collapsible_margins);
|
let delta =
|
||||||
|
margin_collapse_info.advance_block_end_margin(&kid_base.collapsible_margins);
|
||||||
translate_including_floats(&mut cur_b, delta, &mut floats);
|
translate_including_floats(&mut cur_b, delta, &mut floats);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -974,11 +976,13 @@ impl BlockFlow {
|
||||||
block_size = Au::max(screen_size.block, block_size)
|
block_size = Au::max(screen_size.block, block_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.is_absolutely_positioned() {
|
if self.is_float() || self.is_absolutely_positioned() {
|
||||||
// The content block-size includes all the floats per CSS 2.1 § 10.6.7. The easiest way to
|
// The content block-size includes all the floats per CSS 2.1 § 10.6.7. The easiest way
|
||||||
// handle this is to just treat this as clearance.
|
// to handle this is to just treat this as clearance.
|
||||||
block_size = block_size + floats.clearance(ClearBoth);
|
block_size = block_size + floats.clearance(ClearBoth);
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.is_absolutely_positioned() {
|
||||||
// Fixed position layers get layers.
|
// Fixed position layers get layers.
|
||||||
if self.is_fixed() {
|
if self.is_fixed() {
|
||||||
self.base.flags.set_needs_layer(true)
|
self.base.flags.set_needs_layer(true)
|
||||||
|
@ -990,10 +994,11 @@ impl BlockFlow {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Compute any explicitly-specified block size.
|
||||||
|
// Can't use `for` because we assign to `candidate_block_size_iterator.candidate_value`.
|
||||||
let mut candidate_block_size_iterator = CandidateBSizeIterator::new(
|
let mut candidate_block_size_iterator = CandidateBSizeIterator::new(
|
||||||
self.fragment.style(),
|
self.fragment.style(),
|
||||||
self.base.block_container_explicit_block_size);
|
self.base.block_container_explicit_block_size);
|
||||||
// Can't use `for` because we assign to candidate_block_size_iterator.candidate_value
|
|
||||||
loop {
|
loop {
|
||||||
match candidate_block_size_iterator.next() {
|
match candidate_block_size_iterator.next() {
|
||||||
Some(candidate_block_size) => {
|
Some(candidate_block_size) => {
|
||||||
|
@ -1021,13 +1026,15 @@ impl BlockFlow {
|
||||||
self.fragment.border_box.start.b = Au(0);
|
self.fragment.border_box.start.b = Au(0);
|
||||||
self.base.position.size.block = cur_b;
|
self.base.position.size.block = cur_b;
|
||||||
|
|
||||||
|
// Store the current set of floats in the flow so that flows that come later in the
|
||||||
|
// document can access them.
|
||||||
self.base.floats = floats.clone();
|
self.base.floats = floats.clone();
|
||||||
self.adjust_fragments_for_collapsed_margins_if_root();
|
self.adjust_fragments_for_collapsed_margins_if_root();
|
||||||
|
|
||||||
if self.is_root_of_absolute_flow_tree() {
|
if self.is_root_of_absolute_flow_tree() {
|
||||||
// Assign block-sizes for all flows in this Absolute flow tree.
|
// Assign block-sizes for all flows in this absolute flow tree.
|
||||||
// This is preorder because the block-size of an absolute flow may depend on
|
// This is preorder because the block-size of an absolute flow may depend on
|
||||||
// the block-size of its CB, which may also be an absolute flow.
|
// the block-size of its containing block, which may also be an absolute flow.
|
||||||
self.traverse_preorder_absolute_flows(&mut AbsoluteAssignBSizesTraversal(
|
self.traverse_preorder_absolute_flows(&mut AbsoluteAssignBSizesTraversal(
|
||||||
layout_context));
|
layout_context));
|
||||||
// Store overflow for all absolute descendants.
|
// Store overflow for all absolute descendants.
|
||||||
|
@ -1054,109 +1061,46 @@ impl BlockFlow {
|
||||||
Some(clear) => self.base.floats.clearance(clear),
|
Some(clear) => self.base.floats.clearance(clear),
|
||||||
};
|
};
|
||||||
|
|
||||||
let margin_block_size = self.fragment.margin.block_start_end();
|
let float_info: FloatedBlockInfo = (**self.float.as_ref().unwrap()).clone();
|
||||||
let info = PlacementInfo {
|
let info = PlacementInfo {
|
||||||
size: LogicalSize::new(
|
size: LogicalSize::new(
|
||||||
self.fragment.style.writing_mode,
|
self.fragment.style.writing_mode,
|
||||||
self.base.position.size.inline + self.fragment.margin.inline_start_end() +
|
self.base.position.size.inline + self.fragment.margin.inline_start_end() +
|
||||||
self.fragment.border_padding.inline_start_end(),
|
self.fragment.border_padding.inline_start_end(),
|
||||||
block_size + margin_block_size),
|
block_size + self.fragment.margin.block_start_end()),
|
||||||
ceiling: clearance + self.base.position.start.b,
|
ceiling: clearance + float_info.float_ceiling,
|
||||||
max_inline_size: self.float.as_ref().unwrap().containing_inline_size,
|
max_inline_size: float_info.containing_inline_size,
|
||||||
kind: self.float.as_ref().unwrap().float_kind,
|
kind: float_info.float_kind,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Place the float and return the `Floats` back to the parent flow.
|
// Place the float and return the `Floats` back to the parent flow.
|
||||||
// After, grab the position and use that to set our position.
|
// After, grab the position and use that to set our position.
|
||||||
self.base.floats.add_float(&info);
|
self.base.floats.add_float(&info);
|
||||||
|
|
||||||
self.float.as_mut().unwrap().rel_pos = self.base.floats.last_float_pos().unwrap();
|
// Move in from the margin edge, as per CSS 2.1 § 9.5, floats may not overlap anything on
|
||||||
}
|
// their margin edges.
|
||||||
|
let float_offset = self.base.floats.last_float_pos().unwrap();
|
||||||
/// Assign block-size for current flow.
|
let writing_mode = self.base.floats.writing_mode;
|
||||||
///
|
let margin_offset = LogicalPoint::new(writing_mode,
|
||||||
/// + Set in-flow child flows' y-coordinates now that we know their
|
Au(0),
|
||||||
/// block-sizes. This _doesn't_ do any margin collapsing for its children.
|
self.fragment.margin.block_start);
|
||||||
/// + Calculate block-size and y-coordinate for the flow's box. Ideally, this
|
self.base.position = self.base.position.translate(&float_offset).translate(&margin_offset);
|
||||||
/// should be calculated using CSS Section 10.6.7
|
|
||||||
///
|
|
||||||
/// It does not calculate the block-size of the flow itself.
|
|
||||||
pub fn assign_block_size_float<'a>(&mut self, ctx: &'a LayoutContext<'a>) {
|
|
||||||
let _scope = layout_debug_scope!("assign_block_size_float {:s}", self.base.debug_id());
|
|
||||||
|
|
||||||
let mut floats = Floats::new(self.fragment.style.writing_mode);
|
|
||||||
for kid in self.base.child_iter() {
|
|
||||||
flow::mut_base(kid).floats = floats.clone();
|
|
||||||
kid.assign_block_size_for_inorder_child_if_necessary(ctx);
|
|
||||||
floats = flow::mut_base(kid).floats.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
let block_start_offset = self.fragment.margin.block_start + self.fragment.border_padding.block_start;
|
|
||||||
let mut cur_b = block_start_offset;
|
|
||||||
|
|
||||||
// cur_b is now at the block-start content edge
|
|
||||||
|
|
||||||
for kid in self.base.child_iter() {
|
|
||||||
let child_base = flow::mut_base(kid);
|
|
||||||
child_base.position.start.b = cur_b;
|
|
||||||
// cur_b is now at the block-end margin edge of kid
|
|
||||||
cur_b = cur_b + child_base.position.size.block;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Intrinsic height should include floating descendants with a margin
|
|
||||||
// below the element's bottom edge (see CSS Section 10.6.7).
|
|
||||||
let content_block_size = max(
|
|
||||||
cur_b - block_start_offset,
|
|
||||||
floats.clearance(ClearBoth));
|
|
||||||
|
|
||||||
// Floats establish a block formatting context, so we discard the output floats here.
|
|
||||||
drop(floats);
|
|
||||||
|
|
||||||
// The associated fragment has the border box of this flow.
|
|
||||||
self.fragment.border_box.start.b = self.fragment.margin.block_start;
|
|
||||||
|
|
||||||
// Calculate content block-size, taking `min-block-size` and `max-block-size` into account.
|
|
||||||
let mut candidate_block_size_iterator =
|
|
||||||
CandidateBSizeIterator::new(self.fragment.style(),
|
|
||||||
self.base.block_container_explicit_block_size);
|
|
||||||
// Can't use `for` because we assign to candidate_block_size_iterator.candidate_value
|
|
||||||
loop {
|
|
||||||
match candidate_block_size_iterator.next() {
|
|
||||||
Some(candidate_block_size) => {
|
|
||||||
candidate_block_size_iterator.candidate_value = match candidate_block_size {
|
|
||||||
Auto => content_block_size,
|
|
||||||
Specified(value) => value,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => break,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let content_block_size = candidate_block_size_iterator.candidate_value;
|
|
||||||
let noncontent_block_size = self.fragment.border_padding.block_start_end();
|
|
||||||
debug!("assign_block_size_float -- block_size: {}", content_block_size + noncontent_block_size);
|
|
||||||
self.fragment.border_box.size.block = content_block_size + noncontent_block_size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_display_list_block_common(&mut self,
|
fn build_display_list_block_common(&mut self,
|
||||||
layout_context: &LayoutContext,
|
layout_context: &LayoutContext,
|
||||||
offset: LogicalPoint<Au>,
|
|
||||||
background_border_level: BackgroundAndBorderLevel) {
|
background_border_level: BackgroundAndBorderLevel) {
|
||||||
let rel_offset =
|
let rel_offset =
|
||||||
self.fragment.relative_position(&self.base
|
self.fragment.relative_position(&self.base
|
||||||
.absolute_position_info
|
.absolute_position_info
|
||||||
.relative_containing_block_size);
|
.relative_containing_block_size);
|
||||||
|
|
||||||
// FIXME(#2795): Get the real container size
|
|
||||||
let container_size = Size2D::zero();
|
|
||||||
|
|
||||||
// Add the box that starts the block context.
|
// Add the box that starts the block context.
|
||||||
let mut display_list = DisplayList::new();
|
let mut display_list = DisplayList::new();
|
||||||
let mut accumulator = self.fragment.build_display_list(
|
let mut accumulator = self.fragment.build_display_list(
|
||||||
&mut display_list,
|
&mut display_list,
|
||||||
layout_context,
|
layout_context,
|
||||||
self.base.abs_position + (offset + rel_offset).to_physical(
|
self.base.abs_position.add_size(&rel_offset.to_physical(self.base.writing_mode)),
|
||||||
self.base.writing_mode, container_size),
|
|
||||||
background_border_level);
|
background_border_level);
|
||||||
|
|
||||||
let mut child_layers = DList::new();
|
let mut child_layers = DList::new();
|
||||||
|
@ -1194,17 +1138,12 @@ impl BlockFlow {
|
||||||
} else if self.is_absolutely_positioned() {
|
} else if self.is_absolutely_positioned() {
|
||||||
self.build_display_list_abs(layout_context)
|
self.build_display_list_abs(layout_context)
|
||||||
} else {
|
} else {
|
||||||
let writing_mode = self.base.writing_mode;
|
self.build_display_list_block_common(layout_context, BlockLevel)
|
||||||
self.build_display_list_block_common(
|
|
||||||
layout_context, LogicalPoint::zero(writing_mode), BlockLevel)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_display_list_float(&mut self, layout_context: &LayoutContext) {
|
pub fn build_display_list_float(&mut self, layout_context: &LayoutContext) {
|
||||||
let float_offset = self.float.as_ref().unwrap().rel_pos;
|
self.build_display_list_block_common(layout_context, RootOfStackingContextLevel);
|
||||||
self.build_display_list_block_common(layout_context,
|
|
||||||
float_offset,
|
|
||||||
RootOfStackingContextLevel);
|
|
||||||
self.base.display_list = mem::replace(&mut self.base.display_list,
|
self.base.display_list = mem::replace(&mut self.base.display_list,
|
||||||
DisplayList::new()).flatten(FloatStackingLevel)
|
DisplayList::new()).flatten(FloatStackingLevel)
|
||||||
}
|
}
|
||||||
|
@ -1305,10 +1244,7 @@ impl BlockFlow {
|
||||||
|
|
||||||
/// Add display items for Absolutely Positioned flow.
|
/// Add display items for Absolutely Positioned flow.
|
||||||
fn build_display_list_abs(&mut self, layout_context: &LayoutContext) {
|
fn build_display_list_abs(&mut self, layout_context: &LayoutContext) {
|
||||||
let writing_mode = self.base.writing_mode;
|
self.build_display_list_block_common(layout_context, RootOfStackingContextLevel);
|
||||||
self.build_display_list_block_common(layout_context,
|
|
||||||
LogicalPoint::zero(writing_mode),
|
|
||||||
RootOfStackingContextLevel);
|
|
||||||
|
|
||||||
if !self.base.absolute_position_info.layers_needed_for_positioned_flows &&
|
if !self.base.absolute_position_info.layers_needed_for_positioned_flows &&
|
||||||
!self.base.flags.needs_layer() {
|
!self.base.flags.needs_layer() {
|
||||||
|
@ -1729,10 +1665,7 @@ impl Flow for BlockFlow {
|
||||||
// Assign block-size for fragment if it is an image fragment.
|
// Assign block-size for fragment if it is an image fragment.
|
||||||
self.fragment.assign_replaced_block_size_if_necessary();
|
self.fragment.assign_replaced_block_size_if_necessary();
|
||||||
self.base.position.size.block = self.fragment.border_box.size.block;
|
self.base.position.size.block = self.fragment.border_box.size.block;
|
||||||
} else if self.is_float() {
|
} else if self.is_root() || self.is_float() {
|
||||||
debug!("assign_block_size_float: assigning block_size for float");
|
|
||||||
self.assign_block_size_float(ctx);
|
|
||||||
} else if self.is_root() {
|
|
||||||
// Root element margins should never be collapsed according to CSS § 8.3.1.
|
// Root element margins should never be collapsed according to CSS § 8.3.1.
|
||||||
debug!("assign_block_size: assigning block_size for root flow");
|
debug!("assign_block_size: assigning block_size for root flow");
|
||||||
self.assign_block_size_block_base(ctx, MarginsMayNotCollapse);
|
self.assign_block_size_block_base(ctx, MarginsMayNotCollapse);
|
||||||
|
@ -1781,12 +1714,6 @@ impl Flow for BlockFlow {
|
||||||
+ relative_offset).to_physical(self.base.writing_mode, container_size)
|
+ relative_offset).to_physical(self.base.writing_mode, container_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
let float_offset = if self.is_float() {
|
|
||||||
self.float.as_ref().unwrap().rel_pos
|
|
||||||
} else {
|
|
||||||
LogicalPoint::zero(self.base.writing_mode)
|
|
||||||
};
|
|
||||||
|
|
||||||
// Compute absolute position info for children.
|
// Compute absolute position info for children.
|
||||||
let mut absolute_position_info = self.base.absolute_position_info;
|
let mut absolute_position_info = self.base.absolute_position_info;
|
||||||
absolute_position_info.relative_containing_block_size = self.fragment.content_box().size;
|
absolute_position_info.relative_containing_block_size = self.fragment.content_box().size;
|
||||||
|
@ -1799,10 +1726,10 @@ impl Flow for BlockFlow {
|
||||||
for kid in self.base.child_iter() {
|
for kid in self.base.child_iter() {
|
||||||
if !kid.is_absolutely_positioned() {
|
if !kid.is_absolutely_positioned() {
|
||||||
let kid_base = flow::mut_base(kid);
|
let kid_base = flow::mut_base(kid);
|
||||||
kid_base.abs_position = this_position + (
|
kid_base.abs_position =
|
||||||
kid_base.position.start
|
this_position +
|
||||||
.add_point(&float_offset)
|
(kid_base.position.start + relative_offset).to_physical(writing_mode,
|
||||||
+ relative_offset).to_physical(writing_mode, container_size);
|
container_size);
|
||||||
kid_base.absolute_position_info = absolute_position_info
|
kid_base.absolute_position_info = absolute_position_info
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -685,9 +685,7 @@ pub struct BaseFlow {
|
||||||
/// The children of this flow.
|
/// The children of this flow.
|
||||||
pub children: FlowList,
|
pub children: FlowList,
|
||||||
|
|
||||||
/* layout computations */
|
/// Intrinsic inline sizes for this flow.
|
||||||
// TODO: min/pref and position are used during disjoint phases of
|
|
||||||
// layout; maybe combine into a single enum to save space.
|
|
||||||
pub intrinsic_inline_sizes: IntrinsicISizes,
|
pub intrinsic_inline_sizes: IntrinsicISizes,
|
||||||
|
|
||||||
/// The upper left corner of the box representing this flow, relative to the box representing
|
/// The upper left corner of the box representing this flow, relative to the box representing
|
||||||
|
|
|
@ -282,7 +282,7 @@ impl Flow for TableWrapperFlow {
|
||||||
// Now compute the real value.
|
// Now compute the real value.
|
||||||
let containing_block_inline_size = self.block_flow.base.position.size.inline;
|
let containing_block_inline_size = self.block_flow.base.position.size.inline;
|
||||||
if self.is_float() {
|
if self.is_float() {
|
||||||
self.block_flow.float.get_mut_ref().containing_inline_size =
|
self.block_flow.float.as_mut().unwrap().containing_inline_size =
|
||||||
containing_block_inline_size;
|
containing_block_inline_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -145,3 +145,4 @@ flaky_gpu,flaky_linux == acid2_noscroll.html acid2_ref_broken.html
|
||||||
== block_formatting_context_relative_a.html block_formatting_context_ref.html
|
== block_formatting_context_relative_a.html block_formatting_context_ref.html
|
||||||
== block_formatting_context_translation_a.html block_formatting_context_translation_ref.html
|
== block_formatting_context_translation_a.html block_formatting_context_translation_ref.html
|
||||||
== floated_table_with_margin_a.html floated_table_with_margin_ref.html
|
== floated_table_with_margin_a.html floated_table_with_margin_ref.html
|
||||||
|
== margins_inside_floats_a.html margins_inside_floats_ref.html
|
||||||
|
|
10
tests/ref/margins_inside_floats_a.html
Normal file
10
tests/ref/margins_inside_floats_a.html
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<div style="float: left;">
|
||||||
|
<div style="margin-bottom: 64px;">Must be this tall</div>
|
||||||
|
<div style="margin-top: 64px;">to write multi-threaded code.</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
10
tests/ref/margins_inside_floats_ref.html
Normal file
10
tests/ref/margins_inside_floats_ref.html
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<div>
|
||||||
|
<div style="margin-bottom: 64px;">Must be this tall</div>
|
||||||
|
<div style="margin-top: 64px;">to write multi-threaded code.</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue