1use crate::{
4 character::CharacterCache,
5 color,
6 math::Matrix2d,
7 math::Vec2d,
8 types::{Color, FontSize},
9 DrawState, Graphics, Image, Transformed,
10};
11
12#[derive(Copy, Clone)]
14pub struct Text {
15 pub color: Color,
17 pub font_size: FontSize,
19 pub round: bool,
21}
22
23impl Text {
24 pub fn new(font_size: FontSize) -> Text {
26 Text {
27 color: color::BLACK,
28 font_size,
29 round: false,
30 }
31 }
32
33 pub fn new_color(color: Color, font_size: FontSize) -> Text {
35 Text {
36 color,
37 font_size,
38 round: false,
39 }
40 }
41
42 pub fn round(mut self) -> Text {
44 self.round = true;
45 self
46 }
47
48 pub fn draw_pos<C, G>(
50 &self,
51 text: &str,
52 pos: Vec2d,
53 cache: &mut C,
54 draw_state: &DrawState,
55 transform: Matrix2d,
56 g: &mut G,
57 ) -> Result<(), C::Error>
58 where
59 C: CharacterCache,
60 G: Graphics<Texture = <C as CharacterCache>::Texture>,
61 {
62 self.draw(text, cache, draw_state, transform.trans_pos(pos), g)
63 }
64
65 pub fn draw<C, G>(
67 &self,
68 text: &str,
69 cache: &mut C,
70 draw_state: &DrawState,
71 transform: Matrix2d,
72 g: &mut G,
73 ) -> Result<(), C::Error>
74 where
75 C: CharacterCache,
76 G: Graphics<Texture = <C as CharacterCache>::Texture>,
77 {
78 let mut image = Image::new_color(self.color);
79
80 let mut x = 0.0;
81 let mut y = 0.0;
82 for ch in text.chars() {
83 let character = cache.character(self.font_size, ch)?;
84 let mut ch_x = x + character.left();
85 let mut ch_y = y - character.top();
86 if self.round {
87 ch_x = ch_x.round();
88 ch_y = ch_y.round();
89 }
90 image = image.src_rect([
91 character.atlas_offset[0],
92 character.atlas_offset[1],
93 character.atlas_size[0],
94 character.atlas_size[1],
95 ]);
96 image.draw(
97 character.texture,
98 draw_state,
99 transform.trans(ch_x, ch_y),
100 g,
101 );
102 x += character.advance_width();
103 y += character.advance_height();
104 }
105
106 Ok(())
107 }
108}