diff --git a/components/layout/display_list/builder.rs b/components/layout/display_list/builder.rs index 780ca9e9607..74e324fbe03 100644 --- a/components/layout/display_list/builder.rs +++ b/components/layout/display_list/builder.rs @@ -2172,9 +2172,8 @@ impl FragmentDisplayListBuilding for Fragment { } // Create display items for text decorations. - let text_decorations = self.style() - .get_inheritedtext() - ._servo_text_decorations_in_effect; + let text_decorations = + self.style().get_inheritedtext().text_decorations_in_effect; let stacking_relative_content_box = LogicalRect::from_physical( self.style.writing_mode, diff --git a/components/style/properties/longhand/box.mako.rs b/components/style/properties/longhand/box.mako.rs index 62dea66052d..d1b26de1154 100644 --- a/components/style/properties/longhand/box.mako.rs +++ b/components/style/properties/longhand/box.mako.rs @@ -20,8 +20,6 @@ ${helpers.predefined_type( initial_specified_value="specified::Display::inline()", animation_value_type="discrete", needs_context=False, - custom_cascade= product == 'servo', - custom_cascade_function="specified::Display::cascade_property_custom", flags="APPLIES_TO_PLACEHOLDER", spec="https://drafts.csswg.org/css-display/#propdef-display", )} diff --git a/components/style/properties/longhand/inherited_text.mako.rs b/components/style/properties/longhand/inherited_text.mako.rs index 830886a9569..a9ae76fe9a3 100644 --- a/components/style/properties/longhand/inherited_text.mako.rs +++ b/components/style/properties/longhand/inherited_text.mako.rs @@ -132,68 +132,6 @@ ${helpers.predefined_type("word-spacing", flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", spec="https://drafts.csswg.org/css-text/#propdef-word-spacing")} -<%helpers:longhand name="-servo-text-decorations-in-effect" - derived_from="display text-decoration" - products="servo" - animation_value_type="none" - spec="Nonstandard (Internal property used by Servo)"> - use std::fmt; - use style_traits::ToCss; - - #[derive(Clone, Copy, Debug, Default, MallocSizeOf, PartialEq)] - pub struct SpecifiedValue { - pub underline: bool, - pub overline: bool, - pub line_through: bool, - } - - trivial_to_computed_value!(SpecifiedValue); - - pub mod computed_value { - pub type T = super::SpecifiedValue; - } - - impl ToCss for SpecifiedValue { - fn to_css(&self, _: &mut W) -> fmt::Result where W: fmt::Write { - // Web compat doesn't matter here. - Ok(()) - } - } - - #[inline] - pub fn get_initial_value() -> computed_value::T { - SpecifiedValue::default() - } - - fn derive(context: &Context) -> computed_value::T { - // Start with no declarations if this is an atomic inline-level box; otherwise, start with the - // declarations in effect and add in the text decorations that this block specifies. - let mut result = match context.style().get_box().clone_display() { - super::display::computed_value::T::InlineBlock | - super::display::computed_value::T::InlineTable => get_initial_value(), - _ => context.builder.get_parent_inheritedtext().clone__servo_text_decorations_in_effect() - }; - - result.underline |= context.style().get_text().has_underline(); - result.overline |= context.style().get_text().has_overline(); - result.line_through |= context.style().get_text().has_line_through(); - - result - } - - #[inline] - pub fn derive_from_text_decoration(context: &mut Context) { - let derived = derive(context); - context.builder.set__servo_text_decorations_in_effect(derived); - } - - #[inline] - pub fn derive_from_display(context: &mut Context) { - let derived = derive(context); - context.builder.set__servo_text_decorations_in_effect(derived); - } - - <%helpers:single_keyword_computed name="white-space" values="normal pre nowrap pre-wrap pre-line" extra_gecko_values="-moz-pre-space" diff --git a/components/style/properties/longhand/text.mako.rs b/components/style/properties/longhand/text.mako.rs index fed1ce65c80..2c8bf1b52ff 100644 --- a/components/style/properties/longhand/text.mako.rs +++ b/components/style/properties/longhand/text.mako.rs @@ -29,8 +29,6 @@ ${helpers.predefined_type("text-decoration-line", "TextDecorationLine", "specified::TextDecorationLine::none()", initial_specified_value="specified::TextDecorationLine::none()", - custom_cascade= product == 'servo', - custom_cascade_function="specified::TextDecorationLine::cascade_property_custom", animation_value_type="discrete", flags="APPLIES_TO_FIRST_LETTER APPLIES_TO_FIRST_LINE APPLIES_TO_PLACEHOLDER", spec="https://drafts.csswg.org/css-text-decor/#propdef-text-decoration-line")} diff --git a/components/style/properties/properties.mako.rs b/components/style/properties/properties.mako.rs index c75fd6db958..84be9763490 100644 --- a/components/style/properties/properties.mako.rs +++ b/components/style/properties/properties.mako.rs @@ -1859,6 +1859,13 @@ pub mod style_structs { /// The ${longhand.name} computed value. pub ${longhand.ident}: longhands::${longhand.ident}::computed_value::T, % endfor + % if style_struct.name == "InheritedText": + /// The "used" text-decorations that apply to this box. + /// + /// FIXME(emilio): This is technically a box-tree concept, and + /// would be nice to move away from style. + pub text_decorations_in_effect: ::values::computed::text::TextDecorationsInEffect, + % endif % if style_struct.name == "Font": /// The font hash, used for font caching. pub hash: u64, @@ -1870,9 +1877,8 @@ pub mod style_structs { % endif } % if style_struct.name == "Font": - - impl PartialEq for ${style_struct.name} { - fn eq(&self, other: &${style_struct.name}) -> bool { + impl PartialEq for Font { + fn eq(&self, other: &Font) -> bool { self.hash == other.hash % for longhand in style_struct.longhands: && self.${longhand.ident} == other.${longhand.ident} @@ -3074,6 +3080,9 @@ mod lazy_static_module { % for longhand in style_struct.longhands: ${longhand.ident}: longhands::${longhand.ident}::get_initial_value(), % endfor + % if style_struct.name == "InheritedText": + text_decorations_in_effect: ::values::computed::text::TextDecorationsInEffect::default(), + % endif % if style_struct.name == "Font": hash: 0, % endif diff --git a/components/style/servo/restyle_damage.rs b/components/style/servo/restyle_damage.rs index 68a1145cbd9..f3bb6ef3d63 100644 --- a/components/style/servo/restyle_damage.rs +++ b/components/style/servo/restyle_damage.rs @@ -280,7 +280,7 @@ fn compute_damage(old: &ComputedValues, new: &ComputedValues) -> ServoRestyleDam get_border.border_top_left_radius, get_border.border_top_right_radius, get_border.border_bottom_left_radius, get_border.border_bottom_right_radius, get_position.z_index, get_box._servo_overflow_clip_box, - get_inheritedtext._servo_text_decorations_in_effect, + get_inheritedtext.text_decorations_in_effect, get_pointing.cursor, get_pointing.pointer_events, get_effects.box_shadow, get_effects.clip, get_inheritedtext.text_shadow, get_effects.filter, get_effects.mix_blend_mode, get_inheritedbox.image_rendering, diff --git a/components/style/style_adjuster.rs b/components/style/style_adjuster.rs index c54191b14c7..052d80dbe22 100644 --- a/components/style/style_adjuster.rs +++ b/components/style/style_adjuster.rs @@ -420,6 +420,21 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { } } + /// Computes the used text decoration for Servo. + /// + /// FIXME(emilio): This is a layout tree concept, should move away from + /// style, since otherwise we're going to have the same subtle bugs WebKit + /// and Blink have with this very same thing. + #[cfg(feature = "servo")] + fn adjust_for_text_decorations_in_effect(&mut self) { + use values::computed::text::TextDecorationsInEffect; + + let decorations_in_effect = TextDecorationsInEffect::from_style(&self.style); + if self.style.get_inheritedtext().text_decorations_in_effect != decorations_in_effect { + self.style.mutate_inheritedtext().text_decorations_in_effect = decorations_in_effect; + } + } + #[cfg(feature = "gecko")] fn should_suppress_linebreak( &self, @@ -614,6 +629,10 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { { self.adjust_for_ruby(layout_parent_style, flags); } + #[cfg(feature = "servo")] + { + self.adjust_for_text_decorations_in_effect(); + } self.set_bits(); } } diff --git a/components/style/values/computed/text.rs b/components/style/values/computed/text.rs index bb849b813f9..27c198a46a5 100644 --- a/components/style/values/computed/text.rs +++ b/components/style/values/computed/text.rs @@ -4,6 +4,8 @@ //! Computed types for text properties. +#[cfg(feature = "servo")] +use properties::StyleBuilder; use std::fmt; use style_traits::ToCss; use values::{CSSInteger, CSSFloat}; @@ -103,3 +105,45 @@ impl ToCss for TextDecorationLine { Ok(()) } } + +/// A struct that represents the _used_ value of the text-decoration property. +/// +/// FIXME(emilio): This is done at style resolution time, though probably should +/// be done at layout time, otherwise we need to account for display: contents +/// and similar stuff when we implement it. +/// +/// FIXME(emilio): Also, should be just a bitfield instead of three bytes. +#[derive(Clone, Copy, Debug, Default, MallocSizeOf, PartialEq)] +pub struct TextDecorationsInEffect { + /// Whether an underline is in effect. + pub underline: bool, + /// Whether an overline decoration is in effect. + pub overline: bool, + /// Whether a line-through style is in effect. + pub line_through: bool, +} + +impl TextDecorationsInEffect { + /// Computes the text-decorations in effect for a given style. + #[cfg(feature = "servo")] + pub fn from_style(style: &StyleBuilder) -> Self { + use values::computed::Display; + + // Start with no declarations if this is an atomic inline-level box; + // otherwise, start with the declarations in effect and add in the text + // decorations that this block specifies. + let mut result = match style.get_box().clone_display() { + Display::InlineBlock | + Display::InlineTable => Self::default(), + _ => style.get_parent_inheritedtext().text_decorations_in_effect.clone(), + }; + + let text_style = style.get_text(); + + result.underline |= text_style.has_underline(); + result.overline |= text_style.has_overline(); + result.line_through |= text_style.has_line_through(); + + result + } +} diff --git a/components/style/values/specified/box.rs b/components/style/values/specified/box.rs index a141855d62f..8f046887fe4 100644 --- a/components/style/values/specified/box.rs +++ b/components/style/values/specified/box.rs @@ -7,15 +7,11 @@ use Atom; use cssparser::Parser; use parser::{Parse, ParserContext}; -#[cfg(feature = "servo")] -use properties::{longhands, PropertyDeclaration}; use selectors::parser::SelectorParseErrorKind; use std::fmt; use style_traits::{ParseError, ToCss, StyleParseErrorKind}; use values::CustomIdent; use values::KeyframesName; -#[cfg(feature = "servo")] -use values::computed::Context; use values::generics::box_::AnimationIterationCount as GenericAnimationIterationCount; use values::generics::box_::VerticalAlign as GenericVerticalAlign; use values::specified::{AllowQuirks, Number}; @@ -220,16 +216,6 @@ impl Display { other => other, } } - - #[cfg(feature = "servo")] - #[inline] - /// Custom cascade for the `display` property in servo - pub fn cascade_property_custom( - _declaration: &PropertyDeclaration, - context: &mut Context - ) { - longhands::_servo_text_decorations_in_effect::derive_from_display(context); - } } /// A specified value for the `vertical-align` property. diff --git a/components/style/values/specified/text.rs b/components/style/values/specified/text.rs index caca98ab3f2..d9e05b50057 100644 --- a/components/style/values/specified/text.rs +++ b/components/style/values/specified/text.rs @@ -6,8 +6,6 @@ use cssparser::{Parser, Token}; use parser::{Parse, ParserContext}; -#[cfg(feature = "servo")] -use properties::{longhands, PropertyDeclaration}; use selectors::parser::SelectorParseErrorKind; #[allow(unused_imports)] use std::ascii::AsciiExt; use std::fmt; @@ -281,13 +279,6 @@ impl TextDecorationLine { pub fn none() -> Self { TextDecorationLine::NONE } - - #[cfg(feature = "servo")] - #[inline] - /// Custom cascade for the text-decoration-line property in servo - pub fn cascade_property_custom(_declaration: &PropertyDeclaration, context: &mut Context) { - longhands::_servo_text_decorations_in_effect::derive_from_text_decoration(context); - } } impl Parse for TextDecorationLine {