fonts_traits/
font_descriptor.rs1use 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::{Descriptors, FontStyle as FontFaceStyle};
12use style::properties::style_structs::Font as FontStyleStruct;
13use style::stylesheets::FontFaceRule;
14use style::values::computed::font::{FixedPoint, FontStyleFixedPoint};
15use style::values::computed::{Au, FontStretch, FontStyle, FontSynthesis, FontWeight};
16use style::values::specified::FontStretch as SpecifiedFontStretch;
17use webrender_api::FontVariation;
18
19#[derive(Clone, Debug, Deserialize, Hash, MallocSizeOf, PartialEq, Serialize)]
24pub struct FontDescriptor {
25 pub weight: FontWeight,
26 pub stretch: FontStretch,
27 pub style: FontStyle,
28 pub variant: font_variant_caps::T,
29 pub pt_size: Au,
30 pub variation_settings: Vec<FontVariation>,
31 pub synthesis_weight: FontSynthesis,
32 pub optical_sizing: FontOpticalSizing,
33}
34
35impl Eq for FontDescriptor {}
36
37impl<'a> From<&'a FontStyleStruct> for FontDescriptor {
38 fn from(style: &'a FontStyleStruct) -> Self {
39 let variation_settings = style
40 .clone_font_variation_settings()
41 .0
42 .into_iter()
43 .map(|setting| FontVariation {
44 tag: setting.tag.0,
45 value: setting.value,
46 })
47 .collect();
48 FontDescriptor {
49 weight: style.font_weight,
50 stretch: style.font_stretch,
51 style: style.font_style,
52 variant: style.font_variant_caps,
53 pt_size: Au::from_f32_px(style.font_size.computed_size().px()),
54 variation_settings,
55 synthesis_weight: style.clone_font_synthesis_weight(),
56 optical_sizing: style.clone_font_optical_sizing(),
57 }
58 }
59}
60
61impl FontDescriptor {
62 pub fn with_variation_settings(&self, variation_settings: Vec<FontVariation>) -> Self {
63 FontDescriptor {
64 variation_settings,
65 ..*self
66 }
67 }
68}
69
70#[derive(Clone, Debug, Deserialize, Serialize)]
73pub enum ComputedFontStyleDescriptor {
74 Italic,
75 Oblique(FontStyleFixedPoint, FontStyleFixedPoint),
76}
77
78#[derive(Clone, Debug, Default, Deserialize, Serialize)]
84pub struct CSSFontFaceDescriptors {
85 pub family_name: LowercaseFontFamilyName,
86 pub weight: Option<(FontWeight, FontWeight)>,
87 pub stretch: Option<(FontStretch, FontStretch)>,
88 pub style: Option<ComputedFontStyleDescriptor>,
89 pub unicode_range: Option<Vec<RangeInclusive<u32>>>,
90}
91
92impl CSSFontFaceDescriptors {
93 pub fn new(family_name: &str) -> Self {
94 CSSFontFaceDescriptors {
95 family_name: family_name.into(),
96 ..Default::default()
97 }
98 }
99}
100
101impl From<&Descriptors> for CSSFontFaceDescriptors {
102 fn from(descriptors: &Descriptors) -> Self {
103 let family_name = descriptors
104 .font_family
105 .as_ref()
106 .expect("Expected rule to contain a font family.")
107 .name
108 .clone();
109 let weight = descriptors
110 .font_weight
111 .as_ref()
112 .map(|weight_range| (weight_range.0.compute(), weight_range.1.compute()));
113
114 let stretch_to_computed = |specified: SpecifiedFontStretch| match specified {
115 SpecifiedFontStretch::Stretch(percentage) => {
116 FontStretch::from_percentage(percentage.compute().0)
117 },
118 SpecifiedFontStretch::Keyword(keyword) => keyword.compute(),
119 SpecifiedFontStretch::System(_) => FontStretch::NORMAL,
120 };
121 let stretch = descriptors.font_stretch.as_ref().map(|stretch_range| {
122 (
123 stretch_to_computed(stretch_range.0),
124 stretch_to_computed(stretch_range.1),
125 )
126 });
127
128 fn style_to_computed(specified: &FontFaceStyle) -> ComputedFontStyleDescriptor {
129 match specified {
130 FontFaceStyle::Italic => ComputedFontStyleDescriptor::Italic,
131 FontFaceStyle::Oblique(angle_a, angle_b) => ComputedFontStyleDescriptor::Oblique(
132 FixedPoint::from_float(angle_a.degrees()),
133 FixedPoint::from_float(angle_b.degrees()),
134 ),
135 }
136 }
137 let style = descriptors.font_style.as_ref().map(style_to_computed);
138 let unicode_range = descriptors
139 .unicode_range
140 .as_ref()
141 .map(|ranges| ranges.iter().map(|range| range.start..=range.end).collect());
142
143 CSSFontFaceDescriptors {
144 family_name: family_name.into(),
145 weight,
146 stretch,
147 style,
148 unicode_range,
149 }
150 }
151}
152
153impl From<&FontFaceRule> for CSSFontFaceDescriptors {
154 fn from(rule: &FontFaceRule) -> Self {
155 (&rule.descriptors).into()
156 }
157}
158
159#[derive(Clone, Debug, Default, Deserialize, Eq, Hash, MallocSizeOf, PartialEq, Serialize)]
160pub struct LowercaseFontFamilyName {
161 inner: String,
162}
163
164impl<T: AsRef<str>> From<T> for LowercaseFontFamilyName {
165 fn from(value: T) -> Self {
166 LowercaseFontFamilyName {
167 inner: value.as_ref().to_lowercase(),
168 }
169 }
170}
171
172impl Deref for LowercaseFontFamilyName {
173 type Target = str;
174
175 #[inline]
176 fn deref(&self) -> &str {
177 &self.inner
178 }
179}
180
181impl std::fmt::Display for LowercaseFontFamilyName {
182 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
183 self.inner.fmt(f)
184 }
185}