freya_core/values/
font.rs

1use freya_engine::prelude::*;
2
3use crate::parsing::{
4    Parse,
5    ParseError,
6};
7
8impl Parse for TextAlign {
9    fn parse(value: &str) -> Result<Self, ParseError> {
10        Ok(match value {
11            "center" => TextAlign::Center,
12            "justify" => TextAlign::Justify,
13            "start" => TextAlign::Start,
14            "end" => TextAlign::End,
15            "left" => TextAlign::Left,
16            "right" => TextAlign::Right,
17            _ => TextAlign::default(),
18        })
19    }
20}
21
22impl Parse for Slant {
23    fn parse(value: &str) -> Result<Self, ParseError> {
24        Ok(match value {
25            "upright" => Slant::Upright,
26            "italic" => Slant::Italic,
27            "oblique" => Slant::Oblique,
28            _ => Slant::Upright,
29        })
30    }
31}
32
33impl Parse for Width {
34    fn parse(value: &str) -> Result<Self, ParseError> {
35        Ok(match value {
36            "ultra-condensed" => Width::ULTRA_CONDENSED,
37            "extra-condensed" => Width::EXTRA_CONDENSED,
38            "condensed" => Width::CONDENSED,
39            "semi-condensed" => Width::SEMI_CONDENSED,
40            "normal" => Width::NORMAL,
41            "semi-expanded" => Width::SEMI_EXPANDED,
42            "expanded" => Width::EXPANDED,
43            "extra-expanded" => Width::EXTRA_EXPANDED,
44            "ultra-expanded" => Width::ULTRA_EXPANDED,
45            _ => Width::NORMAL,
46        })
47    }
48}
49
50impl Parse for Weight {
51    // NOTES:
52    // This is mostly taken from the OpenType specification (https://learn.microsoft.com/en-us/typography/opentype/spec/os2#usweightclass)
53    // CSS has one deviation from this spec, which uses the value "950" for extra_black.
54    // skia_safe also has an "invisible" weight smaller than the thin weight, which could fall under CSS's interpretation of OpenType's
55    // version. In this case it would be font_weight: "50".
56    fn parse(value: &str) -> Result<Self, ParseError> {
57        Ok(match value {
58            "invisible" => Weight::INVISIBLE,
59            "thin" => Weight::THIN,
60            "extra-light" => Weight::EXTRA_LIGHT,
61            "light" => Weight::LIGHT,
62            "normal" => Weight::NORMAL,
63            "medium" => Weight::MEDIUM,
64            "semi-bold" => Weight::SEMI_BOLD,
65            "bold" => Weight::BOLD,
66            "extra-bold" => Weight::EXTRA_BOLD,
67            "black" => Weight::BLACK,
68            "extra-black" => Weight::EXTRA_BLACK,
69            "50" => Weight::INVISIBLE,
70            "100" => Weight::THIN,
71            "200" => Weight::EXTRA_LIGHT,
72            "300" => Weight::LIGHT,
73            "400" => Weight::NORMAL,
74            "500" => Weight::MEDIUM,
75            "600" => Weight::SEMI_BOLD,
76            "700" => Weight::BOLD,
77            "800" => Weight::EXTRA_BOLD,
78            "900" => Weight::BLACK,
79            "950" => Weight::EXTRA_BLACK,
80            _ => Weight::NORMAL,
81        })
82    }
83}
84
85#[derive(Default, Clone, Debug, PartialEq)]
86pub enum TextOverflow {
87    #[default]
88    Clip,
89    Ellipsis,
90    Custom(String),
91}
92
93impl TextOverflow {
94    pub fn get_ellipsis(&self) -> Option<&str> {
95        match self {
96            Self::Clip => None,
97            Self::Ellipsis => Some("…"),
98            Self::Custom(custom) => Some(custom),
99        }
100    }
101
102    pub fn pretty(&self) -> String {
103        match self {
104            TextOverflow::Clip => "clip".to_string(),
105            TextOverflow::Ellipsis => "ellipsis".to_string(),
106            TextOverflow::Custom(text_overflow) => text_overflow.to_string(),
107        }
108    }
109}
110
111impl Parse for TextOverflow {
112    fn parse(value: &str) -> Result<Self, ParseError> {
113        Ok(match value {
114            "ellipsis" => TextOverflow::Ellipsis,
115            "clip" => TextOverflow::Clip,
116            value => TextOverflow::Custom(value.to_string()),
117        })
118    }
119}