diff --git a/components/layout_2020/display_list/mod.rs b/components/layout_2020/display_list/mod.rs index 9d93410e00f..c89a6f272ac 100644 --- a/components/layout_2020/display_list/mod.rs +++ b/components/layout_2020/display_list/mod.rs @@ -707,7 +707,6 @@ impl<'a> BuilderForBoxFragment<'a> { painting_area_override: None, positioning_area_override: Some( positioning_area - .to_physical(self.fragment.style.effective_writing_mode()) .translate(self.containing_block.origin.to_vector()) .to_webrender(), ), diff --git a/components/layout_2020/flexbox/layout.rs b/components/layout_2020/flexbox/layout.rs index af7d3ec583d..11e2717f56a 100644 --- a/components/layout_2020/flexbox/layout.rs +++ b/components/layout_2020/flexbox/layout.rs @@ -171,13 +171,13 @@ impl FlexItemLayoutResult { let flags = fragment_info.flags; let containing_block = flex_context.containing_block; - let container_writing_mode = containing_block.effective_writing_mode(); + let container_writing_mode = containing_block.style.writing_mode; let style = item.box_.style(); let mut fragment = BoxFragment::new( fragment_info, style.clone(), self.fragments, - content_rect.to_physical(container_writing_mode), + content_rect.to_physical(Some(flex_context.containing_block)), flex_context .sides_to_flow_relative(item.padding) .to_physical(container_writing_mode), @@ -199,7 +199,7 @@ impl FlexItemLayoutResult { if style.clone_position() == Position::Relative { fragment.content_rect.origin += relative_adjustement(style, containing_block) - .to_physical_size(containing_block.effective_writing_mode()) + .to_physical_size(containing_block.style.writing_mode) } (fragment, self.positioning_context) @@ -409,7 +409,7 @@ impl FlexContainer { let mut sum_of_flex_shrink_factors = 0.0; let mut item_infos = vec![]; - let container_is_horizontal = self.style.effective_writing_mode().is_horizontal(); + let container_is_horizontal = self.style.writing_mode.is_horizontal(); for kid in self.children.iter() { let kid = &mut *kid.borrow_mut(); match kid { @@ -806,8 +806,8 @@ impl FlexContainer { all_baselines.last = line_all_baselines.last; } - let physical_line_position = flow_relative_line_position - .to_physical_size(self.style.effective_writing_mode()); + let physical_line_position = + flow_relative_line_position.to_physical_size(self.style.writing_mode); for (fragment, _) in &mut final_line_layout.item_fragments { fragment.content_rect.origin += physical_line_position; } @@ -912,12 +912,13 @@ impl FlexContainer { start_corner: LogicalVec2::zero(), size: self.config.flex_axis.vec2_to_flow_relative(container_size), } - .to_physical(containing_block.effective_writing_mode()); + .to_physical(Some(containing_block)); let hoisted_box = AbsolutelyPositionedBox::to_hoisted( absolutely_positioned_box, static_position_rect, logical_alignment, + self.config.writing_mode, ); let hoisted_fragment = hoisted_box.fragment.clone(); positioning_context.push(hoisted_box); @@ -995,14 +996,8 @@ fn allocate_free_cross_space_for_flex_line( impl<'a> FlexItem<'a> { fn new(flex_context: &FlexContext, box_: &'a mut FlexItemBox) -> Self { let containing_block = flex_context.containing_block; - let parent_writing_mode = containing_block.effective_writing_mode(); - let item_writing_mode = box_.style().effective_writing_mode(); - - // https://drafts.csswg.org/css-writing-modes/#orthogonal-flows - assert_eq!( - parent_writing_mode, item_writing_mode, - "Mixed writing modes are not supported yet" - ); + let parent_writing_mode = containing_block.style.writing_mode; + let item_writing_mode = box_.style().writing_mode; let container_is_horizontal = parent_writing_mode.is_horizontal(); let item_is_horizontal = item_writing_mode.is_horizontal(); @@ -1697,15 +1692,6 @@ impl FlexItem<'_> { ) }); - // https://drafts.csswg.org/css-writing-modes/#orthogonal-flows - let container_writing_mode = containing_block.effective_writing_mode(); - assert_eq!( - container_writing_mode, - self.box_.style().effective_writing_mode(), - "Mixed writing modes are not supported yet" - ); - // … and also the item’s inline axis. - let cross_size = match used_cross_size_override { Some(s) => AuOrAuto::LengthPercentage(s), None => self.content_box_size.cross.map(|cross_size| { @@ -1717,14 +1703,11 @@ impl FlexItem<'_> { }; let ifc = &mut self.box_.independent_formatting_context; - let item_writing_mode = ifc.style().effective_writing_mode(); + let item_writing_mode = ifc.style().writing_mode; let item_is_horizontal = item_writing_mode.is_horizontal(); let flex_axis = flex_context.config.flex_axis; let cross_axis_is_item_block_axis = cross_axis_is_item_block_axis( - containing_block - .style - .effective_writing_mode() - .is_horizontal(), + containing_block.style.writing_mode.is_horizontal(), item_is_horizontal, flex_axis, ); @@ -1769,6 +1752,7 @@ impl FlexItem<'_> { ) }; + let container_writing_mode = containing_block.style.writing_mode; match ifc { IndependentFormattingContext::Replaced(replaced) => { let size = replaced @@ -1820,7 +1804,7 @@ impl FlexItem<'_> { let item_writing_mode_is_orthogonal_to_container_writing_mode = flex_context.config.writing_mode.is_horizontal() != - non_replaced.style.effective_writing_mode().is_horizontal(); + non_replaced.style.writing_mode.is_horizontal(); let has_compatible_baseline = match flex_context.config.flex_axis { FlexAxis::Row => !item_writing_mode_is_orthogonal_to_container_writing_mode, FlexAxis::Column => item_writing_mode_is_orthogonal_to_container_writing_mode, @@ -2013,7 +1997,7 @@ impl FlexItemBox { let flex_axis = config.flex_axis; let main_start_cross_start = config.main_start_cross_start_sides_are; let style = self.style().clone(); - let item_writing_mode = style.effective_writing_mode(); + let item_writing_mode = style.writing_mode; let item_is_horizontal = item_writing_mode.is_horizontal(); let cross_axis_is_item_block_axis = cross_axis_is_item_block_axis(container_is_horizontal, item_is_horizontal, flex_axis); diff --git a/components/layout_2020/flexbox/mod.rs b/components/layout_2020/flexbox/mod.rs index b78be05cd8f..b0ef118b4e0 100644 --- a/components/layout_2020/flexbox/mod.rs +++ b/components/layout_2020/flexbox/mod.rs @@ -17,7 +17,6 @@ use crate::cell::ArcRefCell; use crate::formatting_contexts::IndependentFormattingContext; use crate::fragment_tree::BaseFragmentInfo; use crate::positioned::AbsolutelyPositionedBox; -use crate::style_ext::ComputedValuesExt; mod construct; mod geom; @@ -69,7 +68,7 @@ impl FlexContainerConfig { FlexContainerConfig { container_is_single_line, - writing_mode: container_style.effective_writing_mode(), + writing_mode: container_style.writing_mode, flex_axis, flex_direction, flex_direction_is_reversed, diff --git a/components/layout_2020/flow/float.rs b/components/layout_2020/flow/float.rs index 687a305820f..f3c66a5febb 100644 --- a/components/layout_2020/flow/float.rs +++ b/components/layout_2020/flow/float.rs @@ -16,6 +16,7 @@ use euclid::num::Zero; use serde::Serialize; use servo_arc::Arc; use style::computed_values::float::T as FloatProperty; +use style::computed_values::position::T as Position; use style::logical_geometry::WritingMode; use style::properties::ComputedValues; use style::values::computed::Clear; @@ -26,8 +27,8 @@ use crate::dom::NodeExt; use crate::dom_traversal::{Contents, NodeAndStyleInfo}; use crate::formatting_contexts::IndependentFormattingContext; use crate::fragment_tree::{BoxFragment, CollapsedBlockMargins, CollapsedMargin}; -use crate::geom::{LogicalRect, LogicalVec2, ToLogical}; -use crate::positioned::PositioningContext; +use crate::geom::{LogicalRect, LogicalVec2, PhysicalPoint, PhysicalRect, ToLogical}; +use crate::positioned::{relative_adjustement, PositioningContext}; use crate::style_ext::{Clamp, ComputedValuesExt, DisplayInside, PaddingBorderMargin}; use crate::{ContainingBlock, IndefiniteContainingBlock}; @@ -412,7 +413,7 @@ impl FloatContext { // The object fits perfectly here. Place it. match object.side { - FloatSide::Left => { + FloatSide::InlineStart => { let left_object_edge = match first_band.left { Some(band_left) => band_left.max(self.containing_block_info.inline_start), None => self.containing_block_info.inline_start, @@ -422,7 +423,7 @@ impl FloatContext { block: first_band.top.max(ceiling), } }, - FloatSide::Right => { + FloatSide::InlineEnd => { let right_object_edge = match first_band.right { Some(band_right) => band_right.min(self.containing_block_info.inline_end), None => self.containing_block_info.inline_end, @@ -441,8 +442,8 @@ impl FloatContext { let ceiling = self.ceiling(); let new_float_origin = self.place_object(new_float, ceiling); let new_float_extent = match new_float.side { - FloatSide::Left => new_float_origin.inline + new_float.size.inline, - FloatSide::Right => new_float_origin.inline, + FloatSide::InlineStart => new_float_origin.inline + new_float.size.inline, + FloatSide::InlineEnd => new_float_origin.inline, }; let new_float_rect = LogicalRect { @@ -459,11 +460,11 @@ impl FloatContext { // Update clear. match new_float.side { - FloatSide::Left => { + FloatSide::InlineStart => { self.clear_left_position .max_assign(new_float_rect.max_block_position()); }, - FloatSide::Right => { + FloatSide::InlineEnd => { self.clear_right_position .max_assign(new_float_rect.max_block_position()); }, @@ -513,8 +514,8 @@ pub struct PlacementInfo { /// See CSS 2.1 § 9.5.1: #[derive(Clone, Copy, Debug, PartialEq)] pub enum FloatSide { - Left, - Right, + InlineStart, + InlineEnd, } /// Internal data structure that describes a nonoverlapping vertical region in which floats may be @@ -536,11 +537,18 @@ pub struct FloatBand { } impl FloatSide { - fn from_style(style: &ComputedValues) -> Option { - match style.get_box().float { - FloatProperty::None => None, - FloatProperty::Left => Some(FloatSide::Left), - FloatProperty::Right => Some(FloatSide::Right), + fn from_style_and_container_writing_mode( + style: &ComputedValues, + container_writing_mode: WritingMode, + ) -> Option { + match (style.get_box().float, container_writing_mode.is_bidi_ltr()) { + (FloatProperty::None, _) => None, + (FloatProperty::Left, true) | (FloatProperty::Right, false) => { + Some(FloatSide::InlineStart) + }, + (FloatProperty::Right, true) | (FloatProperty::Left, false) => { + Some(FloatSide::InlineEnd) + }, } } } @@ -549,7 +557,7 @@ impl FloatBand { /// Determines whether an object fits in a band. Returns true if the object fits. fn object_fits(&self, object: &PlacementInfo, walls: &ContainingBlockPositionInfo) -> bool { match object.side { - FloatSide::Left => { + FloatSide::InlineStart => { // Compute a candidate left position for the object. let candidate_left = match self.left { None => walls.inline_start, @@ -570,7 +578,7 @@ impl FloatBand { } }, - FloatSide::Right => { + FloatSide::InlineEnd => { // Compute a candidate right position for the object. let candidate_right = match self.right { None => walls.inline_end, @@ -694,13 +702,13 @@ impl FloatBandNode { let mut new_band = self.band; if self.band.top >= range.start && self.band.top < range.end { match side { - FloatSide::Left => { + FloatSide::InlineStart => { new_band.left = match new_band.left { Some(old_value) => Some(std::cmp::max(old_value, new_value)), None => Some(new_value), }; }, - FloatSide::Right => { + FloatSide::InlineEnd => { new_band.right = match new_band.right { Some(old_value) => Some(std::cmp::min(old_value, new_value)), None => Some(new_value), @@ -984,23 +992,22 @@ impl FloatBox { ); children = replaced.contents.make_fragments( &replaced.style, - content_size - .to_physical_size(containing_block.effective_writing_mode()), + content_size.to_physical_size(containing_block.style.writing_mode), ) }, }; - let content_rect = LogicalRect { - start_corner: LogicalVec2::zero(), - size: content_size, - }; + let containing_block_writing_mode = containing_block.style.writing_mode; + let content_rect = PhysicalRect::new( + PhysicalPoint::zero(), + content_size.to_physical_size(containing_block_writing_mode), + ); - let containing_block_writing_mode = containing_block.effective_writing_mode(); BoxFragment::new( self.contents.base_fragment_info(), style.clone(), children, - content_rect.to_physical(containing_block_writing_mode), + content_rect, pbm.padding.to_physical(containing_block_writing_mode), pbm.border.to_physical(containing_block_writing_mode), margin.to_physical(containing_block_writing_mode), @@ -1203,7 +1210,7 @@ impl SequentialLayoutState { pub(crate) fn place_float_fragment( &mut self, box_fragment: &mut BoxFragment, - container_writing_mode: WritingMode, + containing_block: &ContainingBlock, margins_collapsing_with_parent_containing_block: CollapsedMargin, block_offset_from_containing_block_top: Au, ) { @@ -1218,19 +1225,35 @@ impl SequentialLayoutState { block_start_of_containing_block_in_bfc + block_offset_from_containing_block_top, ); - let pbm_sums = (box_fragment.padding + box_fragment.border + box_fragment.margin) + let container_writing_mode = containing_block.style.writing_mode; + let logical_float_size = box_fragment + .content_rect + .size + .to_logical(container_writing_mode); + let pbm_sums = box_fragment + .padding_border_margin() .to_logical(container_writing_mode); - let content_rect = &box_fragment.content_rect.to_logical(container_writing_mode); let margin_box_start_corner = self.floats.add_float(&PlacementInfo { - size: content_rect.size + pbm_sums.sum(), - side: FloatSide::from_style(&box_fragment.style).expect("Float box wasn't floated!"), + size: logical_float_size + pbm_sums.sum(), + side: FloatSide::from_style_and_container_writing_mode( + &box_fragment.style, + container_writing_mode, + ) + .expect("Float box wasn't floated!"), clear: box_fragment.style.get_box().clear, }); + // Re-calculate relative adjustment so that it is not lost when the BoxFragment's + // `content_rect` is overwritten below. + let relative_offset = match box_fragment.style.clone_position() { + Position::Relative => relative_adjustement(&box_fragment.style, containing_block), + _ => LogicalVec2::zero(), + }; + // This is the position of the float in the float-containing block formatting context. We add the // existing start corner here because we may have already gotten some relative positioning offset. let new_position_in_bfc = - margin_box_start_corner + pbm_sums.start_offset() + content_rect.start_corner; + margin_box_start_corner + pbm_sums.start_offset() + relative_offset; // This is the position of the float relative to the containing block start. let new_position_in_containing_block = LogicalVec2 { @@ -1238,7 +1261,13 @@ impl SequentialLayoutState { block: new_position_in_bfc.block - block_start_of_containing_block_in_bfc, }; - box_fragment.content_rect.origin = - new_position_in_containing_block.to_physical_point(container_writing_mode); + box_fragment.content_rect = LogicalRect { + start_corner: new_position_in_containing_block, + size: box_fragment + .content_rect + .size + .to_logical(container_writing_mode), + } + .to_physical(Some(&containing_block)); } } diff --git a/components/layout_2020/flow/inline/line.rs b/components/layout_2020/flow/inline/line.rs index 81fed6222dc..0484b294b9b 100644 --- a/components/layout_2020/flow/inline/line.rs +++ b/components/layout_2020/flow/inline/line.rs @@ -5,6 +5,7 @@ use app_units::Au; use bitflags::bitflags; use fonts::{FontMetrics, GlyphStore}; +use itertools::Either; use servo_arc::Arc; use style::computed_values::white_space_collapse::T as WhiteSpaceCollapse; use style::properties::ComputedValues; @@ -14,7 +15,6 @@ use style::values::generics::font::LineHeight; use style::values::specified::align::AlignFlags; use style::values::specified::box_::DisplayOutside; use style::values::specified::text::TextDecorationLine; -use style::values::Either; use style::Zero; use unicode_bidi::{BidiInfo, Level}; use webrender_api::FontInstanceKey; @@ -25,10 +25,11 @@ use crate::cell::ArcRefCell; use crate::fragment_tree::{ BaseFragmentInfo, BoxFragment, CollapsedBlockMargins, Fragment, TextFragment, }; -use crate::geom::{LogicalRect, LogicalVec2}; +use crate::geom::{AuOrAuto, LogicalRect, LogicalVec2, PhysicalRect, ToLogical}; use crate::positioned::{ relative_adjustement, AbsolutelyPositionedBox, PositioningContext, PositioningContextLength, }; +use crate::ContainingBlock; pub(super) struct LineMetrics { /// The block offset of the line start in the containing @@ -49,10 +50,10 @@ bitflags! { const HAD_ANY_LINE_ITEMS = 1 << 0; /// Whether or not the starting inline border, padding, or margin of the inline box /// was encountered. - const HAD_START_PBM = 1 << 2; + const HAD_LEFT_PBM = 1 << 2; /// Whether or not the ending inline border, padding, or margin of the inline box /// was encountered. - const HAD_END_PBM = 1 << 3; + const HAD_RIGHT_PBM = 1 << 3; /// Whether or not any floats were encountered while laying out this inline box. const HAD_ANY_FLOATS = 1 << 4; } @@ -66,16 +67,21 @@ pub(super) struct LineItemLayoutInlineContainerState { /// that is currently being laid out. pub identifier: Option, - /// The fragments that are laid out into this inline container on a line. - pub fragments: Vec, + /// The fragments and their logical rectangle relative within the current inline box (or + /// line). These logical rectangles will be converted into physical ones and the Fragment's + /// `content_rect` will be updated once the inline box's final size is known in + /// [`LineItemLayout::end_inline_box`]. + pub fragments: Vec<(Fragment, LogicalRect)>, - /// The current inline adavnce of the layout in the coordinates of this inline box. + /// The current inline advance of the layout in the coordinates of this inline box. pub inline_advance: Au, /// Flags which track various features during layout. flags: LineLayoutInlineContainerFlags, - /// The offset of the parent, relative to the start position of the line. + /// The offset of the parent, relative to the start position of the line, not including + /// any inline start and end borders which are only processed when the inline box is + /// finished. pub parent_offset: LogicalVec2, /// The block offset of the parent's baseline relative to the block start of the line. This @@ -117,7 +123,7 @@ impl LineItemLayoutInlineContainerState { None, LogicalVec2::zero(), baseline_offset, - Either::Second(PositioningContextLength::zero()), + Either::Right(PositioningContextLength::zero()), ); state.inline_advance = starting_inline_advance; state @@ -208,8 +214,8 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { // TODO: This level needs either to be last_level, or if there were // unicode characters inserted for the inline box, we need to get the // level from them. - LineItem::StartInlineBoxPaddingBorderMargin(_) => last_level, - LineItem::EndInlineBoxPaddingBorderMargin(_) => last_level, + LineItem::LeftInlineBoxPaddingBorderMargin(_) => last_level, + LineItem::RightInlineBoxPaddingBorderMargin(_) => last_level, LineItem::Atomic(_, atomic) => atomic.bidi_level, LineItem::AbsolutelyPositioned(..) => last_level, LineItem::Float(..) => { @@ -227,7 +233,25 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { sort_by_indices_in_place(&mut line_items, BidiInfo::reorder_visual(&levels)); } - for item in line_items.into_iter().by_ref() { + // `BidiInfo::reorder_visual` will reorder the contents of the line so that they + // are in the correct order as if one was looking at the line from left-to-right. + // During this layout we do not lay out from left to right. Instead we lay out + // from inline-start to inline-end. If the overall line contents have been flipped + // for BiDi, flip them again so that they are in line start-to-end order rather + // than left-to-right order. + let line_item_iterator = if self + .layout + .containing_block + .style + .writing_mode + .is_bidi_ltr() + { + Either::Left(line_items.into_iter()) + } else { + Either::Right(line_items.into_iter().rev()) + }; + + for item in line_item_iterator.into_iter().by_ref() { // When preparing to lay out a new line item, start and end inline boxes, so that the current // inline box state reflects the item's parent. Items in the line are not necessarily in tree // order due to BiDi and other reordering so the inline box of the item could potentially be @@ -238,15 +262,15 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { .flags .insert(LineLayoutInlineContainerFlags::HAD_ANY_LINE_ITEMS); match item { - LineItem::StartInlineBoxPaddingBorderMargin(_) => { + LineItem::LeftInlineBoxPaddingBorderMargin(_) => { self.current_state .flags - .insert(LineLayoutInlineContainerFlags::HAD_START_PBM); + .insert(LineLayoutInlineContainerFlags::HAD_LEFT_PBM); }, - LineItem::EndInlineBoxPaddingBorderMargin(_) => { + LineItem::RightInlineBoxPaddingBorderMargin(_) => { self.current_state .flags - .insert(LineLayoutInlineContainerFlags::HAD_END_PBM); + .insert(LineLayoutInlineContainerFlags::HAD_RIGHT_PBM); }, LineItem::TextRun(_, text_run) => self.layout_text_run(text_run), LineItem::Atomic(_, atomic) => self.layout_atomic(atomic), @@ -257,11 +281,29 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { // Move back to the root of the inline box tree, so that all boxes are ended. self.prepare_layout_for_inline_box(None); - std::mem::take(&mut self.current_state.fragments) + + let fragments_and_rectangles = std::mem::take(&mut self.current_state.fragments); + fragments_and_rectangles + .into_iter() + .map(|(mut fragment, logical_rect)| { + if matches!(fragment, Fragment::Float(_)) { + return fragment; + } + + // We do not know the actual physical position of a logically laid out inline element, until + // we know the width of the containing inline block. This step converts the logical rectangle + // into a physical one based on the inline formatting context width. + if let Some(content_rect) = fragment.content_rect_mut() { + *content_rect = logical_rect.to_physical(Some(self.layout.containing_block)) + } + + fragment + }) + .collect() } fn current_positioning_context_mut(&mut self) -> &mut PositioningContext { - if let Either::First(ref mut positioning_context) = self + if let Either::Left(ref mut positioning_context) = self .current_state .positioning_context_or_start_offset_in_parent { @@ -272,8 +314,8 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { .rev() .find_map( |state| match state.positioning_context_or_start_offset_in_parent { - Either::First(ref mut positioning_context) => Some(positioning_context), - Either::Second(_) => None, + Either::Left(ref mut positioning_context) => Some(positioning_context), + Either::Right(_) => None, }, ) .unwrap_or(self.layout.positioning_context) @@ -292,8 +334,8 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { let positioning_context_or_start_offset_in_parent = match PositioningContext::new_for_style(style) { - Some(positioning_context) => Either::First(positioning_context), - None => Either::Second(self.current_positioning_context_mut().len()), + Some(positioning_context) => Either::Left(positioning_context), + None => Either::Right(self.current_positioning_context_mut().len()), }; let parent_offset = LogicalVec2 { @@ -316,7 +358,7 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { fn end_inline_box(&mut self) { let outer_state = self.state_stack.pop().expect("Ended unknown inline box"); - let mut inner_state = std::mem::replace(&mut self.current_state, outer_state); + let inner_state = std::mem::replace(&mut self.current_state, outer_state); let identifier = inner_state.identifier.expect("Ended unknown inline box"); let inline_box_state = @@ -328,12 +370,24 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { let mut border = inline_box_state.pbm.border; let mut margin = inline_box_state.pbm.margin.auto_is(Au::zero); - let had_start = inner_state + let had_left = inner_state .flags - .contains(LineLayoutInlineContainerFlags::HAD_START_PBM); - let had_end = inner_state + .contains(LineLayoutInlineContainerFlags::HAD_LEFT_PBM); + let had_right = inner_state .flags - .contains(LineLayoutInlineContainerFlags::HAD_END_PBM); + .contains(LineLayoutInlineContainerFlags::HAD_RIGHT_PBM); + + let (had_start, had_end) = if self + .layout + .containing_block + .style + .writing_mode + .is_bidi_ltr() + { + (had_left, had_right) + } else { + (had_right, had_left) + }; if !had_start { padding.inline_start = Au::zero(); @@ -368,14 +422,6 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { }, }; - let ifc_writing_mode = self.layout.containing_block.effective_writing_mode(); - for fragment in inner_state.fragments.iter_mut() { - if let Fragment::Float(box_fragment) = fragment { - box_fragment.content_rect.origin -= - pbm_sums.start_offset().to_physical_size(ifc_writing_mode); - } - } - // Relative adjustment should not affect the rest of line layout, so we can // do it right before creating the Fragment. let style = &inline_box.style; @@ -383,11 +429,40 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { content_rect.start_corner += relative_adjustement(style, self.layout.containing_block); } + let ifc_writing_mode = self.layout.containing_block.style.writing_mode; + let inline_box_containing_block = ContainingBlock { + inline_size: content_rect.size.inline, + block_size: AuOrAuto::Auto, + style: &self.layout.containing_block.style, + }; + let fragments = inner_state + .fragments + .into_iter() + .map(|(mut fragment, logical_rect)| { + let is_float = matches!(fragment, Fragment::Float(_)); + if let Some(content_rect) = fragment.content_rect_mut() { + if is_float { + content_rect.origin -= + pbm_sums.start_offset().to_physical_size(ifc_writing_mode); + } else { + // We do not know the actual physical position of a logically laid out inline element, until + // we know the width of the containing inline block. This step converts the logical rectangle + // into a physical one now that we've computed inline size of the containing inline block above. + *content_rect = logical_rect.to_physical(Some(&inline_box_containing_block)) + } + } + fragment + }) + .collect(); + + // Previously all the fragment's children were positioned relative to the linebox, + // but they need to be made relative to this fragment. + let physical_content_rect = content_rect.to_physical(Some(self.layout.containing_block)); let mut fragment = BoxFragment::new( inline_box.base_fragment_info, style.clone(), - inner_state.fragments, - content_rect.to_physical(ifc_writing_mode), + fragments, + physical_content_rect, padding.to_physical(ifc_writing_mode), border.to_physical(ifc_writing_mode), margin.to_physical(ifc_writing_mode), @@ -395,28 +470,36 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { CollapsedBlockMargins::zero(), ); + let offset_from_parent_ifc = LogicalVec2 { + inline: pbm_sums.inline_start + self.current_state.inline_advance, + block: content_rect.start_corner.block, + } + .to_physical_vector(self.layout.containing_block.style.writing_mode); + match inner_state.positioning_context_or_start_offset_in_parent { - Either::First(mut positioning_context) => { + Either::Left(mut positioning_context) => { positioning_context .layout_collected_children(self.layout.layout_context, &mut fragment); positioning_context.adjust_static_position_of_hoisted_fragments_with_offset( - &fragment.content_rect.origin.to_vector(), + &offset_from_parent_ifc, PositioningContextLength::zero(), ); self.current_positioning_context_mut() .append(positioning_context); }, - Either::Second(start_offset) => { + Either::Right(start_offset) => { self.current_positioning_context_mut() .adjust_static_position_of_hoisted_fragments_with_offset( - &fragment.content_rect.origin.to_vector(), + &offset_from_parent_ifc, start_offset, ); }, } self.current_state.inline_advance += inner_state.inline_advance + pbm_sums.inline_sum(); - self.current_state.fragments.push(Fragment::Box(fragment)); + self.current_state + .fragments + .push((Fragment::Box(fragment), content_rect)); } fn calculate_inline_box_block_start( @@ -477,8 +560,7 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { text_item.font_metrics.ascent - self.current_state.parent_offset.block, }; - - let rect = LogicalRect { + let content_rect = LogicalRect { start_corner, size: LogicalVec2 { block: text_item.font_metrics.line_gap, @@ -487,29 +569,37 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { }; self.current_state.inline_advance += inline_advance; - self.current_state - .fragments - .push(Fragment::Text(TextFragment { + self.current_state.fragments.push(( + Fragment::Text(TextFragment { base: text_item.base_fragment_info.into(), parent_style: text_item.parent_style, - rect: rect.to_physical(self.layout.containing_block.effective_writing_mode()), + rect: PhysicalRect::zero(), font_metrics: text_item.font_metrics, font_key: text_item.font_key, glyphs: text_item.text, text_decoration_line: text_item.text_decoration_line, justification_adjustment: self.justification_adjustment, - })); + }), + content_rect, + )); } - fn layout_atomic(&mut self, mut atomic: AtomicLineItem) { + fn layout_atomic(&mut self, atomic: AtomicLineItem) { // The initial `start_corner` of the Fragment is only the PaddingBorderMargin sum start // offset, which is the sum of the start component of the padding, border, and margin. // This needs to be added to the calculated block and inline positions. // Make the final result relative to the parent box. + let ifc_writing_mode = self.layout.containing_block.style.writing_mode; + let padding_border_margin_sides = atomic + .fragment + .padding_border_margin() + .to_logical(ifc_writing_mode); + let mut atomic_offset = LogicalVec2 { - inline: self.current_state.inline_advance, + inline: self.current_state.inline_advance + padding_border_margin_sides.inline_start, block: atomic.calculate_block_start(&self.line_metrics) - - self.current_state.parent_offset.block, + self.current_state.parent_offset.block + + padding_border_margin_sides.block_start, }; if atomic.fragment.style.clone_position().is_relative() { @@ -517,14 +607,25 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { relative_adjustement(&atomic.fragment.style, self.layout.containing_block); } - let ifc_writing_mode = self.layout.containing_block.effective_writing_mode(); - atomic.fragment.content_rect.origin += atomic_offset.to_physical_size(ifc_writing_mode); + // Reconstruct a logical rectangle relative to the inline box container that will be used + // after the inline box is procesed to find a final physical rectangle. + let content_rect = LogicalRect { + start_corner: atomic_offset, + size: atomic + .fragment + .content_rect + .size + .to_logical(ifc_writing_mode), + }; if let Some(mut positioning_context) = atomic.positioning_context { + let physical_rect_as_if_in_root = + content_rect.to_physical(Some(self.layout.containing_block)); positioning_context.adjust_static_position_of_hoisted_fragments_with_offset( - &atomic.fragment.content_rect.origin.to_vector(), + &physical_rect_as_if_in_root.origin.to_vector(), PositioningContextLength::zero(), ); + self.current_positioning_context_mut() .append(positioning_context); } @@ -532,7 +633,7 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { self.current_state.inline_advance += atomic.size.inline; self.current_state .fragments - .push(Fragment::Box(atomic.fragment)); + .push((Fragment::Box(atomic.fragment), content_rect)); } fn layout_absolute(&mut self, absolute: AbsolutelyPositionedLineItem) { @@ -572,7 +673,7 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { start_corner: initial_start_corner, size: LogicalVec2::zero(), } - .to_physical(self.layout.containing_block.effective_writing_mode()); + .to_physical(Some(self.layout.containing_block)); let hoisted_box = AbsolutelyPositionedBox::to_hoisted( absolute.absolutely_positioned_box.clone(), @@ -581,12 +682,15 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { inline: AlignFlags::START, block: AlignFlags::START, }, + self.layout.containing_block.style.writing_mode, ); + let hoisted_fragment = hoisted_box.fragment.clone(); self.current_positioning_context_mut().push(hoisted_box); - self.current_state - .fragments - .push(Fragment::AbsoluteOrFixedPositioned(hoisted_fragment)); + self.current_state.fragments.push(( + Fragment::AbsoluteOrFixedPositioned(hoisted_fragment), + LogicalRect::zero(), + )); } fn layout_float(&mut self, mut float: FloatLineItem) { @@ -604,16 +708,17 @@ impl<'layout_data, 'layout> LineItemLayout<'layout_data, 'layout> { block: self.line_metrics.block_offset + self.current_state.parent_offset.block, }; float.fragment.content_rect.origin -= distance_from_parent_to_ifc - .to_physical_size(self.layout.containing_block.effective_writing_mode()); + .to_physical_size(self.layout.containing_block.style.writing_mode); + self.current_state .fragments - .push(Fragment::Float(float.fragment)); + .push((Fragment::Float(float.fragment), LogicalRect::zero())); } } pub(super) enum LineItem { - StartInlineBoxPaddingBorderMargin(InlineBoxIdentifier), - EndInlineBoxPaddingBorderMargin(InlineBoxIdentifier), + LeftInlineBoxPaddingBorderMargin(InlineBoxIdentifier), + RightInlineBoxPaddingBorderMargin(InlineBoxIdentifier), TextRun(Option, TextRunLineItem), Atomic(Option, AtomicLineItem), AbsolutelyPositioned(Option, AbsolutelyPositionedLineItem), @@ -623,8 +728,8 @@ pub(super) enum LineItem { impl LineItem { fn inline_box_identifier(&self) -> Option { match self { - LineItem::StartInlineBoxPaddingBorderMargin(identifier) => Some(*identifier), - LineItem::EndInlineBoxPaddingBorderMargin(identifier) => Some(*identifier), + LineItem::LeftInlineBoxPaddingBorderMargin(identifier) => Some(*identifier), + LineItem::RightInlineBoxPaddingBorderMargin(identifier) => Some(*identifier), LineItem::TextRun(identifier, _) => *identifier, LineItem::Atomic(identifier, _) => *identifier, LineItem::AbsolutelyPositioned(identifier, _) => *identifier, @@ -634,8 +739,8 @@ impl LineItem { pub(super) fn trim_whitespace_at_end(&mut self, whitespace_trimmed: &mut Au) -> bool { match self { - LineItem::StartInlineBoxPaddingBorderMargin(_) => true, - LineItem::EndInlineBoxPaddingBorderMargin(_) => true, + LineItem::LeftInlineBoxPaddingBorderMargin(_) => true, + LineItem::RightInlineBoxPaddingBorderMargin(_) => true, LineItem::TextRun(_, ref mut item) => item.trim_whitespace_at_end(whitespace_trimmed), LineItem::Atomic(..) => false, LineItem::AbsolutelyPositioned(..) => true, @@ -645,8 +750,8 @@ impl LineItem { pub(super) fn trim_whitespace_at_start(&mut self, whitespace_trimmed: &mut Au) -> bool { match self { - LineItem::StartInlineBoxPaddingBorderMargin(_) => true, - LineItem::EndInlineBoxPaddingBorderMargin(_) => true, + LineItem::LeftInlineBoxPaddingBorderMargin(_) => true, + LineItem::RightInlineBoxPaddingBorderMargin(_) => true, LineItem::TextRun(_, ref mut item) => item.trim_whitespace_at_start(whitespace_trimmed), LineItem::Atomic(..) => false, LineItem::AbsolutelyPositioned(..) => true, diff --git a/components/layout_2020/flow/inline/mod.rs b/components/layout_2020/flow/inline/mod.rs index 123538eebc3..8653a3dff8c 100644 --- a/components/layout_2020/flow/inline/mod.rs +++ b/components/layout_2020/flow/inline/mod.rs @@ -123,7 +123,7 @@ use crate::fragment_tree::{ BoxFragment, CollapsedBlockMargins, CollapsedMargin, Fragment, FragmentFlags, PositioningFragment, }; -use crate::geom::{LogicalRect, LogicalVec2, PhysicalRect, ToLogical}; +use crate::geom::{LogicalRect, LogicalVec2, PhysicalPoint, PhysicalRect, ToLogical}; use crate::positioned::{AbsolutelyPositionedBox, PositioningContext}; use crate::sizing::ContentSizes; use crate::style_ext::{Clamp, ComputedValuesExt, PaddingBorderMargin}; @@ -719,7 +719,7 @@ impl<'layout_dta> InlineFormattingContextLayout<'layout_dta> { inline_box_state.pbm.margin.inline_start.auto_is(Au::zero); self.current_line_segment .line_items - .push(LineItem::StartInlineBoxPaddingBorderMargin( + .push(LineItem::LeftInlineBoxPaddingBorderMargin( inline_box.identifier, )); } @@ -764,7 +764,7 @@ impl<'layout_dta> InlineFormattingContextLayout<'layout_dta> { self.current_line_segment.inline_size += pbm_end; self.current_line_segment .line_items - .push(LineItem::EndInlineBoxPaddingBorderMargin( + .push(LineItem::RightInlineBoxPaddingBorderMargin( inline_box_state.identifier, )) } @@ -872,30 +872,34 @@ impl<'layout_dta> InlineFormattingContextLayout<'layout_dta> { self.baselines.first.get_or_insert(baseline); self.baselines.last = Some(baseline); - let line_rect = LogicalRect { - // The inline part of this start offset was taken into account when determining - // the inline start of the line in `calculate_inline_start_for_current_line` so - // we do not need to include it in the `start_corner` of the line's main Fragment. - start_corner: LogicalVec2 { - inline: Au::zero(), - block: block_start_position, - }, + // The inline part of this start offset was taken into account when determining + // the inline start of the line in `calculate_inline_start_for_current_line` so + // we do not need to include it in the `start_corner` of the line's main Fragment. + let start_corner = LogicalVec2 { + inline: Au::zero(), + block: block_start_position, + }; + + let logical_origin_in_physical_coordinates = + start_corner.to_physical_vector(self.containing_block.style.writing_mode); + self.positioning_context + .adjust_static_position_of_hoisted_fragments_with_offset( + &logical_origin_in_physical_coordinates, + start_positioning_context_length, + ); + + let physical_line_rect = LogicalRect { + start_corner, size: LogicalVec2 { inline: self.containing_block.inline_size, block: effective_block_advance.resolve(), }, - }; - - let line_rect = line_rect.to_physical(self.containing_block.effective_writing_mode()); - self.positioning_context - .adjust_static_position_of_hoisted_fragments_with_offset( - &line_rect.origin.to_vector(), - start_positioning_context_length, - ); - + } + .to_physical(Some(self.containing_block)); self.fragments .push(Fragment::Positioning(PositioningFragment::new_anonymous( - line_rect, fragments, + physical_line_rect, + fragments, ))); } @@ -909,9 +913,9 @@ impl<'layout_dta> InlineFormattingContextLayout<'layout_dta> { last_line_or_forced_line_break: bool, ) -> (Au, Au) { enum TextAlign { - Left, + Start, Center, - Right, + End, } let style = self.containing_block.style; let mut text_align_keyword = style.clone_text_align(); @@ -932,24 +936,24 @@ impl<'layout_dta> InlineFormattingContextLayout<'layout_dta> { } let text_align = match text_align_keyword { - TextAlignKeyword::Start => { - if style.writing_mode.line_left_is_inline_start() { - TextAlign::Left - } else { - TextAlign::Right - } - }, + TextAlignKeyword::Start => TextAlign::Start, TextAlignKeyword::Center | TextAlignKeyword::MozCenter => TextAlign::Center, - TextAlignKeyword::End => { + TextAlignKeyword::End => TextAlign::End, + TextAlignKeyword::Left | TextAlignKeyword::MozLeft => { if style.writing_mode.line_left_is_inline_start() { - TextAlign::Right + TextAlign::Start } else { - TextAlign::Left + TextAlign::End } }, - TextAlignKeyword::Left | TextAlignKeyword::MozLeft => TextAlign::Left, - TextAlignKeyword::Right | TextAlignKeyword::MozRight => TextAlign::Right, - TextAlignKeyword::Justify => TextAlign::Left, + TextAlignKeyword::Right | TextAlignKeyword::MozRight => { + if style.writing_mode.line_left_is_inline_start() { + TextAlign::End + } else { + TextAlign::Start + } + }, + TextAlignKeyword::Justify => TextAlign::Start, }; let (line_start, available_space) = match self.current_line.placement_among_floats.get() { @@ -970,8 +974,8 @@ impl<'layout_dta> InlineFormattingContextLayout<'layout_dta> { let line_length = self.current_line.inline_position - whitespace_trimmed - text_indent; let adjusted_line_start = line_start + match text_align { - TextAlign::Left => text_indent, - TextAlign::Right => (available_space - line_length).max(text_indent), + TextAlign::Start => text_indent, + TextAlign::End => (available_space - line_length).max(text_indent), TextAlign::Center => (available_space - line_length + text_indent) .scale_by(0.5) .max(text_indent), @@ -1015,7 +1019,7 @@ impl<'layout_dta> InlineFormattingContextLayout<'layout_dta> { state.current_containing_block_offset(); state.place_float_fragment( fragment, - self.containing_block.effective_writing_mode(), + self.containing_block, CollapsedMargin::zero(), block_offset_from_containining_block_top, ); @@ -1034,11 +1038,12 @@ impl<'layout_dta> InlineFormattingContextLayout<'layout_dta> { float_item: &mut FloatLineItem, line_inline_size_without_trailing_whitespace: Au, ) { - let margin_box = float_item + let logical_margin_rect_size = float_item .fragment .margin_rect() - .to_logical(self.containing_block.effective_writing_mode()); - let inline_size = margin_box.size.inline.max(Au::zero()); + .size + .to_logical(self.containing_block.style.writing_mode); + let inline_size = logical_margin_rect_size.inline.max(Au::zero()); let available_inline_size = match self.current_line.placement_among_floats.get() { Some(placement_among_floats) => placement_among_floats.size.inline, @@ -1902,36 +1907,22 @@ impl IndependentFormattingContext { bidi_level: Level, ) { let style = self.style(); - let container_writing_mode = layout.containing_block.style.effective_writing_mode(); + let container_writing_mode = layout.containing_block.style.writing_mode; let pbm = style.padding_border_margin(layout.containing_block); let margin = pbm.margin.auto_is(Au::zero); let pbm_sums = pbm.padding + pbm.border + margin; - let pbm_physical_origin = pbm_sums - .start_offset() - .to_physical_point(container_writing_mode); - let mut child_positioning_context = None; // We need to know the inline size of the atomic before deciding whether to do the line break. - let fragment = match self { + let (fragments, content_rect, baselines, mut child_positioning_context) = match self { IndependentFormattingContext::Replaced(replaced) => { let size = replaced .contents .used_size_as_if_inline_element(layout.containing_block, &replaced.style, &pbm) .to_physical_size(container_writing_mode); let fragments = replaced.contents.make_fragments(&replaced.style, size); - let content_rect = PhysicalRect::new(pbm_physical_origin, size); - BoxFragment::new( - replaced.base_fragment_info, - replaced.style.clone(), - fragments, - content_rect, - pbm.padding.to_physical(container_writing_mode), - pbm.border.to_physical(container_writing_mode), - margin.to_physical(container_writing_mode), - None, /* clearance */ - CollapsedBlockMargins::zero(), - ) + let content_rect = PhysicalRect::new(PhysicalPoint::zero(), size); + (fragments, content_rect, None, None) }, IndependentFormattingContext::NonReplaced(non_replaced) => { let box_size = non_replaced @@ -2010,7 +2001,7 @@ impl IndependentFormattingContext { }; let content_rect = PhysicalRect::new( - pbm_physical_origin, + PhysicalPoint::zero(), LogicalVec2 { block: block_size, inline: inline_size, @@ -2018,32 +2009,50 @@ impl IndependentFormattingContext { .to_physical_size(container_writing_mode), ); - let mut fragment = BoxFragment::new( - non_replaced.base_fragment_info, - non_replaced.style.clone(), + ( independent_layout.fragments, content_rect, - pbm.padding.to_physical(container_writing_mode), - pbm.border.to_physical(container_writing_mode), - margin.to_physical(container_writing_mode), - None, - CollapsedBlockMargins::zero(), + Some(independent_layout.baselines), + Some(positioning_context), ) - .with_baselines(independent_layout.baselines); - - if fragment - .style - .establishes_containing_block_for_absolute_descendants(fragment.base.flags) - { - positioning_context - .layout_collected_children(layout.layout_context, &mut fragment); - } - child_positioning_context = Some(positioning_context); - - fragment }, }; + // Offset the content rectangle by the physical offset of the padding, border, and margin. + let pbm_physical_offset = pbm_sums + .start_offset() + .to_physical_size(container_writing_mode); + let content_rect = content_rect.translate(pbm_physical_offset.to_vector()); + + let fragment = BoxFragment::new( + self.base_fragment_info(), + self.style().clone(), + fragments, + content_rect, + pbm.padding.to_physical(container_writing_mode), + pbm.border.to_physical(container_writing_mode), + margin.to_physical(container_writing_mode), + None, /* clearance */ + CollapsedBlockMargins::zero(), + ); + + // Apply baselines if necessary. + let mut fragment = match baselines { + Some(baselines) => fragment.with_baselines(baselines), + None => fragment, + }; + + // Lay out absolutely positioned children if this new atomic establishes a containing block + // for absolutes. + if let Some(positioning_context) = child_positioning_context.as_mut() { + if fragment + .style + .establishes_containing_block_for_absolute_descendants(fragment.base.flags) + { + positioning_context.layout_collected_children(layout.layout_context, &mut fragment); + } + } + if layout.text_wrap_mode == TextWrapMode::Wrap && !layout .ifc @@ -2055,8 +2064,8 @@ impl IndependentFormattingContext { let size = pbm_sums.sum() + fragment .content_rect - .to_logical(container_writing_mode) - .size; + .size + .to_logical(container_writing_mode); let baseline_offset = self .pick_baseline(&fragment.baselines(container_writing_mode)) .map(|baseline| pbm_sums.block_start + baseline) diff --git a/components/layout_2020/flow/mod.rs b/components/layout_2020/flow/mod.rs index 60a7bffaa90..b3f630cbe48 100644 --- a/components/layout_2020/flow/mod.rs +++ b/components/layout_2020/flow/mod.rs @@ -12,7 +12,6 @@ use serde::Serialize; use servo_arc::Arc; use style::computed_values::clear::T as Clear; use style::computed_values::float::T as Float; -use style::logical_geometry::WritingMode; use style::properties::ComputedValues; use style::values::computed::{Length, Size}; use style::values::specified::align::AlignFlags; @@ -32,6 +31,7 @@ use crate::fragment_tree::{ }; use crate::geom::{ AuOrAuto, LogicalRect, LogicalSides, LogicalVec2, PhysicalRect, PhysicalSides, ToLogical, + ToLogicalWithContainingBlock, }; use crate::positioned::{AbsolutelyPositionedBox, PositioningContext, PositioningContextLength}; use crate::replaced::ReplacedContent; @@ -245,7 +245,6 @@ impl OutsideMarker { collapsible_with_parent_start_margin.unwrap_or(CollapsibleWithParentStartMargin(false)), ); - let containing_block_writing_mode = containing_block.effective_writing_mode(); let max_inline_size = flow_layout .fragments @@ -265,7 +264,7 @@ impl OutsideMarker { ); }, } - .to_logical(containing_block_writing_mode) + .to_logical(&containing_block_for_children) .max_inline_position(), ) }); @@ -297,7 +296,7 @@ impl OutsideMarker { base_fragment_info, self.marker_style.clone(), flow_layout.fragments, - content_rect.to_physical(containing_block_writing_mode), + content_rect.to_physical(Some(containing_block)), PhysicalSides::zero(), PhysicalSides::zero(), PhysicalSides::zero(), @@ -534,7 +533,7 @@ fn layout_block_level_children( collapsible_with_parent_start_margin: CollapsibleWithParentStartMargin, ) -> FlowLayout { let mut placement_state = - PlacementState::new(collapsible_with_parent_start_margin, containing_block.style); + PlacementState::new(collapsible_with_parent_start_margin, containing_block); let fragments = match sequential_layout_state { Some(ref mut sequential_layout_state) => layout_block_level_children_sequentially( @@ -705,6 +704,9 @@ impl BlockLevelBox { }, }, BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(box_) => { + // The static position of zero here is incorrect, however we do not know + // the correct positioning until later, in place_block_level_fragment, and + // this value will be adjusted there. let hoisted_box = AbsolutelyPositionedBox::to_hoisted( box_.clone(), // This is incorrect, however we do not know the correct positioning @@ -715,6 +717,7 @@ impl BlockLevelBox { inline: AlignFlags::START, block: AlignFlags::START, }, + containing_block.style.writing_mode, ); let hoisted_fragment = hoisted_box.fragment.clone(); positioning_context.push(hoisted_box); @@ -934,12 +937,12 @@ fn layout_in_flow_non_replaced_block_level_same_formatting_context( }, }; - let containing_block_writing_mode = containing_block.effective_writing_mode(); + let containing_block_writing_mode = containing_block.style.writing_mode; BoxFragment::new( base_fragment_info, style.clone(), flow_layout.fragments, - content_rect.to_physical(containing_block_writing_mode), + content_rect.to_physical(Some(containing_block)), pbm.padding.to_physical(containing_block_writing_mode), pbm.border.to_physical(containing_block_writing_mode), margin.to_physical(containing_block_writing_mode), @@ -1019,12 +1022,12 @@ impl NonReplacedFormattingContext { }; let block_margins_collapsed_with_children = CollapsedBlockMargins::from_margin(&margin); - let containing_block_writing_mode = containing_block.effective_writing_mode(); + let containing_block_writing_mode = containing_block.style.writing_mode; BoxFragment::new( self.base_fragment_info, self.style.clone(), layout.fragments, - content_rect.to_physical(containing_block_writing_mode), + content_rect.to_physical(Some(containing_block)), pbm.padding.to_physical(containing_block_writing_mode), pbm.border.to_physical(containing_block_writing_mode), margin.to_physical(containing_block_writing_mode), @@ -1269,12 +1272,12 @@ impl NonReplacedFormattingContext { }; let block_margins_collapsed_with_children = CollapsedBlockMargins::from_margin(&margin); - let containing_block_writing_mode = containing_block.effective_writing_mode(); + let containing_block_writing_mode = containing_block.style.writing_mode; BoxFragment::new( self.base_fragment_info, self.style.clone(), layout.fragments, - content_rect.to_physical(containing_block_writing_mode), + content_rect.to_physical(Some(containing_block)), pbm.padding.to_physical(containing_block_writing_mode), pbm.border.to_physical(containing_block_writing_mode), margin.to_physical(containing_block_writing_mode), @@ -1303,7 +1306,7 @@ fn layout_in_flow_replaced_block_level( let effective_margin_inline_start; let (margin_block_start, margin_block_end) = solve_block_margins_for_in_flow_block_level(&pbm); - let containing_block_writing_mode = containing_block.effective_writing_mode(); + let containing_block_writing_mode = containing_block.style.writing_mode; let physical_content_size = content_size.to_physical_size(containing_block_writing_mode); let fragments = replaced.make_fragments(style, physical_content_size); @@ -1371,11 +1374,12 @@ fn layout_in_flow_replaced_block_level( clearance.unwrap_or_else(Au::zero), inline: pbm.padding.inline_start + pbm.border.inline_start + effective_margin_inline_start, }; + let content_rect = LogicalRect { + start_corner, + size: content_size, + } + .to_physical(Some(containing_block)); - let content_rect = PhysicalRect::new( - start_corner.to_physical_point(containing_block_writing_mode), - physical_content_size, - ); let block_margins_collapsed_with_children = CollapsedBlockMargins::from_margin(&margin); BoxFragment::new( @@ -1455,9 +1459,12 @@ fn solve_containing_block_padding_and_border_for_in_flow_box<'a>( }; // https://drafts.csswg.org/css-writing-modes/#orthogonal-flows assert_eq!( - containing_block.effective_writing_mode(), - containing_block_for_children.effective_writing_mode(), - "Mixed writing modes are not supported yet" + containing_block.style.writing_mode.is_horizontal(), + containing_block_for_children + .style + .writing_mode + .is_horizontal(), + "Vertical writing modes are not supported yet" ); ContainingBlockPaddingAndBorder { containing_block: containing_block_for_children, @@ -1510,16 +1517,8 @@ fn justify_self_alignment(containing_block: &ContainingBlock, free_space: Au) -> debug_assert!(free_space >= Au::zero()); match style.clone_text_align() { TextAlignKeyword::MozCenter => free_space / 2, - TextAlignKeyword::MozLeft - if !style.effective_writing_mode().line_left_is_inline_start() => - { - free_space - }, - TextAlignKeyword::MozRight - if style.effective_writing_mode().line_left_is_inline_start() => - { - free_space - }, + TextAlignKeyword::MozLeft if !style.writing_mode.line_left_is_inline_start() => free_space, + TextAlignKeyword::MozRight if style.writing_mode.line_left_is_inline_start() => free_space, _ => Au::zero(), } } @@ -1643,7 +1642,7 @@ fn solve_clearance_and_inline_margins_avoiding_floats( /// /// In parallel mode, this placement is done after all child blocks are laid out. In /// sequential mode, this is done right after each block is laid out. -struct PlacementState { +struct PlacementState<'container> { next_in_flow_margin_collapses_with_parent_start_margin: bool, last_in_flow_margin_collapses_with_parent_end_margin: bool, start_margin: CollapsedMargin, @@ -1658,17 +1657,18 @@ struct PlacementState { /// position of the placement. marker_block_size: Option, - /// The [`WritingMode`] of the containing fragment where these fragments are being laid out. - writing_mode: WritingMode, + /// The [`ContainingBlock`] of the container into which this [`PlacementState`] is laying out + /// fragments. This is used to convert between physical and logical geometry. + containing_block: &'container ContainingBlock<'container>, } -impl PlacementState { +impl<'container> PlacementState<'container> { fn new( collapsible_with_parent_start_margin: CollapsibleWithParentStartMargin, - containing_block_style: &ComputedValues, + containing_block: &'container ContainingBlock<'container>, ) -> PlacementState { let is_inline_block_context = - containing_block_style.get_box().clone_display() == Display::InlineBlock; + containing_block.style.get_box().clone_display() == Display::InlineBlock; PlacementState { next_in_flow_margin_collapses_with_parent_start_margin: collapsible_with_parent_start_margin.0, @@ -1679,7 +1679,7 @@ impl PlacementState { inflow_baselines: Baselines::default(), is_inline_block_context, marker_block_size: None, - writing_mode: containing_block_style.effective_writing_mode(), + containing_block, } } @@ -1708,9 +1708,10 @@ impl PlacementState { let box_block_offset = box_fragment .content_rect .origin - .to_logical(self.writing_mode) + .to_logical(self.containing_block) .block; - let box_fragment_baselines = box_fragment.baselines(self.writing_mode); + let box_fragment_baselines = + box_fragment.baselines(self.containing_block.style.writing_mode); if let (None, Some(first)) = (self.inflow_baselines.first, box_fragment_baselines.first) { self.inflow_baselines.first = Some(first + box_block_offset); } @@ -1746,7 +1747,7 @@ impl PlacementState { fragment .content_rect .size - .to_logical(self.writing_mode) + .to_logical(self.containing_block.style.writing_mode) .block, ); return; @@ -1755,8 +1756,8 @@ impl PlacementState { let fragment_block_margins = &fragment.block_margins_collapsed_with_children; let mut fragment_block_size = fragment .border_rect() - .to_logical(self.writing_mode) .size + .to_logical(self.containing_block.style.writing_mode) .block; // We use `last_in_flow_margin_collapses_with_parent_end_margin` to implement @@ -1798,7 +1799,7 @@ impl PlacementState { inline: Au::zero(), block: self.current_margin.solve() + self.current_block_direction_position, } - .to_physical_size(self.writing_mode); + .to_physical_size(self.containing_block.style.writing_mode); if fragment_block_margins.collapsed_through { // `fragment_block_size` is typically zero when collapsing through, @@ -1823,7 +1824,7 @@ impl PlacementState { }, size: LogicalVec2::zero(), } - .to_physical(self.writing_mode); + .to_physical(Some(self.containing_block)); }, Fragment::Float(box_fragment) => { let sequential_layout_state = sequential_layout_state @@ -1832,7 +1833,7 @@ impl PlacementState { self.current_block_direction_position + self.current_margin.solve(); sequential_layout_state.place_float_fragment( box_fragment, - self.writing_mode, + self.containing_block, self.start_margin, block_offset_from_containing_block_top, ); diff --git a/components/layout_2020/fragment_tree/box_fragment.rs b/components/layout_2020/fragment_tree/box_fragment.rs index 10c119df65c..eac31c6a478 100644 --- a/components/layout_2020/fragment_tree/box_fragment.rs +++ b/components/layout_2020/fragment_tree/box_fragment.rs @@ -16,9 +16,7 @@ use style::Zero; use super::{BaseFragment, BaseFragmentInfo, CollapsedBlockMargins, Fragment}; use crate::cell::ArcRefCell; use crate::formatting_contexts::Baselines; -use crate::geom::{ - AuOrAuto, LogicalRect, PhysicalPoint, PhysicalRect, PhysicalSides, PhysicalSize, ToLogical, -}; +use crate::geom::{AuOrAuto, PhysicalPoint, PhysicalRect, PhysicalSides, PhysicalSize, ToLogical}; use crate::style_ext::ComputedValuesExt; /// Describes how a [`BoxFragment`] paints its background. @@ -36,7 +34,7 @@ pub(crate) enum BackgroundMode { pub(crate) struct ExtraBackground { pub style: ServoArc, - pub rect: LogicalRect, + pub rect: PhysicalRect, } #[derive(Serialize)] @@ -165,16 +163,15 @@ impl BoxFragment { /// Get the baselines for this [`BoxFragment`] if they are compatible with the given [`WritingMode`]. /// If they are not compatible, [`Baselines::default()`] is returned. pub fn baselines(&self, writing_mode: WritingMode) -> Baselines { - let mut baselines = if writing_mode.is_horizontal() == - self.style.effective_writing_mode().is_horizontal() - { - self.baselines - } else { - // If the writing mode of the container requesting baselines is not - // compatible, ensure that the baselines established by this fragment are - // not used. - Baselines::default() - }; + let mut baselines = + if writing_mode.is_horizontal() == self.style.writing_mode.is_horizontal() { + self.baselines + } else { + // If the writing mode of the container requesting baselines is not + // compatible, ensure that the baselines established by this fragment are + // not used. + Baselines::default() + }; // From the https://drafts.csswg.org/css-align-3/#baseline-export section on "block containers": // > However, for legacy reasons if its baseline-source is auto (the initial @@ -185,12 +182,12 @@ impl BoxFragment { // This applies even if there is no baseline set, so we unconditionally set the value here // and ignore anything that is set via [`Self::with_baselines`]. if self.style.establishes_scroll_container() { - let content_rect = self.content_rect.to_logical(writing_mode); + let content_rect_size = self.content_rect.size.to_logical(writing_mode); let padding = self.padding.to_logical(writing_mode); let border = self.border.to_logical(writing_mode); let margin = self.margin.to_logical(writing_mode); baselines.last = Some( - content_rect.size.block + padding.block_end + border.block_end + margin.block_end, + content_rect_size.block + padding.block_end + border.block_end + margin.block_end, ) } baselines @@ -229,6 +226,10 @@ impl BoxFragment { self.border_rect().outer_rect(self.margin) } + pub(crate) fn padding_border_margin(&self) -> PhysicalSides { + self.margin + self.border + self.padding + } + pub fn print(&self, tree: &mut PrintTree) { tree.new_level(format!( "Box\ diff --git a/components/layout_2020/fragment_tree/fragment.rs b/components/layout_2020/fragment_tree/fragment.rs index 111e8009b6c..30bd4840c2e 100644 --- a/components/layout_2020/fragment_tree/fragment.rs +++ b/components/layout_2020/fragment_tree/fragment.rs @@ -109,6 +109,17 @@ impl Fragment { Fragment::Float(fragment) => &fragment.base, }) } + pub(crate) fn content_rect_mut(&mut self) -> Option<&mut PhysicalRect> { + match self { + Fragment::Box(box_fragment) | Fragment::Float(box_fragment) => { + Some(&mut box_fragment.content_rect) + }, + Fragment::Positioning(_) | Fragment::AbsoluteOrFixedPositioned(_) => None, + Fragment::Text(text_fragment) => Some(&mut text_fragment.rect), + Fragment::Image(image_fragment) => Some(&mut image_fragment.rect), + Fragment::IFrame(iframe_fragment) => Some(&mut iframe_fragment.rect), + } + } pub fn tag(&self) -> Option { self.base().and_then(|base| base.tag) diff --git a/components/layout_2020/fragment_tree/hoisted_shared_fragment.rs b/components/layout_2020/fragment_tree/hoisted_shared_fragment.rs index 71c1f9d37c9..d54c76b30d0 100644 --- a/components/layout_2020/fragment_tree/hoisted_shared_fragment.rs +++ b/components/layout_2020/fragment_tree/hoisted_shared_fragment.rs @@ -4,6 +4,7 @@ use app_units::Au; use serde::Serialize; +use style::logical_geometry::WritingMode; use style::values::specified::align::AlignFlags; use super::Fragment; @@ -26,17 +27,24 @@ pub(crate) struct HoistedSharedFragment { /// These values are dependent on the layout mode (currently only interesting for /// flexbox). pub resolved_alignment: LogicalVec2, + /// This is the [`WritingMode`] of the original parent of the element that created this + /// hoisted absolutely-positioned fragment. This helps to interpret the offset for + /// static positioning. If the writing mode is right-to-left or bottom-to-top, the static + /// offset needs to be adjusted by the absolutely positioned element's inline size. + pub original_parent_writing_mode: WritingMode, } impl HoistedSharedFragment { pub(crate) fn new( static_position_rect: PhysicalRect, resolved_alignment: LogicalVec2, + original_parent_writing_mode: WritingMode, ) -> Self { HoistedSharedFragment { fragment: None, static_position_rect, resolved_alignment, + original_parent_writing_mode, } } } diff --git a/components/layout_2020/geom.rs b/components/layout_2020/geom.rs index 98bebdcb3c9..aa48bf3ce08 100644 --- a/components/layout_2020/geom.rs +++ b/components/layout_2020/geom.rs @@ -70,19 +70,6 @@ impl LogicalVec2 { } } - pub fn from_physical_point(physical_point: &PhysicalPoint, mode: WritingMode) -> Self { - // https://drafts.csswg.org/css-writing-modes/#logical-to-physical - let (i, b) = if mode.is_horizontal() { - (&physical_point.x, &physical_point.y) - } else { - (&physical_point.y, &physical_point.x) - }; - LogicalVec2 { - inline: i.clone(), - block: b.clone(), - } - } - pub fn map(&self, f: impl Fn(&T) -> U) -> LogicalVec2 { LogicalVec2 { inline: f(&self.inline), @@ -271,15 +258,48 @@ impl LogicalVec2 { }; PhysicalSize::new(x.clone(), y.clone()) } +} - pub fn to_physical_point(&self, mode: WritingMode) -> PhysicalPoint { - // https://drafts.csswg.org/css-writing-modes/#logical-to-physical - let (x, y) = if mode.is_horizontal() { - (&self.inline, &self.block) +impl> LogicalVec2 { + pub fn to_physical_vector(&self, mode: WritingMode) -> PhysicalVec { + if mode.is_horizontal() { + if mode.is_bidi_ltr() { + PhysicalVec::new(self.inline, self.block) + } else { + PhysicalVec::new(-self.inline, self.block) + } } else { - (&self.block, &self.inline) - }; - PhysicalPoint::new(x.clone(), y.clone()) + if mode.is_inline_tb() { + PhysicalVec::new(self.block, self.inline) + } else { + PhysicalVec::new(-self.block, self.inline) + } + } + } +} + +impl LogicalVec2 { + #[inline] + pub fn to_physical_point( + &self, + containing_block: Option<&ContainingBlock>, + ) -> PhysicalPoint { + let mode = containing_block.map_or_else(WritingMode::horizontal_tb, |containing_block| { + containing_block.style.writing_mode + }); + if mode.is_vertical() { + // TODO: Bottom-to-top writing modes are not supported yet. + PhysicalPoint::new(self.block, self.inline) + } else { + let y = self.block; + let x = match containing_block { + Some(containing_block) if !mode.is_bidi_ltr() => { + containing_block.inline_size - self.inline + }, + _ => self.inline, + }; + PhysicalPoint::new(x, y) + } } } @@ -540,15 +560,36 @@ impl LogicalRect { }, } } +} - pub fn to_physical(&self, mode: WritingMode) -> PhysicalRect - where - T: Copy, - { - PhysicalRect::new( - self.start_corner.to_physical_point(mode), - self.size.to_physical_size(mode), - ) +impl LogicalRect { + pub fn to_physical<'a>( + &self, + containing_block: Option<&ContainingBlock<'a>>, + ) -> PhysicalRect { + let mode = containing_block.map_or_else(WritingMode::horizontal_tb, |containing_block| { + containing_block.style.writing_mode + }); + let (x, y, width, height) = if mode.is_vertical() { + // TODO: Bottom-to-top writing modes are not supported. + ( + self.start_corner.block, + self.start_corner.inline, + self.size.block, + self.size.inline, + ) + } else { + let y = self.start_corner.block; + let x = match containing_block { + Some(containing_block) if !mode.is_bidi_ltr() => { + containing_block.inline_size - self.max_inline_position() + }, + _ => self.start_corner.inline, + }; + (x, y, self.size.inline, self.size.block) + }; + + PhysicalRect::new(PhysicalPoint::new(x, y), PhysicalSize::new(width, height)) } } @@ -592,32 +633,74 @@ pub(crate) trait ToLogical { fn to_logical(&self, writing_mode: WritingMode) -> LogicalType; } -impl ToLogical> for PhysicalRect { - fn to_logical(&self, writing_mode: WritingMode) -> LogicalRect { - LogicalRect { - start_corner: LogicalVec2::from_physical_size( - &PhysicalSize::new(self.origin.x, self.origin.y), - writing_mode, - ), - size: LogicalVec2::from_physical_size(&self.size, writing_mode), - } - } -} - impl ToLogical> for PhysicalSize { fn to_logical(&self, writing_mode: WritingMode) -> LogicalVec2 { LogicalVec2::from_physical_size(self, writing_mode) } } -impl ToLogical> for PhysicalPoint { - fn to_logical(&self, writing_mode: WritingMode) -> LogicalVec2 { - LogicalVec2::from_physical_point(self, writing_mode) - } -} - impl ToLogical> for PhysicalSides { fn to_logical(&self, writing_mode: WritingMode) -> LogicalSides { LogicalSides::from_physical(self, writing_mode) } } + +pub(crate) trait ToLogicalWithContainingBlock { + fn to_logical(&self, containing_block: &ContainingBlock) -> LogicalType; +} + +impl ToLogicalWithContainingBlock> for PhysicalPoint { + fn to_logical(&self, containing_block: &ContainingBlock) -> LogicalVec2 { + let writing_mode = containing_block.style.writing_mode; + // TODO: Bottom-to-top and right-to-left vertical writing modes are not supported yet. + if writing_mode.is_vertical() { + LogicalVec2 { + inline: self.y, + block: self.x, + } + } else { + LogicalVec2 { + inline: if writing_mode.is_bidi_ltr() { + self.x + } else { + containing_block.inline_size - self.x + }, + block: self.y, + } + } + } +} + +impl ToLogicalWithContainingBlock> for PhysicalRect { + fn to_logical(&self, containing_block: &ContainingBlock) -> LogicalRect { + let inline_start; + let block_start; + let inline; + let block; + + let writing_mode = containing_block.style.writing_mode; + if writing_mode.is_vertical() { + // TODO: Bottom-to-top and right-to-left vertical writing modes are not supported yet. + inline = self.size.height; + block = self.size.width; + block_start = self.origin.x; + inline_start = self.origin.y; + } else { + inline = self.size.width; + block = self.size.height; + block_start = self.origin.y; + if writing_mode.is_bidi_ltr() { + inline_start = self.origin.x; + } else { + inline_start = containing_block.inline_size - (self.origin.x + self.size.width); + } + } + LogicalRect { + start_corner: LogicalVec2 { + inline: inline_start, + block: block_start, + }, + size: LogicalVec2 { inline, block }, + } + } +} diff --git a/components/layout_2020/lib.rs b/components/layout_2020/lib.rs index b4c3ae1cf6d..800fd54216e 100644 --- a/components/layout_2020/lib.rs +++ b/components/layout_2020/lib.rs @@ -29,7 +29,6 @@ use app_units::Au; pub use flow::BoxTree; pub use fragment_tree::FragmentTree; use geom::AuOrAuto; -use style::logical_geometry::WritingMode; use style::properties::ComputedValues; use style_ext::{Clamp, ComputedValuesExt}; @@ -107,12 +106,6 @@ pub struct ContainingBlock<'a> { style: &'a ComputedValues, } -impl<'a> ContainingBlock<'a> { - pub(crate) fn effective_writing_mode(&self) -> WritingMode { - self.style.effective_writing_mode() - } -} - impl<'a> TryFrom<&'_ IndefiniteContainingBlock<'a>> for ContainingBlock<'a> { type Error = &'static str; @@ -135,12 +128,6 @@ struct DefiniteContainingBlock<'a> { style: &'a ComputedValues, } -impl<'a> DefiniteContainingBlock<'a> { - pub(crate) fn effective_writing_mode(&self) -> WritingMode { - self.style.effective_writing_mode() - } -} - impl<'a> From<&'_ DefiniteContainingBlock<'a>> for ContainingBlock<'a> { fn from(definite: &DefiniteContainingBlock<'a>) -> Self { ContainingBlock { diff --git a/components/layout_2020/positioned.rs b/components/layout_2020/positioned.rs index 99a1c7516e7..3b835a86403 100644 --- a/components/layout_2020/positioned.rs +++ b/components/layout_2020/positioned.rs @@ -7,6 +7,7 @@ use rayon::iter::IntoParallelRefMutIterator; use rayon::prelude::{IndexedParallelIterator, ParallelIterator}; use serde::Serialize; use style::computed_values::position::T as Position; +use style::logical_geometry::WritingMode; use style::properties::ComputedValues; use style::values::specified::align::{AlignFlags, AxisDirection}; use style::values::specified::text::TextDecorationLine; @@ -22,7 +23,7 @@ use crate::fragment_tree::{ }; use crate::geom::{ AuOrAuto, LengthPercentageOrAuto, LogicalRect, LogicalSides, LogicalVec2, PhysicalPoint, - PhysicalRect, PhysicalVec, ToLogical, + PhysicalRect, PhysicalVec, ToLogical, ToLogicalWithContainingBlock, }; use crate::style_ext::{ComputedValuesExt, DisplayInside}; use crate::{ContainingBlock, DefiniteContainingBlock, IndefiniteContainingBlock}; @@ -73,11 +74,13 @@ impl AbsolutelyPositionedBox { absolutely_positioned_box: ArcRefCell, static_position_rectangle: PhysicalRect, resolved_alignment: LogicalVec2, + original_parent_writing_mode: WritingMode, ) -> HoistedAbsolutelyPositionedBox { HoistedAbsolutelyPositionedBox { fragment: ArcRefCell::new(HoistedSharedFragment::new( static_position_rectangle, resolved_alignment, + original_parent_writing_mode, )), absolutely_positioned_box, } @@ -211,7 +214,7 @@ impl PositioningContext { if style.clone_position() == Position::Relative { new_fragment.content_rect.origin += relative_adjustement(style, containing_block) - .to_physical_size(containing_block.effective_writing_mode()) + .to_physical_vector(containing_block.style.writing_mode) } new_fragment @@ -233,7 +236,7 @@ impl PositioningContext { let containing_block = DefiniteContainingBlock { size: padding_rect .size - .to_logical(new_fragment.style.effective_writing_mode()), + .to_logical(new_fragment.style.writing_mode), style: &new_fragment.style, }; @@ -376,7 +379,7 @@ impl PositioningContext { } /// A data structure which stores the size of a positioning context. -#[derive(Clone, Copy, PartialEq)] +#[derive(Clone, Copy, Debug, PartialEq)] pub(crate) struct PositioningContextLength { /// The number of boxes that will be hoisted the the nearest positioned ancestor for /// layout. @@ -452,9 +455,10 @@ impl HoistedAbsolutelyPositionedBox { let cbis = containing_block.size.inline; let cbbs = containing_block.size.block; let mut absolutely_positioned_box = self.absolutely_positioned_box.borrow_mut(); - let containing_block_writing_mode = containing_block.style.effective_writing_mode(); + let containing_block_writing_mode = containing_block.style.writing_mode; let style = absolutely_positioned_box.context.style().clone(); let pbm = style.padding_border_margin(&containing_block.into()); + let indefinite_containing_block = containing_block.into(); let computed_size = match &absolutely_positioned_box.context { IndependentFormattingContext::Replaced(replaced) => { @@ -470,17 +474,16 @@ impl HoistedAbsolutelyPositionedBox { block: AuOrAuto::LengthPercentage(used_size.block), } }, - IndependentFormattingContext::NonReplaced(..) => { - style.content_box_size(&containing_block.into(), &pbm) - }, + IndependentFormattingContext::NonReplaced(non_replaced) => non_replaced + .style + .content_box_size(&indefinite_containing_block, &pbm), }; let shared_fragment = self.fragment.borrow(); let static_position_rect = shared_fragment .static_position_rect - .to_logical(containing_block_writing_mode); + .to_logical(&indefinite_containing_block); - let indefinite_containing_block = containing_block.into(); let box_offset = style.box_offsets(&indefinite_containing_block); // When the "static-position rect" doesn't come into play, we do not do any alignment @@ -504,6 +507,8 @@ impl HoistedAbsolutelyPositionedBox { box_offsets: inline_box_offsets, static_position_rect_axis: static_position_rect.get_axis(AxisDirection::Inline), alignment: inline_alignment, + flip_anchor: !(shared_fragment.original_parent_writing_mode.is_bidi_ltr() == + indefinite_containing_block.style.writing_mode.is_bidi_ltr()), }; // When the "static-position rect" doesn't come into play, we re-resolve "align-self" @@ -526,6 +531,7 @@ impl HoistedAbsolutelyPositionedBox { box_offsets: block_box_offsets, static_position_rect_axis: static_position_rect.get_axis(AxisDirection::Block), alignment: block_alignment, + flip_anchor: false, }; let overconstrained = LogicalVec2 { inline: inline_axis_solver.is_overconstrained_for_size(computed_size.inline), @@ -535,8 +541,7 @@ impl HoistedAbsolutelyPositionedBox { let mut inline_axis = inline_axis_solver.solve_for_size(computed_size.inline); let mut block_axis = block_axis_solver.solve_for_size(computed_size.block); - let mut positioning_context = - PositioningContext::new_for_style(absolutely_positioned_box.context.style()).unwrap(); + let mut positioning_context = PositioningContext::new_for_style(&style).unwrap(); let mut new_fragment = { let content_size: LogicalVec2; let fragments; @@ -544,10 +549,9 @@ impl HoistedAbsolutelyPositionedBox { IndependentFormattingContext::Replaced(replaced) => { // https://drafts.csswg.org/css2/visudet.html#abs-replaced-width // https://drafts.csswg.org/css2/visudet.html#abs-replaced-height - let style = &replaced.style; content_size = computed_size.auto_is(|| unreachable!()); fragments = replaced.contents.make_fragments( - style, + &style, content_size.to_physical_size(containing_block_writing_mode), ); }, @@ -558,8 +562,7 @@ impl HoistedAbsolutelyPositionedBox { .style .content_min_box_size(&indefinite_containing_block, &pbm) .map(|t| t.map(Au::from).auto_is(Au::zero)); - let max_size = non_replaced - .style + let max_size = style .content_max_box_size(&containing_block.into(), &pbm) .map(|t| t.map(Au::from)); @@ -622,13 +625,16 @@ impl HoistedAbsolutelyPositionedBox { let containing_block_for_children = ContainingBlock { inline_size, block_size: size, - style: &non_replaced.style, + style: &style, }; // https://drafts.csswg.org/css-writing-modes/#orthogonal-flows assert_eq!( - containing_block.effective_writing_mode(), - containing_block_for_children.effective_writing_mode(), - "Mixed writing modes are not supported yet" + containing_block.style.writing_mode.is_horizontal(), + containing_block_for_children + .style + .writing_mode + .is_horizontal(), + "Mixed horizontal and vertical writing modes are not supported yet" ); // Clear the context since we will lay out the same descendants @@ -732,13 +738,13 @@ impl HoistedAbsolutelyPositionedBox { inline_axis_solver.solve_alignment(margin_box_rect, &mut content_rect); let physical_overconstrained = - overconstrained.to_physical_size(containing_block.effective_writing_mode()); + overconstrained.to_physical_size(containing_block.style.writing_mode); BoxFragment::new_with_overconstrained( absolutely_positioned_box.context.base_fragment_info(), - absolutely_positioned_box.context.style().clone(), + style, fragments, - content_rect.to_physical(containing_block_writing_mode), + content_rect.to_physical(Some(&containing_block.into())), pbm.padding.to_physical(containing_block_writing_mode), pbm.border.to_physical(containing_block_writing_mode), margin.to_physical(containing_block_writing_mode), @@ -826,8 +832,8 @@ struct AbsoluteAxisSolver<'a> { box_offsets: AbsoluteBoxOffsets<'a>, static_position_rect_axis: RectAxis, alignment: AlignFlags, + flip_anchor: bool, } - impl<'a> AbsoluteAxisSolver<'a> { /// This unifies some of the parts in common in: /// @@ -846,7 +852,11 @@ impl<'a> AbsoluteAxisSolver<'a> { self.box_offsets.end.non_auto(), ) { (None, None) => AxisResult { - anchor: Anchor::Start(self.static_position_rect_axis.origin), + anchor: if self.flip_anchor { + Anchor::End(self.containing_size - self.static_position_rect_axis.origin) + } else { + Anchor::Start(self.static_position_rect_axis.origin) + }, size: computed_size, margin_start: self.computed_margin_start.auto_is(Au::zero), margin_end: self.computed_margin_end.auto_is(Au::zero), diff --git a/components/layout_2020/query.rs b/components/layout_2020/query.rs index afb76838e45..baad3cbb285 100644 --- a/components/layout_2020/query.rs +++ b/components/layout_2020/query.rs @@ -32,7 +32,6 @@ use style::values::generics::font::LineHeight; use style_traits::{ParsingMode, ToCss}; use crate::fragment_tree::{BoxFragment, Fragment, FragmentFlags, FragmentTree, Tag}; -use crate::style_ext::ComputedValuesExt; pub fn process_content_box_request( requested_node: OpaqueNode, @@ -136,7 +135,7 @@ pub fn process_resolved_style_request<'dom>( return style.computed_value_to_string(PropertyDeclarationId::Custom(name)); }, } - .to_physical(style.effective_writing_mode()); + .to_physical(style.writing_mode); let computed_style = || style.computed_value_to_string(PropertyDeclarationId::Longhand(longhand_id)); diff --git a/components/layout_2020/replaced.rs b/components/layout_2020/replaced.rs index f5541836848..880e31cd70e 100644 --- a/components/layout_2020/replaced.rs +++ b/components/layout_2020/replaced.rs @@ -235,7 +235,7 @@ impl ReplacedContent { fn flow_relative_intrinsic_size(&self, style: &ComputedValues) -> LogicalVec2> { let intrinsic_size = PhysicalSize::new(self.intrinsic.width, self.intrinsic.height); - LogicalVec2::from_physical_size(&intrinsic_size, style.effective_writing_mode()) + LogicalVec2::from_physical_size(&intrinsic_size, style.writing_mode) } fn inline_size_over_block_size_intrinsic_ratio( @@ -243,7 +243,7 @@ impl ReplacedContent { style: &ComputedValues, ) -> Option { self.intrinsic.ratio.map(|width_over_height| { - if style.effective_writing_mode().is_vertical() { + if style.writing_mode.is_vertical() { 1. / width_over_height } else { width_over_height @@ -351,7 +351,7 @@ impl ReplacedContent { style.preferred_aspect_ratio( self.inline_size_over_block_size_intrinsic_ratio(style), containing_block.try_into().ok().as_ref(), - containing_block.style.effective_writing_mode(), + containing_block.style.writing_mode, ) } @@ -398,7 +398,7 @@ impl ReplacedContent { min_box_size: LogicalVec2, max_box_size: LogicalVec2>, ) -> LogicalVec2 { - let mode = style.effective_writing_mode(); + let mode = style.writing_mode; let intrinsic_size = self.flow_relative_intrinsic_size(style); let intrinsic_ratio = self.preferred_aspect_ratio(&containing_block.into(), style); diff --git a/components/layout_2020/style_ext.rs b/components/layout_2020/style_ext.rs index 9acf861c93b..83b6de39f60 100644 --- a/components/layout_2020/style_ext.rs +++ b/components/layout_2020/style_ext.rs @@ -139,13 +139,6 @@ impl PaddingBorderMargin { padding_border_sums: LogicalVec2::zero(), } } - - pub(crate) fn border_padding_start(&self) -> LogicalVec2 { - LogicalVec2 { - inline: self.border.inline_start + self.padding.inline_start, - block: self.border.block_start + self.padding.block_start, - } - } } /// Resolved `aspect-ratio` property with respect to a specific element. Depends @@ -186,7 +179,6 @@ impl AspectRatio { } pub(crate) trait ComputedValuesExt { - fn effective_writing_mode(&self) -> WritingMode; fn box_offsets( &self, containing_block: &ContainingBlock, @@ -291,10 +283,6 @@ pub(crate) trait ComputedValuesExt { } impl ComputedValuesExt for ComputedValues { - fn effective_writing_mode(&self) -> WritingMode { - WritingMode::horizontal_tb() - } - fn box_offsets( &self, containing_block: &ContainingBlock, @@ -307,7 +295,7 @@ impl ComputedValuesExt for ComputedValues { position.bottom.as_ref(), position.left.as_ref(), ), - containing_block.effective_writing_mode(), + containing_block.style.writing_mode, ) } @@ -362,7 +350,7 @@ impl ComputedValuesExt for ComputedValues { pbm: &PaddingBorderMargin, ) -> LogicalVec2 { let box_size = self - .box_size(containing_block.effective_writing_mode()) + .box_size(containing_block.style.writing_mode) .percentages_relative_to(containing_block); self.content_box_size_for_box_size(box_size, pbm) } @@ -393,7 +381,7 @@ impl ComputedValuesExt for ComputedValues { pbm: &PaddingBorderMargin, ) -> LogicalVec2 { let box_size = self - .min_box_size(containing_block.effective_writing_mode()) + .min_box_size(containing_block.style.writing_mode) .percentages_relative_to(containing_block); self.content_min_box_size_for_min_size(box_size, pbm) } @@ -423,7 +411,7 @@ impl ComputedValuesExt for ComputedValues { pbm: &PaddingBorderMargin, ) -> LogicalVec2> { let max_box_size = self - .max_box_size(containing_block.effective_writing_mode()) + .max_box_size(containing_block.style.writing_mode) .percentages_relative_to(containing_block); self.content_max_box_size_for_max_size(max_box_size, pbm) @@ -495,23 +483,10 @@ impl ComputedValuesExt for ComputedValues { } fn padding_border_margin(&self, containing_block: &ContainingBlock) -> PaddingBorderMargin { - let cbis = containing_block.inline_size; - let padding = self - .padding(containing_block.effective_writing_mode()) - .percentages_relative_to(cbis); - let border = self.border_width(containing_block.effective_writing_mode()); - let margin = self - .margin(containing_block.effective_writing_mode()) - .percentages_relative_to(cbis); - PaddingBorderMargin { - padding_border_sums: LogicalVec2 { - inline: (padding.inline_sum() + border.inline_sum()), - block: (padding.block_sum() + border.block_sum()), - }, - padding, - border, - margin, - } + self.padding_border_margin_with_writing_mode_and_containing_block_inline_size( + containing_block.style.writing_mode, + containing_block.inline_size, + ) } fn padding_border_margin_for_intrinsic_size( diff --git a/components/layout_2020/table/layout.rs b/components/layout_2020/table/layout.rs index b9ad442dc33..49e94ad5ba4 100644 --- a/components/layout_2020/table/layout.rs +++ b/components/layout_2020/table/layout.rs @@ -28,8 +28,8 @@ use crate::fragment_tree::{ PositioningFragment, }; use crate::geom::{ - AuOrAuto, LengthPercentageOrAuto, LogicalRect, LogicalSides, LogicalVec2, PhysicalSides, - ToLogical, + AuOrAuto, LengthPercentageOrAuto, LogicalRect, LogicalSides, LogicalVec2, PhysicalPoint, + PhysicalRect, PhysicalSides, ToLogical, ToLogicalWithContainingBlock, }; use crate::positioned::{relative_adjustement, PositioningContext, PositioningContextLength}; use crate::sizing::ContentSizes; @@ -1135,14 +1135,14 @@ impl<'a> TableLayout<'a> { let border: LogicalSides = self .get_collapsed_borders_for_cell(cell, coordinates) .unwrap_or_else(|| { - cell.style.border_width( - containing_block_for_table.effective_writing_mode(), - ) - }); + cell.style + .border_width(containing_block_for_table.style.writing_mode) + }) + .into(); let padding: LogicalSides = cell .style - .padding(containing_block_for_table.effective_writing_mode()) + .padding(containing_block_for_table.style.writing_mode) .percentages_relative_to(self.basis_for_cell_padding_percentage); let inline_border_padding_sum = border.inline_sum() + padding.inline_sum(); @@ -1541,7 +1541,7 @@ impl<'a> TableLayout<'a> { style: containing_block.style, }; - let mut box_fragment = context.layout_in_flow_block_level( + let box_fragment = context.layout_in_flow_block_level( layout_context, positioning_context .as_mut() @@ -1550,16 +1550,6 @@ impl<'a> TableLayout<'a> { None, /* sequential_layout_state */ ); - let margin_offset = LogicalVec2 { - inline: Au::zero(), - block: box_fragment - .block_margins_collapsed_with_children - .start - .solve(), - } - .to_physical_size(containing_block.effective_writing_mode()); - box_fragment.content_rect.origin += margin_offset; - if let Some(positioning_context) = positioning_context.take() { parent_positioning_context.append(positioning_context); } @@ -1576,10 +1566,10 @@ impl<'a> TableLayout<'a> { containing_block_for_children: &ContainingBlock, containing_block_for_table: &ContainingBlock, ) -> IndependentLayout { - let writing_mode = containing_block_for_children.effective_writing_mode(); - let grid_min_max = self.compute_grid_min_max(layout_context, writing_mode); + let table_writing_mode = containing_block_for_children.style.writing_mode; + let grid_min_max = self.compute_grid_min_max(layout_context, table_writing_mode); let caption_minimum_inline_size = - self.compute_caption_minimum_inline_size(layout_context, writing_mode); + self.compute_caption_minimum_inline_size(layout_context, table_writing_mode); self.compute_table_width( containing_block_for_children, containing_block_for_table, @@ -1596,10 +1586,23 @@ impl<'a> TableLayout<'a> { // // TODO: This is a pretty large hack. It would be nicer to actually have the grid sized properly, // but it works for now. + // + // Get the padding, border, and margin of the table using the inline size of the table's containing + // block but in the writing of the table itself. + // TODO: This is broken for orthoganol flows, because the inline size of the parent isn't necessarily + // the inline size of the table. + let containing_block_for_logical_conversion = ContainingBlock { + inline_size: self.table_width, + block_size: containing_block_for_table.block_size, + style: containing_block_for_children.style, + }; let table_pbm = self .table .style - .padding_border_margin(containing_block_for_table); + .padding_border_margin_with_writing_mode_and_containing_block_inline_size( + table_writing_mode, + containing_block_for_table.inline_size, + ); let offset_from_wrapper = -table_pbm.padding - table_pbm.border; let mut current_block_offset = offset_from_wrapper.block_start; @@ -1609,7 +1612,6 @@ impl<'a> TableLayout<'a> { content_inline_size_for_table: None, baselines: Baselines::default(), }; - let table_writing_mode = containing_block_for_children.effective_writing_mode(); table_layout .fragments @@ -1627,12 +1629,23 @@ impl<'a> TableLayout<'a> { positioning_context, ); - let caption_offset = LogicalVec2 { - inline: offset_from_wrapper.inline_start, - block: current_block_offset, + // The caption is not placed yet. Construct a rectangle for it in the adjusted containing block + // for the table children and only then convert the result to physical geometry. + let caption_pbm = caption_fragment + .padding_border_margin() + .to_logical(table_writing_mode); + caption_fragment.content_rect = LogicalRect { + start_corner: LogicalVec2 { + inline: offset_from_wrapper.inline_start + caption_pbm.inline_start, + block: current_block_offset + caption_pbm.block_start, + }, + size: caption_fragment + .content_rect + .size + .to_logical(table_writing_mode), } - .to_physical_size(table_writing_mode); - caption_fragment.content_rect.origin += caption_offset; + .to_physical(Some(&containing_block_for_logical_conversion)); + current_block_offset += caption_fragment .margin_rect() .size @@ -1652,22 +1665,37 @@ impl<'a> TableLayout<'a> { layout_context, &table_pbm, positioning_context, + &containing_block_for_logical_conversion, containing_block_for_children, containing_block_for_table, ); // Take the baseline of the grid fragment, after adjusting it to be in the coordinate system // of the table wrapper. - let logical_grid_content_rect = grid_fragment.content_rect.to_logical(table_writing_mode); - table_layout.baselines = grid_fragment - .baselines(table_writing_mode) - .offset(current_block_offset + logical_grid_content_rect.start_corner.block); + let logical_grid_content_rect = grid_fragment + .content_rect + .to_logical(&containing_block_for_logical_conversion); + let grid_pbm = grid_fragment + .padding_border_margin() + .to_logical(table_writing_mode); + table_layout.baselines = grid_fragment.baselines(table_writing_mode).offset( + current_block_offset + + logical_grid_content_rect.start_corner.block + + grid_pbm.block_start, + ); - grid_fragment.content_rect.origin += LogicalVec2 { - inline: offset_from_wrapper.inline_start, - block: current_block_offset, + grid_fragment.content_rect = LogicalRect { + start_corner: LogicalVec2 { + inline: offset_from_wrapper.inline_start + grid_pbm.inline_start, + block: current_block_offset + grid_pbm.block_start, + }, + size: grid_fragment + .content_rect + .size + .to_logical(table_writing_mode), } - .to_physical_size(table_writing_mode); + .to_physical(Some(&containing_block_for_logical_conversion)); + current_block_offset += grid_fragment .border_rect() .size @@ -1698,12 +1726,23 @@ impl<'a> TableLayout<'a> { positioning_context, ); - let caption_offset = LogicalVec2 { - inline: offset_from_wrapper.inline_start, - block: current_block_offset, + // The caption is not placed yet. Construct a rectangle for it in the adjusted containing block + // for the table children and only then convert the result to physical geometry. + let caption_pbm = caption_fragment + .padding_border_margin() + .to_logical(table_writing_mode); + caption_fragment.content_rect = LogicalRect { + start_corner: LogicalVec2 { + inline: offset_from_wrapper.inline_start + caption_pbm.inline_start, + block: current_block_offset + caption_pbm.block_start, + }, + size: caption_fragment + .content_rect + .size + .to_logical(table_writing_mode), } - .to_physical_size(containing_block_for_children.effective_writing_mode()); - caption_fragment.content_rect.origin += caption_offset; + .to_physical(Some(&containing_block_for_logical_conversion)); + current_block_offset += caption_fragment .margin_rect() .size @@ -1729,6 +1768,7 @@ impl<'a> TableLayout<'a> { layout_context: &LayoutContext, table_pbm: &PaddingBorderMargin, positioning_context: &mut PositioningContext, + containing_block_for_logical_conversion: &ContainingBlock, containing_block_for_children: &ContainingBlock, containing_block_for_table: &ContainingBlock, ) -> BoxFragment { @@ -1738,8 +1778,8 @@ impl<'a> TableLayout<'a> { containing_block_for_children, positioning_context, ); - let writing_mode = containing_block_for_children.effective_writing_mode(); - let first_layout_row_heights = self.do_first_row_layout(writing_mode); + let table_writing_mode = containing_block_for_children.style.writing_mode; + let first_layout_row_heights = self.do_first_row_layout(table_writing_mode); self.compute_table_height_and_final_row_heights( first_layout_row_heights, containing_block_for_children, @@ -1749,16 +1789,15 @@ impl<'a> TableLayout<'a> { assert_eq!(self.table.size.height, self.row_sizes.len()); assert_eq!(self.table.size.width, self.distributed_column_widths.len()); - let table_writing_mode = containing_block_for_children.effective_writing_mode(); if self.table.size.width == 0 && self.table.size.height == 0 { let content_rect = LogicalRect { - start_corner: table_pbm.border_padding_start(), + start_corner: LogicalVec2::zero(), size: LogicalVec2 { inline: self.table_width, block: self.final_table_height, }, } - .to_physical(table_writing_mode); + .to_physical(Some(containing_block_for_logical_conversion)); return BoxFragment::new( self.table.grid_base_fragment_info, self.table.grid_style.clone(), @@ -1804,8 +1843,12 @@ impl<'a> TableLayout<'a> { } let table_row = &self.table.rows[row_index]; - let mut row_fragment_layout = - RowFragmentLayout::new(table_row, row_index, &table_and_track_dimensions); + let mut row_fragment_layout = RowFragmentLayout::new( + table_row, + row_index, + &table_and_track_dimensions, + &self.table.style, + ); let old_row_group_index = row_group_fragment_layout .as_ref() @@ -1816,6 +1859,7 @@ impl<'a> TableLayout<'a> { table_fragments.push(Fragment::Box(old_row_group_layout.finish( layout_context, positioning_context, + containing_block_for_logical_conversion, containing_block_for_children, ))); } @@ -1837,31 +1881,21 @@ impl<'a> TableLayout<'a> { continue; } - // The PositioningContext for cells is, in order or preference, the PositioningContext of the row, - // the PositioningContext of the row group, or the PositioningContext of the table. - let row_group_positioning_context = row_group_fragment_layout - .as_mut() - .and_then(|layout| layout.positioning_context.as_mut()); - let positioning_context_for_cells = row_fragment_layout - .positioning_context - .as_mut() - .or(row_group_positioning_context) - .unwrap_or(positioning_context); - self.do_final_cell_layout( row_index, column_index, &table_and_track_dimensions, - &row_fragment_layout.rect, - positioning_context_for_cells, &mut baselines, - &mut row_fragment_layout.fragments, + &mut row_fragment_layout, + row_group_fragment_layout.as_mut(), + positioning_context, ); } let row_fragment = Fragment::Box(row_fragment_layout.finish( layout_context, positioning_context, + containing_block_for_logical_conversion, containing_block_for_children, &mut row_group_fragment_layout, )); @@ -1876,18 +1910,19 @@ impl<'a> TableLayout<'a> { table_fragments.push(Fragment::Box(row_group_layout.finish( layout_context, positioning_context, + containing_block_for_logical_conversion, containing_block_for_children, ))); } let content_rect = LogicalRect { - start_corner: table_pbm.border_padding_start(), + start_corner: LogicalVec2::zero(), size: LogicalVec2 { inline: table_and_track_dimensions.table_rect.max_inline_position(), block: table_and_track_dimensions.table_rect.max_block_position(), }, } - .to_physical(table_writing_mode); + .to_physical(Some(containing_block_for_logical_conversion)); BoxFragment::new( self.table.grid_base_fragment_info, self.table.grid_style.clone(), @@ -1930,17 +1965,26 @@ impl<'a> TableLayout<'a> { col_group.style.get_inherited_box().visibility == Visibility::Collapse } - #[allow(clippy::too_many_arguments)] fn do_final_cell_layout( &mut self, row_index: usize, column_index: usize, dimensions: &TableAndTrackDimensions, - row_rect: &LogicalRect, - positioning_context: &mut PositioningContext, baselines: &mut Baselines, - cell_fragments: &mut Vec, + row_fragment_layout: &mut RowFragmentLayout, + row_group_fragment_layout: Option<&mut RowGroupFragmentLayout>, + positioning_context_for_table: &mut PositioningContext, ) { + // The PositioningContext for cells is, in order or preference, the PositioningContext of the row, + // the PositioningContext of the row group, or the PositioningContext of the table. + let row_group_positioning_context = + row_group_fragment_layout.and_then(|layout| layout.positioning_context.as_mut()); + let positioning_context = row_fragment_layout + .positioning_context + .as_mut() + .or(row_group_positioning_context) + .unwrap_or(positioning_context_for_table); + let layout = match self.cells_laid_out[row_index][column_index].take() { Some(layout) => layout, None => { @@ -1955,7 +1999,8 @@ impl<'a> TableLayout<'a> { }, }; - let row_block_offset = row_rect.start_corner.block; + // If this cell has baseline alignment, it can adjust the table's overall baseline. + let row_block_offset = row_fragment_layout.rect.start_corner.block; let row_baseline = self.row_baselines[row_index]; if cell.effective_vertical_align() == VerticalAlignKeyword::Baseline && !layout.is_empty() { let baseline = row_block_offset + row_baseline; @@ -1969,21 +2014,43 @@ impl<'a> TableLayout<'a> { cell.rowspan, cell.colspan, ); - row_relative_cell_rect.start_corner -= row_rect.start_corner; + row_relative_cell_rect.start_corner -= row_fragment_layout.rect.start_corner; let mut fragment = cell.create_fragment( layout, row_relative_cell_rect, row_baseline, positioning_context, &self.table.style, + &row_fragment_layout.containing_block, ); + + // Make a table part rectangle relative to the row fragment for the purposes of + // drawing extra backgrounds. + // + // This rectangle is an offset between the row fragment and the other table + // part rectangle (row group, column, column group). Everything between them + // is laid out in a left-to-right fashion, but respecting the veritcality of + // the writing mode. This is why below, only the axes are flipped, but the + // rectangle is not flipped for RTL. + let make_relative_to_row_start = |mut rect: LogicalRect| { + rect.start_corner -= row_fragment_layout.rect.start_corner; + let writing_mode = row_fragment_layout.containing_block.style.writing_mode; + PhysicalRect::new( + if !writing_mode.is_vertical() { + PhysicalPoint::new(rect.start_corner.inline, rect.start_corner.block) + } else { + PhysicalPoint::new(rect.start_corner.block, rect.start_corner.inline) + }, + rect.size.to_physical_size(writing_mode), + ) + }; + let column = self.table.columns.get(column_index); let column_group = column .and_then(|column| column.group_index) .and_then(|index| self.table.column_groups.get(index)); if let Some(column_group) = column_group { - let mut rect = dimensions.get_column_group_rect(column_group); - rect.start_corner -= row_rect.start_corner; + let rect = make_relative_to_row_start(dimensions.get_column_group_rect(column_group)); fragment.add_extra_background(ExtraBackground { style: column_group.style.clone(), rect, @@ -1991,8 +2058,7 @@ impl<'a> TableLayout<'a> { } if let Some(column) = column { if !column.is_anonymous { - let mut rect = dimensions.get_column_rect(column_index); - rect.start_corner -= row_rect.start_corner; + let rect = make_relative_to_row_start(dimensions.get_column_rect(column_index)); fragment.add_extra_background(ExtraBackground { style: column.style.clone(), rect, @@ -2004,24 +2070,20 @@ impl<'a> TableLayout<'a> { .and_then(|row| row.group_index) .and_then(|index| self.table.row_groups.get(index)); if let Some(row_group) = row_group { - let mut rect = dimensions.get_row_group_rect(row_group); - rect.start_corner -= row_rect.start_corner; + let rect = make_relative_to_row_start(dimensions.get_row_group_rect(row_group)); fragment.add_extra_background(ExtraBackground { style: row_group.style.clone(), rect, }) } if let Some(row) = row { - let mut rect = *row_rect; - rect.start_corner = LogicalVec2::zero(); + let rect = make_relative_to_row_start(row_fragment_layout.rect); fragment.add_extra_background(ExtraBackground { style: row.style.clone(), rect, }) } - cell_fragments.push(Fragment::Box(fragment)); - - // If this cell has baseline alignment, it can adjust the table's overall baseline. + row_fragment_layout.fragments.push(Fragment::Box(fragment)); } fn make_fragments_for_columns_and_column_groups( @@ -2029,14 +2091,13 @@ impl<'a> TableLayout<'a> { dimensions: &TableAndTrackDimensions, fragments: &mut Vec, ) { - let table_writing_mode = self.table.style.effective_writing_mode(); for column_group in self.table.column_groups.iter() { if !column_group.is_empty() { fragments.push(Fragment::Positioning(PositioningFragment::new_empty( column_group.base_fragment_info, dimensions .get_column_group_rect(column_group) - .to_physical(table_writing_mode), + .to_physical(None), column_group.style.clone(), ))); } @@ -2045,9 +2106,7 @@ impl<'a> TableLayout<'a> { for (column_index, column) in self.table.columns.iter().enumerate() { fragments.push(Fragment::Positioning(PositioningFragment::new_empty( column.base_fragment_info, - dimensions - .get_column_rect(column_index) - .to_physical(table_writing_mode), + dimensions.get_column_rect(column_index).to_physical(None), column.style.clone(), ))); } @@ -2117,16 +2176,29 @@ impl<'a> TableLayout<'a> { struct RowFragmentLayout<'a> { row: &'a TableTrack, rect: LogicalRect, + containing_block: ContainingBlock<'a>, positioning_context: Option, fragments: Vec, } impl<'a> RowFragmentLayout<'a> { - fn new(table_row: &'a TableTrack, index: usize, dimensions: &TableAndTrackDimensions) -> Self { + fn new( + table_row: &'a TableTrack, + index: usize, + dimensions: &TableAndTrackDimensions, + table_style: &'a ComputedValues, + ) -> Self { + let rect = dimensions.get_row_rect(index); + let containing_block = ContainingBlock { + inline_size: rect.size.inline, + block_size: AuOrAuto::LengthPercentage(rect.size.inline), + style: table_style, + }; Self { row: table_row, - rect: dimensions.get_row_rect(index), + rect, positioning_context: PositioningContext::new_for_style(&table_row.style), + containing_block, fragments: Vec::new(), } } @@ -2134,23 +2206,40 @@ impl<'a> RowFragmentLayout<'a> { mut self, layout_context: &LayoutContext, table_positioning_context: &mut PositioningContext, - containing_block: &ContainingBlock, + containing_block_for_logical_conversion: &ContainingBlock, + containing_block_for_children: &ContainingBlock, row_group_fragment_layout: &mut Option, ) -> BoxFragment { if self.positioning_context.is_some() { - self.rect.start_corner += relative_adjustement(&self.row.style, containing_block); + self.rect.start_corner += + relative_adjustement(&self.row.style, containing_block_for_children); } - if let Some(ref row_group_layout) = row_group_fragment_layout { - self.rect.start_corner -= row_group_layout.rect.start_corner; - } + let (inline_size, block_size) = + if let Some(ref row_group_layout) = row_group_fragment_layout { + self.rect.start_corner -= row_group_layout.rect.start_corner; + ( + row_group_layout.rect.size.inline, + AuOrAuto::LengthPercentage(row_group_layout.rect.size.block), + ) + } else { + ( + containing_block_for_logical_conversion.inline_size, + containing_block_for_logical_conversion.block_size, + ) + }; + + let row_group_containing_block = ContainingBlock { + inline_size, + block_size, + style: containing_block_for_logical_conversion.style, + }; let mut row_fragment = BoxFragment::new( self.row.base_fragment_info, self.row.style.clone(), self.fragments, - self.rect - .to_physical(containing_block.effective_writing_mode()), + self.rect.to_physical(Some(&row_group_containing_block)), PhysicalSides::zero(), /* padding */ PhysicalSides::zero(), /* border */ PhysicalSides::zero(), /* margin */ @@ -2203,10 +2292,12 @@ impl RowGroupFragmentLayout { mut self, layout_context: &LayoutContext, table_positioning_context: &mut PositioningContext, - containing_block: &ContainingBlock, + containing_block_for_logical_conversion: &ContainingBlock, + containing_block_for_children: &ContainingBlock, ) -> BoxFragment { if self.positioning_context.is_some() { - self.rect.start_corner += relative_adjustement(&self.style, containing_block); + self.rect.start_corner += + relative_adjustement(&self.style, containing_block_for_children); } let mut row_group_fragment = BoxFragment::new( @@ -2214,7 +2305,7 @@ impl RowGroupFragmentLayout { self.style, self.fragments, self.rect - .to_physical(containing_block.effective_writing_mode()), + .to_physical(Some(containing_block_for_logical_conversion)), PhysicalSides::zero(), /* padding */ PhysicalSides::zero(), /* border */ PhysicalSides::zero(), /* margin */ @@ -2414,7 +2505,7 @@ impl Table { layout_context: &LayoutContext, containing_block_for_children: &IndefiniteContainingBlock, ) -> ContentSizes { - let writing_mode = containing_block_for_children.style.effective_writing_mode(); + let writing_mode = containing_block_for_children.style.writing_mode; let mut layout = TableLayout::new(self); let mut table_content_sizes = layout.compute_grid_min_max(layout_context, writing_mode); @@ -2536,6 +2627,7 @@ impl TableSlotCell { cell_baseline: Au, positioning_context: &mut PositioningContext, table_style: &ComputedValues, + containing_block: &ContainingBlock, ) -> BoxFragment { // This must be scoped to this function because it conflicts with euclid's Zero. use style::Zero as StyleZero; @@ -2570,7 +2662,7 @@ impl TableSlotCell { block: vertical_align_offset, }; let vertical_align_fragment = PositioningFragment::new_anonymous( - vertical_align_fragment_rect.to_physical(table_style.effective_writing_mode()), + vertical_align_fragment_rect.to_physical(None), layout.layout.fragments, ); @@ -2581,8 +2673,7 @@ impl TableSlotCell { // TODO(mrobinson): This is correct for absolutes that are direct children of the table // cell, but wrong for absolute fragments that are more deeply nested in the hierarchy of // fragments. - let physical_cell_rect = - cell_content_rect.to_physical(table_style.effective_writing_mode()); + let physical_cell_rect = cell_content_rect.to_physical(Some(containing_block)); layout .positioning_context .adjust_static_position_of_hoisted_fragments_with_offset( @@ -2596,12 +2687,8 @@ impl TableSlotCell { self.style.clone(), vec![Fragment::Positioning(vertical_align_fragment)], physical_cell_rect, - layout - .padding - .to_physical(table_style.effective_writing_mode()), - layout - .border - .to_physical(table_style.effective_writing_mode()), + layout.padding.to_physical(table_style.writing_mode), + layout.border.to_physical(table_style.writing_mode), PhysicalSides::zero(), /* margin */ None, /* clearance */ CollapsedBlockMargins::zero(), diff --git a/components/layout_2020/tests/floats.rs b/components/layout_2020/tests/floats.rs index 0035bd265c9..3a9b755eac6 100644 --- a/components/layout_2020/tests/floats.rs +++ b/components/layout_2020/tests/floats.rs @@ -83,9 +83,9 @@ impl Arbitrary for FloatRangeInput { FloatRangeInput { start_index, side: if is_left { - FloatSide::Left + FloatSide::InlineStart } else { - FloatSide::Right + FloatSide::InlineEnd }, length, } @@ -185,8 +185,8 @@ fn check_node_range_setting( ) { if node.band.top >= block_range.start && node.band.top < block_range.end { match side { - FloatSide::Left => assert!(node.band.left.unwrap() >= value), - FloatSide::Right => assert!(node.band.right.unwrap() <= value), + FloatSide::InlineStart => assert!(node.band.left.unwrap() >= value), + FloatSide::InlineEnd => assert!(node.band.right.unwrap() <= value), } } @@ -357,9 +357,9 @@ impl Arbitrary for FloatInput { block: Au::from_f32_px(height as f32), }, side: if is_left { - FloatSide::Left + FloatSide::InlineStart } else { - FloatSide::Right + FloatSide::InlineEnd }, clear: new_clear(clear), }, @@ -504,10 +504,10 @@ impl FloatPlacement { fn check_floats_rule_1(placement: &FloatPlacement) { for placed_float in &placement.placed_floats { match placed_float.info.side { - FloatSide::Left => assert!( + FloatSide::InlineStart => assert!( placed_float.origin.inline >= placed_float.containing_block_info.inline_start ), - FloatSide::Right => { + FloatSide::InlineEnd => { assert!( placed_float.rect().max_inline_position() <= placed_float.containing_block_info.inline_end @@ -526,19 +526,20 @@ fn check_floats_rule_2(placement: &FloatPlacement) { for (this_float_index, this_float) in placement.placed_floats.iter().enumerate() { for prev_float in &placement.placed_floats[0..this_float_index] { match (this_float.info.side, prev_float.info.side) { - (FloatSide::Left, FloatSide::Left) => { + (FloatSide::InlineStart, FloatSide::InlineStart) => { assert!( this_float.origin.inline >= prev_float.rect().max_inline_position() || this_float.origin.block >= prev_float.rect().max_block_position() ); }, - (FloatSide::Right, FloatSide::Right) => { + (FloatSide::InlineEnd, FloatSide::InlineEnd) => { assert!( this_float.rect().max_inline_position() <= prev_float.origin.inline || this_float.origin.block >= prev_float.rect().max_block_position() ); }, - (FloatSide::Left, FloatSide::Right) | (FloatSide::Right, FloatSide::Left) => {}, + (FloatSide::InlineStart, FloatSide::InlineEnd) | + (FloatSide::InlineEnd, FloatSide::InlineStart) => {}, } } } @@ -568,13 +569,14 @@ fn check_floats_rule_3(placement: &FloatPlacement) { } match (this_float.info.side, other_float.info.side) { - (FloatSide::Left, FloatSide::Right) => { + (FloatSide::InlineStart, FloatSide::InlineEnd) => { assert!(this_float.rect().max_inline_position() <= other_float.origin.inline); }, - (FloatSide::Right, FloatSide::Left) => { + (FloatSide::InlineEnd, FloatSide::InlineStart) => { assert!(this_float.origin.inline >= other_float.rect().max_inline_position()); }, - (FloatSide::Left, FloatSide::Left) | (FloatSide::Right, FloatSide::Right) => {}, + (FloatSide::InlineStart, FloatSide::InlineStart) | + (FloatSide::InlineEnd, FloatSide::InlineEnd) => {}, } } } @@ -616,14 +618,14 @@ fn check_floats_rule_7(placement: &FloatPlacement) { for (placed_float_index, placed_float) in placement.placed_floats.iter().enumerate() { // Only consider floats that stick out. match placed_float.info.side { - FloatSide::Left => { + FloatSide::InlineStart => { if placed_float.rect().max_inline_position() <= placed_float.containing_block_info.inline_end { continue; } }, - FloatSide::Right => { + FloatSide::InlineEnd => { if placed_float.origin.inline >= placed_float.containing_block_info.inline_start { continue; } @@ -686,8 +688,8 @@ fn check_floats_rule_9(floats_and_perturbations: Vec<(FloatInput, u32)>) { let placed_float = &mut placement.placed_floats[float_index]; let perturbation = Au::from_f32_px(perturbation as f32); match placed_float.info.side { - FloatSide::Left => placed_float.origin.inline -= perturbation, - FloatSide::Right => placed_float.origin.inline += perturbation, + FloatSide::InlineStart => placed_float.origin.inline -= perturbation, + FloatSide::InlineEnd => placed_float.origin.inline += perturbation, } } @@ -737,8 +739,8 @@ fn check_floats_rule_10(placement: &FloatPlacement) { } match this_float.info.clear { - Clear::Left => assert_ne!(other_float.info.side, FloatSide::Left), - Clear::Right => assert_ne!(other_float.info.side, FloatSide::Right), + Clear::Left => assert_ne!(other_float.info.side, FloatSide::InlineStart), + Clear::Right => assert_ne!(other_float.info.side, FloatSide::InlineEnd), Clear::Both => assert!(false), Clear::None => unreachable!(), } diff --git a/tests/wpt/meta/css/CSS2/floats/floats-placement-vertical-001b.xht.ini b/tests/wpt/meta/css/CSS2/floats/floats-placement-vertical-001b.xht.ini new file mode 100644 index 00000000000..bd706c1a2cb --- /dev/null +++ b/tests/wpt/meta/css/CSS2/floats/floats-placement-vertical-001b.xht.ini @@ -0,0 +1,2 @@ +[floats-placement-vertical-001b.xht] + expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/floats/floats-placement-vertical-001c.xht.ini b/tests/wpt/meta/css/CSS2/floats/floats-placement-vertical-001c.xht.ini new file mode 100644 index 00000000000..ef7c5a18c80 --- /dev/null +++ b/tests/wpt/meta/css/CSS2/floats/floats-placement-vertical-001c.xht.ini @@ -0,0 +1,2 @@ +[floats-placement-vertical-001c.xht] + expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/margin-padding-clear/margin-right-100.xht.ini b/tests/wpt/meta/css/CSS2/margin-padding-clear/margin-right-100.xht.ini deleted file mode 100644 index ab285bee736..00000000000 --- a/tests/wpt/meta/css/CSS2/margin-padding-clear/margin-right-100.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[margin-right-100.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/margin-padding-clear/margin-right-101.xht.ini b/tests/wpt/meta/css/CSS2/margin-padding-clear/margin-right-101.xht.ini deleted file mode 100644 index e4b570b5132..00000000000 --- a/tests/wpt/meta/css/CSS2/margin-padding-clear/margin-right-101.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[margin-right-101.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/margin-padding-clear/margin-right-102.xht.ini b/tests/wpt/meta/css/CSS2/margin-padding-clear/margin-right-102.xht.ini deleted file mode 100644 index 6fdd642373f..00000000000 --- a/tests/wpt/meta/css/CSS2/margin-padding-clear/margin-right-102.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[margin-right-102.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-right-061.xht.ini b/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-right-061.xht.ini deleted file mode 100644 index abf08a86d96..00000000000 --- a/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-right-061.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[padding-right-061.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-right-062.xht.ini b/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-right-062.xht.ini deleted file mode 100644 index 808bd738481..00000000000 --- a/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-right-062.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[padding-right-062.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-right-073.xht.ini b/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-right-073.xht.ini deleted file mode 100644 index af108b0720c..00000000000 --- a/tests/wpt/meta/css/CSS2/margin-padding-clear/padding-right-073.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[padding-right-073.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/normal-flow/block-in-inline-margins-002a.xht.ini b/tests/wpt/meta/css/CSS2/normal-flow/block-in-inline-margins-002a.xht.ini deleted file mode 100644 index ff177fde90f..00000000000 --- a/tests/wpt/meta/css/CSS2/normal-flow/block-in-inline-margins-002a.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[block-in-inline-margins-002a.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/normal-flow/block-in-inline-margins-002b.xht.ini b/tests/wpt/meta/css/CSS2/normal-flow/block-in-inline-margins-002b.xht.ini deleted file mode 100644 index 30dba7bc31a..00000000000 --- a/tests/wpt/meta/css/CSS2/normal-flow/block-in-inline-margins-002b.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[block-in-inline-margins-002b.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-002.xht.ini b/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-002.xht.ini deleted file mode 100644 index f5a667ecb82..00000000000 --- a/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-002.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[absolute-non-replaced-width-002.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-005.xht.ini b/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-005.xht.ini deleted file mode 100644 index a5c04fe02e7..00000000000 --- a/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-005.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[absolute-non-replaced-width-005.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-012.xht.ini b/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-012.xht.ini deleted file mode 100644 index 18c3d658702..00000000000 --- a/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-012.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[absolute-non-replaced-width-012.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-021.xht.ini b/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-021.xht.ini deleted file mode 100644 index b69397bb822..00000000000 --- a/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-021.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[absolute-non-replaced-width-021.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-022.xht.ini b/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-022.xht.ini deleted file mode 100644 index 7c8a38fe848..00000000000 --- a/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-022.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[absolute-non-replaced-width-022.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-023.xht.ini b/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-023.xht.ini deleted file mode 100644 index 156e1a5dd50..00000000000 --- a/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-023.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[absolute-non-replaced-width-023.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-024.xht.ini b/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-024.xht.ini deleted file mode 100644 index 8befc137000..00000000000 --- a/tests/wpt/meta/css/CSS2/positioning/absolute-non-replaced-width-024.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[absolute-non-replaced-width-024.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/positioning/absolute-replaced-width-015.xht.ini b/tests/wpt/meta/css/CSS2/positioning/absolute-replaced-width-015.xht.ini deleted file mode 100644 index 0fc908e1852..00000000000 --- a/tests/wpt/meta/css/CSS2/positioning/absolute-replaced-width-015.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[absolute-replaced-width-015.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/positioning/absolute-replaced-width-020.xht.ini b/tests/wpt/meta/css/CSS2/positioning/absolute-replaced-width-020.xht.ini deleted file mode 100644 index 4fe605a11cb..00000000000 --- a/tests/wpt/meta/css/CSS2/positioning/absolute-replaced-width-020.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[absolute-replaced-width-020.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/positioning/absolute-replaced-width-034.xht.ini b/tests/wpt/meta/css/CSS2/positioning/absolute-replaced-width-034.xht.ini deleted file mode 100644 index 95d132dc8a0..00000000000 --- a/tests/wpt/meta/css/CSS2/positioning/absolute-replaced-width-034.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[absolute-replaced-width-034.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/positioning/absolute-replaced-width-071.xht.ini b/tests/wpt/meta/css/CSS2/positioning/absolute-replaced-width-071.xht.ini deleted file mode 100644 index 9821c39718c..00000000000 --- a/tests/wpt/meta/css/CSS2/positioning/absolute-replaced-width-071.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[absolute-replaced-width-071.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/positioning/absolute-replaced-width-076.xht.ini b/tests/wpt/meta/css/CSS2/positioning/absolute-replaced-width-076.xht.ini deleted file mode 100644 index ed6836dc12d..00000000000 --- a/tests/wpt/meta/css/CSS2/positioning/absolute-replaced-width-076.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[absolute-replaced-width-076.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/positioning/abspos-024.xht.ini b/tests/wpt/meta/css/CSS2/positioning/abspos-024.xht.ini deleted file mode 100644 index 1a49cae446c..00000000000 --- a/tests/wpt/meta/css/CSS2/positioning/abspos-024.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[abspos-024.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/positioning/abspos-block-level-001.html.ini b/tests/wpt/meta/css/CSS2/positioning/abspos-block-level-001.html.ini deleted file mode 100644 index 288e23b6065..00000000000 --- a/tests/wpt/meta/css/CSS2/positioning/abspos-block-level-001.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[abspos-block-level-001.html] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/positioning/position-relative-010.xht.ini b/tests/wpt/meta/css/CSS2/positioning/position-relative-010.xht.ini deleted file mode 100644 index c2391ca9766..00000000000 --- a/tests/wpt/meta/css/CSS2/positioning/position-relative-010.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[position-relative-010.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/positioning/position-relative-038.xht.ini b/tests/wpt/meta/css/CSS2/positioning/position-relative-038.xht.ini deleted file mode 100644 index e4630b3779d..00000000000 --- a/tests/wpt/meta/css/CSS2/positioning/position-relative-038.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[position-relative-038.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/positioning/relpos-calcs-006.xht.ini b/tests/wpt/meta/css/CSS2/positioning/relpos-calcs-006.xht.ini deleted file mode 100644 index 0c067e44232..00000000000 --- a/tests/wpt/meta/css/CSS2/positioning/relpos-calcs-006.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[relpos-calcs-006.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/positioning/right-113.xht.ini b/tests/wpt/meta/css/CSS2/positioning/right-113.xht.ini deleted file mode 100644 index 5b6c9db5376..00000000000 --- a/tests/wpt/meta/css/CSS2/positioning/right-113.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[right-113.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/text/text-align-white-space-005.xht.ini b/tests/wpt/meta/css/CSS2/text/text-align-white-space-005.xht.ini deleted file mode 100644 index 78c85f7aefa..00000000000 --- a/tests/wpt/meta/css/CSS2/text/text-align-white-space-005.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[text-align-white-space-005.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/CSS2/text/text-indent-rtl-001.xht.ini b/tests/wpt/meta/css/CSS2/text/text-indent-rtl-001.xht.ini deleted file mode 100644 index 47787874bbc..00000000000 --- a/tests/wpt/meta/css/CSS2/text/text-indent-rtl-001.xht.ini +++ /dev/null @@ -1,2 +0,0 @@ -[text-indent-rtl-001.xht] - expected: FAIL diff --git a/tests/wpt/meta/css/css-align/abspos/safe-align-self-vlr.html.ini b/tests/wpt/meta/css/css-align/abspos/safe-align-self-vlr.html.ini index 0b2d83b4668..678bda8046f 100644 --- a/tests/wpt/meta/css/css-align/abspos/safe-align-self-vlr.html.ini +++ b/tests/wpt/meta/css/css-align/abspos/safe-align-self-vlr.html.ini @@ -17,20 +17,20 @@ [.item 12] expected: FAIL - [.item 19] + [.item 13] expected: FAIL - [.item 20] + [.item 14] expected: FAIL - [.item 21] + [.item 15] expected: FAIL - [.item 22] + [.item 16] expected: FAIL - [.item 23] + [.item 17] expected: FAIL - [.item 24] + [.item 18] expected: FAIL diff --git a/tests/wpt/meta/css/css-align/abspos/safe-align-self-vrl.html.ini b/tests/wpt/meta/css/css-align/abspos/safe-align-self-vrl.html.ini index da103ce6245..cbb1c161645 100644 --- a/tests/wpt/meta/css/css-align/abspos/safe-align-self-vrl.html.ini +++ b/tests/wpt/meta/css/css-align/abspos/safe-align-self-vrl.html.ini @@ -17,20 +17,20 @@ [.item 6] expected: FAIL - [.item 13] + [.item 19] expected: FAIL - [.item 14] + [.item 20] expected: FAIL - [.item 15] + [.item 21] expected: FAIL - [.item 16] + [.item 22] expected: FAIL - [.item 17] + [.item 23] expected: FAIL - [.item 18] + [.item 24] expected: FAIL diff --git a/tests/wpt/meta/css/css-align/abspos/safe-justify-self-htb.html.ini b/tests/wpt/meta/css/css-align/abspos/safe-justify-self-htb.html.ini index 45b3cfd5335..bafb7a7d2c2 100644 --- a/tests/wpt/meta/css/css-align/abspos/safe-justify-self-htb.html.ini +++ b/tests/wpt/meta/css/css-align/abspos/safe-justify-self-htb.html.ini @@ -17,20 +17,20 @@ [.item 12] expected: FAIL - [.item 13] + [.item 19] expected: FAIL - [.item 14] + [.item 20] expected: FAIL - [.item 15] + [.item 21] expected: FAIL - [.item 16] + [.item 22] expected: FAIL - [.item 17] + [.item 23] expected: FAIL - [.item 18] + [.item 24] expected: FAIL diff --git a/tests/wpt/meta/css/css-align/blocks/safe-justify-self-htb.html.ini b/tests/wpt/meta/css/css-align/blocks/safe-justify-self-htb.html.ini index 45b3cfd5335..bafb7a7d2c2 100644 --- a/tests/wpt/meta/css/css-align/blocks/safe-justify-self-htb.html.ini +++ b/tests/wpt/meta/css/css-align/blocks/safe-justify-self-htb.html.ini @@ -17,20 +17,20 @@ [.item 12] expected: FAIL - [.item 13] + [.item 19] expected: FAIL - [.item 14] + [.item 20] expected: FAIL - [.item 15] + [.item 21] expected: FAIL - [.item 16] + [.item 22] expected: FAIL - [.item 17] + [.item 23] expected: FAIL - [.item 18] + [.item 24] expected: FAIL diff --git a/tests/wpt/meta/css/css-align/self-alignment/self-align-safe-unsafe-grid-003.html.ini b/tests/wpt/meta/css/css-align/self-alignment/self-align-safe-unsafe-grid-003.html.ini new file mode 100644 index 00000000000..3bbf9830320 --- /dev/null +++ b/tests/wpt/meta/css/css-align/self-alignment/self-align-safe-unsafe-grid-003.html.ini @@ -0,0 +1,2 @@ +[self-align-safe-unsafe-grid-003.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-001.html.ini b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-001.html.ini index 4f75db4711a..ff8feac1419 100644 --- a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-001.html.ini +++ b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-001.html.ini @@ -1,19 +1,10 @@ [position-absolute-001.html] - [.flexbox 38] - expected: FAIL - [.flexbox 39] expected: FAIL [.flexbox 34] expected: FAIL - [.flexbox 36] - expected: FAIL - - [.flexbox 37] - expected: FAIL - [.flexbox 89] expected: FAIL @@ -35,18 +26,6 @@ [.flexbox 86] expected: FAIL - [.flexbox 16] - expected: FAIL - - [.flexbox 17] - expected: FAIL - - [.flexbox 18] - expected: FAIL - - [.flexbox 19] - expected: FAIL - [.flexbox 108] expected: FAIL @@ -59,9 +38,6 @@ [.flexbox 96] expected: FAIL - [.flexbox 97] - expected: FAIL - [.flexbox 95] expected: FAIL @@ -98,9 +74,6 @@ [.flexbox 64] expected: FAIL - [.flexbox 69] - expected: FAIL - [.flexbox 68] expected: FAIL @@ -140,9 +113,6 @@ [.flexbox 115] expected: FAIL - [.flexbox 116] - expected: FAIL - [.flexbox 117] expected: FAIL @@ -164,9 +134,6 @@ [.flexbox 41] expected: FAIL - [.flexbox 40] - expected: FAIL - [.flexbox 43] expected: FAIL @@ -194,12 +161,6 @@ [.flexbox 104] expected: FAIL - [.flexbox 6] - expected: FAIL - - [.flexbox 9] - expected: FAIL - [.flexbox 58] expected: FAIL @@ -224,32 +185,32 @@ [.flexbox 55] expected: FAIL - [.flexbox 27] - expected: FAIL - [.flexbox 24] expected: FAIL - [.flexbox 20] - expected: FAIL - [.flexbox 120] expected: FAIL - [.flexbox 7] - expected: FAIL - - [.flexbox 26] - expected: FAIL - [.flexbox 52] expected: FAIL [.flexbox 71] expected: FAIL - [.flexbox 87] + [.flexbox 29] expected: FAIL - [.flexbox 106] + [.flexbox 47] + expected: FAIL + + [.flexbox 57] + expected: FAIL + + [.flexbox 66] + expected: FAIL + + [.flexbox 76] + expected: FAIL + + [.flexbox 109] expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-002.html.ini b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-002.html.ini index a02b4f5d68e..a5fb3f0a0d3 100644 --- a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-002.html.ini +++ b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-002.html.ini @@ -2,9 +2,6 @@ [.flexbox 5] expected: FAIL - [.flexbox 4] - expected: FAIL - [.flexbox 8] expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-003.html.ini b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-003.html.ini index 514a578845e..304357ad53a 100644 --- a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-003.html.ini +++ b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-003.html.ini @@ -1,7 +1,4 @@ [position-absolute-003.html] - [.rect 13] - expected: FAIL - [.rect 15] expected: FAIL @@ -17,9 +14,6 @@ [.rect 5] expected: FAIL - [.rect 14] - expected: FAIL - [.rect 16] expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-012.html.ini b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-012.html.ini index 093adb429a8..45e84962258 100644 --- a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-012.html.ini +++ b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-012.html.ini @@ -190,3 +190,15 @@ [.flexbox 95] expected: FAIL + + [.flexbox 38] + expected: FAIL + + [.flexbox 46] + expected: FAIL + + [.flexbox 54] + expected: FAIL + + [.flexbox 62] + expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-013.html.ini b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-013.html.ini index e3d9ec89029..d7090e0818d 100644 --- a/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-013.html.ini +++ b/tests/wpt/meta/css/css-flexbox/abspos/position-absolute-013.html.ini @@ -862,3 +862,57 @@ [.flexbox 432] expected: FAIL + + [.flexbox 152] + expected: FAIL + + [.flexbox 166] + expected: FAIL + + [.flexbox 168] + expected: FAIL + + [.flexbox 179] + expected: FAIL + + [.flexbox 187] + expected: FAIL + + [.flexbox 189] + expected: FAIL + + [.flexbox 200] + expected: FAIL + + [.flexbox 214] + expected: FAIL + + [.flexbox 216] + expected: FAIL + + [.flexbox 227] + expected: FAIL + + [.flexbox 235] + expected: FAIL + + [.flexbox 237] + expected: FAIL + + [.flexbox 247] + expected: FAIL + + [.flexbox 249] + expected: FAIL + + [.flexbox 263] + expected: FAIL + + [.flexbox 274] + expected: FAIL + + [.flexbox 276] + expected: FAIL + + [.flexbox 284] + expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/flex-direction-row-vertical.html.ini b/tests/wpt/meta/css/css-flexbox/flex-direction-row-vertical.html.ini deleted file mode 100644 index 396bd3b6898..00000000000 --- a/tests/wpt/meta/css/css-flexbox/flex-direction-row-vertical.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[flex-direction-row-vertical.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/flex-flow-013.html.ini b/tests/wpt/meta/css/css-flexbox/flex-flow-013.html.ini index 959eaa7d215..f42a2a0010d 100644 --- a/tests/wpt/meta/css/css-flexbox/flex-flow-013.html.ini +++ b/tests/wpt/meta/css/css-flexbox/flex-flow-013.html.ini @@ -8,15 +8,9 @@ [.flexbox 4] expected: FAIL - [.flexbox 7] - expected: FAIL - [.flexbox 2] expected: FAIL - [.flexbox 8] - expected: FAIL - [.flexbox 1] expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/flexbox-align-self-vert-rtl-001.xhtml.ini b/tests/wpt/meta/css/css-flexbox/flexbox-align-self-vert-rtl-001.xhtml.ini deleted file mode 100644 index 837886b0dad..00000000000 --- a/tests/wpt/meta/css/css-flexbox/flexbox-align-self-vert-rtl-001.xhtml.ini +++ /dev/null @@ -1,2 +0,0 @@ -[flexbox-align-self-vert-rtl-001.xhtml] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/flexbox-align-self-vert-rtl-002.xhtml.ini b/tests/wpt/meta/css/css-flexbox/flexbox-align-self-vert-rtl-002.xhtml.ini deleted file mode 100644 index 9509f937736..00000000000 --- a/tests/wpt/meta/css/css-flexbox/flexbox-align-self-vert-rtl-002.xhtml.ini +++ /dev/null @@ -1,2 +0,0 @@ -[flexbox-align-self-vert-rtl-002.xhtml] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/flexbox-align-self-vert-rtl-003.xhtml.ini b/tests/wpt/meta/css/css-flexbox/flexbox-align-self-vert-rtl-003.xhtml.ini deleted file mode 100644 index 2fff2b7cd45..00000000000 --- a/tests/wpt/meta/css/css-flexbox/flexbox-align-self-vert-rtl-003.xhtml.ini +++ /dev/null @@ -1,2 +0,0 @@ -[flexbox-align-self-vert-rtl-003.xhtml] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/flexbox-align-self-vert-rtl-004.xhtml.ini b/tests/wpt/meta/css/css-flexbox/flexbox-align-self-vert-rtl-004.xhtml.ini deleted file mode 100644 index 817b0705577..00000000000 --- a/tests/wpt/meta/css/css-flexbox/flexbox-align-self-vert-rtl-004.xhtml.ini +++ /dev/null @@ -1,2 +0,0 @@ -[flexbox-align-self-vert-rtl-004.xhtml] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/flexbox-mbp-horiz-001-rtl-reverse.xhtml.ini b/tests/wpt/meta/css/css-flexbox/flexbox-mbp-horiz-001-rtl-reverse.xhtml.ini deleted file mode 100644 index 57977cc1eef..00000000000 --- a/tests/wpt/meta/css/css-flexbox/flexbox-mbp-horiz-001-rtl-reverse.xhtml.ini +++ /dev/null @@ -1,2 +0,0 @@ -[flexbox-mbp-horiz-001-rtl-reverse.xhtml] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/flexbox-mbp-horiz-001-rtl.xhtml.ini b/tests/wpt/meta/css/css-flexbox/flexbox-mbp-horiz-001-rtl.xhtml.ini deleted file mode 100644 index ab2abca56b0..00000000000 --- a/tests/wpt/meta/css/css-flexbox/flexbox-mbp-horiz-001-rtl.xhtml.ini +++ /dev/null @@ -1,2 +0,0 @@ -[flexbox-mbp-horiz-001-rtl.xhtml] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/flexbox_justifycontent-rtl-001.html.ini b/tests/wpt/meta/css/css-flexbox/flexbox_justifycontent-rtl-001.html.ini index 81b7e481fea..aa294531057 100644 --- a/tests/wpt/meta/css/css-flexbox/flexbox_justifycontent-rtl-001.html.ini +++ b/tests/wpt/meta/css/css-flexbox/flexbox_justifycontent-rtl-001.html.ini @@ -1,24 +1,3 @@ [flexbox_justifycontent-rtl-001.html] - [.container > div 1] - expected: FAIL - - [.container > div 2] - expected: FAIL - - [.container > div 5] - expected: FAIL - - [.container > div 7] - expected: FAIL - - [.container > div 8] - expected: FAIL - - [.container > div 9] - expected: FAIL - - [.container > div 10] - expected: FAIL - - [.container > div 12] + [.container > div 11] expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/flexbox_justifycontent-rtl-002.html.ini b/tests/wpt/meta/css/css-flexbox/flexbox_justifycontent-rtl-002.html.ini deleted file mode 100644 index 1659e111d26..00000000000 --- a/tests/wpt/meta/css/css-flexbox/flexbox_justifycontent-rtl-002.html.ini +++ /dev/null @@ -1,36 +0,0 @@ -[flexbox_justifycontent-rtl-002.html] - [.container > div 1] - expected: FAIL - - [.container > div 2] - expected: FAIL - - [.container > div 3] - expected: FAIL - - [.container > div 4] - expected: FAIL - - [.container > div 5] - expected: FAIL - - [.container > div 6] - expected: FAIL - - [.container > div 7] - expected: FAIL - - [.container > div 8] - expected: FAIL - - [.container > div 9] - expected: FAIL - - [.container > div 10] - expected: FAIL - - [.container > div 11] - expected: FAIL - - [.container > div 12] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/flexbox_rtl-direction.html.ini b/tests/wpt/meta/css/css-flexbox/flexbox_rtl-direction.html.ini deleted file mode 100644 index f67d263ce6d..00000000000 --- a/tests/wpt/meta/css/css-flexbox/flexbox_rtl-direction.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[flexbox_rtl-direction.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/gap-001-rtl.html.ini b/tests/wpt/meta/css/css-flexbox/gap-001-rtl.html.ini deleted file mode 100644 index 9251a8bbc6d..00000000000 --- a/tests/wpt/meta/css/css-flexbox/gap-001-rtl.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[gap-001-rtl.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/gap-004-rtl.html.ini b/tests/wpt/meta/css/css-flexbox/gap-004-rtl.html.ini deleted file mode 100644 index ab6594b3895..00000000000 --- a/tests/wpt/meta/css/css-flexbox/gap-004-rtl.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[gap-004-rtl.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-flexbox/gap-007-rtl.html.ini b/tests/wpt/meta/css/css-flexbox/gap-007-rtl.html.ini deleted file mode 100644 index d603df8eefb..00000000000 --- a/tests/wpt/meta/css/css-flexbox/gap-007-rtl.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[gap-007-rtl.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-logical/logical-box-border-color.html.ini b/tests/wpt/meta/css/css-logical/logical-box-border-color.html.ini index 7061e71e7ca..a87b3d9a4a2 100644 --- a/tests/wpt/meta/css/css-logical/logical-box-border-color.html.ini +++ b/tests/wpt/meta/css/css-logical/logical-box-border-color.html.ini @@ -1,16 +1,4 @@ [logical-box-border-color.html] - [Test that logical border-*-color properties share computed values with their physical associates, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that border-*-color shorthands set the computed value of both logical and physical longhands, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that border-*-color properties honor order of appearance when both logical and physical associates are declared, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that border-*-color properties honor selector specificty when both logical and physical associates are declared, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - [Test that logical border-*-color properties share computed values with their physical associates, with 'writing-mode: vertical-rl; direction: rtl; '.] expected: FAIL diff --git a/tests/wpt/meta/css/css-logical/logical-box-border-radius.html.ini b/tests/wpt/meta/css/css-logical/logical-box-border-radius.html.ini index 23f29534bac..664c18a2711 100644 --- a/tests/wpt/meta/css/css-logical/logical-box-border-radius.html.ini +++ b/tests/wpt/meta/css/css-logical/logical-box-border-radius.html.ini @@ -1,13 +1,4 @@ [logical-box-border-radius.html] - [Test that logical border-*-radius properties share computed values with their physical associates, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that border-*-radius properties honor order of appearance when both logical and physical associates are declared, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that border-*-radius properties honor selector specificty when both logical and physical associates are declared, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - [Test that logical border-*-radius properties share computed values with their physical associates, with 'writing-mode: vertical-rl; direction: rtl; '.] expected: FAIL diff --git a/tests/wpt/meta/css/css-logical/logical-box-border-style.html.ini b/tests/wpt/meta/css/css-logical/logical-box-border-style.html.ini index 5c7eb1b17fd..adceefe0925 100644 --- a/tests/wpt/meta/css/css-logical/logical-box-border-style.html.ini +++ b/tests/wpt/meta/css/css-logical/logical-box-border-style.html.ini @@ -1,16 +1,4 @@ [logical-box-border-style.html] - [Test that logical border-*-style properties share computed values with their physical associates, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that border-*-style shorthands set the computed value of both logical and physical longhands, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that border-*-style properties honor order of appearance when both logical and physical associates are declared, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that border-*-style properties honor selector specificty when both logical and physical associates are declared, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - [Test that logical border-*-style properties share computed values with their physical associates, with 'writing-mode: vertical-rl; direction: rtl; '.] expected: FAIL diff --git a/tests/wpt/meta/css/css-logical/logical-box-border-width.html.ini b/tests/wpt/meta/css/css-logical/logical-box-border-width.html.ini index 85a1e4591d8..05d23050bd6 100644 --- a/tests/wpt/meta/css/css-logical/logical-box-border-width.html.ini +++ b/tests/wpt/meta/css/css-logical/logical-box-border-width.html.ini @@ -1,16 +1,4 @@ [logical-box-border-width.html] - [Test that logical border-*-width properties share computed values with their physical associates, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that border-*-width shorthands set the computed value of both logical and physical longhands, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that border-*-width properties honor order of appearance when both logical and physical associates are declared, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that border-*-width properties honor selector specificty when both logical and physical associates are declared, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - [Test that logical border-*-width properties share computed values with their physical associates, with 'writing-mode: vertical-rl; direction: rtl; '.] expected: FAIL diff --git a/tests/wpt/meta/css/css-logical/logical-box-inset.html.ini b/tests/wpt/meta/css/css-logical/logical-box-inset.html.ini index af078f0ce27..6637b8e7bfa 100644 --- a/tests/wpt/meta/css/css-logical/logical-box-inset.html.ini +++ b/tests/wpt/meta/css/css-logical/logical-box-inset.html.ini @@ -1,16 +1,4 @@ [logical-box-inset.html] - [Test that logical inset-* properties share computed values with their physical associates, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that inset-* shorthands set the computed value of both logical and physical longhands, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that inset-* properties honor order of appearance when both logical and physical associates are declared, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that inset-* properties honor selector specificty when both logical and physical associates are declared, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - [Test that logical inset-* properties share computed values with their physical associates, with 'writing-mode: vertical-rl; direction: rtl; '.] expected: FAIL diff --git a/tests/wpt/meta/css/css-logical/logical-box-margin.html.ini b/tests/wpt/meta/css/css-logical/logical-box-margin.html.ini index a994ad13a39..be9993ae34e 100644 --- a/tests/wpt/meta/css/css-logical/logical-box-margin.html.ini +++ b/tests/wpt/meta/css/css-logical/logical-box-margin.html.ini @@ -1,16 +1,4 @@ [logical-box-margin.html] - [Test that logical margin-* properties share computed values with their physical associates, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that margin-* shorthands set the computed value of both logical and physical longhands, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that margin-* properties honor order of appearance when both logical and physical associates are declared, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that margin-* properties honor selector specificty when both logical and physical associates are declared, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - [Test that logical margin-* properties share computed values with their physical associates, with 'writing-mode: vertical-rl; direction: rtl; '.] expected: FAIL diff --git a/tests/wpt/meta/css/css-logical/logical-box-padding.html.ini b/tests/wpt/meta/css/css-logical/logical-box-padding.html.ini index eda5bee95ae..7f7f3281dae 100644 --- a/tests/wpt/meta/css/css-logical/logical-box-padding.html.ini +++ b/tests/wpt/meta/css/css-logical/logical-box-padding.html.ini @@ -1,16 +1,4 @@ [logical-box-padding.html] - [Test that logical padding-* properties share computed values with their physical associates, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that padding-* shorthands set the computed value of both logical and physical longhands, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that padding-* properties honor order of appearance when both logical and physical associates are declared, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - - [Test that padding-* properties honor selector specificty when both logical and physical associates are declared, with 'writing-mode: horizontal-tb; direction: rtl; '.] - expected: FAIL - [Test that logical padding-* properties share computed values with their physical associates, with 'writing-mode: vertical-rl; direction: rtl; '.] expected: FAIL diff --git a/tests/wpt/meta/css/css-position/position-absolute-dynamic-static-position-floats-004.html.ini b/tests/wpt/meta/css/css-position/position-absolute-dynamic-static-position-floats-004.html.ini new file mode 100644 index 00000000000..e488c064bb1 --- /dev/null +++ b/tests/wpt/meta/css/css-position/position-absolute-dynamic-static-position-floats-004.html.ini @@ -0,0 +1,2 @@ +[position-absolute-dynamic-static-position-floats-004.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-position/static-position/inline-level-absolute-in-block-level-context-007.html.ini b/tests/wpt/meta/css/css-position/static-position/inline-level-absolute-in-block-level-context-007.html.ini deleted file mode 100644 index c146d86dd65..00000000000 --- a/tests/wpt/meta/css/css-position/static-position/inline-level-absolute-in-block-level-context-007.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[inline-level-absolute-in-block-level-context-007.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-position/static-position/inline-level-absolute-in-block-level-context-009.html.ini b/tests/wpt/meta/css/css-position/static-position/inline-level-absolute-in-block-level-context-009.html.ini new file mode 100644 index 00000000000..0653a572396 --- /dev/null +++ b/tests/wpt/meta/css/css-position/static-position/inline-level-absolute-in-block-level-context-009.html.ini @@ -0,0 +1,2 @@ +[inline-level-absolute-in-block-level-context-009.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-position/static-position/inline-level-absolute-in-block-level-context-010.html.ini b/tests/wpt/meta/css/css-position/static-position/inline-level-absolute-in-block-level-context-010.html.ini new file mode 100644 index 00000000000..2035850bdc8 --- /dev/null +++ b/tests/wpt/meta/css/css-position/static-position/inline-level-absolute-in-block-level-context-010.html.ini @@ -0,0 +1,2 @@ +[inline-level-absolute-in-block-level-context-010.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-tables/row-group-margin-border-padding.html.ini b/tests/wpt/meta/css/css-tables/row-group-margin-border-padding.html.ini new file mode 100644 index 00000000000..e5b3dd0420d --- /dev/null +++ b/tests/wpt/meta/css/css-tables/row-group-margin-border-padding.html.ini @@ -0,0 +1,2 @@ +[row-group-margin-border-padding.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-tables/row-margin-border-padding.html.ini b/tests/wpt/meta/css/css-tables/row-margin-border-padding.html.ini new file mode 100644 index 00000000000..360b9c1d5bf --- /dev/null +++ b/tests/wpt/meta/css/css-tables/row-margin-border-padding.html.ini @@ -0,0 +1,2 @@ +[row-margin-border-padding.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-text/white-space/trailing-space-and-text-alignment-rtl-002.html.ini b/tests/wpt/meta/css/css-text/white-space/trailing-space-and-text-alignment-rtl-002.html.ini deleted file mode 100644 index f3d84aec8f8..00000000000 --- a/tests/wpt/meta/css/css-text/white-space/trailing-space-and-text-alignment-rtl-002.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[trailing-space-and-text-alignment-rtl-002.html] - expected: FAIL diff --git a/tests/wpt/meta/css/css-text/white-space/trailing-space-and-text-alignment-rtl-003.html.ini b/tests/wpt/meta/css/css-text/white-space/trailing-space-and-text-alignment-rtl-003.html.ini new file mode 100644 index 00000000000..b219bf63b8c --- /dev/null +++ b/tests/wpt/meta/css/css-text/white-space/trailing-space-and-text-alignment-rtl-003.html.ini @@ -0,0 +1,2 @@ +[trailing-space-and-text-alignment-rtl-003.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-text/white-space/white-space-pre-wrap-trailing-spaces-023.html.ini b/tests/wpt/meta/css/css-text/white-space/white-space-pre-wrap-trailing-spaces-023.html.ini new file mode 100644 index 00000000000..d6e6ea8d141 --- /dev/null +++ b/tests/wpt/meta/css/css-text/white-space/white-space-pre-wrap-trailing-spaces-023.html.ini @@ -0,0 +1,2 @@ +[white-space-pre-wrap-trailing-spaces-023.html] + expected: FAIL diff --git a/tests/wpt/meta/css/css-text/word-break/word-break-normal-ar-000.html.ini b/tests/wpt/meta/css/css-text/word-break/word-break-normal-ar-000.html.ini deleted file mode 100644 index b79a864a815..00000000000 --- a/tests/wpt/meta/css/css-text/word-break/word-break-normal-ar-000.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[word-break-normal-ar-000.html] - expected: FAIL diff --git a/tests/wpt/meta/css/cssom-view/getClientRects-inline.html.ini b/tests/wpt/meta/css/cssom-view/getClientRects-inline.html.ini deleted file mode 100644 index 68e4f894023..00000000000 --- a/tests/wpt/meta/css/cssom-view/getClientRects-inline.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[getClientRects-inline.html] - expected: FAIL diff --git a/tests/wpt/meta/html/rendering/non-replaced-elements/tables/table-direction.html.ini b/tests/wpt/meta/html/rendering/non-replaced-elements/tables/table-direction.html.ini deleted file mode 100644 index d07ebc774ad..00000000000 --- a/tests/wpt/meta/html/rendering/non-replaced-elements/tables/table-direction.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[table-direction.html] - expected: FAIL diff --git a/tests/wpt/meta/html/rendering/non-replaced-elements/tables/table-row-direction.html.ini b/tests/wpt/meta/html/rendering/non-replaced-elements/tables/table-row-direction.html.ini deleted file mode 100644 index f4cb6beb159..00000000000 --- a/tests/wpt/meta/html/rendering/non-replaced-elements/tables/table-row-direction.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[table-row-direction.html] - expected: FAIL diff --git a/tests/wpt/meta/html/rendering/non-replaced-elements/tables/table-row-group-direction.html.ini b/tests/wpt/meta/html/rendering/non-replaced-elements/tables/table-row-group-direction.html.ini deleted file mode 100644 index e3b84ba2c22..00000000000 --- a/tests/wpt/meta/html/rendering/non-replaced-elements/tables/table-row-group-direction.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[table-row-group-direction.html] - expected: FAIL diff --git a/tests/wpt/meta/html/rendering/replaced-elements/the-textarea-element/textarea-padding-iend-overlaps-content-001.tentative.html.ini b/tests/wpt/meta/html/rendering/replaced-elements/the-textarea-element/textarea-padding-iend-overlaps-content-001.tentative.html.ini deleted file mode 100644 index b27eb2ddc98..00000000000 --- a/tests/wpt/meta/html/rendering/replaced-elements/the-textarea-element/textarea-padding-iend-overlaps-content-001.tentative.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[textarea-padding-iend-overlaps-content-001.tentative.html] - expected: FAIL diff --git a/tests/wpt/meta/html/rendering/replaced-elements/the-textarea-element/textarea-padding-istart-moves-content-001.tentative.html.ini b/tests/wpt/meta/html/rendering/replaced-elements/the-textarea-element/textarea-padding-istart-moves-content-001.tentative.html.ini deleted file mode 100644 index cb174cfc1d3..00000000000 --- a/tests/wpt/meta/html/rendering/replaced-elements/the-textarea-element/textarea-padding-istart-moves-content-001.tentative.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[textarea-padding-istart-moves-content-001.tentative.html] - expected: FAIL diff --git a/tests/wpt/meta/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-wrapped.html.ini b/tests/wpt/meta/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-wrapped.html.ini deleted file mode 100644 index f3404a91429..00000000000 --- a/tests/wpt/meta/html/semantics/text-level-semantics/the-bdi-element/bdi-neutral-wrapped.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[bdi-neutral-wrapped.html] - expected: FAIL diff --git a/tests/wpt/mozilla/meta/css/direction_style_caching.html.ini b/tests/wpt/mozilla/meta/css/direction_style_caching.html.ini deleted file mode 100644 index ac7b32034ba..00000000000 --- a/tests/wpt/mozilla/meta/css/direction_style_caching.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[direction_style_caching.html] - expected: FAIL diff --git a/tests/wpt/mozilla/meta/css/rtl_body.html.ini b/tests/wpt/mozilla/meta/css/rtl_body.html.ini deleted file mode 100644 index 8eeeca59b7c..00000000000 --- a/tests/wpt/mozilla/meta/css/rtl_body.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[rtl_body.html] - expected: FAIL diff --git a/tests/wpt/mozilla/meta/css/rtl_margin_a.html.ini b/tests/wpt/mozilla/meta/css/rtl_margin_a.html.ini deleted file mode 100644 index 46481ce2255..00000000000 --- a/tests/wpt/mozilla/meta/css/rtl_margin_a.html.ini +++ /dev/null @@ -1,2 +0,0 @@ -[rtl_margin_a.html] - expected: FAIL