graphics/
text.rs

1//! Draw text
2
3use crate::{
4    character::CharacterCache,
5    color,
6    math::Matrix2d,
7    math::Vec2d,
8    types::{Color, FontSize},
9    DrawState, Graphics, Image, Transformed,
10};
11
12/// Renders text
13#[derive(Copy, Clone)]
14pub struct Text {
15    /// The color
16    pub color: Color,
17    /// The font size
18    pub font_size: FontSize,
19    /// Whether or not the text's position should be rounded (to a signed distance field).
20    pub round: bool,
21}
22
23impl Text {
24    /// Creates a new text with black color
25    pub fn new(font_size: FontSize) -> Text {
26        Text {
27            color: color::BLACK,
28            font_size,
29            round: false,
30        }
31    }
32
33    /// Creates a new colored text
34    pub fn new_color(color: Color, font_size: FontSize) -> Text {
35        Text {
36            color,
37            font_size,
38            round: false,
39        }
40    }
41
42    /// A builder method indicating that the Text's position should be rounded upon drawing.
43    pub fn round(mut self) -> Text {
44        self.round = true;
45        self
46    }
47
48    /// Draws text at position with a character cache
49    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    /// Draws text with a character cache
66    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}