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

Text refactor #470

Merged
merged 9 commits into from
Nov 15, 2020
Merged

Text refactor #470

merged 9 commits into from
Nov 15, 2020

Conversation

rfuest
Copy link
Member

@rfuest rfuest commented Nov 11, 2020

Thank you for helping out with embedded-graphics development! Please:

  • Check that you've added passing tests and documentation
  • Add a CHANGELOG.md entry in the Unreleased section under the appropriate heading (Added, Fixed, etc) if your changes affect the public API
  • Run rustfmt on the project
  • Run just build (Linux/macOS only) and make sure it passes. If you use Windows, check that CI passes once you've opened the PR.

PR description

This PR adds support for external text renderers to e-g. TextStyle was converted to a trait that can be also implemented in other crates. To make drawing more efficient text renderers get direct access to the draw target and can use optimizations like fill_contiguous. Renderers can implement TextStylePixels to also provide a pixel iterator, but this isn't required.

Are the names MonospacedTextStyle and MonospacedTextStyleBuilder too long? Do you have a better suggestion?

@jamwaffles
Copy link
Member

I'm a bit frazzled at the moment so I'll get round to a review later (sorry), but as for

Are the names MonospacedTextStyle and MonospacedTextStyleBuilder too long? Do you have a better suggestion?

How about MonoTextStyle and MonoTextStyleBuilder? You could change MonospacedFont to MonoFont, etc as well. Mono might be a bit ambiguous at this point, but my hope is that if it's used everywhere for all the monospaced fonts, the name along with all the documentation around it will be clear.

@rfuest
Copy link
Member Author

rfuest commented Nov 11, 2020

I've also implemented an example of an external text renderer in my fork of the simulator repo: https://github.com/rfuest/simulator/blob/text-refactor/examples/text-seven-segment.rs

It can be used to draw seven segment displays with any scale:

grafik

The code is too complex to keep it as an example, but I think it could be useful to release the renderer as a separate crate.

@rfuest
Copy link
Member Author

rfuest commented Nov 11, 2020

I'm a bit frazzled at the moment so I'll get round to a review later (sorry), but as for

Never mind, it's only a draft PR and you can review it when it's done.

How about MonoTextStyle and MonoTextStyleBuilder? You could change MonospacedFont to MonoFont, etc as well. Mono might be a bit ambiguous at this point, but my hope is that if it's used everywhere for all the monospaced fonts, the name along with all the documentation around it will be clear.

Sounds good to me, thanks for the suggestion.

src/fonts/mod.rs Outdated Show resolved Hide resolved
break Some(Pixel(Point::new(x, y), color));
}
} else if let Some(current_char) = self.current_char {
let color = if F::character_pixel(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it's not a huge difference, this lookup has a bit of perf impact. In embedded-text, I made a glyph renderer struct that contains the pixel offset instead of the character and avoids some unnecessary re-calculations for each pixel. Also I think it would be nice if this code could be reused in embedded-text, but I think I might implement that after this is merged :)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to try to reuse the RawDataIter that is used to draw images. This would reduce some code duplication but I'm not sure about the performance impact yet. If that doesn't work out we can look into optimizing this code.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it's not a huge difference, this lookup has a bit of perf impact.

Did you see a perf impact running just bench font? I realise they're contrived benchmarks and perhaps not representative of realworld performance, but the text benches improve ~10% for me on this branch compared to master.

@rfuest rfuest force-pushed the text-refactor branch 2 times, most recently from 1a40674 to 784d7f7 Compare November 14, 2020 16:32
@rfuest rfuest marked this pull request as ready for review November 14, 2020 16:43
@rfuest rfuest requested a review from jamwaffles November 14, 2020 16:43
CHANGELOG.md Show resolved Hide resolved
break Some(Pixel(Point::new(x, y), color));
}
} else if let Some(current_char) = self.current_char {
let color = if F::character_pixel(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it's not a huge difference, this lookup has a bit of perf impact.

Did you see a perf impact running just bench font? I realise they're contrived benchmarks and perhaps not representative of realworld performance, but the text benches improve ~10% for me on this branch compared to master.

Copy link
Member

@jamwaffles jamwaffles left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My eyes have gone a bit square looking at the word Mono over and over again, but looks good overall.

One thing that's missing that I think is important is an example of implementing a custom font. I don't know if it's possible to add one that's short enough to show in the docs, but it would really help tie all the traits and structs together.

There's a reference to the text-custom-font simulator example somewhere (I can't find it in the diff now for some reason) which might be worth turning into a link too.

src/fonts/mod.rs Show resolved Hide resolved
src/fonts/mod.rs Outdated Show resolved Hide resolved
src/fonts/monospaced_pixels.rs Show resolved Hide resolved
src/style/mono_text_style.rs Outdated Show resolved Hide resolved
@rfuest
Copy link
Member Author

rfuest commented Nov 15, 2020

I couldn't reply to this above:

Did you see a perf impact running just bench font? I realise they're contrived benchmarks and perhaps not representative of realworld performance, but the text benches improve ~10% for me on this branch compared to master.

I hadn't noticed that before, but I also get some performance improvements. Not quite 10%, but I hadn't expected any performance gains at all, so the 3%-7% are also welcome.

Since the benches were updated to use a framebuffer they should be pretty representative, but only for displays drivers with a framebuffer. Perhaps we should look into also adding benches for other displays, where the number of draw calls or the amount of data that has to be transmitted are better metrics.

@rfuest
Copy link
Member Author

rfuest commented Nov 15, 2020

One thing that's missing that I think is important is an example of implementing a custom font. I don't know if it's possible to add one that's short enough to show in the docs, but it would really help tie all the traits and structs together.

There's a reference to the text-custom-font simulator example somewhere (I can't find it in the diff now for some reason) which might be worth turning into a link too.

An example in the docs wouldn't be much shorter than text-custom-font. If it's OK, I would like to create a new issue for the doc improvements and wait until the text refactor is finished.

@rfuest rfuest requested a review from jamwaffles November 15, 2020 15:49
@jamwaffles
Copy link
Member

An example in the docs wouldn't be much shorter than text-custom-font. If it's OK, I would like to create a new issue for the doc improvements and wait until the text refactor is finished.

I thought that might be the case. No worries - we can add more in later.

Copy link
Member

@jamwaffles jamwaffles left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good from my side. I don't know if @bugadani had anything else to add?

@bugadani
Copy link
Member

Don't wait for me, I can't review in depth :(

@rfuest
Copy link
Member Author

rfuest commented Nov 15, 2020

I've also implemented an example of an external text renderer in my fork of the simulator repo: https://github.com/rfuest/simulator/blob/text-refactor/examples/text-seven-segment.rs

It can be used to draw seven segment displays with any scale:

grafik

The code is too complex to keep it as an example, but I think it could be useful to release the renderer as a separate crate.

@jamwaffles If I decide to convert this example into a reusable crate do you think it would be useful enough to be an official e-g project or should I release it myself?

@jamwaffles
Copy link
Member

I think it'd be right at home in the e-g org if that's what you mean. Would it end up being published on crates.io?

As complex as it is, it would also be a good example for those looking to implement a custom font.

@rfuest
Copy link
Member Author

rfuest commented Nov 15, 2020

I think it'd be right at home in the e-g org if that's what you mean.

Yes, that's what I meant.

Would it end up being published on crates.io?

Yes. IMO a freely scalable seven segment font could be useful for different projects.

As complex as it is, it would also be a good example for those looking to implement a custom font.

Just to be clear: It's not a custom font, but a custom text renderer. But I agree that it could still be a good example for how an external renderer can be integrated.

@jamwaffles
Copy link
Member

Yes, that's what I meant.

Yes. IMO a freely scalable seven segment font could be useful for different projects.

Definitely! You should be able to make repositories in the e-g org, so feel free to do so when you have time. Let me know if you run into permissions errors.

Just to be clear: It's not a custom font, but a custom text renderer. But I agree that it could still be a good example for how an external renderer can be integrated.

Right, renderer not font. I'll do my best to be clearer with the terminology from now on :)

@rfuest
Copy link
Member Author

rfuest commented Nov 15, 2020

I'll do my best to be clearer with the terminology from now on :)

I just wanted to make sure we talk about the same thing ;).

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

Successfully merging this pull request may close these issues.

3 participants