diff --git a/components/layout_2020/display_list/mod.rs b/components/layout_2020/display_list/mod.rs index f85d0308d72..ebdfd07a4fa 100644 --- a/components/layout_2020/display_list/mod.rs +++ b/components/layout_2020/display_list/mod.rs @@ -17,6 +17,7 @@ use style::computed_values::text_decoration_style::T as ComputedTextDecorationSt use style::dom::OpaqueNode; use style::properties::ComputedValues; use style::values::computed::{BorderStyle, Length, LengthPercentage}; +use style::values::specified::text::TextDecorationLine; use style::values::specified::ui::CursorKind; use webrender_api::{self as wr, units}; @@ -128,14 +129,13 @@ impl Fragment { common.hit_info = hit_info(&fragment.parent_style, fragment.tag, Cursor::Text); let color = fragment.parent_style.clone_color(); - let text_decorations = fragment - .parent_style - .get_inherited_text() - .text_decorations_in_effect; let font_metrics = &fragment.font_metrics; // Underline. - if text_decorations.underline { + if fragment + .text_decorations_in_effect + .contains(TextDecorationLine::UNDERLINE) + { let mut rect = rect; rect.origin.y = rect.origin.y + font_metrics.ascent - font_metrics.underline_offset; rect.size.height = font_metrics.underline_size; @@ -143,7 +143,10 @@ impl Fragment { } // Overline. - if text_decorations.overline { + if fragment + .text_decorations_in_effect + .contains(TextDecorationLine::OVERLINE) + { let mut rect = rect; rect.size.height = font_metrics.underline_size; self.build_display_list_for_text_decoration(fragment, builder, &rect, color); @@ -160,7 +163,10 @@ impl Fragment { ); // Line-through. - if text_decorations.line_through { + if fragment + .text_decorations_in_effect + .contains(TextDecorationLine::LINE_THROUGH) + { let mut rect = rect; rect.origin.y = rect.origin.y + font_metrics.ascent - font_metrics.strikeout_offset; // XXX(ferjm) This does not work on MacOS #942 diff --git a/components/layout_2020/flow/inline.rs b/components/layout_2020/flow/inline.rs index 05e16457fcb..acd6795d639 100644 --- a/components/layout_2020/flow/inline.rs +++ b/components/layout_2020/flow/inline.rs @@ -26,6 +26,7 @@ use style::dom::OpaqueNode; use style::properties::ComputedValues; use style::values::computed::{Length, LengthPercentage, Percentage}; use style::values::specified::text::TextAlignKeyword; +use style::values::specified::text::TextDecorationLine; use style::Zero; use webrender_api::FontInstanceKey; @@ -385,6 +386,18 @@ impl Lines { block: line_block_size, }; self.next_line_block_position += size.block; + + // From https://drafts.csswg.org/css-text-decor/#line-decoration + // "When specified on or propagated to an inline box, + // that box becomes a decorating box for that decoration, + // applying the decoration to all its fragments..." + let text_decoration_line = containing_block.style.clone_text_decoration_line(); + if text_decoration_line != TextDecorationLine::NONE { + for fragment in &mut line_contents { + fragment.set_text_decorations_in_effect(text_decoration_line); + } + } + self.fragments .push(Fragment::Anonymous(AnonymousFragment::new( Rect { start_corner, size }, @@ -775,6 +788,7 @@ impl TextRun { font_metrics, font_key, glyphs, + text_decorations_in_effect: TextDecorationLine::NONE, })); if runs.is_empty() { break; diff --git a/components/layout_2020/fragments.rs b/components/layout_2020/fragments.rs index 5a2a59c8b53..cfe2a913847 100644 --- a/components/layout_2020/fragments.rs +++ b/components/layout_2020/fragments.rs @@ -19,6 +19,7 @@ use style::dom::OpaqueNode; use style::logical_geometry::WritingMode; use style::properties::ComputedValues; use style::values::computed::Length; +use style::values::specified::text::TextDecorationLine; use style::Zero; use webrender_api::{FontInstanceKey, ImageKey}; @@ -121,6 +122,8 @@ pub(crate) struct TextFragment { #[serde(skip_serializing)] pub font_key: FontInstanceKey, pub glyphs: Vec>, + /// A flag that represents the _used_ value of the text-decoration property. + pub text_decorations_in_effect: TextDecorationLine, } #[derive(Serialize)] @@ -192,6 +195,23 @@ impl AbsoluteOrFixedPositionedFragment { pub fn print(&self, tree: &mut PrintTree) { tree.add_item(format!("AbsoluteOrFixedPositionedFragment({:?})", self.0)); } + + pub fn set_text_decorations_in_effect(&mut self, text_decorations: TextDecorationLine) { + match self { + Fragment::Text(fragment) => fragment.text_decorations_in_effect = text_decorations, + Fragment::Box(fragment) => { + for child in &mut fragment.children { + child.set_text_decorations_in_effect(text_decorations); + } + }, + Fragment::Anonymous(fragment) => { + for child in &mut fragment.children { + child.set_text_decorations_in_effect(text_decorations); + } + }, + _ => (), + } + } } impl AnonymousFragment { diff --git a/components/style/values/specified/text.rs b/components/style/values/specified/text.rs index 438b926802f..e54fbeeb2fb 100644 --- a/components/style/values/specified/text.rs +++ b/components/style/values/specified/text.rs @@ -217,7 +217,7 @@ impl ToComputedValue for TextOverflow { } bitflags! { - #[derive(MallocSizeOf, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)] + #[derive(MallocSizeOf, Serialize, SpecifiedValueInfo, ToComputedValue, ToResolvedValue, ToShmem)] #[value_info(other_values = "none,underline,overline,line-through,blink")] #[repr(C)] /// Specified keyword values for the text-decoration-line property.