flo_canvas/
font.rs

1use super::font_face::*;
2
3use flo_curves::geo::*;
4
5use std::sync::*;
6
7///
8/// The possible styles of a font
9///
10#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
11pub enum FontStyle {
12    Normal,
13    Italic,
14    Oblique
15}
16
17///
18/// The properties to use when selecting a font face
19///
20#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
21pub struct FontProperties {
22    pub style: FontStyle,
23    pub weight: u32
24}
25
26impl Default for FontStyle {
27    fn default() -> FontStyle { FontStyle::Normal }
28}
29
30impl Default for FontProperties {
31    fn default() -> FontProperties { FontProperties { style: FontStyle::default(), weight: 400 } }
32}
33
34impl FontProperties {
35    ///
36    /// Returns an updated font properties object with a new weight
37    ///
38    pub fn with_weight(mut self, new_weight: u32) -> FontProperties {
39        self.weight = new_weight;
40        self
41    }
42
43    ///
44    /// Returns an updated font properties object with a new style
45    ///
46    pub fn with_style(mut self, new_style: FontStyle) -> FontProperties {
47        self.style = new_style;
48        self
49    }
50}
51
52///
53/// Determines how text is drawn relative to its alignment's origin point
54///
55#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
56pub enum TextAlignment {
57    Left,
58    Right,
59    Center
60}
61
62///
63/// Operations that can be performed on a font
64///
65#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
66pub enum FontOp { 
67    /// Loads a font from a font data file
68    UseFontDefinition(Arc<CanvasFontFace>),
69
70    /// Sets the font size to use for this font ID (in canvas units)
71    FontSize(f32),
72
73    /// Lays out some text in the active layout, to be rendered in the current fill style
74    LayoutText(String),
75
76    /// Draws a series of glyphs using the current fill style
77    DrawGlyphs(Vec<GlyphPosition>)
78}
79
80///
81/// Describes where to position a line relative to some text
82///
83#[derive(Copy, Clone, PartialEq)]
84pub struct FontLinePosition {
85    pub offset:     f32,
86    pub thickness:  f32
87}
88
89///
90/// Metrics for a font
91///
92#[derive(Copy, Clone, PartialEq)]
93pub struct FontMetrics {
94    /// Size of an em relative to these metrics
95    pub em_size:            f32,
96
97    /// The ascender size for the font
98    pub ascender:           f32,
99
100    /// The descender size for the font
101    pub descender:          f32,
102
103    /// The height for the font
104    pub height:             f32,
105
106    /// The line gap for the font
107    pub line_gap:           f32,
108
109    /// The capital height for the font, if specified
110    pub capital_height:     Option<f32>,
111
112    /// Offset from the baseline and suggested thickness for an underline (can be None if the font does not specify)
113    pub underline_position: Option<FontLinePosition>,
114
115    /// Offset from the baseline and suggested thickness for a strikeout effect
116    pub strikeout_position: Option<FontLinePosition>,
117}
118
119impl FontMetrics {
120    ///
121    /// Returns the metrics adjusted to a new em size
122    ///
123    pub fn with_size(self, em_size: f32) -> FontMetrics {
124        let scale_factor = em_size / self.em_size;
125
126        FontMetrics {
127            em_size:            self.em_size * scale_factor,
128            ascender:           self.ascender * scale_factor,
129            descender:          self.descender * scale_factor,
130            height:             self.height * scale_factor,
131            line_gap:           self.line_gap * scale_factor,
132            capital_height:     self.capital_height.map(|height| height*scale_factor),
133            underline_position: self.underline_position.map(|mut pos| { pos.offset *= scale_factor; pos.thickness *= scale_factor; pos }),
134            strikeout_position: self.strikeout_position.map(|mut pos| { pos.offset *= scale_factor; pos.thickness *= scale_factor; pos }),
135        }
136    }
137}
138
139///
140/// The layout metrics for a piece of text
141///
142#[derive(Copy, Clone, PartialEq)]
143pub struct TextLayoutMetrics {
144    /// The bounding box of the text that was laid out - using the height of the font and the offsets of the glyphs
145    pub inner_bounds: (Coord2, Coord2),
146
147    /// The point where the next glyph will be positioned
148    pub pos: Coord2
149}
150
151///
152/// ID for a glyph within a font
153///
154#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
155pub struct GlyphId(pub u32);
156
157///
158/// Describes how a glyph is positioned on the canvas
159///
160#[derive(Clone, Copy, PartialEq, Debug, Serialize, Deserialize)]
161pub struct GlyphPosition {
162    /// The ID of the glyph to render
163    pub id: GlyphId,
164
165    /// Position of the glyph's baseline
166    pub location: (f32, f32),
167
168    /// The number of canvas units that map to one em in font units
169    pub em_size: f32
170}