diff --git a/components/layout_2020/flow/construct.rs b/components/layout_2020/flow/construct.rs index bd2d0bce23d..f72bbf1ad13 100644 --- a/components/layout_2020/flow/construct.rs +++ b/components/layout_2020/flow/construct.rs @@ -21,6 +21,7 @@ use rayon_croissant::ParallelIteratorExt; use servo_arc::Arc; use std::borrow::Cow; use std::convert::{TryFrom, TryInto}; +use style::logical_geometry::WritingMode; use style::properties::ComputedValues; use style::selector_parser::PseudoElement; use style::values::specified::text::TextDecorationLine; @@ -67,7 +68,12 @@ impl BlockFormattingContext { inline_level_boxes, text_decoration_line, }; - let content_sizes = content_sizes.compute(|| ifc.inline_content_sizes(context)); + // FIXME: this is the wrong writing mode + // but we plan to remove eager content size computation. + let not_actually_containing_block_writing_mode = WritingMode::empty(); + let content_sizes = content_sizes.compute(|| { + ifc.inline_content_sizes(context, not_actually_containing_block_writing_mode) + }); let contents = BlockContainer::InlineFormattingContext(ifc); let bfc = Self { contents, @@ -203,10 +209,13 @@ impl BlockContainer { .is_empty() { if builder.block_level_boxes.is_empty() { + // FIXME: this is the wrong writing mode + // but we plan to remove eager content size computation. + let not_actually_containing_block_writing_mode = info.style.writing_mode; let content_sizes = content_sizes.compute(|| { builder .ongoing_inline_formatting_context - .inline_content_sizes(context) + .inline_content_sizes(context, not_actually_containing_block_writing_mode) }); let container = BlockContainer::InlineFormattingContext( builder.ongoing_inline_formatting_context, @@ -678,6 +687,9 @@ where max_assign_in_flow_outer_content_sizes_to: Option<&mut ContentSizes>, ) -> (ArcRefCell, ContainsFloats) { let info = &self.info; + // FIXME: this is the wrong writing mode + // but we plan to remove eager content size computation. + let not_actually_containing_block_writing_mode = info.style.writing_mode; let (block_level_box, contains_floats) = match self.kind { BlockLevelCreator::SameFormattingContextBlock(contents) => { let (contents, contains_floats, box_content_sizes) = contents.finish( @@ -689,7 +701,10 @@ where ), ); if let Some(to) = max_assign_in_flow_outer_content_sizes_to { - to.max_assign(&box_content_sizes.outer_inline(&info.style)) + to.max_assign( + &box_content_sizes + .outer_inline(&info.style, not_actually_containing_block_writing_mode), + ) } let block_level_box = ArcRefCell::new(BlockLevelBox::SameFormattingContextBlock { tag: Tag::from_node_and_style_info(info), @@ -716,7 +731,12 @@ where propagated_text_decoration_line, ); if let Some(to) = max_assign_in_flow_outer_content_sizes_to { - to.max_assign(&contents.content_sizes.outer_inline(&contents.style)) + to.max_assign( + &contents.content_sizes.outer_inline( + &contents.style, + not_actually_containing_block_writing_mode, + ), + ) } ( ArcRefCell::new(BlockLevelBox::Independent(contents)), @@ -771,7 +791,12 @@ impl IntermediateBlockContainer { ) }, IntermediateBlockContainer::InlineFormattingContext(ifc) => { - let content_sizes = content_sizes.compute(|| ifc.inline_content_sizes(context)); + // FIXME: this is the wrong writing mode + // but we plan to remove eager content size computation. + let not_actually_containing_block_writing_mode = info.style.writing_mode; + let content_sizes = content_sizes.compute(|| { + ifc.inline_content_sizes(context, not_actually_containing_block_writing_mode) + }); // If that inline formatting context contained any float, those // were already taken into account during the first phase of // box construction. diff --git a/components/layout_2020/flow/inline.rs b/components/layout_2020/flow/inline.rs index 47d9deacfbf..c1ca982d41b 100644 --- a/components/layout_2020/flow/inline.rs +++ b/components/layout_2020/flow/inline.rs @@ -23,6 +23,7 @@ use app_units::Au; use atomic_refcell::AtomicRef; use gfx::text::text_run::GlyphRun; use servo_arc::Arc; +use style::logical_geometry::WritingMode; use style::properties::ComputedValues; use style::values::computed::{Length, LengthPercentage, Percentage}; use style::values::specified::text::TextAlignKeyword; @@ -139,24 +140,30 @@ impl InlineFormattingContext { // This works on an already-constructed `InlineFormattingContext`, // Which would have to change if/when // `BlockContainer::construct` parallelize their construction. - pub(super) fn inline_content_sizes(&self, layout_context: &LayoutContext) -> ContentSizes { - struct Computation { + pub(super) fn inline_content_sizes( + &self, + layout_context: &LayoutContext, + containing_block_writing_mode: WritingMode, + ) -> ContentSizes { + struct Computation<'a> { + layout_context: &'a LayoutContext<'a>, + containing_block_writing_mode: WritingMode, paragraph: ContentSizes, current_line: ContentSizes, current_line_percentages: Percentage, } - impl Computation { - fn traverse( - &mut self, - layout_context: &LayoutContext, - inline_level_boxes: &[ArcRefCell], - ) { + impl Computation<'_> { + fn traverse(&mut self, inline_level_boxes: &[ArcRefCell]) { for inline_level_box in inline_level_boxes { match &*inline_level_box.borrow() { InlineLevelBox::InlineBox(inline_box) => { - let padding = inline_box.style.padding(); - let border = inline_box.style.border_width(); - let margin = inline_box.style.margin(); + let padding = + inline_box.style.padding(self.containing_block_writing_mode); + let border = inline_box + .style + .border_width(self.containing_block_writing_mode); + let margin = + inline_box.style.margin(self.containing_block_writing_mode); macro_rules! add { ($condition: ident, $side: ident) => { if inline_box.$condition { @@ -170,7 +177,7 @@ impl InlineFormattingContext { } add!(first_fragment, inline_start); - self.traverse(layout_context, &inline_box.children); + self.traverse(&inline_box.children); add!(last_fragment, inline_end); }, InlineLevelBox::TextRun(text_run) => { @@ -178,7 +185,7 @@ impl InlineFormattingContext { runs, break_at_start, .. - } = text_run.break_and_shape(layout_context); + } = text_run.break_and_shape(self.layout_context); if break_at_start { self.line_break_opportunity() } @@ -193,9 +200,10 @@ impl InlineFormattingContext { } }, InlineLevelBox::Atomic(atomic) => { - let (outer, pc) = atomic - .content_sizes - .outer_inline_and_percentages(&atomic.style); + let (outer, pc) = atomic.content_sizes.outer_inline_and_percentages( + &atomic.style, + self.containing_block_writing_mode, + ); self.current_line.min_content += outer.min_content; self.current_line.max_content += outer.max_content; self.current_line_percentages += pc; @@ -239,11 +247,13 @@ impl InlineFormattingContext { std::mem::replace(x, T::zero()) } let mut computation = Computation { + layout_context, + containing_block_writing_mode, paragraph: ContentSizes::zero(), current_line: ContentSizes::zero(), current_line_percentages: Percentage::zero(), }; - computation.traverse(layout_context, &self.inline_level_boxes); + computation.traverse(&self.inline_level_boxes); computation.forced_line_break(); computation.paragraph } @@ -308,6 +318,7 @@ impl InlineFormattingContext { box_.clone(), initial_start_corner, tree_rank, + ifc.containing_block, ); let hoisted_fragment = hoisted_box.fragment.clone(); ifc.push_hoisted_box_to_positioning_context(hoisted_box); diff --git a/components/layout_2020/flow/mod.rs b/components/layout_2020/flow/mod.rs index 4f22b857e84..8558d7a68bd 100644 --- a/components/layout_2020/flow/mod.rs +++ b/components/layout_2020/flow/mod.rs @@ -316,8 +316,12 @@ impl BlockLevelBox { )) }, BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(box_) => { - let hoisted_box = - AbsolutelyPositionedBox::to_hoisted(box_.clone(), Vec2::zero(), tree_rank); + let hoisted_box = AbsolutelyPositionedBox::to_hoisted( + box_.clone(), + Vec2::zero(), + tree_rank, + containing_block, + ); let hoisted_fragment = hoisted_box.fragment.clone(); positioning_context.push(hoisted_box); Fragment::AbsoluteOrFixedPositioned(AbsoluteOrFixedPositionedFragment { diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs index 7a5496d10e1..1c873cbc8f5 100644 --- a/components/layout_2020/positioned.rs +++ b/components/layout_2020/positioned.rs @@ -100,6 +100,7 @@ impl AbsolutelyPositionedBox { self_: ArcRefCell, initial_start_corner: Vec2, tree_rank: usize, + containing_block: &ContainingBlock, ) -> HoistedAbsolutelyPositionedBox { fn absolute_box_offsets( initial_static_start: Length, @@ -123,7 +124,7 @@ impl AbsolutelyPositionedBox { let box_offsets = { let box_ = self_.borrow(); - let box_offsets = box_.contents.style.box_offsets(); + let box_offsets = box_.contents.style.box_offsets(containing_block); Vec2 { inline: absolute_box_offsets( initial_start_corner.inline, @@ -708,10 +709,12 @@ pub(crate) fn relative_adjustement( ) -> 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), - ); + let box_offsets = style + .box_offsets(containing_block) + .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(), diff --git a/components/layout_2020/sizing.rs b/components/layout_2020/sizing.rs index 7e788cc4898..af8c6ac0ecb 100644 --- a/components/layout_2020/sizing.rs +++ b/components/layout_2020/sizing.rs @@ -5,6 +5,7 @@ //! https://drafts.csswg.org/css-sizing/ use crate::style_ext::ComputedValuesExt; +use style::logical_geometry::WritingMode; use style::properties::longhands::box_sizing::computed_value::T as BoxSizing; use style::properties::ComputedValues; use style::values::computed::{Length, LengthPercentage, Percentage}; @@ -105,8 +106,13 @@ impl BoxContentSizes { } /// https://dbaron.org/css/intrinsic/#outer-intrinsic - pub fn outer_inline(&self, style: &ComputedValues) -> ContentSizes { - let (mut outer, percentages) = self.outer_inline_and_percentages(style); + pub fn outer_inline( + &self, + style: &ComputedValues, + containing_block_writing_mode: WritingMode, + ) -> ContentSizes { + let (mut outer, percentages) = + self.outer_inline_and_percentages(style, containing_block_writing_mode); outer.adjust_for_pbm_percentages(percentages); outer } @@ -114,10 +120,11 @@ impl BoxContentSizes { pub(crate) fn outer_inline_and_percentages( &self, style: &ComputedValues, + containing_block_writing_mode: WritingMode, ) -> (ContentSizes, Percentage) { - let padding = style.padding(); - let border = style.border_width(); - let margin = style.margin(); + let padding = style.padding(containing_block_writing_mode); + let border = style.border_width(containing_block_writing_mode); + let margin = style.margin(containing_block_writing_mode); let mut pbm_percentages = Percentage::zero(); let mut decompose = |x: &LengthPercentage| { @@ -136,20 +143,20 @@ impl BoxContentSizes { let box_sizing = style.get_position().box_sizing; let inline_size = style - .box_size() + .box_size(containing_block_writing_mode) .inline .non_auto() // Percentages for 'width' are treated as 'auto' .and_then(|lp| lp.to_length()); let min_inline_size = style - .min_box_size() + .min_box_size(containing_block_writing_mode) .inline // Percentages for 'min-width' are treated as zero .percentage_relative_to(Length::zero()) // FIXME: 'auto' is not zero in Flexbox .auto_is(Length::zero); let max_inline_size = style - .max_box_size() + .max_box_size(containing_block_writing_mode) .inline // Percentages for 'max-width' are treated as 'none' .and_then(|lp| lp.to_length()); diff --git a/components/layout_2020/style_ext.rs b/components/layout_2020/style_ext.rs index 0bc10fc5e68..9aa2ea73160 100644 --- a/components/layout_2020/style_ext.rs +++ b/components/layout_2020/style_ext.rs @@ -8,6 +8,7 @@ use crate::ContainingBlock; use style::computed_values::mix_blend_mode::T as ComputedMixBlendMode; use style::computed_values::position::T as ComputedPosition; use style::computed_values::transform_style::T as ComputedTransformStyle; +use style::logical_geometry::WritingMode; use style::properties::longhands::backface_visibility::computed_value::T as BackfaceVisiblity; use style::properties::longhands::box_sizing::computed_value::T as BoxSizing; use style::properties::ComputedValues; @@ -64,10 +65,22 @@ pub(crate) struct PaddingBorderMargin { pub(crate) trait ComputedValuesExt { fn inline_size_is_length(&self) -> bool; fn inline_box_offsets_are_both_non_auto(&self) -> bool; - fn box_offsets(&self) -> flow_relative::Sides>; - fn box_size(&self) -> flow_relative::Vec2>; - fn min_box_size(&self) -> flow_relative::Vec2>; - fn max_box_size(&self) -> flow_relative::Vec2>; + fn box_offsets( + &self, + containing_block: &ContainingBlock, + ) -> flow_relative::Sides>; + fn box_size( + &self, + containing_block_writing_mode: WritingMode, + ) -> flow_relative::Vec2>; + fn min_box_size( + &self, + containing_block_writing_mode: WritingMode, + ) -> flow_relative::Vec2>; + fn max_box_size( + &self, + containing_block_writing_mode: WritingMode, + ) -> flow_relative::Vec2>; fn content_box_size( &self, containing_block: &ContainingBlock, @@ -84,9 +97,18 @@ pub(crate) trait ComputedValuesExt { pbm: &PaddingBorderMargin, ) -> flow_relative::Vec2>; fn padding_border_margin(&self, containing_block: &ContainingBlock) -> PaddingBorderMargin; - fn padding(&self) -> flow_relative::Sides<&LengthPercentage>; - fn border_width(&self) -> flow_relative::Sides; - fn margin(&self) -> flow_relative::Sides>; + fn padding( + &self, + containing_block_writing_mode: WritingMode, + ) -> flow_relative::Sides<&LengthPercentage>; + fn border_width( + &self, + containing_block_writing_mode: WritingMode, + ) -> flow_relative::Sides; + fn margin( + &self, + containing_block_writing_mode: WritingMode, + ) -> flow_relative::Sides>; fn has_transform_or_perspective(&self) -> bool; fn effective_z_index(&self) -> i32; fn establishes_stacking_context(&self) -> bool; @@ -99,6 +121,7 @@ pub(crate) trait ComputedValuesExt { impl ComputedValuesExt for ComputedValues { fn inline_size_is_length(&self) -> bool { let position = self.get_position(); + // FIXME: this is the wrong writing mode but we plan to remove eager content size computation. let size = if self.writing_mode.is_horizontal() { &position.width } else { @@ -109,6 +132,7 @@ impl ComputedValuesExt for ComputedValues { fn inline_box_offsets_are_both_non_auto(&self) -> bool { let position = self.get_position(); + // FIXME: this is the wrong writing mode but we plan to remove eager content size computation. let (a, b) = if self.writing_mode.is_horizontal() { (&position.left, &position.right) } else { @@ -117,7 +141,10 @@ impl ComputedValuesExt for ComputedValues { !a.is_auto() && !b.is_auto() } - fn box_offsets(&self) -> flow_relative::Sides> { + fn box_offsets( + &self, + containing_block: &ContainingBlock, + ) -> flow_relative::Sides> { let position = self.get_position(); flow_relative::Sides::from_physical( &PhysicalSides::new( @@ -126,33 +153,42 @@ impl ComputedValuesExt for ComputedValues { position.bottom.as_ref(), position.left.as_ref(), ), - self.writing_mode, + containing_block.style.writing_mode, ) } - fn box_size(&self) -> flow_relative::Vec2> { + fn box_size( + &self, + containing_block_writing_mode: WritingMode, + ) -> flow_relative::Vec2> { let position = self.get_position(); flow_relative::Vec2::from_physical_size( &PhysicalSize::new( size_to_length(&position.width), size_to_length(&position.height), ), - self.writing_mode, + containing_block_writing_mode, ) } - fn min_box_size(&self) -> flow_relative::Vec2> { + fn min_box_size( + &self, + containing_block_writing_mode: WritingMode, + ) -> flow_relative::Vec2> { let position = self.get_position(); flow_relative::Vec2::from_physical_size( &PhysicalSize::new( size_to_length(&position.min_width), size_to_length(&position.min_height), ), - self.writing_mode, + containing_block_writing_mode, ) } - fn max_box_size(&self) -> flow_relative::Vec2> { + fn max_box_size( + &self, + containing_block_writing_mode: WritingMode, + ) -> flow_relative::Vec2> { fn unwrap(max_size: &MaxSize) -> Option<&LengthPercentage> { match max_size { MaxSize::LengthPercentage(length) => Some(&length.0), @@ -162,7 +198,7 @@ impl ComputedValuesExt for ComputedValues { let position = self.get_position(); flow_relative::Vec2::from_physical_size( &PhysicalSize::new(unwrap(&position.max_width), unwrap(&position.max_height)), - self.writing_mode, + containing_block_writing_mode, ) } @@ -171,7 +207,9 @@ impl ComputedValuesExt for ComputedValues { containing_block: &ContainingBlock, pbm: &PaddingBorderMargin, ) -> flow_relative::Vec2 { - let box_size = self.box_size().percentages_relative_to(containing_block); + let box_size = self + .box_size(containing_block.style.writing_mode) + .percentages_relative_to(containing_block); match self.get_position().box_sizing { BoxSizing::ContentBox => box_size, BoxSizing::BorderBox => flow_relative::Vec2 { @@ -189,7 +227,7 @@ impl ComputedValuesExt for ComputedValues { pbm: &PaddingBorderMargin, ) -> flow_relative::Vec2 { let min_box_size = self - .min_box_size() + .min_box_size(containing_block.style.writing_mode) .percentages_relative_to(containing_block); match self.get_position().box_sizing { BoxSizing::ContentBox => min_box_size, @@ -211,7 +249,7 @@ impl ComputedValuesExt for ComputedValues { pbm: &PaddingBorderMargin, ) -> flow_relative::Vec2> { let max_box_size = self - .max_box_size() + .max_box_size(containing_block.style.writing_mode) .percentages_relative_to(containing_block); match self.get_position().box_sizing { BoxSizing::ContentBox => max_box_size, @@ -232,8 +270,10 @@ impl ComputedValuesExt for ComputedValues { fn padding_border_margin(&self, containing_block: &ContainingBlock) -> PaddingBorderMargin { let cbis = containing_block.inline_size; - let padding = self.padding().percentages_relative_to(cbis); - let border = self.border_width(); + let padding = self + .padding(containing_block.style.writing_mode) + .percentages_relative_to(cbis); + let border = self.border_width(containing_block.style.writing_mode); PaddingBorderMargin { padding_border_sums: flow_relative::Vec2 { inline: padding.inline_sum() + border.inline_sum(), @@ -241,11 +281,16 @@ impl ComputedValuesExt for ComputedValues { }, padding, border, - margin: self.margin().percentages_relative_to(cbis), + margin: self + .margin(containing_block.style.writing_mode) + .percentages_relative_to(cbis), } } - fn padding(&self) -> flow_relative::Sides<&LengthPercentage> { + fn padding( + &self, + containing_block_writing_mode: WritingMode, + ) -> flow_relative::Sides<&LengthPercentage> { let padding = self.get_padding(); flow_relative::Sides::from_physical( &PhysicalSides::new( @@ -254,11 +299,14 @@ impl ComputedValuesExt for ComputedValues { &padding.padding_bottom.0, &padding.padding_left.0, ), - self.writing_mode, + containing_block_writing_mode, ) } - fn border_width(&self) -> flow_relative::Sides { + fn border_width( + &self, + containing_block_writing_mode: WritingMode, + ) -> flow_relative::Sides { let border = self.get_border(); flow_relative::Sides::from_physical( &PhysicalSides::new( @@ -267,11 +315,14 @@ impl ComputedValuesExt for ComputedValues { border.border_bottom_width.0, border.border_left_width.0, ), - self.writing_mode, + containing_block_writing_mode, ) } - fn margin(&self) -> flow_relative::Sides> { + fn margin( + &self, + containing_block_writing_mode: WritingMode, + ) -> flow_relative::Sides> { let margin = self.get_margin(); flow_relative::Sides::from_physical( &PhysicalSides::new( @@ -280,7 +331,7 @@ impl ComputedValuesExt for ComputedValues { margin.margin_bottom.as_ref(), margin.margin_left.as_ref(), ), - self.writing_mode, + containing_block_writing_mode, ) }