Skip to main content

fonts_traits/
font_descriptor.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use std::ops::{Deref, RangeInclusive};
6
7use malloc_size_of_derive::MallocSizeOf;
8use serde::{Deserialize, Serialize};
9use style::computed_values::font_optical_sizing::T as FontOpticalSizing;
10use style::computed_values::font_variant_caps;
11use style::font_face::{
12    ComputedFontStretchRange, ComputedFontStyleDescriptor, ComputedFontWeightRange, Descriptors,
13    FontStretchRange, FontStyle as FontFaceStyle, FontWeightRange,
14};
15use style::properties::style_structs::Font as FontStyleStruct;
16use style::stylesheets::FontFaceRule;
17use style::values::computed::{Au, FontStretch, FontStyle, FontSynthesis, FontWeight};
18use webrender_api::FontVariation;
19
20/// `FontDescriptor` describes the parameters of a `Font`. It represents rendering a given font
21/// template at a particular size, with a particular font-variant-caps applied, etc. This contrasts
22/// with `FontTemplateDescriptor` in that the latter represents only the parameters inherent in the
23/// font data (weight, stretch, etc.).
24#[derive(Clone, Debug, Deserialize, Hash, MallocSizeOf, PartialEq, Serialize)]
25pub struct FontDescriptor {
26    pub weight: FontWeight,
27    pub stretch: FontStretch,
28    pub style: FontStyle,
29    pub variant: font_variant_caps::T,
30    pub pt_size: Au,
31    pub variation_settings: Vec<FontVariation>,
32    pub synthesis_weight: FontSynthesis,
33    pub optical_sizing: FontOpticalSizing,
34}
35
36impl Eq for FontDescriptor {}
37
38impl<'a> From<&'a FontStyleStruct> for FontDescriptor {
39    fn from(style: &'a FontStyleStruct) -> Self {
40        let variation_settings = style
41            .clone_font_variation_settings()
42            .0
43            .into_iter()
44            .map(|setting| FontVariation {
45                tag: setting.tag.0,
46                value: setting.value,
47            })
48            .collect();
49        FontDescriptor {
50            weight: style.font_weight,
51            stretch: style.font_stretch,
52            style: style.font_style,
53            variant: style.font_variant_caps,
54            pt_size: Au::from_f32_px(style.font_size.computed_size().px()),
55            variation_settings,
56            synthesis_weight: style.clone_font_synthesis_weight(),
57            optical_sizing: style.clone_font_optical_sizing(),
58        }
59    }
60}
61
62impl FontDescriptor {
63    pub fn with_variation_settings(&self, variation_settings: Vec<FontVariation>) -> Self {
64        FontDescriptor {
65            variation_settings,
66            ..*self
67        }
68    }
69}
70
71/// This data structure represents the various optional descriptors that can be
72/// applied to a `@font-face` rule in CSS. These are used to create a [`FontTemplate`]
73/// from the given font data used as the source of the `@font-face` rule. If values
74/// like weight, stretch, and style are not specified they are initialized based
75/// on the contents of the font itself.
76#[derive(Clone, Debug, Default, Deserialize, MallocSizeOf, Serialize)]
77pub struct CSSFontFaceDescriptors {
78    pub family_name: LowercaseFontFamilyName,
79    pub weight: Option<ComputedFontWeightRange>,
80    pub stretch: Option<ComputedFontStretchRange>,
81    pub style: Option<ComputedFontStyleDescriptor>,
82    pub unicode_range: Option<Vec<RangeInclusive<u32>>>,
83}
84
85impl CSSFontFaceDescriptors {
86    pub fn new(family_name: &str) -> Self {
87        CSSFontFaceDescriptors {
88            family_name: family_name.into(),
89            ..Default::default()
90        }
91    }
92}
93
94impl From<&Descriptors> for CSSFontFaceDescriptors {
95    fn from(descriptors: &Descriptors) -> Self {
96        let family_name = descriptors
97            .font_family
98            .as_ref()
99            .expect("Expected rule to contain a font family.")
100            .name
101            .clone();
102        let weight = descriptors
103            .font_weight
104            .as_ref()
105            .and_then(FontWeightRange::compute);
106        let stretch = descriptors
107            .font_stretch
108            .as_ref()
109            .and_then(FontStretchRange::compute);
110        let style = descriptors
111            .font_style
112            .as_ref()
113            .and_then(FontFaceStyle::compute);
114        let unicode_range = descriptors
115            .unicode_range
116            .as_ref()
117            .map(|ranges| ranges.iter().map(|range| range.start..=range.end).collect());
118
119        CSSFontFaceDescriptors {
120            family_name: family_name.into(),
121            weight,
122            stretch,
123            style,
124            unicode_range,
125        }
126    }
127}
128
129impl From<&FontFaceRule> for CSSFontFaceDescriptors {
130    fn from(rule: &FontFaceRule) -> Self {
131        (&rule.descriptors).into()
132    }
133}
134
135#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
136pub struct LowercaseFontFamilyName {
137    inner: String,
138}
139
140impl<T: AsRef<str>> From<T> for LowercaseFontFamilyName {
141    fn from(value: T) -> Self {
142        LowercaseFontFamilyName {
143            inner: value.as_ref().to_lowercase(),
144        }
145    }
146}
147
148impl Deref for LowercaseFontFamilyName {
149    type Target = str;
150
151    #[inline]
152    fn deref(&self) -> &str {
153        &self.inner
154    }
155}
156
157impl std::fmt::Display for LowercaseFontFamilyName {
158    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
159        self.inner.fmt(f)
160    }
161}