Skip to content

Commit d8d6141

Browse files
JaniMnot-fl3
authored andcommitted
add measure_multiline_text
1 parent c6d620c commit d8d6141

File tree

2 files changed

+60
-10
lines changed

2 files changed

+60
-10
lines changed

examples/text_wrap.rs

Lines changed: 11 additions & 3 deletions
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

Lines changed: 49 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ pub fn draw_multiline_text(
410410
font_size: f32,
411411
line_distance_factor: Option<f32>,
412412
color: Color,
413-
) {
413+
) -> TextDimensions {
414414
draw_multiline_text_ex(
415415
text,
416416
x,
@@ -422,7 +422,7 @@ pub fn draw_multiline_text(
422422
color,
423423
..Default::default()
424424
},
425-
);
425+
)
426426
}
427427

428428
/// Draw multiline text with the given line distance and custom params such as font, font size and font scale.
@@ -433,9 +433,7 @@ pub fn draw_multiline_text_ex(
433433
mut y: f32,
434434
line_distance_factor: Option<f32>,
435435
params: TextParams,
436-
) {
437-
let text = text.as_ref();
438-
436+
) -> TextDimensions {
439437
let line_distance = match line_distance_factor {
440438
Some(distance) => distance,
441439
None => {
@@ -453,11 +451,23 @@ pub fn draw_multiline_text_ex(
453451
}
454452
};
455453

456-
for line in text.lines() {
457-
draw_text_ex(line, x, y, params.clone());
454+
let mut dimensions = TextDimensions::default();
455+
let y_step = line_distance * params.font_size as f32 * params.font_scale;
456+
457+
for line in text.as_ref().lines() {
458+
let line_dimensions = draw_text_ex(line, x, y, params.clone());
458459
x -= (line_distance * params.font_size as f32 * params.font_scale) * params.rotation.sin();
459460
y += (line_distance * params.font_size as f32 * params.font_scale) * params.rotation.cos();
461+
462+
dimensions.width = f32::max(dimensions.width, line_dimensions.width);
463+
dimensions.height += y_step;
464+
465+
if dimensions.offset_y == 0.0 {
466+
dimensions.offset_y = line_dimensions.offset_y;
467+
}
460468
}
469+
470+
dimensions
461471
}
462472

463473
/// Get the text center.
@@ -487,6 +497,38 @@ pub fn measure_text(
487497
font.measure_text(text, font_size, font_scale, font_scale, |_| {})
488498
}
489499

500+
pub fn measure_multiline_text(
501+
text: &str,
502+
font: Option<&Font>,
503+
font_size: u16,
504+
font_scale: f32,
505+
line_distance_factor: Option<f32>,
506+
) -> TextDimensions {
507+
let font = font.unwrap_or_else(|| &get_context().fonts_storage.default_font);
508+
let line_distance = match line_distance_factor {
509+
Some(distance) => distance,
510+
None => match font.font.horizontal_line_metrics(1.0) {
511+
Some(metrics) => metrics.new_line_size,
512+
None => 1.0,
513+
},
514+
};
515+
516+
let mut dimensions = TextDimensions::default();
517+
let y_step = line_distance * font_size as f32 * font_scale;
518+
519+
for line in text.lines() {
520+
let line_dimensions = font.measure_text(line, font_size, font_scale, font_scale, |_| {});
521+
522+
dimensions.width = f32::max(dimensions.width, line_dimensions.width);
523+
dimensions.height += y_step;
524+
if dimensions.offset_y == 0.0 {
525+
dimensions.offset_y = line_dimensions.offset_y;
526+
}
527+
}
528+
529+
dimensions
530+
}
531+
490532
/// Converts word breaks to newlines wherever the text would otherwise exceed the given length.
491533
pub fn wrap_text(
492534
text: &str,

0 commit comments

Comments
 (0)