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

Support multiple fonts #8

Closed
sapir opened this issue Jul 18, 2022 · 6 comments
Closed

Support multiple fonts #8

sapir opened this issue Jul 18, 2022 · 6 comments

Comments

@sapir
Copy link
Contributor

sapir commented Jul 18, 2022

No description provided.

@LPGhatguy LPGhatguy changed the title Support changing the text font Support multiple fonts Jul 19, 2022
@LPGhatguy
Copy link
Member

This raises a couple interesting questions.

How much should yakui-core know about text? Right now, all of this lives in yakui-widgets. I've thought about breaking that code into a separate yakui-text crate because:

  1. Other sets of widgets probably want text and it should be easy to get "good enough" text rendering.
  2. Some users might want to replace the text rendering completely, so they should have the option to use their own text widgets.

At the same time, I think that it makes the most ergonomic sense to have access to FontId and adding fonts from the top-level yakui API, which currently lives in yakui-core. I think users should be able to do something like

let mut yak = yakui::State::new();

// load a font from some bytes
let my_font = yak.add_font(yakui::Font::from_bytes(include_bytes!("my-font.ttf")));

// set the default font by using an enum? maybe this could
// be a struct with fields that you can get mutable access
// to instead.
yak.set_font(yakui::Font::Default, my_font);

// ...

// the user can always directly assign a font on a text widget
let mut text = yakui::Text::new("Hello, world!");
text.font = my_font;
text.font_size = 18.0;
text.show();

@LPGhatguy
Copy link
Member

Banged out a prototype for this. It isn't super pretty, but you can do this now:

// Add a custom font for some of the examples.
let fonts = yak.dom().get_global_or_init(Fonts::default);
let font = Font::from_bytes(
    include_bytes!("../assets/Hack-Regular.ttf").as_slice(),
    FontSettings::default(),
)
.unwrap();
fonts.add(font, Some("monospace"));

// Using fonts.add(font, Some("default")) will replace the default font.

You can also turn off the default-fonts feature to stop yakui from bundling its default fonts. This saves a few hundred kB of final executable size for games that want to use their own fonts.

@LPGhatguy
Copy link
Member

Oh yeah, here's a demo, too!

demo_8debOM5CwB

@sanbox-irl
Copy link
Contributor

just want to drop in that i'd strongly prefer doing all the font rendering myself. if that involves replacing the text widget, that's not a problem, but since the engine i'm going to try adding yakui too has font rendering done already, i don't see a reason to double up on it

@LPGhatguy
Copy link
Member

just want to drop in that i'd strongly prefer doing all the font rendering myself. if that involves replacing the text widget, that's not a problem, but since the engine i'm going to try adding yakui too has font rendering done already, i don't see a reason to double up on it

The goal is that this should be no problem. You've got a couple options right now, but maybe we can do better:

  1. Use just yakui-core, which won't come with any widgets. This would let you build things from the ground-up, but I understand if this isn't appealing.
  2. Use yakui or yakui-widgets, but replace any widget that makes text with your own version. There's a lot of logic still in stuff like buttons, so this might be kinda tedious. yakui-widgets is designed to be forkable if there's anything you want to change, but forking early would be kinda lame.

Maybe we could introduce some way to hook into the text rendering so that you can provide yakui the metrics it wants and then paint text when asked to. I'd be a little worried about slowing down the common path, but this seems like a good possibility.

One trick we could employ is to move the text rendering code into a new crate, like yakui-text. Then, you could fork the crate, use your own rendering implementation, and then use Cargo to patch the crate to make yakui use it.

@LPGhatguy
Copy link
Member

I'm going to mark this closed. I opened #17 for @sanbox-irl's concern.

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

3 participants