telar_renderer_core/style/
mod.rs1mod gradient;
2mod paint;
3mod scale;
4mod shape;
5
6pub use gradient::{Gradient, GradientKind, GradientStop, GradientStops};
7pub use paint::{FillRule, LineCap, LineJoin, Paint, Shadow, Stroke};
8pub use shape::{BorderWidths, PathStyle, RectStyle, ShapeStyle, border_inner_shape};
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
12pub enum TextAlign {
13 #[default]
14 Start,
15 Center,
16 End,
17 Justify,
18}
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
26pub enum GlyphRaster {
27 #[default]
29 Smooth,
30 Pixel,
37}
38
39#[derive(Debug, Clone, Copy, PartialEq)]
40pub struct TextStyle {
41 pub font_size: f32,
42 pub paint: Paint,
43 pub shadow: Option<Shadow>,
44 pub weight: u16,
46 pub italic: bool,
47 pub align: TextAlign,
48 pub max_lines: Option<u16>,
50 pub ellipsis: bool,
52 pub line_height: Option<f32>,
54 pub letter_spacing: f32,
56 pub raster: GlyphRaster,
58 pub no_wrap: bool,
65}
66
67impl TextStyle {
68 pub fn new(font_size: f32, paint: impl Into<Paint>) -> Self {
69 Self {
70 font_size,
71 paint: paint.into(),
72 shadow: None,
73 weight: 400,
74 italic: false,
75 align: TextAlign::Start,
76 max_lines: None,
77 ellipsis: false,
78 line_height: None,
79 letter_spacing: 0.0,
80 raster: GlyphRaster::Smooth,
81 no_wrap: false,
82 }
83 }
84
85 pub fn with_no_wrap(mut self, no_wrap: bool) -> Self {
87 self.no_wrap = no_wrap;
88 self
89 }
90
91 pub fn with_weight(mut self, weight: u16) -> Self {
92 self.weight = weight;
93 self
94 }
95
96 pub fn with_shadow(mut self, shadow: Shadow) -> Self {
98 self.shadow = Some(shadow);
99 self
100 }
101
102 pub fn with_italic(mut self, italic: bool) -> Self {
103 self.italic = italic;
104 self
105 }
106
107 pub fn with_align(mut self, align: TextAlign) -> Self {
108 self.align = align;
109 self
110 }
111
112 pub fn with_max_lines(mut self, max_lines: u16) -> Self {
113 self.max_lines = Some(max_lines);
114 self
115 }
116
117 pub fn with_ellipsis(mut self, ellipsis: bool) -> Self {
118 self.ellipsis = ellipsis;
119 self
120 }
121
122 pub fn with_line_height(mut self, line_height: f32) -> Self {
123 self.line_height = Some(line_height);
124 self
125 }
126
127 pub fn with_letter_spacing(mut self, letter_spacing: f32) -> Self {
128 self.letter_spacing = letter_spacing;
129 self
130 }
131
132 pub fn with_raster(mut self, raster: GlyphRaster) -> Self {
134 self.raster = raster;
135 self
136 }
137}
138
139pub trait Scale: Sized {
140 fn scale(self, sf: f32) -> Self;
141}
142
143#[cfg(test)]
144mod tests {
145 use super::*;
146 use crate::Color;
147
148 #[test]
149 fn text_style_new_stores_font_size() {
150 let style = TextStyle::new(16.0, Color::BLACK);
151 assert_eq!(style.font_size, 16.0);
152 }
153
154 #[test]
155 fn text_style_new_stores_color() {
156 let style = TextStyle::new(12.0, Color::WHITE);
157 assert_eq!(style.paint, Paint::Solid(Color::WHITE));
158 }
159
160 #[test]
161 fn text_style_defaults_to_natural_spacing() {
162 let style = TextStyle::new(16.0, Color::BLACK);
163 assert_eq!(style.line_height, None);
164 assert_eq!(style.letter_spacing, 0.0);
165 }
166
167 #[test]
168 fn text_style_builders_set_spacing() {
169 let style = TextStyle::new(16.0, Color::BLACK)
170 .with_line_height(1.5)
171 .with_letter_spacing(2.0);
172 assert_eq!(style.line_height, Some(1.5));
173 assert_eq!(style.letter_spacing, 2.0);
174 }
175}