Skip to content

Commit 161164d

Browse files
committed
add measure_multiline_text
1 parent 5d7b2f1 commit 161164d

File tree

2 files changed

+69
-8
lines changed

2 files changed

+69
-8
lines changed

examples/text_wrap.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ use macroquad::prelude::*;
33
static LOREM: &str = "Lorem ipsum odor amet, consectetuer adipiscing elit. Ultrices nostra volutpat facilisis magna mus. Rhoncus tempor feugiat netus maecenas pretium leo vitae. Eros aliquet maecenas eu diam aliquet varius hac elementum. Sociosqu platea per ultricies vitae praesent mauris nostra ridiculus. Est cursus pulvinar efficitur mus vel leo. Integer et nec eleifend non leo. Lorem rutrum ultrices potenti facilisis hendrerit facilisi metus sit. AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
44
55
Intentional newlines
6-
are preserved.
7-
";
6+
are preserved.";
87

98
#[macroquad::main("Text Wrap")]
109
async fn main() {
@@ -14,8 +13,17 @@ async fn main() {
1413

1514
let maximum_line_length = f32::max(20.0, mouse_position().0 - 20.0);
1615
let text = wrap_text(LOREM, None, font_size, 1.0, maximum_line_length);
16+
let dimensions = measure_multiline_text(&text, None, font_size, 1.0, Some(1.0));
1717

18-
draw_multiline_text(&text, 20.0, 20.0, font_size as f32, Some(1.0), WHITE);
18+
draw_multiline_text(
19+
&text,
20+
20.0,
21+
20.0 + dimensions.offset_y,
22+
font_size as f32,
23+
Some(1.0),
24+
WHITE,
25+
);
26+
draw_rectangle_lines(20.0, 20.0, dimensions.width, dimensions.height, 2.0, BLUE);
1927
draw_line(
2028
20.0 + maximum_line_length,
2129
0.0,

src/text.rs

+58-5
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@ pub fn draw_multiline_text(
398398
font_size: f32,
399399
line_distance_factor: Option<f32>,
400400
color: Color,
401-
) {
401+
) -> TextDimensions {
402402
draw_multiline_text_ex(
403403
text,
404404
x,
@@ -410,7 +410,7 @@ pub fn draw_multiline_text(
410410
color,
411411
..Default::default()
412412
},
413-
);
413+
)
414414
}
415415

416416
/// Draw multiline text with the given line distance and custom params such as font, font size and font scale.
@@ -421,7 +421,7 @@ pub fn draw_multiline_text_ex(
421421
mut y: f32,
422422
line_distance_factor: Option<f32>,
423423
params: TextParams,
424-
) {
424+
) -> TextDimensions {
425425
let line_distance = match line_distance_factor {
426426
Some(distance) => distance,
427427
None => {
@@ -435,10 +435,25 @@ pub fn draw_multiline_text_ex(
435435
}
436436
};
437437

438+
let mut dimensions = TextDimensions::default();
439+
let y_step = line_distance * params.font_size as f32 * params.font_scale;
440+
438441
for line in text.lines() {
439-
draw_text_ex(line, x, y, params.clone());
440-
y += line_distance * params.font_size as f32 * params.font_scale;
442+
// Trailing whitespace has a size, but isn't shown in any way.
443+
let line = line.trim_end();
444+
445+
let line_dimensions = draw_text_ex(line, x, y, params.clone());
446+
447+
y += y_step;
448+
449+
dimensions.width = f32::max(dimensions.width, line_dimensions.width);
450+
dimensions.height += y_step;
451+
if dimensions.offset_y == 0.0 {
452+
dimensions.offset_y = line_dimensions.offset_y;
453+
}
441454
}
455+
456+
dimensions
442457
}
443458

444459
/// Get the text center.
@@ -468,6 +483,44 @@ pub fn measure_text(
468483
font.measure_text(text, font_size, font_scale, font_scale, |_| {})
469484
}
470485

486+
pub fn measure_multiline_text(
487+
text: &str,
488+
font: Option<&Font>,
489+
font_size: u16,
490+
font_scale: f32,
491+
line_distance_factor: Option<f32>,
492+
) -> TextDimensions {
493+
let font = font.unwrap_or_else(|| &get_context().fonts_storage.default_font);
494+
let line_distance = match line_distance_factor {
495+
Some(distance) => distance,
496+
None => {
497+
let mut font_line_distance = 0.0;
498+
if let Some(metrics) = font.font.horizontal_line_metrics(1.0) {
499+
font_line_distance = metrics.new_line_size;
500+
}
501+
font_line_distance
502+
}
503+
};
504+
505+
let mut dimensions = TextDimensions::default();
506+
let y_step = line_distance * font_size as f32 * font_scale;
507+
508+
for line in text.lines() {
509+
// Trailing whitespace has a size, but isn't shown in any way.
510+
let line = line.trim_end();
511+
512+
let line_dimensions = font.measure_text(line, font_size, font_scale, font_scale, |_| {});
513+
514+
dimensions.width = f32::max(dimensions.width, line_dimensions.width);
515+
dimensions.height += y_step;
516+
if dimensions.offset_y == 0.0 {
517+
dimensions.offset_y = line_dimensions.offset_y;
518+
}
519+
}
520+
521+
dimensions
522+
}
523+
471524
/// Converts word breaks to newlines wherever the text would otherwise exceed the given length.
472525
pub fn wrap_text(
473526
text: &str,

0 commit comments

Comments
 (0)