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