servo: Merge #16371 - stylo: Cascade relative font-sizes applied to keyword sizes (from Manishearth:stylo-rel-base-size); r=heycam

r=heycam https://bugzilla.mozilla.org/show_bug.cgi?id=1355707

Source-Repo: https://github.com/servo/servo
Source-Revision: 805b29cd53179d3812be272f5f5ab5330965365d

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : e706d5f79410a992a98913909e0292a24d514d27
This commit is contained in:
Manish Goregaokar 2017-04-12 04:33:10 -05:00
Родитель 9493a7eab5
Коммит 14534660f7
4 изменённых файлов: 68 добавлений и 19 удалений

Просмотреть файл

@ -79,7 +79,21 @@ pub struct ComputedValues {
custom_properties: Option<Arc<ComputedValuesMap>>,
pub writing_mode: WritingMode,
pub root_font_size: Au,
pub font_size_keyword: Option<longhands::font_size::KeywordSize>,
/// font-size keyword values (and font-size-relative values applied
/// to keyword values) need to preserve their identity as originating
/// from keywords and relative font sizes. We store this information
/// out of band in the ComputedValues. When None, the font size on the
/// current struct was computed from a value that was not a keyword
/// or a chain of font-size-relative values applying to successive parents
/// terminated by a keyword. When Some, this means the font-size was derived
/// from a keyword value or a keyword value on some ancestor with only
/// font-size-relative keywords and regular inheritance in between. The
/// integer stores the final ratio of the chain of font size relative values.
/// and is 1 when there was just a keyword and no relative values.
///
/// When this is Some, we compute font sizes by computing the keyword against
/// the generic font, and then multiplying it by the ratio.
pub font_size_keyword: Option<(longhands::font_size::KeywordSize, f32)>,
}
impl ComputedValues {
@ -102,7 +116,7 @@ impl ComputedValues {
pub fn new(custom_properties: Option<Arc<ComputedValuesMap>>,
writing_mode: WritingMode,
root_font_size: Au,
font_size_keyword: Option<longhands::font_size::KeywordSize>,
font_size_keyword: Option<(longhands::font_size::KeywordSize, f32)>,
% for style_struct in data.style_structs:
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
% endfor
@ -123,7 +137,7 @@ impl ComputedValues {
custom_properties: None,
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()),
font_size_keyword: Some((Default::default(), 1.)),
% for style_struct in data.style_structs:
${style_struct.ident}: style_structs::${style_struct.name}::default(pres_context),
% endfor

Просмотреть файл

@ -267,8 +267,21 @@
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);
if let longhands::font_size::SpecifiedValue::Keyword(kw, fraction)
= **specified_value {
context.mutate_style().font_size_keyword = Some((kw, fraction));
} else if let Some(ratio) = specified_value.as_font_ratio() {
// In case a font-size-relative value was applied to a keyword
// value, we must preserve this fact in case the generic font family
// changes. relative values (em and %) applied to keywords must be
// recomputed from the base size for the keyword and the relative size.
//
// See bug 1355707
if let Some((kw, fraction)) = context.inherited_style().font_size_keyword {
context.mutate_style().font_size_keyword = Some((kw, fraction * ratio));
} else {
context.mutate_style().font_size_keyword = None;
}
} else {
context.mutate_style().font_size_keyword = None;
}
@ -294,7 +307,7 @@
.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());
context.mutate_style().font_size_keyword = Some((Default::default(), 1.));
% else:
// We assume that it's faster to use copy_*_from rather than
// set_*(get_initial_value());

Просмотреть файл

@ -415,13 +415,14 @@ ${helpers.single_keyword("font-variant-caps",
use std::fmt;
use style_traits::ToCss;
use values::{FONT_MEDIUM_PX, HasViewportPercentage};
use values::specified::{LengthOrPercentage, Length, NoCalcLength, Percentage};
use values::specified::{FontRelativeLength, LengthOrPercentage, Length};
use values::specified::{NoCalcLength, Percentage};
impl ToCss for SpecifiedValue {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result where W: fmt::Write {
match *self {
SpecifiedValue::Length(ref lop) => lop.to_css(dest),
SpecifiedValue::Keyword(kw) => kw.to_css(dest),
SpecifiedValue::Keyword(kw, _) => kw.to_css(dest),
SpecifiedValue::Smaller => dest.write_str("smaller"),
SpecifiedValue::Larger => dest.write_str("larger"),
}
@ -441,7 +442,13 @@ ${helpers.single_keyword("font-variant-caps",
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum SpecifiedValue {
Length(specified::LengthOrPercentage),
Keyword(KeywordSize),
/// A keyword value, along with a ratio.
/// The ratio in any specified keyword value
/// will be 1, but we cascade keywordness even
/// after font-relative (percent and em) values
/// have been applied, which is where the keyword
/// comes in. See bug 1355707
Keyword(KeywordSize, f32),
Smaller,
Larger,
}
@ -596,7 +603,22 @@ ${helpers.single_keyword("font-variant-caps",
6 => XXLarge,
// If value is greater than 7, let it be 7.
_ => XXXLarge,
})
}, 1.)
}
/// If this value is specified as a ratio of the parent font (em units or percent)
/// return the ratio
pub fn as_font_ratio(&self) -> Option<f32> {
if let SpecifiedValue::Length(ref lop) = *self {
if let LengthOrPercentage::Percentage(pc) = *lop {
return Some(pc.0)
} else if let LengthOrPercentage::Length(ref nocalc) = *lop {
if let NoCalcLength::FontRelative(FontRelativeLength::Em(em)) = *nocalc {
return Some(em)
}
}
}
None
}
}
@ -608,7 +630,7 @@ ${helpers.single_keyword("font-variant-caps",
#[inline]
pub fn get_initial_specified_value() -> SpecifiedValue {
SpecifiedValue::Keyword(Medium)
SpecifiedValue::Keyword(Medium, 1.)
}
impl ToComputedValue for SpecifiedValue {
@ -637,8 +659,8 @@ ${helpers.single_keyword("font-variant-caps",
calc.length() + context.inherited_style().get_font().clone_font_size()
.scale_by(calc.percentage())
}
SpecifiedValue::Keyword(ref key) => {
key.to_computed_value(context)
SpecifiedValue::Keyword(ref key, fraction) => {
key.to_computed_value(context).scale_by(fraction)
}
SpecifiedValue::Smaller => {
FontRelativeLength::Em(0.85).to_computed_value(context,
@ -665,7 +687,7 @@ ${helpers.single_keyword("font-variant-caps",
}
if let Ok(kw) = input.try(KeywordSize::parse) {
return Ok(SpecifiedValue::Keyword(kw))
return Ok(SpecifiedValue::Keyword(kw, 1.))
}
match_ignore_ascii_case! {&*input.expect_ident()?,

Просмотреть файл

@ -1569,7 +1569,7 @@ pub struct ComputedValues {
/// 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>,
pub font_size_keyword: Option<(longhands::font_size::KeywordSize, f32)>,
}
#[cfg(feature = "servo")]
@ -1578,7 +1578,7 @@ impl ComputedValues {
pub fn new(custom_properties: Option<Arc<::custom_properties::ComputedValuesMap>>,
writing_mode: WritingMode,
root_font_size: Au,
font_size_keyword: Option<longhands::font_size::KeywordSize>,
font_size_keyword: Option<(longhands::font_size::KeywordSize, f32)>,
% for style_struct in data.active_style_structs():
${style_struct.ident}: Arc<style_structs::${style_struct.name}>,
% endfor
@ -1910,7 +1910,7 @@ mod lazy_static_module {
custom_properties: None,
writing_mode: WritingMode::empty(),
root_font_size: longhands::font_size::get_initial_value(),
font_size_keyword: Some(Default::default()),
font_size_keyword: Some((Default::default(), 1.)),
};
}
}
@ -2205,12 +2205,12 @@ pub fn apply_declarations<'a, F, I>(device: &Device,
&mut cacheable,
&mut cascade_info,
error_reporter);
} else if let Some(kw) = inherited_style.font_size_keyword {
} else if let Some((kw, fraction)) = 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)
longhands::font_size::SpecifiedValue::Keyword(kw, fraction)
);
(CASCADE_PROPERTY[discriminant])(&size,
inherited_style,