Skip to main content

measure_text

Function measure_text 

Source
pub fn measure_text(
    text: impl AsRef<str>,
    font: Option<&Font>,
    font_size: u16,
    font_scale: f32,
) -> TextDimensions
Examples found in repository?
examples/text_measures.rs (line 4)
3fn draw_text_annotated(text: &str, font: Option<&Font>, x: f32, baseline: f32) {
4    let size = measure_text(text, font, 100, 1.0);
5
6    // Full background rect
7    draw_rectangle(x, baseline - size.offset_y, size.width, size.height, BLUE);
8
9    // Base line
10    draw_rectangle(x, baseline - 2.0, size.width, 4.0, RED);
11
12    // Base line annotation
13    draw_rectangle(x + size.width, baseline - 1.0, 120.0, 1.0, GRAY);
14    draw_text(
15        "baseline",
16        x + size.width + 10.0,
17        baseline - 5.0,
18        30.0,
19        WHITE,
20    );
21
22    // Top line
23    draw_rectangle(x, baseline - 2.0 - size.offset_y, size.width, 4.0, RED);
24
25    // Top line annotation
26    draw_rectangle(
27        x + size.width,
28        baseline - size.offset_y - 1.0,
29        120.0,
30        1.0,
31        GRAY,
32    );
33    draw_text(
34        "topline",
35        x + size.width + 10.0,
36        baseline - size.offset_y - 5.0,
37        30.0,
38        WHITE,
39    );
40
41    // Bottom line
42    draw_rectangle(
43        x,
44        baseline - 2.0 - size.offset_y + size.height,
45        size.width,
46        4.0,
47        RED,
48    );
49
50    // Bottom line annotation
51    draw_rectangle(
52        x + size.width,
53        baseline - size.offset_y + size.height - 1.0,
54        120.0,
55        1.0,
56        GRAY,
57    );
58    draw_text(
59        "bottomline",
60        x + size.width + 10.0,
61        baseline - size.offset_y + size.height - 5.0,
62        30.0,
63        WHITE,
64    );
65
66    draw_text_ex(
67        text,
68        x,
69        baseline,
70        TextParams {
71            font_size: 100,
72            font,
73            ..Default::default()
74        },
75    );
76}
More examples
Hide additional examples
examples/snake.rs (line 139)
16async fn main() {
17    let mut snake = Snake {
18        head: (0, 0),
19        dir: (1, 0),
20        body: LinkedList::new(),
21    };
22    let mut fruit: Point = (rand::gen_range(0, SQUARES), rand::gen_range(0, SQUARES));
23    let mut score = 0;
24    let mut speed = 0.3;
25    let mut last_update = get_time();
26    let mut navigation_lock = false;
27    let mut game_over = false;
28
29    let up = (0, -1);
30    let down = (0, 1);
31    let right = (1, 0);
32    let left = (-1, 0);
33
34    loop {
35        if !game_over {
36            if is_key_down(KeyCode::Right) && snake.dir != left && !navigation_lock {
37                snake.dir = right;
38                navigation_lock = true;
39            } else if is_key_down(KeyCode::Left) && snake.dir != right && !navigation_lock {
40                snake.dir = left;
41                navigation_lock = true;
42            } else if is_key_down(KeyCode::Up) && snake.dir != down && !navigation_lock {
43                snake.dir = up;
44                navigation_lock = true;
45            } else if is_key_down(KeyCode::Down) && snake.dir != up && !navigation_lock {
46                snake.dir = down;
47                navigation_lock = true;
48            }
49
50            if get_time() - last_update > speed {
51                last_update = get_time();
52                snake.body.push_front(snake.head);
53                snake.head = (snake.head.0 + snake.dir.0, snake.head.1 + snake.dir.1);
54                if snake.head == fruit {
55                    fruit = (rand::gen_range(0, SQUARES), rand::gen_range(0, SQUARES));
56                    score += 100;
57                    speed *= 0.9;
58                } else {
59                    snake.body.pop_back();
60                }
61                if snake.head.0 < 0
62                    || snake.head.1 < 0
63                    || snake.head.0 >= SQUARES
64                    || snake.head.1 >= SQUARES
65                {
66                    game_over = true;
67                }
68                for (x, y) in &snake.body {
69                    if *x == snake.head.0 && *y == snake.head.1 {
70                        game_over = true;
71                    }
72                }
73                navigation_lock = false;
74            }
75        }
76        if !game_over {
77            clear_background(LIGHTGRAY);
78
79            let game_size = screen_width().min(screen_height());
80            let offset_x = (screen_width() - game_size) / 2. + 10.;
81            let offset_y = (screen_height() - game_size) / 2. + 10.;
82            let sq_size = (screen_height() - offset_y * 2.) / SQUARES as f32;
83
84            draw_rectangle(offset_x, offset_y, game_size - 20., game_size - 20., WHITE);
85
86            for i in 1..SQUARES {
87                draw_line(
88                    offset_x,
89                    offset_y + sq_size * i as f32,
90                    screen_width() - offset_x,
91                    offset_y + sq_size * i as f32,
92                    2.,
93                    LIGHTGRAY,
94                );
95            }
96
97            for i in 1..SQUARES {
98                draw_line(
99                    offset_x + sq_size * i as f32,
100                    offset_y,
101                    offset_x + sq_size * i as f32,
102                    screen_height() - offset_y,
103                    2.,
104                    LIGHTGRAY,
105                );
106            }
107
108            draw_rectangle(
109                offset_x + snake.head.0 as f32 * sq_size,
110                offset_y + snake.head.1 as f32 * sq_size,
111                sq_size,
112                sq_size,
113                DARKGREEN,
114            );
115
116            for (x, y) in &snake.body {
117                draw_rectangle(
118                    offset_x + *x as f32 * sq_size,
119                    offset_y + *y as f32 * sq_size,
120                    sq_size,
121                    sq_size,
122                    LIME,
123                );
124            }
125
126            draw_rectangle(
127                offset_x + fruit.0 as f32 * sq_size,
128                offset_y + fruit.1 as f32 * sq_size,
129                sq_size,
130                sq_size,
131                GOLD,
132            );
133
134            draw_text(format!("SCORE: {score}").as_str(), 10., 20., 20., DARKGRAY);
135        } else {
136            clear_background(WHITE);
137            let text = "Game Over. Press [enter] to play again.";
138            let font_size = 30.;
139            let text_size = measure_text(text, None, font_size as _, 1.0);
140
141            draw_text(
142                text,
143                screen_width() / 2. - text_size.width / 2.,
144                screen_height() / 2. + text_size.height / 2.,
145                font_size,
146                DARKGRAY,
147            );
148
149            if is_key_down(KeyCode::Enter) {
150                snake = Snake {
151                    head: (0, 0),
152                    dir: (1, 0),
153                    body: LinkedList::new(),
154                };
155                fruit = (rand::gen_range(0, SQUARES), rand::gen_range(0, SQUARES));
156                score = 0;
157                speed = 0.3;
158                last_update = get_time();
159                game_over = false;
160            }
161        }
162        next_frame().await;
163    }
164}
examples/asteroids.rs (line 69)
46async fn main() {
47    let mut ship = Ship {
48        pos: Vec2::new(screen_width() / 2., screen_height() / 2.),
49        rot: 0.,
50        vel: Vec2::new(0., 0.),
51    };
52
53    let mut bullets = Vec::new();
54    let mut last_shot = get_time();
55    let mut asteroids = Vec::new();
56    let mut gameover = false;
57
58    let mut screen_center;
59
60    loop {
61        if gameover {
62            clear_background(LIGHTGRAY);
63            let mut text = "You Win!. Press [enter] to play again.";
64            let font_size = 30.;
65
66            if asteroids.len() > 0 {
67                text = "Game Over. Press [enter] to play again.";
68            }
69            let text_size = measure_text(text, None, font_size as _, 1.0);
70            draw_text(
71                text,
72                screen_width() / 2. - text_size.width / 2.,
73                screen_height() / 2. - text_size.height / 2.,
74                font_size,
75                DARKGRAY,
76            );
77            if is_key_down(KeyCode::Enter) {
78                ship = Ship {
79                    pos: Vec2::new(screen_width() / 2., screen_height() / 2.),
80                    rot: 0.,
81                    vel: Vec2::new(0., 0.),
82                };
83                bullets = Vec::new();
84                asteroids = Vec::new();
85                gameover = false;
86                screen_center = Vec2::new(screen_width() / 2., screen_height() / 2.);
87                for _ in 0..10 {
88                    asteroids.push(Asteroid {
89                        pos: screen_center
90                            + Vec2::new(rand::gen_range(-1., 1.), rand::gen_range(-1., 1.))
91                                .normalize()
92                                * screen_width().min(screen_height())
93                                / 2.,
94                        vel: Vec2::new(rand::gen_range(-1., 1.), rand::gen_range(-1., 1.)),
95                        rot: 0.,
96                        rot_speed: rand::gen_range(-2., 2.),
97                        size: screen_width().min(screen_height()) / 10.,
98                        sides: rand::gen_range(3, 8),
99                        collided: false,
100                    })
101                }
102            }
103            next_frame().await;
104            continue;
105        }
106        let frame_t = get_time();
107        let rotation = ship.rot.to_radians();
108
109        let mut acc = -ship.vel / 100.; // Friction
110
111        // Forward
112        if is_key_down(KeyCode::Up) {
113            acc = Vec2::new(rotation.sin(), -rotation.cos()) / 3.;
114        }
115
116        // Shot
117        if is_key_down(KeyCode::Space) && frame_t - last_shot > 0.5 {
118            let rot_vec = Vec2::new(rotation.sin(), -rotation.cos());
119            bullets.push(Bullet {
120                pos: ship.pos + rot_vec * SHIP_HEIGHT / 2.,
121                vel: rot_vec * 7.,
122                shot_at: frame_t,
123                collided: false,
124            });
125            last_shot = frame_t;
126        }
127
128        // Steer
129        if is_key_down(KeyCode::Right) {
130            ship.rot += 5.;
131        } else if is_key_down(KeyCode::Left) {
132            ship.rot -= 5.;
133        }
134
135        // Euler integration
136        ship.vel += acc;
137        if ship.vel.length() > 5. {
138            ship.vel = ship.vel.normalize() * 5.;
139        }
140        ship.pos += ship.vel;
141        ship.pos = wrap_around(&ship.pos);
142
143        // Move each bullet
144        for bullet in bullets.iter_mut() {
145            bullet.pos += bullet.vel;
146        }
147
148        // Move each asteroid
149        for asteroid in asteroids.iter_mut() {
150            asteroid.pos += asteroid.vel;
151            asteroid.pos = wrap_around(&asteroid.pos);
152            asteroid.rot += asteroid.rot_speed;
153        }
154
155        // Bullet lifetime
156        bullets.retain(|bullet| bullet.shot_at + 1.5 > frame_t);
157
158        let mut new_asteroids = Vec::new();
159        for asteroid in asteroids.iter_mut() {
160            // Asteroid/ship collision
161            if (asteroid.pos - ship.pos).length() < asteroid.size + SHIP_HEIGHT / 3. {
162                gameover = true;
163                break;
164            }
165
166            // Asteroid/bullet collision
167            for bullet in bullets.iter_mut() {
168                if (asteroid.pos - bullet.pos).length() < asteroid.size {
169                    asteroid.collided = true;
170                    bullet.collided = true;
171
172                    // Break the asteroid
173                    if asteroid.sides > 3 {
174                        new_asteroids.push(Asteroid {
175                            pos: asteroid.pos,
176                            vel: Vec2::new(bullet.vel.y, -bullet.vel.x).normalize()
177                                * rand::gen_range(1., 3.),
178                            rot: rand::gen_range(0., 360.),
179                            rot_speed: rand::gen_range(-2., 2.),
180                            size: asteroid.size * 0.8,
181                            sides: asteroid.sides - 1,
182                            collided: false,
183                        });
184                        new_asteroids.push(Asteroid {
185                            pos: asteroid.pos,
186                            vel: Vec2::new(-bullet.vel.y, bullet.vel.x).normalize()
187                                * rand::gen_range(1., 3.),
188                            rot: rand::gen_range(0., 360.),
189                            rot_speed: rand::gen_range(-2., 2.),
190                            size: asteroid.size * 0.8,
191                            sides: asteroid.sides - 1,
192                            collided: false,
193                        })
194                    }
195                    break;
196                }
197            }
198        }
199
200        // Remove the collided objects
201        bullets.retain(|bullet| bullet.shot_at + 1.5 > frame_t && !bullet.collided);
202        asteroids.retain(|asteroid| !asteroid.collided);
203        asteroids.append(&mut new_asteroids);
204
205        // You win?
206        if asteroids.len() == 0 {
207            gameover = true;
208        }
209
210        if gameover {
211            continue;
212        }
213
214        clear_background(LIGHTGRAY);
215
216        for bullet in bullets.iter() {
217            draw_circle(bullet.pos.x, bullet.pos.y, 2., BLACK);
218        }
219
220        for asteroid in asteroids.iter() {
221            draw_poly_lines(
222                asteroid.pos.x,
223                asteroid.pos.y,
224                asteroid.sides,
225                asteroid.size,
226                asteroid.rot,
227                2.,
228                BLACK,
229            )
230        }
231
232        let v1 = Vec2::new(
233            ship.pos.x + rotation.sin() * SHIP_HEIGHT / 2.,
234            ship.pos.y - rotation.cos() * SHIP_HEIGHT / 2.,
235        );
236        let v2 = Vec2::new(
237            ship.pos.x - rotation.cos() * SHIP_BASE / 2. - rotation.sin() * SHIP_HEIGHT / 2.,
238            ship.pos.y - rotation.sin() * SHIP_BASE / 2. + rotation.cos() * SHIP_HEIGHT / 2.,
239        );
240        let v3 = Vec2::new(
241            ship.pos.x + rotation.cos() * SHIP_BASE / 2. - rotation.sin() * SHIP_HEIGHT / 2.,
242            ship.pos.y + rotation.sin() * SHIP_BASE / 2. + rotation.cos() * SHIP_HEIGHT / 2.,
243        );
244        draw_triangle_lines(v1, v2, v3, 2., BLACK);
245
246        next_frame().await
247    }
248}