three_d_text_builder/
text.rs

1// External Dependencies ------------------------------------------------------
2// ----------------------------------------------------------------------------
3use three_d::{Srgba, Mat4, vec2, Vec2, SquareMatrix};
4
5
6// Internal Dependencies ------------------------------------------------------
7// ----------------------------------------------------------------------------
8use crate::{TextAlign, TextPosition, TextRef};
9
10
11// Types Dependencies ---------------------------------------------------------
12// ----------------------------------------------------------------------------
13type CharacterColor = dyn Fn(usize, usize, char) -> Srgba;
14type CharacterTransform = dyn Fn(usize, usize, char) -> (Mat4, Mat4);
15
16///
17/// Description of how an owned String should be rendered as a text mesh.
18///
19pub struct Text {
20    /// Text to render
21    pub text: String,
22    /// Font size used by the resulting mesh
23    pub size: f32,
24    /// Font size used for glyph rasterization; when `None`, [``Text::size``] will be used
25    pub raster_size: Option<f32>,
26    /// Line height scaling used by the resulting mesh
27    pub line_height: Option<f32>,
28    /// Padding used by the resuling mesh
29    pub padding: Vec2,
30    /// Font color used by the resulting mesh
31    pub color: Srgba,
32    /// Shadow color and offset user by the resulting mesh
33    pub shadow: Option<(Srgba, Vec2)>,
34    /// Function to generate per-character colors
35    pub character_color: Option<Box<CharacterColor>>,
36    /// Alignment used by the resulting mesh.
37    pub align: TextAlign,
38    /// Position used by the resulting; see [``TextAlign``] for how this is computed
39    pub position: TextPosition,
40    /// Transform used by the resulting mesh
41    pub transform: Mat4,
42    /// Function to generate per-character position and vertex transforms
43    pub character_transform: Option<Box<CharacterTransform>>
44}
45
46impl Default for Text {
47    fn default() -> Self {
48        Self {
49            text: "Text".to_string(),
50            size: 32.0,
51            raster_size: None,
52            line_height: None,
53            padding: vec2(0.0, 0.0),
54            color: Srgba::WHITE,
55            character_color: None,
56            align: TextAlign::default(),
57            shadow: None,
58            position: TextPosition::Pixels(vec2(0.0, 0.0)),
59            transform: Mat4::identity(),
60            character_transform: None
61        }
62    }
63}
64
65impl Text {
66    /// Creates a new text description for the given String.
67    pub fn new<S: Into<String>>(text: S) -> Self {
68        Self {
69            text: text.into(),
70            ..Default::default()
71        }
72    }
73
74    /// Specifies the font size used by the resulting mesh.
75    pub fn size(mut self, size: f32) -> Self {
76        self.size = size;
77        self
78    }
79
80    /// Specifies the font size used for glyph rasterization; when `None`, [``Text::size``] will be used.
81    pub fn raster_size(mut self, raster_size: f32) -> Self {
82        self.raster_size = Some(raster_size);
83        self
84    }
85
86    /// Specifies the line height scaling used by the resulting mesh.
87    pub fn line_height(mut self, line_height: f32) -> Self {
88        self.line_height = Some(line_height);
89        self
90    }
91
92    /// Specifies the padding used by the resulting mesh.
93    pub fn padding(mut self, padding: Vec2) -> Self {
94        self.padding = padding;
95        self
96    }
97
98    /// Specifies the font color used by the resulting mesh.
99    pub fn color(mut self, color: Srgba) -> Self {
100        self.color = color;
101        self
102    }
103
104    /// Specifies the shadow color and offset user by the resulting mesh.
105    pub fn shadow(mut self, color: Srgba, offset: Vec2) -> Self {
106        self.shadow = Some((color, offset));
107        self
108    }
109
110    /// Specifies the function to generate per-character colors.
111    ///
112    /// These colors do overide the color set by [``Text::color``].
113    pub fn character_color(mut self, color: Box<CharacterColor>) -> Self {
114        self.character_color = Some(color);
115        self
116    }
117
118    /// Specifies the alignment used by the resulting mesh.
119    pub fn align(mut self, align: TextAlign) -> Self {
120        self.align = align;
121        self
122    }
123
124    /// Specifies the position used by the resulting; see [``TextAlign``] for how this is computed.
125    pub fn position(mut self, position: TextPosition) -> Self {
126        self.position = position;
127        self
128    }
129
130    /// Specifies the transform used by the resulting mesh.
131    pub fn transform(mut self, transform: Mat4) -> Self {
132        self.transform = transform;
133        self
134    }
135
136    /// Specifies the function to generate per-character position and vertex transforms.
137    pub fn character_transform(mut self, transform: Box<CharacterTransform>) -> Self {
138        self.character_transform = Some(transform);
139        self
140    }
141
142    /// Creates a [``TextRef``] referencing this text's data.
143    pub fn as_ref(&self) -> TextRef {
144        TextRef {
145            text: self.text.as_str(),
146            size: self.size,
147            raster_size: self.raster_size,
148            line_height: self.line_height,
149            padding: self.padding,
150            color: self.color,
151            character_color: self.character_color.as_deref(),
152            align: self.align,
153            shadow: self.shadow,
154            position: self.position,
155            transform: self.transform,
156            character_transform: self.character_transform.as_deref()
157        }
158    }
159}
160