Bug 1341775 - Part 4: stylo: Special-case initial-computation of font-size; r?heycam
MozReview-Commit-ID: Ff6kt8RLChI
--- a/servo/components/style/properties/gecko.mako.rs
+++ b/servo/components/style/properties/gecko.mako.rs
@@ -75,60 +75,65 @@ pub struct ComputedValues {
% for style_struct in data.style_structs:
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
% endfor
custom_properties: Option<Arc<ComputedValuesMap>>,
shareable: bool,
pub writing_mode: WritingMode,
pub root_font_size: Au,
+ pub font_size_keyword: Option<longhands::font_size::KeywordSize>,
}
impl ComputedValues {
pub fn inherit_from(parent: &Self, default: &Self) -> Arc<Self> {
Arc::new(ComputedValues {
custom_properties: parent.custom_properties.clone(),
shareable: parent.shareable,
writing_mode: parent.writing_mode,
root_font_size: parent.root_font_size,
+ font_size_keyword: parent.font_size_keyword,
% for style_struct in data.style_structs:
% if style_struct.inherited:
${style_struct.ident}: parent.${style_struct.ident}.clone(),
% else:
${style_struct.ident}: default.${style_struct.ident}.clone(),
% endif
% endfor
})
}
pub fn new(custom_properties: Option<Arc<ComputedValuesMap>>,
shareable: bool,
writing_mode: WritingMode,
root_font_size: Au,
+ font_size_keyword: Option<longhands::font_size::KeywordSize>,
% for style_struct in data.style_structs:
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
% endfor
) -> Self {
ComputedValues {
custom_properties: custom_properties,
shareable: shareable,
writing_mode: writing_mode,
root_font_size: root_font_size,
+ font_size_keyword: font_size_keyword,
% for style_struct in data.style_structs:
${style_struct.ident}: ${style_struct.ident},
% endfor
}
}
pub fn default_values(pres_context: RawGeckoPresContextBorrowed) -> Arc<Self> {
Arc::new(ComputedValues {
custom_properties: None,
shareable: true,
writing_mode: WritingMode::empty(), // FIXME(bz): This seems dubious
root_font_size: longhands::font_size::get_initial_value(), // FIXME(bz): Also seems dubious?
+ font_size_keyword: Some(Default::default()),
% for style_struct in data.style_structs:
${style_struct.ident}: style_structs::${style_struct.name}::default(pres_context),
% endfor
})
}
#[inline]
pub fn is_display_contents(&self) -> bool {
--- a/servo/components/style/properties/helpers.mako.rs
+++ b/servo/components/style/properties/helpers.mako.rs
@@ -261,50 +261,70 @@
}
% if property.logical:
let wm = context.style.writing_mode;
% endif
<% maybe_wm = ", wm" if property.logical else "" %>
match *value {
DeclaredValue::Value(ref specified_value) => {
let computed = specified_value.to_computed_value(context);
+ % if property.ident == "font_size":
+ if let longhands::font_size::SpecifiedValue::Keyword(kw) = **specified_value {
+ context.mutate_style().font_size_keyword = Some(kw);
+ } else {
+ context.mutate_style().font_size_keyword = None;
+ }
+ % endif
% if property.has_uncacheable_values:
context.mutate_style().mutate_${data.current_style_struct.name_lower}()
.set_${property.ident}(computed, cacheable ${maybe_wm});
% else:
context.mutate_style().mutate_${data.current_style_struct.name_lower}()
.set_${property.ident}(computed ${maybe_wm});
% endif
}
DeclaredValue::WithVariables(_) => unreachable!(),
DeclaredValue::CSSWideKeyword(keyword) => match keyword {
% if not data.current_style_struct.inherited:
CSSWideKeyword::Unset |
% endif
CSSWideKeyword::Initial => {
- // We assume that it's faster to use copy_*_from rather than
- // set_*(get_initial_value());
- let initial_struct = default_style
- .get_${data.current_style_struct.name_lower}();
- context.mutate_style().mutate_${data.current_style_struct.name_lower}()
- .copy_${property.ident}_from(initial_struct ${maybe_wm});
+ % if property.ident == "font_size":
+ // font-size's default ("medium") does not always
+ // compute to the same value and depends on the font
+ let computed = longhands::font_size::get_initial_specified_value()
+ .to_computed_value(context);
+ context.mutate_style().mutate_${data.current_style_struct.name_lower}()
+ .set_font_size(computed);
+ context.mutate_style().font_size_keyword = Some(Default::default());
+ % else:
+ // We assume that it's faster to use copy_*_from rather than
+ // set_*(get_initial_value());
+ let initial_struct = default_style
+ .get_${data.current_style_struct.name_lower}();
+ context.mutate_style().mutate_${data.current_style_struct.name_lower}()
+ .copy_${property.ident}_from(initial_struct ${maybe_wm});
+ % endif
},
% if data.current_style_struct.inherited:
CSSWideKeyword::Unset |
% endif
CSSWideKeyword::Inherit => {
// This is a bit slow, but this is rare so it shouldn't
// matter.
//
// FIXME: is it still?
*cacheable = false;
let inherited_struct =
inherited_style.get_${data.current_style_struct.name_lower}();
context.mutate_style().mutate_${data.current_style_struct.name_lower}()
.copy_${property.ident}_from(inherited_struct ${maybe_wm});
+ % if property.ident == "font_size":
+ context.mutate_style().font_size_keyword = context.inherited_style.font_size_keyword;
+ % endif
}
}
}
}, error_reporter);
}
% if property.custom_cascade:
cascade_property_custom(declaration,
--- a/servo/components/style/properties/longhand/font.mako.rs
+++ b/servo/components/style/properties/longhand/font.mako.rs
@@ -460,16 +460,22 @@
"large" => Large,
"x-large" => XLarge,
"xx-large" => XXLarge,
_ => return Err(())
})
}
}
+ impl Default for KeywordSize {
+ fn default() -> Self {
+ Medium
+ }
+ }
+
impl ToCss for KeywordSize {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
dest.write_str(match *self {
XXSmall => "xx-small",
XSmall => "x-small",
Small => "small",
Medium => "medium",
Large => "large",
--- a/servo/components/style/properties/properties.mako.rs
+++ b/servo/components/style/properties/properties.mako.rs
@@ -1497,34 +1497,38 @@ pub struct ComputedValues {
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
% endfor
custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
shareable: bool,
/// The writing mode of this computed values struct.
pub writing_mode: WritingMode,
/// The root element's computed font size.
pub root_font_size: Au,
+ /// The keyword behind the current font-size property, if any
+ pub font_size_keyword: Option<longhands::font_size::KeywordSize>,
}
#[cfg(feature = "servo")]
impl ComputedValues {
/// Construct a `ComputedValues` instance.
pub fn new(custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
shareable: bool,
writing_mode: WritingMode,
root_font_size: Au,
+ font_size_keyword: Option<longhands::font_size::KeywordSize>,
% for style_struct in data.active_style_structs():
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
% endfor
) -> Self {
ComputedValues {
custom_properties: custom_properties,
shareable: shareable,
writing_mode: writing_mode,
root_font_size: root_font_size,
+ font_size_keyword: font_size_keyword,
% for style_struct in data.active_style_structs():
${style_struct.ident}: ${style_struct.ident},
% endfor
}
}
/// Get the initial computed values.
pub fn initial_values() -> &'static Self { &*INITIAL_SERVO_VALUES }
@@ -1838,16 +1842,17 @@ mod lazy_static_module {
hash: 0,
% endif
}),
% endfor
custom_properties: None,
shareable: true,
writing_mode: WritingMode::empty(),
root_font_size: longhands::font_size::get_initial_value(),
+ font_size_keyword: Some(Default::default()),
};
}
}
/// A per-longhand function that performs the CSS cascade for that longhand.
pub type CascadePropertyFn =
extern "Rust" fn(declaration: &PropertyDeclaration,
inherited_style: &ComputedValues,
@@ -1979,29 +1984,31 @@ pub fn apply_declarations<'a, F, I>(devi
::custom_properties::finish_cascade(
custom_properties, &inherited_custom_properties);
let starting_style = if !flags.contains(INHERIT_ALL) {
ComputedValues::new(custom_properties,
flags.contains(SHAREABLE),
WritingMode::empty(),
inherited_style.root_font_size,
+ inherited_style.font_size_keyword,
% for style_struct in data.active_style_structs():
% if style_struct.inherited:
inherited_style.clone_${style_struct.name_lower}(),
% else:
default_style.clone_${style_struct.name_lower}(),
% endif
% endfor
)
} else {
ComputedValues::new(custom_properties,
flags.contains(SHAREABLE),
WritingMode::empty(),
inherited_style.root_font_size,
+ inherited_style.font_size_keyword,
% for style_struct in data.active_style_structs():
inherited_style.clone_${style_struct.name_lower}(),
% endfor
)
};
let mut context = computed::Context {
is_root_element: is_root_element,
@@ -2071,34 +2078,35 @@ pub fn apply_declarations<'a, F, I>(devi
if
% if category_to_cascade_now == "early":
!
% endif
is_early_property
{
continue
}
+
+ <% maybe_to_physical = ".to_physical(writing_mode)" if category_to_cascade_now != "early" else "" %>
+ let physical_longhand_id = longhand_id ${maybe_to_physical};
+ if seen.contains(physical_longhand_id) {
+ continue
+ }
+ seen.insert(physical_longhand_id);
+
% if category_to_cascade_now == "early":
if LonghandId::FontSize == longhand_id {
font_size = Some(declaration);
continue;
}
if LonghandId::FontFamily == longhand_id {
font_family = Some(declaration);
continue;
}
% endif
- <% maybe_to_physical = ".to_physical(writing_mode)" if category_to_cascade_now != "early" else "" %>
- let physical_longhand_id = longhand_id ${maybe_to_physical};
- if seen.contains(physical_longhand_id) {
- continue
- }
- seen.insert(physical_longhand_id);
-
let discriminant = longhand_id as usize;
(CASCADE_PROPERTY[discriminant])(declaration,
inherited_style,
default_style,
&mut context,
&mut cacheable,
&mut cascade_info,
error_reporter);
@@ -2131,16 +2139,30 @@ pub fn apply_declarations<'a, F, I>(devi
let discriminant = LonghandId::FontSize as usize;
(CASCADE_PROPERTY[discriminant])(declaration,
inherited_style,
default_style,
&mut context,
&mut cacheable,
&mut cascade_info,
error_reporter);
+ } else if let Some(kw) = inherited_style.font_size_keyword {
+ // Font size keywords will inherit as keywords and be recomputed
+ // each time.
+ let discriminant = LonghandId::FontSize as usize;
+ let size = PropertyDeclaration::FontSize(
+ longhands::font_size::SpecifiedValue::Keyword(kw)
+ );
+ (CASCADE_PROPERTY[discriminant])(&size,
+ inherited_style,
+ default_style,
+ &mut context,
+ &mut cacheable,
+ &mut cascade_info,
+ error_reporter);
}
% endif
% endfor
let mut style = context.style;
let positioned = matches!(style.get_box().clone_position(),
longhands::position::SpecifiedValue::absolute |