1use crate::ModelError;
2
3#[derive(Default, Eq, PartialEq, Clone, Debug)]
4pub struct Font {
5 pub weight: Option<Weight>,
6 pub style: Option<Style>,
7 pub underline: Option<bool>,
8 pub strike_out: Option<bool>,
9 pub size: Option<FontSize>,
10 pub capitalisation: Option<Capitalisation>,
11 pub families: Option<Vec<String>>,
12 pub letter_spacing: Option<isize>,
13 pub letter_spacing_type: Option<SpacingType>,
14 pub word_spacing: Option<isize>,
16}
17
18impl Font {
19 pub fn new() -> Self {
20 Font {
21 ..Default::default()
22 }
23 }
24
25 pub fn set_bold(&mut self, is_bold: bool) {
26 if is_bold {
27 self.weight = Some(Weight::Bold)
28 } else {
29 self.weight = Some(Weight::Normal)
30 }
31 }
32
33 pub fn bold(&self) -> bool {
34 self.weight >= Some(Weight::Bold)
35 }
36
37 pub fn set_italic(&mut self, is_italic: bool) {
38 if is_italic {
39 self.style = Some(Style::Italic)
40 } else {
41 self.style = Some(Style::Normal)
42 }
43 }
44
45 pub fn italic(&self) -> bool {
46 self.style >= Some(Style::Italic)
47 }
48
49 pub fn family(&self) -> Option<&String> {
50 if let Some(families) = &self.families {
51 families.first()
52 } else {
53 None
54 }
55 }
56
57 pub(crate) fn merge_with(&mut self, other_font: &Self) -> Result<(), ModelError>
66 where
67 Self: Sized,
68 {
69 if let Some(value) = other_font.weight {
70 self.weight = Some(value);
71 }
72
73 if let Some(value) = other_font.style {
74 self.style = Some(value);
75 }
76
77 if let Some(value) = other_font.underline {
78 self.underline = Some(value);
79 }
80
81 if let Some(value) = other_font.strike_out {
82 self.strike_out = Some(value);
83 }
84
85 if let Some(value) = other_font.size {
86 self.size = Some(value);
87 }
88
89 if let Some(value) = other_font.capitalisation {
90 self.capitalisation = Some(value);
91 }
92
93 if let Some(value) = other_font.families.clone() {
94 self.families = Some(value);
95 }
96 if let Some(value) = other_font.letter_spacing {
97 self.letter_spacing = Some(value);
98 }
99 if let Some(value) = other_font.letter_spacing_type {
100 self.letter_spacing_type = Some(value);
101 }
102 if let Some(value) = other_font.word_spacing {
103 self.word_spacing = Some(value);
104 }
105
106 Ok(())
107 }
108}
109#[derive(Eq, PartialEq, Clone, Copy, Debug)]
110pub struct FontSize {
111 size_type: SizeType,
112 size: usize,
113}
114
115impl PartialOrd for FontSize {
116 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
117 if self.size_type.eq(&other.size_type) {
118 self.size.partial_cmp(&other.size)
119 } else {
120 None
121 }
122 }
123}
124
125#[derive(Eq, PartialEq, Clone, Copy, Debug)]
126pub enum SizeType {
127 Point,
128 Pixel,
129}
130
131pub enum UnderlineStyle {}
132#[derive(Eq, PartialEq, Clone, Copy, Debug)]
133pub enum Capitalisation {
134 MixedCase,
135 AllUppercase,
136 AllLowercase,
137 SmallCaps,
138 Capitalize,
139}
140
141impl Default for Capitalisation {
142 fn default() -> Self {
143 Capitalisation::MixedCase
144 }
145}
146
147#[derive(Eq, PartialEq, PartialOrd, Clone, Copy, Debug)]
148pub enum Style {
149 Normal,
151 Italic,
153 Oblique,
155}
156
157impl Default for Style {
158 fn default() -> Self {
159 Style::Normal
160 }
161}
162
163#[derive(Eq, PartialEq, PartialOrd, Clone, Copy, Debug)]
165pub enum SpacingType {
166 PercentageSpacing,
168 AbsoluteSpacing,
170}
171
172impl Default for SpacingType {
173 fn default() -> Self {
174 SpacingType::PercentageSpacing
175 }
176}
177
178#[derive(Eq, PartialEq, PartialOrd, Clone, Copy, Debug)]
180pub enum Weight {
181 Thin = 100,
182 ExtraLight = 200,
183 Light = 300,
184 Normal = 400,
185 Medium = 500,
186 DemiBold = 600,
187 Bold = 700,
188 ExtraBold = 800,
189 Black = 900,
190}
191
192impl Default for Weight {
193 fn default() -> Self {
194 Weight::Normal
195 }
196}