text_document/
font.rs

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    /// Sets the word spacing for the font to spacing. Word spacing changes the default spacing between individual words. A positive value increases the word spacing by a corresponding amount of pixels, while a negative value decreases the inter-word spacing accordingly.
15    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 fn to_string(&self) -> String {
58    //     "".to_string()
59    // }
60
61    // pub fn from_string(&self, string: &String) -> Result<(), FontError>{
62
63    // }
64
65    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 glyphs used in unstyled text.
150    Normal,
151    /// Italic glyphs that are specifically designed for the purpose of representing italicized text.
152    Italic,
153    /// Glyphs with an italic appearance that are typically based on the unstyled glyphs, but are not fine-tuned for the purpose of representing italicized text.
154    Oblique,
155}
156
157impl Default for Style {
158    fn default() -> Self {
159        Style::Normal
160    }
161}
162
163/// Spacing between letters
164#[derive(Eq, PartialEq, PartialOrd, Clone, Copy, Debug)]
165pub enum SpacingType {
166    /// A value of 100 will keep the spacing unchanged; a value of 200 will enlarge the spacing after a character by the width of the character itself.
167    PercentageSpacing,
168    /// A positive value increases the letter spacing by the corresponding pixels; a negative value decreases the spacing.
169    AbsoluteSpacing,
170}
171
172impl Default for SpacingType {
173    fn default() -> Self {
174        SpacingType::PercentageSpacing
175    }
176}
177
178/// Predefined font weights. Compatible with OpenType. A weight of 1 will be thin, whilst 1000 will be extremely black.
179#[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}