Closed fossegutten closed 3 years ago
Tetra currently uses ab-glyph
(a fork/rewrite of rusttype) for text rendering, and we just pass the size directly to their code. So I'm not really sure where this could be going wrong on our end.
Could you see if you can replicate this issue with GGEZ? I believe it uses the same underlying text rendering library, so that would determine if this is an upstream issue.
I tried with another font that should be pixel perfect at size 10, but I could't get it to work at any whole pixel size.
ab-glyph
/rusttype
tend to not handle pixel fonts very well, and it's a massive source of frustration to me as someone who almost exclusively makes games with pixel art 😢 The Chevy Ray ones are the first I've seen that haven't ended up with horrible anti-aliasing - perhaps Chevy has done something in the TTF to disable it?
I'm currently working on adding bitmap font support (#80) to support these kinds of fonts better.
I think the fonts are made specifically for pixel art by placing the font coordinates at exact positions. I am not sure how he did it, as I am not a font expert. They work perfectly in unity (I think) and godot, as truetype fonts. I can test it with ggez another day :)
Yeah, I tried to tweak some other pixel fonts in FontForge to get them to have hard edges, but I wasn't able to get it to work. I just assumed ab-glyph
didn't support it - will have to revisit now you've shown me it can be done :)
And yeah, no problem if you can't try it straight away! I just didn't want to assume this is an upstream issue without verifying that first 😄
Results are the same in ggez 0.5.1, which seems to use rusttype. Macroquad 0.3.0.alpha14 uses fontdue and it draws correct sized fonts! Might be worth changing dependencies? It is supposedly faster aswell.
I'd be open to switching to a different library, but Fontdue doesn't support subpixel positioning yet as far as I can tell (at least on the Crates.io version), which would potentially be a regression to text quality.
This issue on the ab_glyph
repo is interesting, though - it looks like the exact same thing you're running into: https://github.com/alexheretic/ab-glyph/issues/15
Someone in the comments seems to have got the expected results by using the units_per_em
in the size calculation, and this is apparently the metric that Fontdue uses too, so I think that's the way forward.
I'd say it's a breaking change to modify how font sizing works (since it'd change how existing games get rendered), but I'll make this change in a 0.6 version soon.
Ok. I am happy to help test it out, as I have some pixel art fonts. However, I think you can download some pixel art .ttf fonts from here: https://www.kenney.nl/
:+1: I'm having some computer troubles at the moment, but once I'm back up and running I'll try to get this change made on a branch for us to try out.
My computer is still out of action, but I was able to push a (completely untested, possibly broken 😅) change from my work laptop. It's on the font-size-fix
branch if you want to test it out. Will be able to give it a proper look myself once my new motherboard gets here, hopefully...
Didn't really work. the font.units_per_em() returns an option. I fixed that, but it returned 4096 with one font and 1024 with another font. The font obviously turned microscopic / invisible.
Edit: I tried this also, from the commented out function in Font.rs from ab-glyph: It seems to create a more reasonable value, but it's still blurry.
pub(crate) struct VectorRasterizer<F> {
font: Rc<F>,
scale: PxScale,
}
impl<F> VectorRasterizer<F>
where
F: AbFont,
{
pub fn new(font: Rc<F>, size: f32) -> VectorRasterizer<F> {
let px_per_em = size * (96.0 / 72.0);
let units_per_em = font.units_per_em().unwrap();
let height = font.height_unscaled();
let px_size = px_per_em * height / units_per_em;
let scale = PxScale::from(px_size);
VectorRasterizer {
font,
scale,
}
}
}
Removing that first line did the trick
Fixed on the 0.6 branch.
Summary: I used a font that is made for pixel perfect text, at size 9. In tetra, it looks very blurry with size 9, but looks fine in size 10. Tried the font in godot engine, where it works fine at size 9, but not 10. The font is "Vector", from Chevy Ray's font pack. I am sure it is reproducible with other (free) fonts as well.
Edit: I tried with another font that should be pixel perfect at size 10, but I could't get it to work at any whole pixel size.
How it looks at size 9:
How it looks at size 10 (expected this at size 9):