Use the writing mode of the containing block when accessing CSS properties

… and converting them to flow-relative geometric values.

These values are almost always used to size and position a fragment within its containing block, so using the mode of the containing block seems more correct.

Note that the `writing-mode` and `direction` properties are disabled in Servo at the moment, so this PR by itself should have no effect: the writing mode of an element is always the same of that of its containing block since they’re both horizontal rtl.
This commit is contained in:
Simon Sapin 2020-06-09 19:58:00 +02:00
parent 554af02ab4
commit 08f008a011
6 changed files with 165 additions and 64 deletions

View file

@ -21,6 +21,7 @@ use rayon_croissant::ParallelIteratorExt;
use servo_arc::Arc; use servo_arc::Arc;
use std::borrow::Cow; use std::borrow::Cow;
use std::convert::{TryFrom, TryInto}; use std::convert::{TryFrom, TryInto};
use style::logical_geometry::WritingMode;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::selector_parser::PseudoElement; use style::selector_parser::PseudoElement;
use style::values::specified::text::TextDecorationLine; use style::values::specified::text::TextDecorationLine;
@ -67,7 +68,12 @@ impl BlockFormattingContext {
inline_level_boxes, inline_level_boxes,
text_decoration_line, 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 contents = BlockContainer::InlineFormattingContext(ifc);
let bfc = Self { let bfc = Self {
contents, contents,
@ -203,10 +209,13 @@ impl BlockContainer {
.is_empty() .is_empty()
{ {
if builder.block_level_boxes.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(|| { let content_sizes = content_sizes.compute(|| {
builder builder
.ongoing_inline_formatting_context .ongoing_inline_formatting_context
.inline_content_sizes(context) .inline_content_sizes(context, not_actually_containing_block_writing_mode)
}); });
let container = BlockContainer::InlineFormattingContext( let container = BlockContainer::InlineFormattingContext(
builder.ongoing_inline_formatting_context, builder.ongoing_inline_formatting_context,
@ -678,6 +687,9 @@ where
max_assign_in_flow_outer_content_sizes_to: Option<&mut ContentSizes>, max_assign_in_flow_outer_content_sizes_to: Option<&mut ContentSizes>,
) -> (ArcRefCell<BlockLevelBox>, ContainsFloats) { ) -> (ArcRefCell<BlockLevelBox>, ContainsFloats) {
let info = &self.info; 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 { let (block_level_box, contains_floats) = match self.kind {
BlockLevelCreator::SameFormattingContextBlock(contents) => { BlockLevelCreator::SameFormattingContextBlock(contents) => {
let (contents, contains_floats, box_content_sizes) = contents.finish( 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 { 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 { let block_level_box = ArcRefCell::new(BlockLevelBox::SameFormattingContextBlock {
tag: Tag::from_node_and_style_info(info), tag: Tag::from_node_and_style_info(info),
@ -716,7 +731,12 @@ where
propagated_text_decoration_line, propagated_text_decoration_line,
); );
if let Some(to) = max_assign_in_flow_outer_content_sizes_to { 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)), ArcRefCell::new(BlockLevelBox::Independent(contents)),
@ -771,7 +791,12 @@ impl IntermediateBlockContainer {
) )
}, },
IntermediateBlockContainer::InlineFormattingContext(ifc) => { 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 // If that inline formatting context contained any float, those
// were already taken into account during the first phase of // were already taken into account during the first phase of
// box construction. // box construction.

View file

@ -23,6 +23,7 @@ use app_units::Au;
use atomic_refcell::AtomicRef; use atomic_refcell::AtomicRef;
use gfx::text::text_run::GlyphRun; use gfx::text::text_run::GlyphRun;
use servo_arc::Arc; use servo_arc::Arc;
use style::logical_geometry::WritingMode;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::values::computed::{Length, LengthPercentage, Percentage}; use style::values::computed::{Length, LengthPercentage, Percentage};
use style::values::specified::text::TextAlignKeyword; use style::values::specified::text::TextAlignKeyword;
@ -139,24 +140,30 @@ impl InlineFormattingContext {
// This works on an already-constructed `InlineFormattingContext`, // This works on an already-constructed `InlineFormattingContext`,
// Which would have to change if/when // Which would have to change if/when
// `BlockContainer::construct` parallelize their construction. // `BlockContainer::construct` parallelize their construction.
pub(super) fn inline_content_sizes(&self, layout_context: &LayoutContext) -> ContentSizes { pub(super) fn inline_content_sizes(
struct Computation { &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, paragraph: ContentSizes,
current_line: ContentSizes, current_line: ContentSizes,
current_line_percentages: Percentage, current_line_percentages: Percentage,
} }
impl Computation { impl Computation<'_> {
fn traverse( fn traverse(&mut self, inline_level_boxes: &[ArcRefCell<InlineLevelBox>]) {
&mut self,
layout_context: &LayoutContext,
inline_level_boxes: &[ArcRefCell<InlineLevelBox>],
) {
for inline_level_box in inline_level_boxes { for inline_level_box in inline_level_boxes {
match &*inline_level_box.borrow() { match &*inline_level_box.borrow() {
InlineLevelBox::InlineBox(inline_box) => { InlineLevelBox::InlineBox(inline_box) => {
let padding = inline_box.style.padding(); let padding =
let border = inline_box.style.border_width(); inline_box.style.padding(self.containing_block_writing_mode);
let margin = inline_box.style.margin(); 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 { macro_rules! add {
($condition: ident, $side: ident) => { ($condition: ident, $side: ident) => {
if inline_box.$condition { if inline_box.$condition {
@ -170,7 +177,7 @@ impl InlineFormattingContext {
} }
add!(first_fragment, inline_start); add!(first_fragment, inline_start);
self.traverse(layout_context, &inline_box.children); self.traverse(&inline_box.children);
add!(last_fragment, inline_end); add!(last_fragment, inline_end);
}, },
InlineLevelBox::TextRun(text_run) => { InlineLevelBox::TextRun(text_run) => {
@ -178,7 +185,7 @@ impl InlineFormattingContext {
runs, runs,
break_at_start, break_at_start,
.. ..
} = text_run.break_and_shape(layout_context); } = text_run.break_and_shape(self.layout_context);
if break_at_start { if break_at_start {
self.line_break_opportunity() self.line_break_opportunity()
} }
@ -193,9 +200,10 @@ impl InlineFormattingContext {
} }
}, },
InlineLevelBox::Atomic(atomic) => { InlineLevelBox::Atomic(atomic) => {
let (outer, pc) = atomic let (outer, pc) = atomic.content_sizes.outer_inline_and_percentages(
.content_sizes &atomic.style,
.outer_inline_and_percentages(&atomic.style); self.containing_block_writing_mode,
);
self.current_line.min_content += outer.min_content; self.current_line.min_content += outer.min_content;
self.current_line.max_content += outer.max_content; self.current_line.max_content += outer.max_content;
self.current_line_percentages += pc; self.current_line_percentages += pc;
@ -239,11 +247,13 @@ impl InlineFormattingContext {
std::mem::replace(x, T::zero()) std::mem::replace(x, T::zero())
} }
let mut computation = Computation { let mut computation = Computation {
layout_context,
containing_block_writing_mode,
paragraph: ContentSizes::zero(), paragraph: ContentSizes::zero(),
current_line: ContentSizes::zero(), current_line: ContentSizes::zero(),
current_line_percentages: Percentage::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.forced_line_break();
computation.paragraph computation.paragraph
} }
@ -308,6 +318,7 @@ impl InlineFormattingContext {
box_.clone(), box_.clone(),
initial_start_corner, initial_start_corner,
tree_rank, tree_rank,
ifc.containing_block,
); );
let hoisted_fragment = hoisted_box.fragment.clone(); let hoisted_fragment = hoisted_box.fragment.clone();
ifc.push_hoisted_box_to_positioning_context(hoisted_box); ifc.push_hoisted_box_to_positioning_context(hoisted_box);

View file

@ -316,8 +316,12 @@ impl BlockLevelBox {
)) ))
}, },
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(box_) => { BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(box_) => {
let hoisted_box = let hoisted_box = AbsolutelyPositionedBox::to_hoisted(
AbsolutelyPositionedBox::to_hoisted(box_.clone(), Vec2::zero(), tree_rank); box_.clone(),
Vec2::zero(),
tree_rank,
containing_block,
);
let hoisted_fragment = hoisted_box.fragment.clone(); let hoisted_fragment = hoisted_box.fragment.clone();
positioning_context.push(hoisted_box); positioning_context.push(hoisted_box);
Fragment::AbsoluteOrFixedPositioned(AbsoluteOrFixedPositionedFragment { Fragment::AbsoluteOrFixedPositioned(AbsoluteOrFixedPositionedFragment {

View file

@ -100,6 +100,7 @@ impl AbsolutelyPositionedBox {
self_: ArcRefCell<Self>, self_: ArcRefCell<Self>,
initial_start_corner: Vec2<Length>, initial_start_corner: Vec2<Length>,
tree_rank: usize, tree_rank: usize,
containing_block: &ContainingBlock,
) -> HoistedAbsolutelyPositionedBox { ) -> HoistedAbsolutelyPositionedBox {
fn absolute_box_offsets( fn absolute_box_offsets(
initial_static_start: Length, initial_static_start: Length,
@ -123,7 +124,7 @@ impl AbsolutelyPositionedBox {
let box_offsets = { let box_offsets = {
let box_ = self_.borrow(); let box_ = self_.borrow();
let box_offsets = box_.contents.style.box_offsets(); let box_offsets = box_.contents.style.box_offsets(containing_block);
Vec2 { Vec2 {
inline: absolute_box_offsets( inline: absolute_box_offsets(
initial_start_corner.inline, initial_start_corner.inline,
@ -708,10 +709,12 @@ pub(crate) fn relative_adjustement(
) -> Vec2<Length> { ) -> Vec2<Length> {
let cbis = containing_block.inline_size; let cbis = containing_block.inline_size;
let cbbs = containing_block.block_size.auto_is(Length::zero); let cbbs = containing_block.block_size.auto_is(Length::zero);
let box_offsets = style.box_offsets().map_inline_and_block_axes( let box_offsets = style
|v| v.percentage_relative_to(cbis), .box_offsets(containing_block)
|v| v.percentage_relative_to(cbbs), .map_inline_and_block_axes(
); |v| v.percentage_relative_to(cbis),
|v| v.percentage_relative_to(cbbs),
);
fn adjust(start: LengthOrAuto, end: LengthOrAuto) -> Length { fn adjust(start: LengthOrAuto, end: LengthOrAuto) -> Length {
match (start, end) { match (start, end) {
(LengthOrAuto::Auto, LengthOrAuto::Auto) => Length::zero(), (LengthOrAuto::Auto, LengthOrAuto::Auto) => Length::zero(),

View file

@ -5,6 +5,7 @@
//! https://drafts.csswg.org/css-sizing/ //! https://drafts.csswg.org/css-sizing/
use crate::style_ext::ComputedValuesExt; use crate::style_ext::ComputedValuesExt;
use style::logical_geometry::WritingMode;
use style::properties::longhands::box_sizing::computed_value::T as BoxSizing; use style::properties::longhands::box_sizing::computed_value::T as BoxSizing;
use style::properties::ComputedValues; use style::properties::ComputedValues;
use style::values::computed::{Length, LengthPercentage, Percentage}; use style::values::computed::{Length, LengthPercentage, Percentage};
@ -105,8 +106,13 @@ impl BoxContentSizes {
} }
/// https://dbaron.org/css/intrinsic/#outer-intrinsic /// https://dbaron.org/css/intrinsic/#outer-intrinsic
pub fn outer_inline(&self, style: &ComputedValues) -> ContentSizes { pub fn outer_inline(
let (mut outer, percentages) = self.outer_inline_and_percentages(style); &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.adjust_for_pbm_percentages(percentages);
outer outer
} }
@ -114,10 +120,11 @@ impl BoxContentSizes {
pub(crate) fn outer_inline_and_percentages( pub(crate) fn outer_inline_and_percentages(
&self, &self,
style: &ComputedValues, style: &ComputedValues,
containing_block_writing_mode: WritingMode,
) -> (ContentSizes, Percentage) { ) -> (ContentSizes, Percentage) {
let padding = style.padding(); let padding = style.padding(containing_block_writing_mode);
let border = style.border_width(); let border = style.border_width(containing_block_writing_mode);
let margin = style.margin(); let margin = style.margin(containing_block_writing_mode);
let mut pbm_percentages = Percentage::zero(); let mut pbm_percentages = Percentage::zero();
let mut decompose = |x: &LengthPercentage| { let mut decompose = |x: &LengthPercentage| {
@ -136,20 +143,20 @@ impl BoxContentSizes {
let box_sizing = style.get_position().box_sizing; let box_sizing = style.get_position().box_sizing;
let inline_size = style let inline_size = style
.box_size() .box_size(containing_block_writing_mode)
.inline .inline
.non_auto() .non_auto()
// Percentages for 'width' are treated as 'auto' // Percentages for 'width' are treated as 'auto'
.and_then(|lp| lp.to_length()); .and_then(|lp| lp.to_length());
let min_inline_size = style let min_inline_size = style
.min_box_size() .min_box_size(containing_block_writing_mode)
.inline .inline
// Percentages for 'min-width' are treated as zero // Percentages for 'min-width' are treated as zero
.percentage_relative_to(Length::zero()) .percentage_relative_to(Length::zero())
// FIXME: 'auto' is not zero in Flexbox // FIXME: 'auto' is not zero in Flexbox
.auto_is(Length::zero); .auto_is(Length::zero);
let max_inline_size = style let max_inline_size = style
.max_box_size() .max_box_size(containing_block_writing_mode)
.inline .inline
// Percentages for 'max-width' are treated as 'none' // Percentages for 'max-width' are treated as 'none'
.and_then(|lp| lp.to_length()); .and_then(|lp| lp.to_length());

View file

@ -8,6 +8,7 @@ use crate::ContainingBlock;
use style::computed_values::mix_blend_mode::T as ComputedMixBlendMode; use style::computed_values::mix_blend_mode::T as ComputedMixBlendMode;
use style::computed_values::position::T as ComputedPosition; use style::computed_values::position::T as ComputedPosition;
use style::computed_values::transform_style::T as ComputedTransformStyle; 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::backface_visibility::computed_value::T as BackfaceVisiblity;
use style::properties::longhands::box_sizing::computed_value::T as BoxSizing; use style::properties::longhands::box_sizing::computed_value::T as BoxSizing;
use style::properties::ComputedValues; use style::properties::ComputedValues;
@ -64,10 +65,22 @@ pub(crate) struct PaddingBorderMargin {
pub(crate) trait ComputedValuesExt { pub(crate) trait ComputedValuesExt {
fn inline_size_is_length(&self) -> bool; fn inline_size_is_length(&self) -> bool;
fn inline_box_offsets_are_both_non_auto(&self) -> bool; fn inline_box_offsets_are_both_non_auto(&self) -> bool;
fn box_offsets(&self) -> flow_relative::Sides<LengthPercentageOrAuto<'_>>; fn box_offsets(
fn box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto<'_>>; &self,
fn min_box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto<'_>>; containing_block: &ContainingBlock,
fn max_box_size(&self) -> flow_relative::Vec2<Option<&LengthPercentage>>; ) -> flow_relative::Sides<LengthPercentageOrAuto<'_>>;
fn box_size(
&self,
containing_block_writing_mode: WritingMode,
) -> flow_relative::Vec2<LengthPercentageOrAuto<'_>>;
fn min_box_size(
&self,
containing_block_writing_mode: WritingMode,
) -> flow_relative::Vec2<LengthPercentageOrAuto<'_>>;
fn max_box_size(
&self,
containing_block_writing_mode: WritingMode,
) -> flow_relative::Vec2<Option<&LengthPercentage>>;
fn content_box_size( fn content_box_size(
&self, &self,
containing_block: &ContainingBlock, containing_block: &ContainingBlock,
@ -84,9 +97,18 @@ pub(crate) trait ComputedValuesExt {
pbm: &PaddingBorderMargin, pbm: &PaddingBorderMargin,
) -> flow_relative::Vec2<Option<Length>>; ) -> flow_relative::Vec2<Option<Length>>;
fn padding_border_margin(&self, containing_block: &ContainingBlock) -> PaddingBorderMargin; fn padding_border_margin(&self, containing_block: &ContainingBlock) -> PaddingBorderMargin;
fn padding(&self) -> flow_relative::Sides<&LengthPercentage>; fn padding(
fn border_width(&self) -> flow_relative::Sides<Length>; &self,
fn margin(&self) -> flow_relative::Sides<LengthPercentageOrAuto<'_>>; containing_block_writing_mode: WritingMode,
) -> flow_relative::Sides<&LengthPercentage>;
fn border_width(
&self,
containing_block_writing_mode: WritingMode,
) -> flow_relative::Sides<Length>;
fn margin(
&self,
containing_block_writing_mode: WritingMode,
) -> flow_relative::Sides<LengthPercentageOrAuto<'_>>;
fn has_transform_or_perspective(&self) -> bool; fn has_transform_or_perspective(&self) -> bool;
fn effective_z_index(&self) -> i32; fn effective_z_index(&self) -> i32;
fn establishes_stacking_context(&self) -> bool; fn establishes_stacking_context(&self) -> bool;
@ -99,6 +121,7 @@ pub(crate) trait ComputedValuesExt {
impl ComputedValuesExt for ComputedValues { impl ComputedValuesExt for ComputedValues {
fn inline_size_is_length(&self) -> bool { fn inline_size_is_length(&self) -> bool {
let position = self.get_position(); 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() { let size = if self.writing_mode.is_horizontal() {
&position.width &position.width
} else { } else {
@ -109,6 +132,7 @@ impl ComputedValuesExt for ComputedValues {
fn inline_box_offsets_are_both_non_auto(&self) -> bool { fn inline_box_offsets_are_both_non_auto(&self) -> bool {
let position = self.get_position(); 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() { let (a, b) = if self.writing_mode.is_horizontal() {
(&position.left, &position.right) (&position.left, &position.right)
} else { } else {
@ -117,7 +141,10 @@ impl ComputedValuesExt for ComputedValues {
!a.is_auto() && !b.is_auto() !a.is_auto() && !b.is_auto()
} }
fn box_offsets(&self) -> flow_relative::Sides<LengthPercentageOrAuto<'_>> { fn box_offsets(
&self,
containing_block: &ContainingBlock,
) -> flow_relative::Sides<LengthPercentageOrAuto<'_>> {
let position = self.get_position(); let position = self.get_position();
flow_relative::Sides::from_physical( flow_relative::Sides::from_physical(
&PhysicalSides::new( &PhysicalSides::new(
@ -126,33 +153,42 @@ impl ComputedValuesExt for ComputedValues {
position.bottom.as_ref(), position.bottom.as_ref(),
position.left.as_ref(), position.left.as_ref(),
), ),
self.writing_mode, containing_block.style.writing_mode,
) )
} }
fn box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto<'_>> { fn box_size(
&self,
containing_block_writing_mode: WritingMode,
) -> flow_relative::Vec2<LengthPercentageOrAuto<'_>> {
let position = self.get_position(); let position = self.get_position();
flow_relative::Vec2::from_physical_size( flow_relative::Vec2::from_physical_size(
&PhysicalSize::new( &PhysicalSize::new(
size_to_length(&position.width), size_to_length(&position.width),
size_to_length(&position.height), size_to_length(&position.height),
), ),
self.writing_mode, containing_block_writing_mode,
) )
} }
fn min_box_size(&self) -> flow_relative::Vec2<LengthPercentageOrAuto<'_>> { fn min_box_size(
&self,
containing_block_writing_mode: WritingMode,
) -> flow_relative::Vec2<LengthPercentageOrAuto<'_>> {
let position = self.get_position(); let position = self.get_position();
flow_relative::Vec2::from_physical_size( flow_relative::Vec2::from_physical_size(
&PhysicalSize::new( &PhysicalSize::new(
size_to_length(&position.min_width), size_to_length(&position.min_width),
size_to_length(&position.min_height), size_to_length(&position.min_height),
), ),
self.writing_mode, containing_block_writing_mode,
) )
} }
fn max_box_size(&self) -> flow_relative::Vec2<Option<&LengthPercentage>> { fn max_box_size(
&self,
containing_block_writing_mode: WritingMode,
) -> flow_relative::Vec2<Option<&LengthPercentage>> {
fn unwrap(max_size: &MaxSize<NonNegativeLengthPercentage>) -> Option<&LengthPercentage> { fn unwrap(max_size: &MaxSize<NonNegativeLengthPercentage>) -> Option<&LengthPercentage> {
match max_size { match max_size {
MaxSize::LengthPercentage(length) => Some(&length.0), MaxSize::LengthPercentage(length) => Some(&length.0),
@ -162,7 +198,7 @@ impl ComputedValuesExt for ComputedValues {
let position = self.get_position(); let position = self.get_position();
flow_relative::Vec2::from_physical_size( flow_relative::Vec2::from_physical_size(
&PhysicalSize::new(unwrap(&position.max_width), unwrap(&position.max_height)), &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, containing_block: &ContainingBlock,
pbm: &PaddingBorderMargin, pbm: &PaddingBorderMargin,
) -> flow_relative::Vec2<LengthOrAuto> { ) -> flow_relative::Vec2<LengthOrAuto> {
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 { match self.get_position().box_sizing {
BoxSizing::ContentBox => box_size, BoxSizing::ContentBox => box_size,
BoxSizing::BorderBox => flow_relative::Vec2 { BoxSizing::BorderBox => flow_relative::Vec2 {
@ -189,7 +227,7 @@ impl ComputedValuesExt for ComputedValues {
pbm: &PaddingBorderMargin, pbm: &PaddingBorderMargin,
) -> flow_relative::Vec2<LengthOrAuto> { ) -> flow_relative::Vec2<LengthOrAuto> {
let min_box_size = self let min_box_size = self
.min_box_size() .min_box_size(containing_block.style.writing_mode)
.percentages_relative_to(containing_block); .percentages_relative_to(containing_block);
match self.get_position().box_sizing { match self.get_position().box_sizing {
BoxSizing::ContentBox => min_box_size, BoxSizing::ContentBox => min_box_size,
@ -211,7 +249,7 @@ impl ComputedValuesExt for ComputedValues {
pbm: &PaddingBorderMargin, pbm: &PaddingBorderMargin,
) -> flow_relative::Vec2<Option<Length>> { ) -> flow_relative::Vec2<Option<Length>> {
let max_box_size = self let max_box_size = self
.max_box_size() .max_box_size(containing_block.style.writing_mode)
.percentages_relative_to(containing_block); .percentages_relative_to(containing_block);
match self.get_position().box_sizing { match self.get_position().box_sizing {
BoxSizing::ContentBox => max_box_size, BoxSizing::ContentBox => max_box_size,
@ -232,8 +270,10 @@ impl ComputedValuesExt for ComputedValues {
fn padding_border_margin(&self, containing_block: &ContainingBlock) -> PaddingBorderMargin { fn padding_border_margin(&self, containing_block: &ContainingBlock) -> PaddingBorderMargin {
let cbis = containing_block.inline_size; let cbis = containing_block.inline_size;
let padding = self.padding().percentages_relative_to(cbis); let padding = self
let border = self.border_width(); .padding(containing_block.style.writing_mode)
.percentages_relative_to(cbis);
let border = self.border_width(containing_block.style.writing_mode);
PaddingBorderMargin { PaddingBorderMargin {
padding_border_sums: flow_relative::Vec2 { padding_border_sums: flow_relative::Vec2 {
inline: padding.inline_sum() + border.inline_sum(), inline: padding.inline_sum() + border.inline_sum(),
@ -241,11 +281,16 @@ impl ComputedValuesExt for ComputedValues {
}, },
padding, padding,
border, 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(); let padding = self.get_padding();
flow_relative::Sides::from_physical( flow_relative::Sides::from_physical(
&PhysicalSides::new( &PhysicalSides::new(
@ -254,11 +299,14 @@ impl ComputedValuesExt for ComputedValues {
&padding.padding_bottom.0, &padding.padding_bottom.0,
&padding.padding_left.0, &padding.padding_left.0,
), ),
self.writing_mode, containing_block_writing_mode,
) )
} }
fn border_width(&self) -> flow_relative::Sides<Length> { fn border_width(
&self,
containing_block_writing_mode: WritingMode,
) -> flow_relative::Sides<Length> {
let border = self.get_border(); let border = self.get_border();
flow_relative::Sides::from_physical( flow_relative::Sides::from_physical(
&PhysicalSides::new( &PhysicalSides::new(
@ -267,11 +315,14 @@ impl ComputedValuesExt for ComputedValues {
border.border_bottom_width.0, border.border_bottom_width.0,
border.border_left_width.0, border.border_left_width.0,
), ),
self.writing_mode, containing_block_writing_mode,
) )
} }
fn margin(&self) -> flow_relative::Sides<LengthPercentageOrAuto<'_>> { fn margin(
&self,
containing_block_writing_mode: WritingMode,
) -> flow_relative::Sides<LengthPercentageOrAuto<'_>> {
let margin = self.get_margin(); let margin = self.get_margin();
flow_relative::Sides::from_physical( flow_relative::Sides::from_physical(
&PhysicalSides::new( &PhysicalSides::new(
@ -280,7 +331,7 @@ impl ComputedValuesExt for ComputedValues {
margin.margin_bottom.as_ref(), margin.margin_bottom.as_ref(),
margin.margin_left.as_ref(), margin.margin_left.as_ref(),
), ),
self.writing_mode, containing_block_writing_mode,
) )
} }