fonts.rs

  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}