Skip to content

Commit

Permalink
Avoid measuring twice
Browse files Browse the repository at this point in the history
  • Loading branch information
w0rm committed Apr 28, 2024
1 parent f69962c commit 93e7818
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 25 deletions.
6 changes: 3 additions & 3 deletions src/rendering/line.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use crate::{
line_iter::{ElementHandler, LineElementParser, LineEndType},
},
style::TextBoxStyle,
utils::{str_left_offset, str_width},
utils::{str_width, str_width_and_left_offset},
};
use embedded_graphics::{
draw_target::DrawTarget,
Expand Down Expand Up @@ -105,8 +105,8 @@ where
str_width(self.text_renderer, st)
}

fn measure_left_offset(&self, st: &str) -> u32 {
str_left_offset(self.text_renderer, st)
fn measure_width_and_left_offset(&self, st: &str) -> (u32, u32) {
str_width_and_left_offset(self.text_renderer, st)
}

fn whitespace(&mut self, st: &str, _space_count: u32, width: u32) -> Result<(), Self::Error> {
Expand Down
18 changes: 10 additions & 8 deletions src/rendering/line_iter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ pub trait ElementHandler {
fn measure(&self, st: &str) -> u32;

/// Returns the left offset in pixels.
fn measure_left_offset(&self, _st: &str) -> u32;
fn measure_width_and_left_offset(&self, _st: &str) -> (u32, u32);

/// A whitespace block with the given width.
fn whitespace(&mut self, _st: &str, _space_count: u32, _width: u32) -> Result<(), Self::Error> {
Expand Down Expand Up @@ -324,16 +324,18 @@ where
}

Token::Word(w) => {
if self.empty {
let width = if self.empty {
// If this is the first word on the line, offset the line by
// the word's left negative boundary to make sure it is not clipped.
let offset = handler.measure_left_offset(w);
let (width, offset) = handler.measure_width_and_left_offset(w);
if offset > 0 && self.move_cursor_forward(offset).is_ok() {
handler.whitespace("", 0, offset).ok();
};
}
width
} else {
handler.measure(w)
};

let width = handler.measure(w);
let (word, remainder) = if self.move_cursor_forward(width).is_ok() {
// We can move the cursor here since `process_word()`
// doesn't depend on it.
Expand Down Expand Up @@ -472,7 +474,7 @@ pub(crate) mod test {
plugin::{NoPlugin, PluginMarker as Plugin, PluginWrapper},
rendering::{cursor::Cursor, space_config::SpaceConfig},
style::TabSize,
utils::{str_left_offset, str_width, test::size_for},
utils::{str_width, str_width_and_left_offset, test::size_for},
};
use embedded_graphics::{
geometry::{Point, Size},
Expand Down Expand Up @@ -524,8 +526,8 @@ pub(crate) mod test {
str_width(&self.style, st)
}

fn measure_left_offset(&self, st: &str) -> u32 {
str_left_offset(&self.style, st)
fn measure_width_and_left_offset(&self, st: &str) -> (u32, u32) {
str_width_and_left_offset(&self.style, st)
}

fn whitespace(&mut self, _string: &str, count: u32, width: u32) -> Result<(), Self::Error> {
Expand Down
6 changes: 3 additions & 3 deletions src/style/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ use crate::{
line_iter::{ElementHandler, LineElementParser, LineEndType},
space_config::SpaceConfig,
},
utils::{str_left_offset, str_width},
utils::{str_width, str_width_and_left_offset},
};
use embedded_graphics::text::{renderer::TextRenderer, LineHeight};

Expand Down Expand Up @@ -385,8 +385,8 @@ impl<'a, S: TextRenderer> ElementHandler for MeasureLineElementHandler<'a, S> {
str_width(self.style, st)
}

fn measure_left_offset(&self, st: &str) -> u32 {
str_left_offset(self.style, st)
fn measure_width_and_left_offset(&self, st: &str) -> (u32, u32) {
str_width_and_left_offset(self.style, st)
}

fn whitespace(&mut self, _st: &str, count: u32, width: u32) -> Result<(), Self::Error> {
Expand Down
21 changes: 10 additions & 11 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,17 @@ pub fn str_width(renderer: &impl TextRenderer, s: &str) -> u32 {
.x as u32
}

/// Measure the distance between the left edge of the bounding box
/// and the left edge of the text.
/// This function is particularly useful when the first glyph on
/// Measure the width of a piece of string and the offset between
/// the left edge of the bounding box and the left edge of the text.
///
/// The offset is particularly useful when the first glyph on
/// the line has a negative left side bearing.
pub fn str_left_offset(renderer: &impl TextRenderer, s: &str) -> u32 {
renderer
.measure_string(s, Point::zero(), Baseline::Top)
.bounding_box
.top_left
.x
.min(0)
.abs() as u32
pub fn str_width_and_left_offset(renderer: &impl TextRenderer, s: &str) -> (u32, u32) {
let tm = renderer.measure_string(s, Point::zero(), Baseline::Top);
(
tm.next_position.x as u32,
tm.bounding_box.top_left.x.min(0).abs() as u32,
)
}

#[cfg(test)]
Expand Down

0 comments on commit 93e7818

Please sign in to comment.