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