aboutsummaryrefslogtreecommitdiffstats
path: root/components/layout
diff options
context:
space:
mode:
Diffstat (limited to 'components/layout')
-rw-r--r--components/layout/construct_modern.rs1
-rw-r--r--components/layout/display_list/conversions.rs8
-rw-r--r--components/layout/display_list/mod.rs130
-rw-r--r--components/layout/display_list/stacking_context.rs76
-rw-r--r--components/layout/flexbox/layout.rs30
-rw-r--r--components/layout/flexbox/mod.rs3
-rw-r--r--components/layout/flow/construct.rs31
-rw-r--r--components/layout/flow/float.rs3
-rw-r--r--components/layout/flow/inline/construct.rs5
-rw-r--r--components/layout/flow/inline/inline_box.rs8
-rw-r--r--components/layout/flow/inline/line.rs3
-rw-r--r--components/layout/flow/inline/mod.rs19
-rw-r--r--components/layout/flow/root.rs2
-rw-r--r--components/layout/fragment_tree/fragment.rs4
-rw-r--r--components/layout/layout_impl.rs2
-rw-r--r--components/layout/lib.rs20
-rw-r--r--components/layout/table/construct.rs13
-rw-r--r--components/layout/taffy/mod.rs3
-rw-r--r--components/layout/traversal.rs12
19 files changed, 210 insertions, 163 deletions
diff --git a/components/layout/construct_modern.rs b/components/layout/construct_modern.rs
index 8f1282ec9f6..d09744b2031 100644
--- a/components/layout/construct_modern.rs
+++ b/components/layout/construct_modern.rs
@@ -150,7 +150,6 @@ impl<'a, 'dom> ModernContainerBuilder<'a, 'dom> {
let inline_formatting_context = inline_formatting_context_builder.finish(
self.context,
- self.propagated_data,
true, /* has_first_formatted_line */
false, /* is_single_line_text_box */
self.info.style.writing_mode.to_bidi_level(),
diff --git a/components/layout/display_list/conversions.rs b/components/layout/display_list/conversions.rs
index 6d78a17e886..a2517c863f1 100644
--- a/components/layout/display_list/conversions.rs
+++ b/components/layout/display_list/conversions.rs
@@ -125,11 +125,15 @@ impl ToWebRender for ComputedTextDecorationStyle {
type Type = LineStyle;
fn to_webrender(&self) -> Self::Type {
match *self {
- ComputedTextDecorationStyle::Solid => LineStyle::Solid,
+ ComputedTextDecorationStyle::Solid | ComputedTextDecorationStyle::Double => {
+ LineStyle::Solid
+ },
ComputedTextDecorationStyle::Dotted => LineStyle::Dotted,
ComputedTextDecorationStyle::Dashed => LineStyle::Dashed,
ComputedTextDecorationStyle::Wavy => LineStyle::Wavy,
- _ => LineStyle::Solid,
+ ComputedTextDecorationStyle::MozNone => {
+ unreachable!("Should never try to draw a moz-none text decoration")
+ },
}
}
}
diff --git a/components/layout/display_list/mod.rs b/components/layout/display_list/mod.rs
index 95689cf1186..3716ff35b2c 100644
--- a/components/layout/display_list/mod.rs
+++ b/components/layout/display_list/mod.rs
@@ -11,7 +11,7 @@ use base::id::ScrollTreeNodeId;
use clip::{Clip, ClipId};
use compositing_traits::display_list::{CompositorDisplayListInfo, SpatialTreeNodeInfo};
use embedder_traits::Cursor;
-use euclid::{Point2D, SideOffsets2D, Size2D, UnknownUnit};
+use euclid::{Point2D, SideOffsets2D, Size2D, UnknownUnit, Vector2D};
use fonts::GlyphStore;
use gradient::WebRenderGradient;
use range::Range as ServoRange;
@@ -21,7 +21,9 @@ use servo_geometry::MaxRect;
use style::Zero;
use style::color::{AbsoluteColor, ColorSpace};
use style::computed_values::border_image_outset::T as BorderImageOutset;
-use style::computed_values::text_decoration_style::T as ComputedTextDecorationStyle;
+use style::computed_values::text_decoration_style::{
+ T as ComputedTextDecorationStyle, T as TextDecorationStyle,
+};
use style::dom::OpaqueNode;
use style::properties::ComputedValues;
use style::properties::longhands::visibility::computed_value::T as Visibility;
@@ -572,6 +574,7 @@ impl Fragment {
section: StackingContextSection,
is_hit_test_for_scrollable_overflow: bool,
is_collapsed_table_borders: bool,
+ text_decorations: &Arc<Vec<FragmentTextDecoration>>,
) {
let spatial_id = builder.spatial_id(builder.current_scroll_node_id);
let clip_chain_id = builder.clip_chain_id(builder.current_clip_id);
@@ -683,9 +686,12 @@ impl Fragment {
.get_inherited_box()
.visibility
{
- Visibility::Visible => {
- self.build_display_list_for_text_fragment(text, builder, containing_block)
- },
+ Visibility::Visible => self.build_display_list_for_text_fragment(
+ text,
+ builder,
+ containing_block,
+ text_decorations,
+ ),
Visibility::Hidden => (),
Visibility::Collapse => (),
}
@@ -723,6 +729,7 @@ impl Fragment {
fragment: &TextFragment,
builder: &mut DisplayListBuilder,
containing_block: &PhysicalRect<Au>,
+ text_decorations: &Arc<Vec<FragmentTextDecoration>>,
) {
// NB: The order of painting text components (CSS Text Decoration Module Level 3) is:
// shadows, underline, overline, text, text-emphasis, and then line-through.
@@ -732,6 +739,7 @@ impl Fragment {
let rect = fragment.rect.translate(containing_block.origin.to_vector());
let mut baseline_origin = rect.origin;
baseline_origin.y += fragment.font_metrics.ascent;
+
let glyphs = glyphs(
&fragment.glyphs,
baseline_origin,
@@ -774,23 +782,36 @@ impl Fragment {
);
}
- if fragment
- .text_decoration_line
- .contains(TextDecorationLine::UNDERLINE)
- {
- let mut rect = rect;
- rect.origin.y += font_metrics.ascent - font_metrics.underline_offset;
- rect.size.height = Au::from_f32_px(font_metrics.underline_size.to_nearest_pixel(dppx));
- self.build_display_list_for_text_decoration(&parent_style, builder, &rect, &color);
+ for text_decoration in text_decorations.iter() {
+ if text_decoration.line.contains(TextDecorationLine::UNDERLINE) {
+ let mut rect = rect;
+ rect.origin.y += font_metrics.ascent - font_metrics.underline_offset;
+ rect.size.height =
+ Au::from_f32_px(font_metrics.underline_size.to_nearest_pixel(dppx));
+
+ self.build_display_list_for_text_decoration(
+ &parent_style,
+ builder,
+ &rect,
+ text_decoration,
+ TextDecorationLine::UNDERLINE,
+ );
+ }
}
- if fragment
- .text_decoration_line
- .contains(TextDecorationLine::OVERLINE)
- {
- let mut rect = rect;
- rect.size.height = Au::from_f32_px(font_metrics.underline_size.to_nearest_pixel(dppx));
- self.build_display_list_for_text_decoration(&parent_style, builder, &rect, &color);
+ for text_decoration in text_decorations.iter() {
+ if text_decoration.line.contains(TextDecorationLine::OVERLINE) {
+ let mut rect = rect;
+ rect.size.height =
+ Au::from_f32_px(font_metrics.underline_size.to_nearest_pixel(dppx));
+ self.build_display_list_for_text_decoration(
+ &parent_style,
+ builder,
+ &rect,
+ text_decoration,
+ TextDecorationLine::OVERLINE,
+ );
+ }
}
// TODO: This caret/text selection implementation currently does not account for vertical text
@@ -867,14 +888,23 @@ impl Fragment {
None,
);
- if fragment
- .text_decoration_line
- .contains(TextDecorationLine::LINE_THROUGH)
- {
- let mut rect = rect;
- rect.origin.y += font_metrics.ascent - font_metrics.strikeout_offset;
- rect.size.height = Au::from_f32_px(font_metrics.strikeout_size.to_nearest_pixel(dppx));
- self.build_display_list_for_text_decoration(&parent_style, builder, &rect, &color);
+ for text_decoration in text_decorations.iter() {
+ if text_decoration
+ .line
+ .contains(TextDecorationLine::LINE_THROUGH)
+ {
+ let mut rect = rect;
+ rect.origin.y += font_metrics.ascent - font_metrics.strikeout_offset;
+ rect.size.height =
+ Au::from_f32_px(font_metrics.strikeout_size.to_nearest_pixel(dppx));
+ self.build_display_list_for_text_decoration(
+ &parent_style,
+ builder,
+ &rect,
+ text_decoration,
+ TextDecorationLine::LINE_THROUGH,
+ );
+ }
}
if !shadows.0.is_empty() {
@@ -887,27 +917,47 @@ impl Fragment {
parent_style: &ServoArc<ComputedValues>,
builder: &mut DisplayListBuilder,
rect: &PhysicalRect<Au>,
- color: &AbsoluteColor,
+ text_decoration: &FragmentTextDecoration,
+ line: TextDecorationLine,
) {
- let rect = rect.to_webrender();
- let wavy_line_thickness = (0.33 * rect.size().height).ceil();
- let text_decoration_color = parent_style
- .clone_text_decoration_color()
- .resolve_to_absolute(color);
- let text_decoration_style = parent_style.clone_text_decoration_style();
- if text_decoration_style == ComputedTextDecorationStyle::MozNone {
+ if text_decoration.style == ComputedTextDecorationStyle::MozNone {
return;
}
+
+ let mut rect = rect.to_webrender();
+ let line_thickness = rect.height().ceil();
+
+ if text_decoration.style == ComputedTextDecorationStyle::Wavy {
+ rect = rect.inflate(0.0, line_thickness * 1.0);
+ }
+
let common_properties = builder.common_properties(rect, parent_style);
builder.wr().push_line(
&common_properties,
&rect,
- wavy_line_thickness,
+ line_thickness,
wr::LineOrientation::Horizontal,
- &rgba(text_decoration_color),
- text_decoration_style.to_webrender(),
+ &rgba(text_decoration.color),
+ text_decoration.style.to_webrender(),
);
- // XXX(ferjm) support text-decoration-style: double
+
+ if text_decoration.style == TextDecorationStyle::Double {
+ let half_height = (rect.height() / 2.0).floor().max(1.0);
+ let y_offset = match line {
+ TextDecorationLine::OVERLINE => -rect.height() - half_height,
+ _ => rect.height() + half_height,
+ };
+ let rect = rect.translate(Vector2D::new(0.0, y_offset));
+ let common_properties = builder.common_properties(rect, parent_style);
+ builder.wr().push_line(
+ &common_properties,
+ &rect,
+ line_thickness,
+ wr::LineOrientation::Horizontal,
+ &rgba(text_decoration.color),
+ text_decoration.style.to_webrender(),
+ );
+ }
}
}
diff --git a/components/layout/display_list/stacking_context.rs b/components/layout/display_list/stacking_context.rs
index bcd882e3fcc..d22a2b6656a 100644
--- a/components/layout/display_list/stacking_context.rs
+++ b/components/layout/display_list/stacking_context.rs
@@ -5,6 +5,7 @@
use core::f32;
use std::cell::RefCell;
use std::mem;
+use std::sync::Arc;
use app_units::Au;
use base::id::ScrollTreeNodeId;
@@ -18,13 +19,15 @@ use euclid::default::{Point2D, Rect, Size2D};
use log::warn;
use servo_config::opts::DebugOptions;
use style::Zero;
+use style::color::AbsoluteColor;
use style::computed_values::float::T as ComputedFloat;
use style::computed_values::mix_blend_mode::T as ComputedMixBlendMode;
use style::computed_values::overflow_x::T as ComputedOverflow;
use style::computed_values::position::T as ComputedPosition;
+use style::computed_values::text_decoration_style::T as TextDecorationStyle;
use style::values::computed::angle::Angle;
use style::values::computed::basic_shape::ClipPath;
-use style::values::computed::{ClipRectOrAuto, Length};
+use style::values::computed::{ClipRectOrAuto, Length, TextDecorationLine};
use style::values::generics::box_::Perspective;
use style::values::generics::transform::{self, GenericRotate, GenericScale, GenericTranslate};
use style::values::specified::box_::DisplayOutside;
@@ -168,12 +171,14 @@ impl StackingContextTree {
};
let mut root_stacking_context = StackingContext::create_root(root_scroll_node_id, debug);
+ let text_decorations = Default::default();
for fragment in &fragment_tree.root_fragments {
fragment.build_stacking_context_tree(
&mut stacking_context_tree,
&containing_block_info,
&mut root_stacking_context,
StackingContextBuildMode::SkipHoisted,
+ &text_decorations,
);
}
root_stacking_context.sort();
@@ -246,6 +251,14 @@ impl StackingContextTree {
}
}
+/// The text decorations for a Fragment, collecting during [`StackingContextTree`] construction.
+#[derive(Clone, Debug)]
+pub(crate) struct FragmentTextDecoration {
+ pub line: TextDecorationLine,
+ pub color: AbsoluteColor,
+ pub style: TextDecorationStyle,
+}
+
/// A piece of content that directly belongs to a section of a stacking context.
///
/// This is generally part of a fragment, like its borders or foreground, but it
@@ -261,6 +274,7 @@ pub(crate) enum StackingContextContent {
fragment: Fragment,
is_hit_test_for_scrollable_overflow: bool,
is_collapsed_table_borders: bool,
+ text_decorations: Arc<Vec<FragmentTextDecoration>>,
},
/// An index into [StackingContext::atomic_inline_stacking_containers].
@@ -292,6 +306,7 @@ impl StackingContextContent {
fragment,
is_hit_test_for_scrollable_overflow,
is_collapsed_table_borders,
+ text_decorations,
} => {
builder.current_scroll_node_id = *scroll_node_id;
builder.current_reference_frame_scroll_node_id = *reference_frame_scroll_node_id;
@@ -302,6 +317,7 @@ impl StackingContextContent {
*section,
*is_hit_test_for_scrollable_overflow,
*is_collapsed_table_borders,
+ text_decorations,
);
},
Self::AtomicInlineStackingContainer { index } => {
@@ -800,6 +816,7 @@ impl Fragment {
containing_block_info: &ContainingBlockInfo,
stacking_context: &mut StackingContext,
mode: StackingContextBuildMode,
+ text_decorations: &Arc<Vec<FragmentTextDecoration>>,
) {
let containing_block = containing_block_info.get_containing_block_for_fragment(self);
let fragment_clone = self.clone();
@@ -812,6 +829,11 @@ impl Fragment {
return;
}
+ let text_decorations = match self {
+ Fragment::Float(..) => &Default::default(),
+ _ => text_decorations,
+ };
+
// If this fragment has a transform applied that makes it take up no space
// then we don't need to create any stacking contexts for it.
let has_non_invertible_transform = fragment
@@ -828,6 +850,7 @@ impl Fragment {
containing_block,
containing_block_info,
stacking_context,
+ text_decorations,
);
},
Fragment::AbsoluteOrFixedPositioned(fragment) => {
@@ -842,6 +865,7 @@ impl Fragment {
containing_block_info,
stacking_context,
StackingContextBuildMode::IncludeHoisted,
+ &Default::default(),
);
},
Fragment::Positioning(fragment) => {
@@ -851,6 +875,7 @@ impl Fragment {
containing_block,
containing_block_info,
stacking_context,
+ text_decorations,
);
},
Fragment::Text(_) | Fragment::Image(_) | Fragment::IFrame(_) => {
@@ -867,6 +892,7 @@ impl Fragment {
fragment: fragment_clone,
is_hit_test_for_scrollable_overflow: false,
is_collapsed_table_borders: false,
+ text_decorations: text_decorations.clone(),
});
},
}
@@ -929,6 +955,7 @@ impl BoxFragment {
containing_block: &ContainingBlock,
containing_block_info: &ContainingBlockInfo,
parent_stacking_context: &mut StackingContext,
+ text_decorations: &Arc<Vec<FragmentTextDecoration>>,
) {
self.build_stacking_context_tree_maybe_creating_reference_frame(
fragment,
@@ -936,6 +963,7 @@ impl BoxFragment {
containing_block,
containing_block_info,
parent_stacking_context,
+ text_decorations,
);
}
@@ -946,6 +974,7 @@ impl BoxFragment {
containing_block: &ContainingBlock,
containing_block_info: &ContainingBlockInfo,
parent_stacking_context: &mut StackingContext,
+ text_decorations: &Arc<Vec<FragmentTextDecoration>>,
) {
let reference_frame_data =
match self.reference_frame_data_if_necessary(&containing_block.rect) {
@@ -957,6 +986,7 @@ impl BoxFragment {
containing_block,
containing_block_info,
parent_stacking_context,
+ text_decorations,
);
},
};
@@ -999,6 +1029,7 @@ impl BoxFragment {
&adjusted_containing_block,
&new_containing_block_info,
parent_stacking_context,
+ text_decorations,
);
}
@@ -1009,6 +1040,7 @@ impl BoxFragment {
containing_block: &ContainingBlock,
containing_block_info: &ContainingBlockInfo,
parent_stacking_context: &mut StackingContext,
+ text_decorations: &Arc<Vec<FragmentTextDecoration>>,
) {
let context_type = match self.get_stacking_context_type() {
Some(context_type) => context_type,
@@ -1019,6 +1051,7 @@ impl BoxFragment {
containing_block,
containing_block_info,
parent_stacking_context,
+ text_decorations,
);
return;
},
@@ -1072,6 +1105,7 @@ impl BoxFragment {
containing_block,
containing_block_info,
&mut child_stacking_context,
+ text_decorations,
);
let mut stolen_children = vec![];
@@ -1097,6 +1131,7 @@ impl BoxFragment {
containing_block: &ContainingBlock,
containing_block_info: &ContainingBlockInfo,
stacking_context: &mut StackingContext,
+ text_decorations: &Arc<Vec<FragmentTextDecoration>>,
) {
let mut new_scroll_node_id = containing_block.scroll_node_id;
let mut new_clip_id = containing_block.clip_id;
@@ -1164,6 +1199,7 @@ impl BoxFragment {
fragment: fragment.clone(),
is_hit_test_for_scrollable_overflow: false,
is_collapsed_table_borders: false,
+ text_decorations: text_decorations.clone(),
});
};
@@ -1198,6 +1234,7 @@ impl BoxFragment {
fragment: fragment.clone(),
is_hit_test_for_scrollable_overflow: true,
is_collapsed_table_borders: false,
+ text_decorations: text_decorations.clone(),
});
}
}
@@ -1239,12 +1276,46 @@ impl BoxFragment {
containing_block_info.new_for_non_absolute_descendants(&for_non_absolute_descendants)
};
+ // Text decorations are not propagated to atomic inline-level descendants.
+ // From https://drafts.csswg.org/css2/#lining-striking-props:
+ // > Note that text decorations are not propagated to floating and absolutely
+ // > positioned descendants, nor to the contents of atomic inline-level descendants
+ // > such as inline blocks and inline tables.
+ let text_decorations = match self.is_atomic_inline_level() ||
+ self.base
+ .flags
+ .contains(FragmentFlags::IS_OUTSIDE_LIST_ITEM_MARKER)
+ {
+ true => &Default::default(),
+ false => text_decorations,
+ };
+
+ let new_text_decoration;
+ let text_decorations = match self.style.clone_text_decoration_line() {
+ TextDecorationLine::NONE => text_decorations,
+ line => {
+ let mut new_vector = (**text_decorations).clone();
+ let color = &self.style.get_inherited_text().color;
+ new_vector.push(FragmentTextDecoration {
+ line,
+ color: self
+ .style
+ .clone_text_decoration_color()
+ .resolve_to_absolute(color),
+ style: self.style.clone_text_decoration_style(),
+ });
+ new_text_decoration = Arc::new(new_vector);
+ &new_text_decoration
+ },
+ };
+
for child in &self.children {
child.build_stacking_context_tree(
stacking_context_tree,
&new_containing_block_info,
stacking_context,
StackingContextBuildMode::SkipHoisted,
+ text_decorations,
);
}
@@ -1263,6 +1334,7 @@ impl BoxFragment {
fragment: fragment.clone(),
is_hit_test_for_scrollable_overflow: false,
is_collapsed_table_borders: true,
+ text_decorations: text_decorations.clone(),
});
}
}
@@ -1646,6 +1718,7 @@ impl PositioningFragment {
containing_block: &ContainingBlock,
containing_block_info: &ContainingBlockInfo,
stacking_context: &mut StackingContext,
+ text_decorations: &Arc<Vec<FragmentTextDecoration>>,
) {
let rect = self
.rect
@@ -1660,6 +1733,7 @@ impl PositioningFragment {
&new_containing_block_info,
stacking_context,
StackingContextBuildMode::SkipHoisted,
+ text_decorations,
);
}
}
diff --git a/components/layout/flexbox/layout.rs b/components/layout/flexbox/layout.rs
index 8fc5aa0778b..985f5f3cf65 100644
--- a/components/layout/flexbox/layout.rs
+++ b/components/layout/flexbox/layout.rs
@@ -417,9 +417,8 @@ struct DesiredFlexFractionAndGrowOrShrinkFactor {
#[derive(Default)]
struct FlexItemBoxInlineContentSizesInfo {
outer_flex_base_size: Au,
- content_min_main_size: Au,
- content_max_main_size: Option<Au>,
- pbm_auto_is_zero: FlexRelativeVec2<Au>,
+ outer_min_main_size: Au,
+ outer_max_main_size: Option<Au>,
min_flex_factors: DesiredFlexFractionAndGrowOrShrinkFactor,
max_flex_factors: DesiredFlexFractionAndGrowOrShrinkFactor,
min_content_main_size_for_multiline_container: Au,
@@ -583,9 +582,8 @@ impl FlexContainer {
for FlexItemBoxInlineContentSizesInfo {
outer_flex_base_size,
- content_min_main_size,
- content_max_main_size,
- pbm_auto_is_zero,
+ outer_min_main_size,
+ outer_max_main_size,
min_flex_factors,
max_flex_factors,
min_content_main_size_for_multiline_container,
@@ -595,16 +593,13 @@ impl FlexContainer {
// > 4. Add each item’s flex base size to the product of its flex grow factor (scaled flex shrink
// > factor, if shrinking) and the chosen flex fraction, then clamp that result by the max main size
// > floored by the min main size.
- let outer_min_main_size = *content_min_main_size + pbm_auto_is_zero.main;
- let outer_max_main_size = content_max_main_size.map(|v| v + pbm_auto_is_zero.main);
-
// > 5. The flex container’s max-content size is the largest sum (among all the lines) of the
// > afore-calculated sizes of all items within a single line.
container_max_content_size += (*outer_flex_base_size +
Au::from_f32_px(
max_flex_factors.flex_grow_or_shrink_factor * chosen_max_flex_fraction,
))
- .clamp_between_extremums(outer_min_main_size, outer_max_main_size);
+ .clamp_between_extremums(*outer_min_main_size, *outer_max_main_size);
// > The min-content main size of a single-line flex container is calculated
// > identically to the max-content main size, except that the flex items’
@@ -621,7 +616,7 @@ impl FlexContainer {
Au::from_f32_px(
min_flex_factors.flex_grow_or_shrink_factor * chosen_min_flex_fraction,
))
- .clamp_between_extremums(outer_min_main_size, outer_max_main_size);
+ .clamp_between_extremums(*outer_min_main_size, *outer_max_main_size);
} else {
container_min_content_size
.max_assign(*min_content_main_size_for_multiline_container);
@@ -2458,6 +2453,8 @@ impl FlexItemBox {
};
let outer_flex_base_size = flex_base_size + pbm_auto_is_zero.main;
+ let outer_min_main_size = content_min_main_size + pbm_auto_is_zero.main;
+ let outer_max_main_size = content_max_main_size.map(|v| v + pbm_auto_is_zero.main);
let max_flex_factors = self.desired_flex_factors_for_preferred_width(
content_contribution_sizes.max_content,
flex_base_size,
@@ -2483,20 +2480,19 @@ impl FlexItemBox {
content_contribution_sizes.min_content;
let style_position = &self.style().get_position();
if style_position.flex_grow.is_zero() {
- min_content_main_size_for_multiline_container.min_assign(flex_base_size);
+ min_content_main_size_for_multiline_container.min_assign(outer_flex_base_size);
}
if style_position.flex_shrink.is_zero() {
- min_content_main_size_for_multiline_container.max_assign(flex_base_size);
+ min_content_main_size_for_multiline_container.max_assign(outer_flex_base_size);
}
min_content_main_size_for_multiline_container =
min_content_main_size_for_multiline_container
- .clamp_between_extremums(content_min_main_size, content_max_main_size);
+ .clamp_between_extremums(outer_min_main_size, outer_max_main_size);
FlexItemBoxInlineContentSizesInfo {
outer_flex_base_size,
- content_min_main_size,
- content_max_main_size,
- pbm_auto_is_zero,
+ outer_min_main_size,
+ outer_max_main_size,
min_flex_factors,
max_flex_factors,
min_content_main_size_for_multiline_container,
diff --git a/components/layout/flexbox/mod.rs b/components/layout/flexbox/mod.rs
index 96a311ee2b5..7f4a869a944 100644
--- a/components/layout/flexbox/mod.rs
+++ b/components/layout/flexbox/mod.rs
@@ -105,8 +105,7 @@ impl FlexContainer {
contents: NonReplacedContents,
propagated_data: PropagatedBoxTreeData,
) -> Self {
- let mut builder =
- ModernContainerBuilder::new(context, info, propagated_data.union(&info.style));
+ let mut builder = ModernContainerBuilder::new(context, info, propagated_data);
contents.traverse(context, info, &mut builder);
let items = builder.finish();
diff --git a/components/layout/flow/construct.rs b/components/layout/flow/construct.rs
index 334da8ae2b0..cc3fe0e6f44 100644
--- a/components/layout/flow/construct.rs
+++ b/components/layout/flow/construct.rs
@@ -199,7 +199,7 @@ impl<'dom, 'style> BlockContainerBuilder<'dom, 'style> {
context,
info,
block_level_boxes: Vec::new(),
- propagated_data: propagated_data.union(&info.style),
+ propagated_data,
have_already_seen_first_line_for_text_indent: false,
anonymous_box_info: None,
anonymous_table_content: Vec::new(),
@@ -228,7 +228,6 @@ impl<'dom, 'style> BlockContainerBuilder<'dom, 'style> {
fn finish_ongoing_inline_formatting_context(&mut self) -> Option<InlineFormattingContext> {
self.inline_formatting_context_builder.take()?.finish(
self.context,
- self.propagated_data,
!self.have_already_seen_first_line_for_text_indent,
self.info.is_single_line_text_input(),
self.info.style.writing_mode.to_bidi_level(),
@@ -280,16 +279,6 @@ impl<'dom, 'style> BlockContainerBuilder<'dom, 'style> {
// creation of an inline table. It requires the parent to be an inline box.
let inline_table = self.currently_processing_inline_box();
- // Text decorations are not propagated to atomic inline-level descendants.
- // From https://drafts.csswg.org/css2/#lining-striking-props:
- // > Note that text decorations are not propagated to floating and absolutely
- // > positioned descendants, nor to the contents of atomic inline-level descendants
- // > such as inline blocks and inline tables.
- let propagated_data = match inline_table {
- true => self.propagated_data.without_text_decorations(),
- false => self.propagated_data,
- };
-
let contents: Vec<AnonymousTableContent<'dom>> =
self.anonymous_table_content.drain(..).collect();
let last_text = match contents.last() {
@@ -298,7 +287,7 @@ impl<'dom, 'style> BlockContainerBuilder<'dom, 'style> {
};
let (table_info, ifc) =
- Table::construct_anonymous(self.context, self.info, contents, propagated_data);
+ Table::construct_anonymous(self.context, self.info, contents, self.propagated_data);
if inline_table {
self.ensure_inline_formatting_context_builder()
@@ -315,7 +304,7 @@ impl<'dom, 'style> BlockContainerBuilder<'dom, 'style> {
info: table_info,
box_slot: BoxSlot::dummy(),
kind: BlockLevelCreator::AnonymousTable { table_block },
- propagated_data,
+ propagated_data: self.propagated_data,
});
}
@@ -464,7 +453,7 @@ impl<'dom> BlockContainerBuilder<'dom, '_> {
contents,
list_item_style,
},
- propagated_data: self.propagated_data.without_text_decorations(),
+ propagated_data: self.propagated_data,
});
}
@@ -480,15 +469,14 @@ impl<'dom> BlockContainerBuilder<'dom, '_> {
else {
// If this inline element is an atomic, handle it and return.
let context = self.context;
- let propagaged_data = self.propagated_data.without_text_decorations();
+ let propagated_data = self.propagated_data;
let atomic = self.ensure_inline_formatting_context_builder().push_atomic(
IndependentFormattingContext::construct(
context,
info,
display_inside,
contents,
- // Text decorations are not propagated to atomic inline-level descendants.
- propagaged_data,
+ propagated_data,
),
);
box_slot.set(LayoutBox::InlineLevel(vec![atomic]));
@@ -550,7 +538,6 @@ impl<'dom> BlockContainerBuilder<'dom, '_> {
.and_then(|builder| {
builder.split_around_block_and_finish(
self.context,
- self.propagated_data,
!self.have_already_seen_first_line_for_text_indent,
self.info.style.writing_mode.to_bidi_level(),
)
@@ -631,7 +618,7 @@ impl<'dom> BlockContainerBuilder<'dom, '_> {
info: info.clone(),
box_slot,
kind,
- propagated_data: self.propagated_data.without_text_decorations(),
+ propagated_data: self.propagated_data,
});
}
@@ -664,7 +651,7 @@ impl<'dom> BlockContainerBuilder<'dom, '_> {
info: info.clone(),
box_slot,
kind,
- propagated_data: self.propagated_data.without_text_decorations(),
+ propagated_data: self.propagated_data,
});
}
@@ -754,7 +741,7 @@ impl BlockLevelJob<'_> {
context,
info,
contents,
- self.propagated_data.without_text_decorations(),
+ self.propagated_data,
false, /* is_list_item */
);
ArcRefCell::new(BlockLevelBox::OutsideMarker(OutsideMarker {
diff --git a/components/layout/flow/float.rs b/components/layout/flow/float.rs
index f1ae2b4459a..bb6c7ca8983 100644
--- a/components/layout/flow/float.rs
+++ b/components/layout/flow/float.rs
@@ -897,8 +897,7 @@ impl FloatBox {
info,
display_inside,
contents,
- // Text decorations are not propagated to any out-of-flow descendants
- propagated_data.without_text_decorations(),
+ propagated_data,
),
}
}
diff --git a/components/layout/flow/inline/construct.rs b/components/layout/flow/inline/construct.rs
index 600da9b721a..07a2e914835 100644
--- a/components/layout/flow/inline/construct.rs
+++ b/components/layout/flow/inline/construct.rs
@@ -16,7 +16,6 @@ use super::{
InlineBox, InlineBoxIdentifier, InlineBoxes, InlineFormattingContext, InlineItem,
SharedInlineStyles,
};
-use crate::PropagatedBoxTreeData;
use crate::cell::ArcRefCell;
use crate::context::LayoutContext;
use crate::dom_traversal::NodeAndStyleInfo;
@@ -344,7 +343,6 @@ impl InlineFormattingContextBuilder {
pub(crate) fn split_around_block_and_finish(
&mut self,
layout_context: &LayoutContext,
- propagated_data: PropagatedBoxTreeData,
has_first_formatted_line: bool,
default_bidi_level: Level,
) -> Option<InlineFormattingContext> {
@@ -386,7 +384,6 @@ impl InlineFormattingContextBuilder {
inline_builder_from_before_split.finish(
layout_context,
- propagated_data,
has_first_formatted_line,
/* is_single_line_text_input = */ false,
default_bidi_level,
@@ -397,7 +394,6 @@ impl InlineFormattingContextBuilder {
pub(crate) fn finish(
self,
layout_context: &LayoutContext,
- propagated_data: PropagatedBoxTreeData,
has_first_formatted_line: bool,
is_single_line_text_input: bool,
default_bidi_level: Level,
@@ -410,7 +406,6 @@ impl InlineFormattingContextBuilder {
Some(InlineFormattingContext::new_with_builder(
self,
layout_context,
- propagated_data,
has_first_formatted_line,
is_single_line_text_input,
default_bidi_level,
diff --git a/components/layout/flow/inline/inline_box.rs b/components/layout/flow/inline/inline_box.rs
index b547f3b5935..a9642d3b222 100644
--- a/components/layout/flow/inline/inline_box.rs
+++ b/components/layout/flow/inline/inline_box.rs
@@ -256,13 +256,7 @@ impl InlineBoxContainerState {
}
Self {
- base: InlineContainerState::new(
- style,
- flags,
- Some(parent_container),
- parent_container.text_decoration_line,
- font_metrics,
- ),
+ base: InlineContainerState::new(style, flags, Some(parent_container), font_metrics),
identifier: inline_box.identifier,
base_fragment_info: inline_box.base.base_fragment_info,
pbm,
diff --git a/components/layout/flow/inline/line.rs b/components/layout/flow/inline/line.rs
index 3b92078d67d..14a1531883f 100644
--- a/components/layout/flow/inline/line.rs
+++ b/components/layout/flow/inline/line.rs
@@ -15,7 +15,6 @@ use style::values::generics::box_::{GenericVerticalAlign, VerticalAlignKeyword};
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 unicode_bidi::{BidiInfo, Level};
use webrender_api::FontInstanceKey;
@@ -572,7 +571,6 @@ impl LineItemLayout<'_, '_> {
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,
selection_range: text_item.selection_range,
})),
@@ -765,7 +763,6 @@ pub(super) struct TextRunLineItem {
pub text: Vec<std::sync::Arc<GlyphStore>>,
pub font_metrics: FontMetrics,
pub font_key: FontInstanceKey,
- pub text_decoration_line: TextDecorationLine,
/// The BiDi level of this [`TextRunLineItem`] to enable reordering.
pub bidi_level: Level,
pub selection_range: Option<Range<ByteIndex>>,
diff --git a/components/layout/flow/inline/mod.rs b/components/layout/flow/inline/mod.rs
index 74d42ca6fb4..6fd4a51a526 100644
--- a/components/layout/flow/inline/mod.rs
+++ b/components/layout/flow/inline/mod.rs
@@ -103,7 +103,7 @@ use style::properties::style_structs::InheritedText;
use style::values::generics::box_::VerticalAlignKeyword;
use style::values::generics::font::LineHeight;
use style::values::specified::box_::BaselineSource;
-use style::values::specified::text::{TextAlignKeyword, TextDecorationLine};
+use style::values::specified::text::TextAlignKeyword;
use style::values::specified::{TextAlignLast, TextJustify};
use text_run::{
TextRun, XI_LINE_BREAKING_CLASS_GL, XI_LINE_BREAKING_CLASS_WJ, XI_LINE_BREAKING_CLASS_ZWJ,
@@ -134,7 +134,7 @@ use crate::geom::{LogicalRect, LogicalVec2, ToLogical};
use crate::positioned::{AbsolutelyPositionedBox, PositioningContext};
use crate::sizing::{ComputeInlineContentSizes, ContentSizes, InlineContentSizesResult};
use crate::style_ext::{ComputedValuesExt, PaddingBorderMargin};
-use crate::{ConstraintSpace, ContainingBlock, PropagatedBoxTreeData, SharedStyle};
+use crate::{ConstraintSpace, ContainingBlock, SharedStyle};
// From gfxFontConstants.h in Firefox.
static FONT_SUBSCRIPT_OFFSET_RATIO: f32 = 0.20;
@@ -163,8 +163,6 @@ pub(crate) struct InlineFormattingContext {
/// share styles with all [`TextRun`] children.
pub(super) shared_inline_styles: SharedInlineStyles,
- pub(super) text_decoration_line: TextDecorationLine,
-
/// Whether this IFC contains the 1st formatted line of an element:
/// <https://www.w3.org/TR/css-pseudo-4/#first-formatted-line>.
pub(super) has_first_formatted_line: bool,
@@ -628,12 +626,6 @@ pub(super) struct InlineContainerState {
/// this inline box on the current line OR any previous line.
has_content: RefCell<bool>,
- /// Indicates whether this nesting level have text decorations in effect.
- /// From <https://drafts.csswg.org/css-text-decor/#line-decoration>
- // "When specified on or propagated to a block container that establishes
- // an IFC..."
- text_decoration_line: TextDecorationLine,
-
/// The block size contribution of this container's default font ie the size of the
/// "strut." Whether this is integrated into the [`Self::nested_strut_block_sizes`]
/// depends on the line-height quirk described in
@@ -1461,7 +1453,6 @@ impl InlineFormattingContextLayout<'_> {
inline_styles: text_run.inline_styles.clone(),
font_metrics,
font_key: ifc_font_info.key,
- text_decoration_line: self.current_inline_container_state().text_decoration_line,
bidi_level,
selection_range,
},
@@ -1655,7 +1646,6 @@ impl InlineFormattingContext {
pub(super) fn new_with_builder(
builder: InlineFormattingContextBuilder,
layout_context: &LayoutContext,
- propagated_data: PropagatedBoxTreeData,
has_first_formatted_line: bool,
is_single_line_text_input: bool,
starting_bidi_level: Level,
@@ -1711,7 +1701,6 @@ impl InlineFormattingContext {
.last()
.expect("Should have at least one SharedInlineStyle for the root of an IFC")
.clone(),
- text_decoration_line: propagated_data.text_decoration,
has_first_formatted_line,
contains_floats: builder.contains_floats,
is_single_line_text_input,
@@ -1781,7 +1770,6 @@ impl InlineFormattingContext {
style.to_arc(),
inline_container_state_flags,
None, /* parent_container */
- self.text_decoration_line,
default_font_metrics.as_ref(),
),
inline_box_state_stack: Vec::new(),
@@ -1879,10 +1867,8 @@ impl InlineContainerState {
style: Arc<ComputedValues>,
flags: InlineContainerStateFlags,
parent_container: Option<&InlineContainerState>,
- parent_text_decoration_line: TextDecorationLine,
font_metrics: Option<&FontMetrics>,
) -> Self {
- let text_decoration_line = parent_text_decoration_line | style.clone_text_decoration_line();
let font_metrics = font_metrics.cloned().unwrap_or_else(FontMetrics::empty);
let line_height = line_height(
&style,
@@ -1919,7 +1905,6 @@ impl InlineContainerState {
style,
flags,
has_content: RefCell::new(false),
- text_decoration_line,
nested_strut_block_sizes: nested_block_sizes,
strut_block_sizes,
baseline_offset,
diff --git a/components/layout/flow/root.rs b/components/layout/flow/root.rs
index a37db54065d..8ad3671032e 100644
--- a/components/layout/flow/root.rs
+++ b/components/layout/flow/root.rs
@@ -314,7 +314,7 @@ fn construct_for_root_element(
let contents = ReplacedContents::for_element(root_element, context)
.map_or_else(|| NonReplacedContents::OfElement.into(), Contents::Replaced);
- let propagated_data = PropagatedBoxTreeData::default().union(&info.style);
+ let propagated_data = PropagatedBoxTreeData::default();
let root_box = if box_style.position.is_absolutely_positioned() {
BlockLevelBox::OutOfFlowAbsolutelyPositionedBox(ArcRefCell::new(
AbsolutelyPositionedBox::construct(context, &info, display_inside, contents),
diff --git a/components/layout/fragment_tree/fragment.rs b/components/layout/fragment_tree/fragment.rs
index 1ebc7b3c989..c81fd59e36b 100644
--- a/components/layout/fragment_tree/fragment.rs
+++ b/components/layout/fragment_tree/fragment.rs
@@ -14,7 +14,6 @@ use range::Range as ServoRange;
use servo_arc::Arc as ServoArc;
use style::Zero;
use style::properties::ComputedValues;
-use style::values::specified::text::TextDecorationLine;
use webrender_api::{FontInstanceKey, ImageKey};
use super::{
@@ -72,9 +71,6 @@ pub(crate) struct TextFragment {
#[conditional_malloc_size_of]
pub glyphs: Vec<Arc<GlyphStore>>,
- /// A flag that represents the _used_ value of the text-decoration property.
- pub text_decoration_line: TextDecorationLine,
-
/// Extra space to add for each justification opportunity.
pub justification_adjustment: Au,
pub selection_range: Option<ServoRange<ByteIndex>>,
diff --git a/components/layout/layout_impl.rs b/components/layout/layout_impl.rs
index b490b4a0506..8162ed1dd0b 100644
--- a/components/layout/layout_impl.rs
+++ b/components/layout/layout_impl.rs
@@ -773,7 +773,7 @@ impl LayoutThread {
let root_node = root_element.as_node();
let damage = compute_damage_and_repair_style(layout_context.shared_context(), root_node);
- if damage == RestyleDamage::REPAINT {
+ if damage.is_empty() || damage == RestyleDamage::REPAINT {
layout_context.style_context.stylist.rule_tree().maybe_gc();
return false;
}
diff --git a/components/layout/lib.rs b/components/layout/lib.rs
index cd992387277..ea254723dcb 100644
--- a/components/layout/lib.rs
+++ b/components/layout/lib.rs
@@ -41,7 +41,6 @@ use malloc_size_of_derive::MallocSizeOf;
use servo_arc::Arc as ServoArc;
use style::logical_geometry::WritingMode;
use style::properties::ComputedValues;
-use style::values::computed::TextDecorationLine;
use crate::geom::{LogicalVec2, SizeConstraint};
use crate::style_ext::AspectRatio;
@@ -163,39 +162,20 @@ impl<'a> From<&'_ DefiniteContainingBlock<'a>> for ContainingBlock<'a> {
/// propoagation, but only during `BoxTree` construction.
#[derive(Clone, Copy, Debug)]
struct PropagatedBoxTreeData {
- text_decoration: TextDecorationLine,
allow_percentage_column_in_tables: bool,
}
impl Default for PropagatedBoxTreeData {
fn default() -> Self {
Self {
- text_decoration: Default::default(),
allow_percentage_column_in_tables: true,
}
}
}
impl PropagatedBoxTreeData {
- pub(crate) fn union(&self, style: &ComputedValues) -> Self {
- Self {
- // FIXME(#31736): This is only taking into account the line style and not the decoration
- // color. This should collect information about both so that they can be rendered properly.
- text_decoration: self.text_decoration | style.clone_text_decoration_line(),
- allow_percentage_column_in_tables: self.allow_percentage_column_in_tables,
- }
- }
-
- pub(crate) fn without_text_decorations(&self) -> Self {
- Self {
- text_decoration: TextDecorationLine::NONE,
- allow_percentage_column_in_tables: self.allow_percentage_column_in_tables,
- }
- }
-
fn disallowing_percentage_table_columns(&self) -> PropagatedBoxTreeData {
Self {
- text_decoration: self.text_decoration,
allow_percentage_column_in_tables: false,
}
}
diff --git a/components/layout/table/construct.rs b/components/layout/table/construct.rs
index 0c238073df2..0b22ea1c13a 100644
--- a/components/layout/table/construct.rs
+++ b/components/layout/table/construct.rs
@@ -81,12 +81,7 @@ impl Table {
contents: NonReplacedContents,
propagated_data: PropagatedBoxTreeData,
) -> Self {
- let mut traversal = TableBuilderTraversal::new(
- context,
- info,
- grid_style,
- propagated_data.union(&info.style),
- );
+ let mut traversal = TableBuilderTraversal::new(context, info, grid_style, propagated_data);
contents.traverse(context, info, &mut traversal);
traversal.finish()
}
@@ -771,9 +766,6 @@ impl<'dom> TraversalHandler<'dom> for TableBuilderTraversal<'_, 'dom> {
});
self.builder.table.row_groups.push(row_group.clone());
- let previous_propagated_data = self.current_propagated_data;
- self.current_propagated_data = self.current_propagated_data.union(&info.style);
-
let new_row_group_index = self.builder.table.row_groups.len() - 1;
self.current_row_group_index = Some(new_row_group_index);
@@ -785,7 +777,6 @@ impl<'dom> TraversalHandler<'dom> for TableBuilderTraversal<'_, 'dom> {
self.finish_anonymous_row_if_needed();
self.current_row_group_index = None;
- self.current_propagated_data = previous_propagated_data;
self.builder.incoming_rowspans.clear();
box_slot.set(LayoutBox::TableLevelBox(TableLevelBox::TrackGroup(
@@ -936,7 +927,7 @@ impl<'style, 'builder, 'dom, 'a> TableRowBuilder<'style, 'builder, 'dom, 'a> {
table_traversal,
info,
current_anonymous_cell_content: Vec::new(),
- propagated_data: propagated_data.union(&info.style),
+ propagated_data,
}
}
diff --git a/components/layout/taffy/mod.rs b/components/layout/taffy/mod.rs
index 2bc7a598d08..05fc09c5511 100644
--- a/components/layout/taffy/mod.rs
+++ b/components/layout/taffy/mod.rs
@@ -36,8 +36,7 @@ impl TaffyContainer {
contents: NonReplacedContents,
propagated_data: PropagatedBoxTreeData,
) -> Self {
- let mut builder =
- ModernContainerBuilder::new(context, info, propagated_data.union(&info.style));
+ let mut builder = ModernContainerBuilder::new(context, info, propagated_data);
contents.traverse(context, info, &mut builder);
let items = builder.finish();
diff --git a/components/layout/traversal.rs b/components/layout/traversal.rs
index d05deb24bfa..faf25dc170d 100644
--- a/components/layout/traversal.rs
+++ b/components/layout/traversal.rs
@@ -105,7 +105,9 @@ pub(crate) fn compute_damage_and_repair_style_inner(
parent_restyle_damage: RestyleDamage,
) -> RestyleDamage {
let original_damage;
- let damage = {
+ let damage;
+
+ {
let mut element_data = node
.style_data()
.expect("Should not run `compute_damage` before styling.")
@@ -113,14 +115,14 @@ pub(crate) fn compute_damage_and_repair_style_inner(
.borrow_mut();
original_damage = std::mem::take(&mut element_data.damage);
+ damage = original_damage | parent_restyle_damage;
+
if let Some(ref style) = element_data.styles.primary {
if style.get_box().display == Display::None {
- return parent_restyle_damage;
+ return damage;
}
}
-
- original_damage | parent_restyle_damage
- };
+ }
let mut propagated_damage = damage;
for child in iter_child_nodes(node) {