1use crate::json::{json, ToJson};
2pub use font_kit::{
3 metrics::Metrics,
4 properties::{Properties, Stretch, Style, Weight},
5};
6use serde::{Deserialize, Deserializer};
7
8#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
9pub struct FontId(pub usize);
10
11pub type GlyphId = u32;
12
13#[allow(non_camel_case_types)]
14#[derive(Deserialize)]
15enum WeightJson {
16 thin,
17 extra_light,
18 light,
19 normal,
20 medium,
21 semibold,
22 bold,
23 extra_bold,
24 black,
25}
26
27#[derive(Deserialize)]
28struct PropertiesJson {
29 weight: Option<WeightJson>,
30 #[serde(default)]
31 italic: bool,
32}
33
34impl Into<Properties> for PropertiesJson {
35 fn into(self) -> Properties {
36 let mut result = Properties::new();
37 result.weight = match self.weight.unwrap_or(WeightJson::normal) {
38 WeightJson::thin => Weight::THIN,
39 WeightJson::extra_light => Weight::EXTRA_LIGHT,
40 WeightJson::light => Weight::LIGHT,
41 WeightJson::normal => Weight::NORMAL,
42 WeightJson::medium => Weight::MEDIUM,
43 WeightJson::semibold => Weight::SEMIBOLD,
44 WeightJson::bold => Weight::BOLD,
45 WeightJson::extra_bold => Weight::EXTRA_BOLD,
46 WeightJson::black => Weight::BLACK,
47 };
48 if self.italic {
49 result.style = Style::Italic;
50 }
51 result
52 }
53}
54
55pub fn deserialize_option_font_properties<'de, D>(
56 deserializer: D,
57) -> Result<Option<Properties>, D::Error>
58where
59 D: Deserializer<'de>,
60{
61 let json: Option<PropertiesJson> = Deserialize::deserialize(deserializer)?;
62 Ok(json.map(Into::into))
63}
64
65pub fn deserialize_font_properties<'de, D>(deserializer: D) -> Result<Properties, D::Error>
66where
67 D: Deserializer<'de>,
68{
69 let json: PropertiesJson = Deserialize::deserialize(deserializer)?;
70 Ok(json.into())
71}
72
73impl ToJson for Properties {
74 fn to_json(&self) -> crate::json::Value {
75 json!({
76 "style": self.style.to_json(),
77 "weight": self.weight.to_json(),
78 "stretch": self.stretch.to_json(),
79 })
80 }
81}
82
83impl ToJson for Style {
84 fn to_json(&self) -> crate::json::Value {
85 match self {
86 Style::Normal => json!("normal"),
87 Style::Italic => json!("italic"),
88 Style::Oblique => json!("oblique"),
89 }
90 }
91}
92
93impl ToJson for Weight {
94 fn to_json(&self) -> crate::json::Value {
95 if self.0 == Weight::THIN.0 {
96 json!("thin")
97 } else if self.0 == Weight::EXTRA_LIGHT.0 {
98 json!("extra light")
99 } else if self.0 == Weight::LIGHT.0 {
100 json!("light")
101 } else if self.0 == Weight::NORMAL.0 {
102 json!("normal")
103 } else if self.0 == Weight::MEDIUM.0 {
104 json!("medium")
105 } else if self.0 == Weight::SEMIBOLD.0 {
106 json!("semibold")
107 } else if self.0 == Weight::BOLD.0 {
108 json!("bold")
109 } else if self.0 == Weight::EXTRA_BOLD.0 {
110 json!("extra bold")
111 } else if self.0 == Weight::BLACK.0 {
112 json!("black")
113 } else {
114 json!(self.0)
115 }
116 }
117}
118
119impl ToJson for Stretch {
120 fn to_json(&self) -> serde_json::Value {
121 json!(self.0)
122 }
123}