Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prevent a line of text that starts with a glyph with negative side bearing from clipping #166

Closed
w0rm opened this issue Apr 11, 2024 · 6 comments

Comments

@w0rm
Copy link
Contributor

w0rm commented Apr 11, 2024

Hi, thanks for the great crate! I am very new to embedded programming in Rust, just started working on a custom font implementation in this repo.

Some glyphs in the font may have negative offsets, to ensure visually pleasing spacing between the glyphs and a nice shape of the text. Such glyphs, like the letter "j", may shift the bounding box to the left from the initial text position:

let style = TextStyle::new(BinaryColor::On);
let metrics = style.measure_string("just testing", Point::zero(), Baseline::Top);
assert_eq!(metrics.bounding_box.top_left, Point::new(-2, 0));  // the letter "j" has a negative left side bearing
assert_eq!(metrics.next_position, Point::new(42, 0));

Unfortunately, such hanging elements are getting cropped by the TextBox bounds. On the screenshot, the leading "j" is not fully rendered:

cropped

I tried looking into the plugin system, but there is no way to change the layout or rendering functionality. I wonder what would be the best way to address this use case and if you think this should be addressed at all. Similarly to CSS, perhaps we could add a setting for overflow: hidden / visible and padding to the TextBoxStyle. I would be happy to contribute such feature.

When rendered with embedded_graphics::text::Text, this doesn't happen. But then obviously I am not getting all the nice text layout functionality provided by the embedded-text crate.

@bugadani
Copy link
Member

Hi, thanks for reporting this issue. Your font looks really cool and it also looks like a quite good edge case for some of the functionality here :) I haven't been working on the crate for a while. The most straight-forward fix would be to force the first character to x=0, although I'll be honest, I don't know how correct/desired that would be. I'll have to try and implement this and I guess we can then decided, although I don't know when I'll have the energy to do so.

Overflow would slightly defeat the purpose of a box in my opinion, and I suspect it would be quite costly in terms of the generated binary's size.

@w0rm
Copy link
Contributor Author

w0rm commented Apr 11, 2024

@bugadani thanks for the fast reply! I actually wanted the stem of "j" to align with the letters below. That's why I thought that maybe padding could make it work (it would offset where the text starts, but keep the rendering area a bit larger for such hanging elements).

Also, no rush on this at all! I'm actually thinking myself, that maybe I could instead use the kerning table to bring j closer to other glyphs, and set the left side bearing to -1 instead of -2. In this case only one pixel of the "j" is going to be cropped and it would still look ok.

By the way, I've checked how this is done on the web (in the Safari browser). This is a textarea with the green padding. You can see how the letter "j" is bleeding into the padding area, and would be totally cropped by the textarea if the padding didn't exist.

What's funny, is that when I type a spacebar in front of "j", this artefact is left on the screen.

@bugadani
Copy link
Member

I'm not entirely sure that following the example of extremely complex browsers is what I want to do in a small(uh... ish)-and-dirty embedded library, although it's fun to see how Safari got things wrong there. Although admittedly I don't exactly have text rendering experience, so maybe that artifact, as well as clipping into the cursor is the correct and expected behaviour, who knows :)

@w0rm
Copy link
Contributor Author

w0rm commented Apr 11, 2024

So for now I changed the left side bearing of letter "j" to be -1 instead of -2, so only 1 pixel is cropped and the word space in front of the second "j" is 1 pixel wider for left aligned text. I think it is probably fine:

Screenshot 2024-04-11 at 22 56 43

Yeah I think you're right and the complexity is not worth it. If you are up for a contribution, I can implement your idea: push the line forward to make the letters fit in the TextBox bounds, if the measurement starts with a negative offset.

@bugadani
Copy link
Member

If you are up for a contribution, I can implement your idea: push the line forward to make the letters fit in the TextBox bounds, if the measurement starts with a negative offset.

That would be wonderful!

@w0rm w0rm changed the title Add support for padding / text overflow Prevent a line of text that starts with a glyph with negative side bearing from clipping Apr 29, 2024
@w0rm
Copy link
Contributor Author

w0rm commented Apr 29, 2024

Closed via #167

@w0rm w0rm closed this as completed Apr 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants