--- a/servo/components/style/values/specified/font.rs
+++ b/servo/components/style/values/specified/font.rs
@@ -21,16 +21,52 @@ use values::computed::{Angle as Computed
use values::computed::{font as computed, Context, Length, NonNegativeLength, ToComputedValue};
use values::computed::font::{FamilyName, FontFamilyList, FontStyleAngle, SingleFontFamily};
use values::generics::NonNegative;
use values::generics::font::{self as generics, FeatureTagValue, FontSettings, FontTag};
use values::generics::font::{KeywordInfo as GenericKeywordInfo, KeywordSize, VariationValue};
use values::specified::{AllowQuirks, Angle, Integer, LengthOrPercentage, NoCalcLength, Number, Percentage};
use values::specified::length::{FontBaseSize, AU_PER_PT, AU_PER_PX};
+// FIXME(emilio): The rest of the system font code is also copy-pasta, and
+// should be cleaned up.
+macro_rules! system_font_copy_pasta {
+ ($ty:ident, $field:ident) => {
+ system_font_copy_pasta!($ty);
+
+ fn compute_system(&self, _context: &Context) -> <$ty as ToComputedValue>::ComputedValue {
+ debug_assert!(matches!(*self, $ty::System(..)));
+ #[cfg(feature = "gecko")]
+ {
+ _context.cached_system_font.as_ref().unwrap().$field.clone()
+ }
+ #[cfg(feature = "servo")]
+ {
+ unreachable!()
+ }
+ }
+ };
+
+ ($ty:ident) => {
+ /// Get a specified value that represents a system font.
+ pub fn system_font(f: SystemFont) -> Self {
+ $ty::System(f)
+ }
+
+ /// Retreive a SystemFont from the specified value.
+ pub fn get_system(&self) -> Option<SystemFont> {
+ if let $ty::System(s) = *self {
+ Some(s)
+ } else {
+ None
+ }
+ }
+ }
+}
+
const DEFAULT_SCRIPT_MIN_SIZE_PT: u32 = 8;
const DEFAULT_SCRIPT_SIZE_MULTIPLIER: f64 = 0.71;
/// The minimum font-weight value per:
///
/// https://drafts.csswg.org/css-fonts-4/#font-weight-numeric-values
pub const MIN_FONT_WEIGHT: f32 = 1.;
@@ -50,42 +86,30 @@ pub enum FontWeight {
Bolder,
/// Lighter variant
Lighter,
/// System font variant.
System(SystemFont),
}
impl FontWeight {
+ system_font_copy_pasta!(FontWeight, font_weight);
+
/// `normal`
#[inline]
pub fn normal() -> Self {
FontWeight::Absolute(AbsoluteFontWeight::Normal)
}
/// Get a specified FontWeight from a gecko keyword
pub fn from_gecko_keyword(kw: u32) -> Self {
debug_assert!(kw % 100 == 0);
debug_assert!(kw as f32 <= MAX_FONT_WEIGHT);
FontWeight::Absolute(AbsoluteFontWeight::Weight(Number::new(kw as f32)))
}
-
- /// Get a specified FontWeight from a SystemFont
- pub fn system_font(f: SystemFont) -> Self {
- FontWeight::System(f)
- }
-
- /// Retreive a SystemFont from FontWeight
- pub fn get_system(&self) -> Option<SystemFont> {
- if let FontWeight::System(s) = *self {
- Some(s)
- } else {
- None
- }
- }
}
impl Parse for FontWeight {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<FontWeight, ParseError<'i>> {
if let Ok(absolute) = input.try(|input| AbsoluteFontWeight::parse(context, input)) {
@@ -111,25 +135,17 @@ impl ToComputedValue for FontWeight {
.get_parent_font()
.clone_font_weight()
.bolder(),
FontWeight::Lighter => context
.builder
.get_parent_font()
.clone_font_weight()
.lighter(),
- #[cfg(feature = "gecko")]
- FontWeight::System(_) => context
- .cached_system_font
- .as_ref()
- .unwrap()
- .font_weight
- .clone(),
- #[cfg(not(feature = "gecko"))]
- FontWeight::System(_) => unreachable!(),
+ FontWeight::System(_) => self.compute_system(context),
}
}
#[inline]
fn from_computed_value(computed: &computed::FontWeight) -> Self {
FontWeight::Absolute(AbsoluteFontWeight::Weight(
Number::from_computed_value(&computed.0)
))
@@ -327,46 +343,26 @@ pub enum FontStyle {
impl FontStyle {
/// Return the `normal` value.
#[inline]
pub fn normal() -> Self {
FontStyle::Specified(generics::FontStyle::Normal)
}
- /// More system font copy-pasta.
- pub fn system_font(f: SystemFont) -> Self {
- FontStyle::System(f)
- }
-
- /// Retreive a SystemFont from FontStyle.
- pub fn get_system(&self) -> Option<SystemFont> {
- if let FontStyle::System(s) = *self {
- Some(s)
- } else {
- None
- }
- }
+ system_font_copy_pasta!(FontStyle, font_style);
}
impl ToComputedValue for FontStyle {
type ComputedValue = computed::FontStyle;
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
match *self {
FontStyle::Specified(ref specified) => specified.to_computed_value(context),
- #[cfg(feature = "gecko")]
- FontStyle::System(..) => context
- .cached_system_font
- .as_ref()
- .unwrap()
- .font_style
- .clone(),
- #[cfg(not(feature = "gecko"))]
- FontStyle::System(_) => unreachable!(),
+ FontStyle::System(..) => self.compute_system(context),
}
}
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
FontStyle::Specified(SpecifiedFontStyle::from_computed_value(computed))
}
}
@@ -426,31 +422,17 @@ impl FontStretchKeyword {
}
impl FontStretch {
/// `normal`.
pub fn normal() -> Self {
FontStretch::Keyword(FontStretchKeyword::Normal)
}
- /// Get a specified FontStretch from a SystemFont.
- ///
- /// FIXME(emilio): All this system font stuff is copy-pasta. :(
- pub fn system_font(f: SystemFont) -> Self {
- FontStretch::System(f)
- }
-
- /// Retreive a SystemFont from FontStretch.
- pub fn get_system(&self) -> Option<SystemFont> {
- if let FontStretch::System(s) = *self {
- Some(s)
- } else {
- None
- }
- }
+ system_font_copy_pasta!(FontStretch, font_stretch);
}
impl Parse for FontStretch {
fn parse<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
) -> Result<Self, ParseError<'i>> {
// From https://drafts.csswg.org/css-fonts-4/#font-stretch-prop:
@@ -472,25 +454,17 @@ impl ToComputedValue for FontStretch {
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
match *self {
FontStretch::Stretch(ref percentage) => {
NonNegative(percentage.to_computed_value(context))
},
FontStretch::Keyword(ref kw) => {
NonNegative(kw.compute())
},
- #[cfg(feature = "gecko")]
- FontStretch::System(_) => context
- .cached_system_font
- .as_ref()
- .unwrap()
- .font_stretch
- .clone(),
- #[cfg(not(feature = "gecko"))]
- FontStretch::System(_) => unreachable!(),
+ FontStretch::System(_) => self.compute_system(context),
}
}
fn from_computed_value(computed: &Self::ComputedValue) -> Self {
FontStretch::Stretch(Percentage::from_computed_value(&computed.0))
}
}
@@ -530,29 +504,17 @@ pub enum FontFamily {
/// List of `font-family`
#[css(comma)]
Values(#[css(iterable)] FontFamilyList),
/// System font
System(SystemFont),
}
impl FontFamily {
- /// Get `font-family` with system font
- pub fn system_font(f: SystemFont) -> Self {
- FontFamily::System(f)
- }
-
- /// Get system font
- pub fn get_system(&self) -> Option<SystemFont> {
- if let FontFamily::System(s) = *self {
- Some(s)
- } else {
- None
- }
- }
+ system_font_copy_pasta!(FontFamily, font_family);
/// Parse a specified font-family value
pub fn parse_specified<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
input
.parse_comma_separated(|input| SingleFontFamily::parse(input))
.map(|v| FontFamily::Values(FontFamilyList::new(v.into_boxed_slice())))
}
@@ -564,29 +526,20 @@ impl FontFamily {
_ => None,
}
}
}
impl ToComputedValue for FontFamily {
type ComputedValue = computed::FontFamily;
- fn to_computed_value(&self, _cx: &Context) -> Self::ComputedValue {
+ fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
match *self {
FontFamily::Values(ref v) => computed::FontFamily(v.clone()),
- FontFamily::System(_) => {
- #[cfg(feature = "gecko")]
- {
- _cx.cached_system_font.as_ref().unwrap().font_family.clone()
- }
- #[cfg(feature = "servo")]
- {
- unreachable!()
- }
- },
+ FontFamily::System(_) => self.compute_system(context),
}
}
fn from_computed_value(other: &computed::FontFamily) -> Self {
FontFamily::Values(other.0.clone())
}
}
@@ -646,54 +599,29 @@ pub enum FontSizeAdjust {
impl FontSizeAdjust {
#[inline]
/// Default value of font-size-adjust
pub fn none() -> Self {
FontSizeAdjust::None
}
- /// Get font-size-adjust with SystemFont
- pub fn system_font(f: SystemFont) -> Self {
- FontSizeAdjust::System(f)
- }
-
- /// Get SystemFont variant
- pub fn get_system(&self) -> Option<SystemFont> {
- if let FontSizeAdjust::System(s) = *self {
- Some(s)
- } else {
- None
- }
- }
+ system_font_copy_pasta!(FontSizeAdjust, font_size_adjust);
}
impl ToComputedValue for FontSizeAdjust {
type ComputedValue = computed::FontSizeAdjust;
fn to_computed_value(&self, context: &Context) -> Self::ComputedValue {
match *self {
FontSizeAdjust::None => computed::FontSizeAdjust::None,
FontSizeAdjust::Number(ref n) => {
computed::FontSizeAdjust::Number(n.to_computed_value(context))
},
- FontSizeAdjust::System(_) => {
- #[cfg(feature = "gecko")]
- {
- context
- .cached_system_font
- .as_ref()
- .unwrap()
- .font_size_adjust
- }
- #[cfg(feature = "servo")]
- {
- unreachable!()
- }
- },
+ FontSizeAdjust::System(_) => self.compute_system(context),
}
}
fn from_computed_value(computed: &computed::FontSizeAdjust) -> Self {
match *computed {
computed::FontSizeAdjust::None => FontSizeAdjust::None,
computed::FontSizeAdjust::Number(ref v) => {
FontSizeAdjust::Number(Number::from_computed_value(v))
@@ -1007,32 +935,20 @@ impl ToComputedValue for FontSize {
fn from_computed_value(computed: &computed::FontSize) -> Self {
FontSize::Length(LengthOrPercentage::Length(
ToComputedValue::from_computed_value(&computed.size.0),
))
}
}
impl FontSize {
- /// Construct a system font value.
- pub fn system_font(f: SystemFont) -> Self {
- FontSize::System(f)
- }
+ system_font_copy_pasta!(FontSize);
- /// Obtain the system font, if any
- pub fn get_system(&self) -> Option<SystemFont> {
- if let FontSize::System(s) = *self {
- Some(s)
- } else {
- None
- }
- }
-
+ /// Get initial value for specified font size.
#[inline]
- /// Get initial value for specified font size.
pub fn medium() -> Self {
FontSize::Keyword(KeywordInfo::medium())
}
/// Parses a font-size, with quirks.
pub fn parse_quirky<'i, 't>(
context: &ParserContext,
input: &mut Parser<'i, 't>,
@@ -1187,52 +1103,26 @@ pub enum FontVariantAlternates {
impl FontVariantAlternates {
#[inline]
/// Get initial specified value with VariantAlternatesList
pub fn get_initial_specified_value() -> Self {
FontVariantAlternates::Value(VariantAlternatesList(vec![].into_boxed_slice()))
}
- /// Get FontVariantAlternates with system font
- pub fn system_font(f: SystemFont) -> Self {
- FontVariantAlternates::System(f)
- }
-
- /// Get SystemFont of FontVariantAlternates
- pub fn get_system(&self) -> Option<SystemFont> {
- if let FontVariantAlternates::System(s) = *self {
- Some(s)
- } else {
- None
- }
- }
+ system_font_copy_pasta!(FontVariantAlternates, font_variant_alternates);
}
impl ToComputedValue for FontVariantAlternates {
type ComputedValue = computed::FontVariantAlternates;
- fn to_computed_value(&self, _context: &Context) -> computed::FontVariantAlternates {
+ fn to_computed_value(&self, context: &Context) -> computed::FontVariantAlternates {
match *self {
FontVariantAlternates::Value(ref v) => v.clone(),
- FontVariantAlternates::System(_) => {
- #[cfg(feature = "gecko")]
- {
- _context
- .cached_system_font
- .as_ref()
- .unwrap()
- .font_variant_alternates
- .clone()
- }
- #[cfg(feature = "servo")]
- {
- unreachable!()
- }
- },
+ FontVariantAlternates::System(_) => self.compute_system(context),
}
}
fn from_computed_value(other: &computed::FontVariantAlternates) -> Self {
FontVariantAlternates::Value(other.clone())
}
}
@@ -1464,52 +1354,26 @@ pub enum FontVariantEastAsian {
impl FontVariantEastAsian {
#[inline]
/// Get default `font-variant-east-asian` with `empty` variant
pub fn empty() -> Self {
FontVariantEastAsian::Value(VariantEastAsian::empty())
}
- /// Get `font-variant-east-asian` with system font
- pub fn system_font(f: SystemFont) -> Self {
- FontVariantEastAsian::System(f)
- }
-
- /// Get system font
- pub fn get_system(&self) -> Option<SystemFont> {
- if let FontVariantEastAsian::System(s) = *self {
- Some(s)
- } else {
- None
- }
- }
+ system_font_copy_pasta!(FontVariantEastAsian, font_variant_east_asian);
}
impl ToComputedValue for FontVariantEastAsian {
type ComputedValue = computed::FontVariantEastAsian;
- fn to_computed_value(&self, _context: &Context) -> computed::FontVariantEastAsian {
+ fn to_computed_value(&self, context: &Context) -> computed::FontVariantEastAsian {
match *self {
FontVariantEastAsian::Value(ref v) => v.clone(),
- FontVariantEastAsian::System(_) => {
- #[cfg(feature = "gecko")]
- {
- _context
- .cached_system_font
- .as_ref()
- .unwrap()
- .font_variant_east_asian
- .clone()
- }
- #[cfg(feature = "servo")]
- {
- unreachable!()
- }
- },
+ FontVariantEastAsian::System(_) => self.compute_system(context),
}
}
fn from_computed_value(other: &computed::FontVariantEastAsian) -> Self {
FontVariantEastAsian::Value(other.clone())
}
}
@@ -1710,64 +1574,38 @@ pub fn assert_variant_ligatures_matches(
pub enum FontVariantLigatures {
/// Value variant with `variant-ligatures`
Value(VariantLigatures),
/// System font variant
System(SystemFont),
}
impl FontVariantLigatures {
- /// Get `font-variant-ligatures` with system font
- pub fn system_font(f: SystemFont) -> Self {
- FontVariantLigatures::System(f)
- }
+ system_font_copy_pasta!(FontVariantLigatures, font_variant_ligatures);
- /// Get system font
- pub fn get_system(&self) -> Option<SystemFont> {
- if let FontVariantLigatures::System(s) = *self {
- Some(s)
- } else {
- None
- }
- }
-
+ /// Default value of `font-variant-ligatures` as `empty`
#[inline]
- /// Default value of `font-variant-ligatures` as `empty`
pub fn empty() -> FontVariantLigatures {
FontVariantLigatures::Value(VariantLigatures::empty())
}
#[inline]
/// Get `none` variant of `font-variant-ligatures`
pub fn none() -> FontVariantLigatures {
FontVariantLigatures::Value(VariantLigatures::NONE)
}
}
impl ToComputedValue for FontVariantLigatures {
type ComputedValue = computed::FontVariantLigatures;
- fn to_computed_value(&self, _context: &Context) -> computed::FontVariantLigatures {
+ fn to_computed_value(&self, context: &Context) -> computed::FontVariantLigatures {
match *self {
FontVariantLigatures::Value(ref v) => v.clone(),
- FontVariantLigatures::System(_) => {
- #[cfg(feature = "gecko")]
- {
- _context
- .cached_system_font
- .as_ref()
- .unwrap()
- .font_variant_ligatures
- .clone()
- }
- #[cfg(feature = "servo")]
- {
- unreachable!()
- }
- },
+ FontVariantLigatures::System(_) => self.compute_system(context),
}
}
fn from_computed_value(other: &computed::FontVariantLigatures) -> Self {
FontVariantLigatures::Value(other.clone())
}
}
@@ -1970,52 +1808,26 @@ pub enum FontVariantNumeric {
impl FontVariantNumeric {
#[inline]
/// Default value of `font-variant-numeric` as `empty`
pub fn empty() -> FontVariantNumeric {
FontVariantNumeric::Value(VariantNumeric::empty())
}
- /// Get `font-variant-numeric` with system font
- pub fn system_font(f: SystemFont) -> Self {
- FontVariantNumeric::System(f)
- }
-
- /// Get system font
- pub fn get_system(&self) -> Option<SystemFont> {
- if let FontVariantNumeric::System(s) = *self {
- Some(s)
- } else {
- None
- }
- }
+ system_font_copy_pasta!(FontVariantNumeric, font_variant_numeric);
}
impl ToComputedValue for FontVariantNumeric {
type ComputedValue = computed::FontVariantNumeric;
- fn to_computed_value(&self, _context: &Context) -> computed::FontVariantNumeric {
+ fn to_computed_value(&self, context: &Context) -> computed::FontVariantNumeric {
match *self {
FontVariantNumeric::Value(ref v) => v.clone(),
- FontVariantNumeric::System(_) => {
- #[cfg(feature = "gecko")]
- {
- _context
- .cached_system_font
- .as_ref()
- .unwrap()
- .font_variant_numeric
- .clone()
- }
- #[cfg(feature = "servo")]
- {
- unreachable!()
- }
- },
+ FontVariantNumeric::System(_) => self.compute_system(context),
}
}
fn from_computed_value(other: &computed::FontVariantNumeric) -> Self {
FontVariantNumeric::Value(other.clone())
}
}
@@ -2103,52 +1915,26 @@ pub enum FontFeatureSettings {
impl FontFeatureSettings {
#[inline]
/// Get default value of `font-feature-settings` as normal
pub fn normal() -> FontFeatureSettings {
FontFeatureSettings::Value(FontSettings::normal())
}
- /// Get `font-feature-settings` with system font
- pub fn system_font(f: SystemFont) -> Self {
- FontFeatureSettings::System(f)
- }
-
- /// Get system font
- pub fn get_system(&self) -> Option<SystemFont> {
- if let FontFeatureSettings::System(s) = *self {
- Some(s)
- } else {
- None
- }
- }
+ system_font_copy_pasta!(FontFeatureSettings, font_feature_settings);
}
impl ToComputedValue for FontFeatureSettings {
type ComputedValue = computed::FontFeatureSettings;
fn to_computed_value(&self, context: &Context) -> computed::FontFeatureSettings {
match *self {
FontFeatureSettings::Value(ref v) => v.to_computed_value(context),
- FontFeatureSettings::System(_) => {
- #[cfg(feature = "gecko")]
- {
- context
- .cached_system_font
- .as_ref()
- .unwrap()
- .font_feature_settings
- .clone()
- }
- #[cfg(feature = "servo")]
- {
- unreachable!()
- }
- },
+ FontFeatureSettings::System(_) => self.compute_system(context),
}
}
fn from_computed_value(other: &computed::FontFeatureSettings) -> Self {
FontFeatureSettings::Value(ToComputedValue::from_computed_value(other))
}
}
@@ -2278,63 +2064,38 @@ pub enum FontLanguageOverride {
impl FontLanguageOverride {
#[inline]
/// Get default value with `normal`
pub fn normal() -> FontLanguageOverride {
FontLanguageOverride::Normal
}
- /// Get `font-language-override` with `system font`
- pub fn system_font(f: SystemFont) -> Self {
- FontLanguageOverride::System(f)
- }
-
- /// Get system font
- pub fn get_system(&self) -> Option<SystemFont> {
- if let FontLanguageOverride::System(s) = *self {
- Some(s)
- } else {
- None
- }
- }
+ system_font_copy_pasta!(FontLanguageOverride, font_language_override);
}
impl ToComputedValue for FontLanguageOverride {
type ComputedValue = computed::FontLanguageOverride;
#[inline]
- fn to_computed_value(&self, _context: &Context) -> computed::FontLanguageOverride {
+ fn to_computed_value(&self, context: &Context) -> computed::FontLanguageOverride {
match *self {
FontLanguageOverride::Normal => computed::FontLanguageOverride(0),
FontLanguageOverride::Override(ref lang) => {
if lang.is_empty() || lang.len() > 4 || !lang.is_ascii() {
return computed::FontLanguageOverride(0);
}
let mut computed_lang = lang.to_string();
while computed_lang.len() < 4 {
computed_lang.push(' ');
}
let bytes = computed_lang.into_bytes();
computed::FontLanguageOverride(BigEndian::read_u32(&bytes))
},
- FontLanguageOverride::System(_) => {
- #[cfg(feature = "gecko")]
- {
- _context
- .cached_system_font
- .as_ref()
- .unwrap()
- .font_language_override
- }
- #[cfg(feature = "servo")]
- {
- unreachable!()
- }
- },
+ FontLanguageOverride::System(_) => self.compute_system(context),
}
}
#[inline]
fn from_computed_value(computed: &computed::FontLanguageOverride) -> Self {
if computed.0 == 0 {
return FontLanguageOverride::Normal;
}
let mut buf = [0; 4];
@@ -2385,52 +2146,26 @@ pub enum FontVariationSettings {
impl FontVariationSettings {
#[inline]
/// Get default value of `font-variation-settings` as normal
pub fn normal() -> FontVariationSettings {
FontVariationSettings::Value(FontSettings::normal())
}
- /// Get `font-variation-settings` with system font
- pub fn system_font(f: SystemFont) -> Self {
- FontVariationSettings::System(f)
- }
-
- /// Get system font
- pub fn get_system(&self) -> Option<SystemFont> {
- if let FontVariationSettings::System(s) = *self {
- Some(s)
- } else {
- None
- }
- }
+ system_font_copy_pasta!(FontVariationSettings, font_variation_settings);
}
impl ToComputedValue for FontVariationSettings {
type ComputedValue = computed::FontVariationSettings;
fn to_computed_value(&self, context: &Context) -> computed::FontVariationSettings {
match *self {
FontVariationSettings::Value(ref v) => v.to_computed_value(context),
- FontVariationSettings::System(_) => {
- #[cfg(feature = "gecko")]
- {
- context
- .cached_system_font
- .as_ref()
- .unwrap()
- .font_variation_settings
- .clone()
- }
- #[cfg(feature = "servo")]
- {
- unreachable!()
- }
- },
+ FontVariationSettings::System(_) => self.compute_system(context),
}
}
fn from_computed_value(other: &computed::FontVariationSettings) -> Self {
FontVariationSettings::Value(ToComputedValue::from_computed_value(other))
}
}