diff --git a/components/style/properties/longhand/font.mako.rs b/components/style/properties/longhand/font.mako.rs index df95d9f464c..c400f513bdc 100644 --- a/components/style/properties/longhand/font.mako.rs +++ b/components/style/properties/longhand/font.mako.rs @@ -418,6 +418,7 @@ ${helpers.single_keyword("font-variant-caps", use values::{FONT_MEDIUM_PX, HasViewportPercentage}; use values::specified::{FontRelativeLength, LengthOrPercentage, Length}; use values::specified::{NoCalcLength, Percentage}; + use values::specified::length::FontBaseSize; impl ToCss for SpecifiedValue { fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { @@ -627,6 +628,43 @@ ${helpers.single_keyword("font-variant-caps", } None } + + /// Compute it against a given base font size + pub fn to_computed_value_against(&self, context: &Context, base_size: FontBaseSize) -> Au { + use values::specified::length::FontRelativeLength; + match *self { + SpecifiedValue::Length(LengthOrPercentage::Length( + NoCalcLength::FontRelative(value))) => { + value.to_computed_value(context, base_size) + } + SpecifiedValue::Length(LengthOrPercentage::Length( + NoCalcLength::ServoCharacterWidth(value))) => { + value.to_computed_value(base_size.resolve(context)) + } + SpecifiedValue::Length(LengthOrPercentage::Length(ref l)) => { + l.to_computed_value(context) + } + SpecifiedValue::Length(LengthOrPercentage::Percentage(Percentage(value))) => { + base_size.resolve(context).scale_by(value) + } + SpecifiedValue::Length(LengthOrPercentage::Calc(ref calc)) => { + let calc = calc.to_computed_value(context); + calc.length() +base_size.resolve(context) + .scale_by(calc.percentage()) + } + SpecifiedValue::Keyword(ref key, fraction) => { + key.to_computed_value(context).scale_by(fraction) + } + SpecifiedValue::Smaller => { + FontRelativeLength::Em(0.85) + .to_computed_value(context, base_size) + } + SpecifiedValue::Larger => { + FontRelativeLength::Em(1.2) + .to_computed_value(context, base_size) + } + } + } } #[inline] @@ -640,44 +678,13 @@ ${helpers.single_keyword("font-variant-caps", SpecifiedValue::Keyword(Medium, 1.) } + impl ToComputedValue for SpecifiedValue { type ComputedValue = computed_value::T; #[inline] fn to_computed_value(&self, context: &Context) -> computed_value::T { - use values::specified::length::FontRelativeLength; - match *self { - SpecifiedValue::Length(LengthOrPercentage::Length( - NoCalcLength::FontRelative(value))) => { - value.to_computed_value(context, /* use inherited */ true) - } - SpecifiedValue::Length(LengthOrPercentage::Length( - NoCalcLength::ServoCharacterWidth(value))) => { - value.to_computed_value(context.inherited_style().get_font().clone_font_size()) - } - SpecifiedValue::Length(LengthOrPercentage::Length(ref l)) => { - l.to_computed_value(context) - } - SpecifiedValue::Length(LengthOrPercentage::Percentage(Percentage(value))) => { - context.inherited_style().get_font().clone_font_size().scale_by(value) - } - SpecifiedValue::Length(LengthOrPercentage::Calc(ref calc)) => { - let calc = calc.to_computed_value(context); - calc.length() + context.inherited_style().get_font().clone_font_size() - .scale_by(calc.percentage()) - } - SpecifiedValue::Keyword(ref key, fraction) => { - key.to_computed_value(context).scale_by(fraction) - } - SpecifiedValue::Smaller => { - FontRelativeLength::Em(0.85).to_computed_value(context, - /* use_inherited */ true) - } - SpecifiedValue::Larger => { - FontRelativeLength::Em(1.2).to_computed_value(context, - /* use_inherited */ true) - } - } + self.to_computed_value_against(context, FontBaseSize::InheritedStyle) } #[inline] diff --git a/components/style/values/computed/length.rs b/components/style/values/computed/length.rs index c21a03c1ca6..9332b03162a 100644 --- a/components/style/values/computed/length.rs +++ b/components/style/values/computed/length.rs @@ -10,7 +10,7 @@ use std::fmt; use style_traits::ToCss; use super::{Number, ToComputedValue, Context}; use values::{Auto, CSSFloat, Either, ExtremumLength, None_, Normal, specified}; -use values::specified::length::{AbsoluteLength, FontRelativeLength, ViewportPercentageLength}; +use values::specified::length::{AbsoluteLength, FontBaseSize, FontRelativeLength, ViewportPercentageLength}; pub use super::image::{EndingShape as GradientShape, Gradient, GradientKind, Image}; pub use super::image::{LengthOrKeyword, LengthOrPercentageOrKeyword}; @@ -25,7 +25,7 @@ impl ToComputedValue for specified::NoCalcLength { specified::NoCalcLength::Absolute(length) => length.to_computed_value(context), specified::NoCalcLength::FontRelative(length) => - length.to_computed_value(context, /* use inherited */ false), + length.to_computed_value(context, /* base_size */ FontBaseSize::CurrentStyle), specified::NoCalcLength::ViewportPercentage(length) => length.to_computed_value(context.viewport_size()), specified::NoCalcLength::ServoCharacterWidth(length) => @@ -139,6 +139,7 @@ impl ToComputedValue for specified::CalcLengthOrPercentage { type ComputedValue = CalcLengthOrPercentage; fn to_computed_value(&self, context: &Context) -> CalcLengthOrPercentage { + let mut length = Au(0); if let Some(absolute) = self.absolute { @@ -159,7 +160,7 @@ impl ToComputedValue for specified::CalcLengthOrPercentage { self.ex.map(FontRelativeLength::Ex), self.rem.map(FontRelativeLength::Rem)] { if let Some(val) = *val { - length += val.to_computed_value(context, /* use inherited */ false); + length += val.to_computed_value(context, /* base_size */ FontBaseSize::CurrentStyle); } } diff --git a/components/style/values/specified/length.rs b/components/style/values/specified/length.rs index 4d41be3e07e..581cd74e3e5 100644 --- a/components/style/values/specified/length.rs +++ b/components/style/values/specified/length.rs @@ -76,10 +76,31 @@ impl ToCss for FontRelativeLength { } } +/// A source to resolve font-relative units against +pub enum FontBaseSize { + /// Use the font-size of the current element + CurrentStyle, + /// Use the inherited font-size + InheritedStyle, + /// Use a custom base size + Custom(Au), +} + +impl FontBaseSize { + /// Calculate the actual size for a given context + pub fn resolve(&self, context: &Context) -> Au { + match *self { + FontBaseSize::Custom(size) => size, + FontBaseSize::CurrentStyle => context.style().get_font().clone_font_size(), + FontBaseSize::InheritedStyle => context.inherited_style().get_font().clone_font_size(), + } + } +} + impl FontRelativeLength { - /// Computes the font-relative length. We use the use_inherited flag to - /// special-case the computation of font-size. - pub fn to_computed_value(&self, context: &Context, use_inherited: bool) -> Au { + /// Computes the font-relative length. We use the inherited_size + /// flag to pass a different size for computing font-size and unconstrained font-size + pub fn to_computed_value(&self, context: &Context, base_size: FontBaseSize) -> Au { fn query_font_metrics(context: &Context, reference_font_size: Au) -> FontMetricsQueryResult { context.font_metrics_provider.query(context.style().get_font(), reference_font_size, @@ -88,11 +109,7 @@ impl FontRelativeLength { context.device) } - let reference_font_size = if use_inherited { - context.inherited_style().get_font().clone_font_size() - } else { - context.style().get_font().clone_font_size() - }; + let reference_font_size = base_size.resolve(context); let root_font_size = context.style().root_font_size; match *self {