From 58b7005a9bb0e6c7a4c339bf82abec9b3b20eef2 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 13 Dec 2019 13:12:57 +0100 Subject: [PATCH] Make `for_maybe_position_relative` take care of relative adjustment. --- components/layout_2020/flow/inline.rs | 20 +++++------- components/layout_2020/flow/mod.rs | 18 ++++------- components/layout_2020/lib.rs | 30 ----------------- components/layout_2020/positioned.rs | 32 ++++++++++++++++++- .../style/properties/longhands/box.mako.rs | 3 ++ .../block-in-inline-relpos-001.xht.ini | 2 -- 6 files changed, 49 insertions(+), 56 deletions(-) delete mode 100644 tests/wpt/metadata-layout-2020/css/CSS2/box-display/block-in-inline-relpos-001.xht.ini diff --git a/components/layout_2020/flow/inline.rs b/components/layout_2020/flow/inline.rs index 82d946b42dc..93d7d6f8bdc 100644 --- a/components/layout_2020/flow/inline.rs +++ b/components/layout_2020/flow/inline.rs @@ -9,10 +9,10 @@ use crate::formatting_contexts::IndependentFormattingContext; use crate::fragments::CollapsedBlockMargins; use crate::fragments::{AnonymousFragment, BoxFragment, Fragment, TextFragment}; use crate::geom::flow_relative::{Rect, Sides, Vec2}; -use crate::positioned::{AbsolutelyPositionedBox, PositioningContext}; +use crate::positioned::{relative_adjustement, AbsolutelyPositionedBox, PositioningContext}; use crate::sizing::ContentSizes; use crate::style_ext::{ComputedValuesExt, Display, DisplayGeneratingBox, DisplayOutside}; -use crate::{relative_adjustement, ContainingBlock}; +use crate::ContainingBlock; use app_units::Au; use gfx::text::text_run::GlyphRun; use servo_arc::Arc; @@ -367,11 +367,9 @@ impl InlineBox { block: padding.block_start + border.block_start + margin.block_start, inline: ifc.inline_position - ifc.current_nesting_level.inline_start, }; - start_corner += &relative_adjustement( - &style, - ifc.containing_block.inline_size, - ifc.containing_block.block_size, - ); + if style.clone_position().is_relative() { + start_corner += &relative_adjustement(&style, ifc.containing_block) + } PartialInlineBoxFragment { style, start_corner, @@ -457,11 +455,9 @@ fn layout_atomic<'box_tree>( block: pbm.block_start, inline: ifc.inline_position - ifc.current_nesting_level.inline_start, }; - start_corner += &relative_adjustement( - &atomic.style, - ifc.containing_block.inline_size, - ifc.containing_block.block_size, - ); + if atomic.style.clone_position().is_relative() { + start_corner += &relative_adjustement(&atomic.style, ifc.containing_block) + } let fragment = match atomic.as_replaced() { Ok(replaced) => { diff --git a/components/layout_2020/flow/mod.rs b/components/layout_2020/flow/mod.rs index 34cce3a31a6..031e7fab787 100644 --- a/components/layout_2020/flow/mod.rs +++ b/components/layout_2020/flow/mod.rs @@ -14,7 +14,7 @@ use crate::geom::flow_relative::{Rect, Sides, Vec2}; use crate::positioned::{AbsolutelyPositionedBox, PositioningContext}; use crate::replaced::ReplacedContent; use crate::style_ext::ComputedValuesExt; -use crate::{relative_adjustement, ContainingBlock}; +use crate::ContainingBlock; use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, ParallelIterator}; use rayon_croissant::ParallelIteratorExt; use servo_arc::Arc; @@ -271,6 +271,7 @@ impl BlockLevelBox { BlockLevelBox::SameFormattingContextBlock { style, contents } => { Fragment::Box(positioning_context.for_maybe_position_relative( layout_context, + containing_block, style, |positioning_context| { layout_in_flow_non_replaced_block_level( @@ -288,6 +289,7 @@ impl BlockLevelBox { BlockLevelBox::Independent(contents) => { Fragment::Box(positioning_context.for_maybe_position_relative( layout_context, + containing_block, &contents.style, |positioning_context| match contents.as_replaced() { Ok(replaced) => layout_in_flow_replaced_block_level( @@ -470,14 +472,13 @@ fn layout_in_flow_non_replaced_block_level<'a>( content_block_size = independent_layout.content_block_size; }, }; - let relative_adjustement = relative_adjustement(style, inline_size, block_size); let block_size = block_size.auto_is(|| { content_block_size.clamp_between_extremums(min_box_size.block, max_box_size.block) }); let content_rect = Rect { start_corner: Vec2 { - block: pb.block_start + relative_adjustement.block, - inline: pb.inline_start + relative_adjustement.inline + margin.inline_start, + block: pb.block_start, + inline: pb.inline_start, }, size: Vec2 { block: block_size, @@ -525,15 +526,10 @@ fn layout_in_flow_replaced_block_level<'a>( block_end: computed_margin.block_end.auto_is(Length::zero), }; let fragments = replaced.make_fragments(style, size.clone()); - let relative_adjustement = relative_adjustement( - style, - size.inline, - LengthOrAuto::LengthPercentage(size.block), - ); let content_rect = Rect { start_corner: Vec2 { - block: pb.block_start + relative_adjustement.block, - inline: pb.inline_start + relative_adjustement.inline + margin.inline_start, + block: pb.block_start, + inline: pb.inline_start + margin.inline_start, }, size, }; diff --git a/components/layout_2020/lib.rs b/components/layout_2020/lib.rs index 8e923f870d7..b8cc003caf5 100644 --- a/components/layout_2020/lib.rs +++ b/components/layout_2020/lib.rs @@ -27,11 +27,8 @@ pub mod wrapper; pub use flow::{BoxTreeRoot, FragmentTreeRoot}; use crate::geom::flow_relative::Vec2; -use crate::style_ext::ComputedValuesExt; -use style::computed_values::position::T as Position; use style::properties::ComputedValues; use style::values::computed::{Length, LengthOrAuto}; -use style::Zero; struct ContainingBlock<'a> { inline_size: Length, @@ -53,30 +50,3 @@ impl<'a> From<&'_ DefiniteContainingBlock<'a>> for ContainingBlock<'a> { } } } - -/// https://drafts.csswg.org/css2/visuren.html#relative-positioning -fn relative_adjustement( - style: &ComputedValues, - inline_size: Length, - block_size: LengthOrAuto, -) -> Vec2 { - if style.get_box().position != Position::Relative { - return Vec2::zero(); - } - fn adjust(start: LengthOrAuto, end: LengthOrAuto) -> Length { - match (start, end) { - (LengthOrAuto::Auto, LengthOrAuto::Auto) => Length::zero(), - (LengthOrAuto::Auto, LengthOrAuto::LengthPercentage(end)) => -end, - (LengthOrAuto::LengthPercentage(start), _) => start, - } - } - let block_size = block_size.auto_is(Length::zero); - let box_offsets = style.box_offsets().map_inline_and_block_axes( - |v| v.percentage_relative_to(inline_size), - |v| v.percentage_relative_to(block_size), - ); - Vec2 { - inline: adjust(box_offsets.inline_start, box_offsets.inline_end), - block: adjust(box_offsets.block_start, box_offsets.block_end), - } -} diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs index bb7629da170..cfe615ae27d 100644 --- a/components/layout_2020/positioned.rs +++ b/components/layout_2020/positioned.rs @@ -150,11 +150,17 @@ impl<'box_tree> PositioningContext<'box_tree> { pub(crate) fn for_maybe_position_relative( &mut self, layout_context: &LayoutContext, + containing_block: &ContainingBlock, style: &ComputedValues, f: impl FnOnce(&mut Self) -> BoxFragment, ) -> BoxFragment { if style.clone_position() == Position::Relative { - Self::for_positioned(layout_context, &mut self.for_initial_containing_block, f) + let mut fragment = + // Establing a containing block for absolutely positioned descendants + Self::for_positioned(layout_context, &mut self.for_initial_containing_block, f); + + fragment.content_rect.start_corner += &relative_adjustement(style, containing_block); + fragment } else { f(self) } @@ -610,3 +616,27 @@ fn vec_append_owned(a: &mut Vec, mut b: Vec) { a.append(&mut b) } } + +/// https://drafts.csswg.org/css2/visuren.html#relative-positioning +pub(crate) fn relative_adjustement( + style: &ComputedValues, + containing_block: &ContainingBlock, +) -> Vec2 { + let cbis = containing_block.inline_size; + let cbbs = containing_block.block_size.auto_is(Length::zero); + let box_offsets = style.box_offsets().map_inline_and_block_axes( + |v| v.percentage_relative_to(cbis), + |v| v.percentage_relative_to(cbbs), + ); + fn adjust(start: LengthOrAuto, end: LengthOrAuto) -> Length { + match (start, end) { + (LengthOrAuto::Auto, LengthOrAuto::Auto) => Length::zero(), + (LengthOrAuto::Auto, LengthOrAuto::LengthPercentage(end)) => -end, + (LengthOrAuto::LengthPercentage(start), _) => start, + } + } + Vec2 { + inline: adjust(box_offsets.inline_start, box_offsets.inline_end), + block: adjust(box_offsets.block_start, box_offsets.block_end), + } +} diff --git a/components/style/properties/longhands/box.mako.rs b/components/style/properties/longhands/box.mako.rs index b8b6cbc8c34..aa6118b8a8a 100644 --- a/components/style/properties/longhands/box.mako.rs +++ b/components/style/properties/longhands/box.mako.rs @@ -55,6 +55,9 @@ impl computed_value::T { pub fn is_absolutely_positioned(self) -> bool { matches!(self, Self::Absolute | Self::Fixed) } + pub fn is_relative(self) -> bool { + self == Self::Relative + } } diff --git a/tests/wpt/metadata-layout-2020/css/CSS2/box-display/block-in-inline-relpos-001.xht.ini b/tests/wpt/metadata-layout-2020/css/CSS2/box-display/block-in-inline-relpos-001.xht.ini deleted file mode 100644 index 36bc0e014bb..00000000000 --- a/tests/wpt/metadata-layout-2020/css/CSS2/box-display/block-in-inline-relpos-001.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[block-in-inline-relpos-001.xht] - expected: FAIL