incular_text/style/
fonts.rs1use incular_core::Lerp;
2use std::sync::Arc;
3
4#[derive(Clone, Debug, PartialEq, Eq, Hash)]
7pub enum FontFamily {
8 SansSerif,
9 Serif,
10 Monospace,
11 Cursive,
12 SystemUi,
13 Named(Arc<str>),
14}
15
16impl FontFamily {
17 #[must_use]
18 pub fn named(name: impl Into<String>) -> Self {
19 Self::Named(name.into().into())
20 }
21}
22
23#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
25pub struct FontWeight(pub u16);
26
27impl FontWeight {
28 pub const W100: Self = Self(100);
29 pub const W200: Self = Self(200);
30 pub const W300: Self = Self(300);
31 pub const W400: Self = Self(400);
32 pub const W500: Self = Self(500);
33 pub const W600: Self = Self(600);
34 pub const W700: Self = Self(700);
35 pub const W800: Self = Self(800);
36 pub const W900: Self = Self(900);
37
38 pub const THIN: Self = Self::W100;
39 pub const EXTRA_LIGHT: Self = Self::W200;
40 pub const LIGHT: Self = Self::W300;
41 pub const NORMAL: Self = Self::W400;
42 pub const MEDIUM: Self = Self::W500;
43 pub const SEMI_BOLD: Self = Self::W600;
44 pub const BOLD: Self = Self::W700;
45 pub const EXTRA_BOLD: Self = Self::W800;
46 pub const BLACK: Self = Self::W900;
47
48 #[must_use]
49 pub const fn new(value: u16) -> Self {
50 Self(if value < 1 {
51 1
52 } else if value > 1000 {
53 1000
54 } else {
55 value
56 })
57 }
58
59 #[must_use]
60 pub const fn value(self) -> u16 {
61 self.0
62 }
63}
64
65impl Lerp for FontWeight {
66 fn lerp(&self, other: &Self, t: f32) -> Self {
67 let t = t.clamp(0.0, 1.0);
68 let left = self.0 as f32;
69 let right = other.0 as f32;
70 Self::new((left + (right - left) * t).round() as u16)
71 }
72}
73
74#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
76pub struct FontFeature {
77 pub tag: [u8; 4],
78 pub value: i32,
79}
80
81impl FontFeature {
82 #[must_use]
83 pub const fn new(tag: [u8; 4], value: i32) -> Self {
84 Self { tag, value }
85 }
86
87 #[must_use]
88 pub const fn enable(tag: [u8; 4]) -> Self {
89 Self::new(tag, 1)
90 }
91
92 #[must_use]
93 pub const fn disable(tag: [u8; 4]) -> Self {
94 Self::new(tag, 0)
95 }
96
97 #[must_use]
98 pub const fn alternative(value: i32) -> Self {
99 Self::new(*b"aalt", value)
100 }
101
102 #[must_use]
103 pub const fn contextual_alternates() -> Self {
104 Self::enable(*b"calt")
105 }
106
107 #[must_use]
108 pub const fn tabular_figures() -> Self {
109 Self::enable(*b"tnum")
110 }
111
112 #[must_use]
113 pub const fn proportional_figures() -> Self {
114 Self::enable(*b"pnum")
115 }
116
117 #[must_use]
118 pub const fn slashed_zero() -> Self {
119 Self::enable(*b"zero")
120 }
121
122 #[must_use]
123 pub fn to_css_setting(&self) -> String {
124 let tag_str = std::str::from_utf8(&self.tag).unwrap_or("????");
125 format!("\"{}\" {}", tag_str, self.value)
126 }
127}
128
129#[derive(Clone, Copy, Debug, PartialEq)]
131pub struct FontVariation {
132 pub axis: [u8; 4],
133 pub value: f32,
134}
135
136impl FontVariation {
137 #[must_use]
138 pub const fn new(axis: [u8; 4], value: f32) -> Self {
139 Self { axis, value }
140 }
141
142 #[must_use]
143 pub const fn weight(value: f32) -> Self {
144 Self::new(*b"wght", value)
145 }
146
147 #[must_use]
148 pub const fn italic(value: f32) -> Self {
149 Self::new(*b"ital", value)
150 }
151
152 #[must_use]
153 pub const fn slant(value: f32) -> Self {
154 Self::new(*b"slnt", value)
155 }
156
157 #[must_use]
158 pub const fn width(value: f32) -> Self {
159 Self::new(*b"wdth", value)
160 }
161
162 #[must_use]
163 pub const fn optical_size(value: f32) -> Self {
164 Self::new(*b"opsz", value)
165 }
166
167 #[must_use]
168 pub fn to_css_setting(&self) -> String {
169 let axis_str = std::str::from_utf8(&self.axis).unwrap_or("????");
170 format!("\"{}\" {:.1}", axis_str, self.value)
171 }
172}
173
174impl Lerp for FontVariation {
175 fn lerp(&self, other: &Self, t: f32) -> Self {
176 Self::new(self.axis, self.value.lerp(&other.value, t))
177 }
178}