Skip to content

Commit

Permalink
add measure_multiline_text
Browse files Browse the repository at this point in the history
  • Loading branch information
JaniM committed Jan 13, 2025
1 parent 5d7b2f1 commit a7c5d7f
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 8 deletions.
14 changes: 11 additions & 3 deletions examples/text_wrap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@ use macroquad::prelude::*;
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
Intentional newlines
are preserved.
";
are preserved.";

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

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

draw_multiline_text(&text, 20.0, 20.0, font_size as f32, Some(1.0), WHITE);
draw_multiline_text(
&text,
20.0,
20.0 + dimensions.offset_y,
font_size as f32,
Some(1.0),
WHITE,
);
draw_rectangle_lines(20.0, 20.0, dimensions.width, dimensions.height, 2.0, BLUE);
draw_line(
20.0 + maximum_line_length,
0.0,
Expand Down
60 changes: 55 additions & 5 deletions src/text.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ pub fn draw_multiline_text(
font_size: f32,
line_distance_factor: Option<f32>,
color: Color,
) {
) -> TextDimensions {
draw_multiline_text_ex(
text,
x,
Expand All @@ -410,7 +410,7 @@ pub fn draw_multiline_text(
color,
..Default::default()
},
);
)
}

/// Draw multiline text with the given line distance and custom params such as font, font size and font scale.
Expand All @@ -421,7 +421,7 @@ pub fn draw_multiline_text_ex(
mut y: f32,
line_distance_factor: Option<f32>,
params: TextParams,
) {
) -> TextDimensions {
let line_distance = match line_distance_factor {
Some(distance) => distance,
None => {
Expand All @@ -435,10 +435,25 @@ pub fn draw_multiline_text_ex(
}
};

let mut dimensions = TextDimensions::default();
let y_step = line_distance * params.font_size as f32 * params.font_scale;

for line in text.lines() {
draw_text_ex(line, x, y, params.clone());
y += line_distance * params.font_size as f32 * params.font_scale;
// Trailing whitespace has a size, but isn't shown in any way.
let line = line.trim_end();

let line_dimensions = draw_text_ex(line, x, y, params.clone());

y += y_step;

dimensions.width = f32::max(dimensions.width, line_dimensions.width);
dimensions.height += y_step;
if dimensions.offset_y == 0.0 {
dimensions.offset_y = line_dimensions.offset_y;
}
}

dimensions
}

/// Get the text center.
Expand Down Expand Up @@ -468,6 +483,41 @@ pub fn measure_text(
font.measure_text(text, font_size, font_scale, font_scale, |_| {})
}

pub fn measure_multiline_text(
text: &str,
font: Option<&Font>,
font_size: u16,
font_scale: f32,
line_distance_factor: Option<f32>,
) -> TextDimensions {
let font = font.unwrap_or_else(|| &get_context().fonts_storage.default_font);
let line_distance = match line_distance_factor {
Some(distance) => distance,
None => match font.font.horizontal_line_metrics(1.0) {
Some(metrics) => metrics.new_line_size,
None => 1.0,
},
};

let mut dimensions = TextDimensions::default();
let y_step = line_distance * font_size as f32 * font_scale;

for line in text.lines() {
// Trailing whitespace has a size, but isn't shown in any way.
let line = line.trim_end();

let line_dimensions = font.measure_text(line, font_size, font_scale, font_scale, |_| {});

dimensions.width = f32::max(dimensions.width, line_dimensions.width);
dimensions.height += y_step;
if dimensions.offset_y == 0.0 {
dimensions.offset_y = line_dimensions.offset_y;
}
}

dimensions
}

/// Converts word breaks to newlines wherever the text would otherwise exceed the given length.
pub fn wrap_text(
text: &str,
Expand Down

0 comments on commit a7c5d7f

Please sign in to comment.