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