glyph-brush icon indicating copy to clipboard operation
glyph-brush copied to clipboard

Is it possible to use this with bitmap glyphs?

Open icefoxen opened this issue 6 years ago • 9 comments

This is a bit of a random question, but it occurs to me that if you're using a bitmap font atlas from ggez then you end up doing a fair bit of work that gfx_glyph does already, at least in terms of maintaining a glyph cache as a GPU texture plus metrics. Is it possible/feasible/interesting to make a way for gfx_glyph to suck in a texture and font metrics from a source outside of Rusttype, so we could use it to render (potentially variable-size) bitmap fonts?

icefoxen avatar Feb 05 '18 15:02 icefoxen

I think while the job gfx_glyph effectively does could apply outside of rusttype and gfx-rs, in reality our API has made a lot of assumptions on these two to simplify usage.

I think glyph data having to come in from rusttype, and going out through gfx-rs, is a design limitation of gfx_glyph.

Couldn't rusttype support bitmap fonts?

alexheretic avatar Feb 05 '18 15:02 alexheretic

https://github.com/redox-os/rusttype/issues/78 I've asked.

If they say no then my next idea would be to start a new crate, with the intent of providing a single abstract API over bitmap fonts and vector fonts, with a backend of rusttype for vector fonts.

Xaeroxe avatar Feb 05 '18 16:02 Xaeroxe

So it looks like the new rusttype maintainer guy doesn't think this should go in rusttype. Not sure about that guy.

So the rusttype bits don't apply too well to pre-baked glyphs, including the gpu_cache because it's all sub-pixelly and alpha-only. But perhaps gfx-glyph layout, and caching could still apply and be helpful.

On the other hand maybe it's best to handle bitmaps separately even from gfx-glyph. Which I guess @icefoxen has already done in ggez. What do you guys think now a few months have gone by?

alexheretic avatar Jun 06 '18 16:06 alexheretic

I wrote an experimental facade to gfx_glyph for ggez; once it's sort of finalized (i.e., has been released for at least one version and gathered some feedback), the plan is to have it replace most of how ggez does text rendering right now (which is, render all letters of a text to a texture, with wrapping if need be, and redo all that if the text needs to be updated).

That means either ditching bitmap fonts altogether, maintaining two distinct APIs, writing a shim to (probably poorly) mimic the new behavior with none of the performance, or implementing a bitmap glyph cache of some sort. Naturally, fourth choice is the most desirable...

However, I feel that doing that well falls a bit outside of ggez' scope. It'd be better if a lib did that for us - doesn't have to be gfx_glyph, doesn't even need to have API similar to that of gfx_glyph.

Ratysz avatar Jun 06 '18 17:06 Ratysz

I'm not terribly awake at the moment but it seems like gfx-glyph deals with rendered fonts as bitmaps already, so it shouldn't be too hard to deal with the original source of the font being another bitmap instead of a Truetype renderer. A pre-made bitmap font is really just a special case of a cached font anyway, right?

icefoxen avatar Jun 06 '18 17:06 icefoxen

Gfx-glyph is a layout -> texture -> vertex pipe.

Layout

The layout code is all written around the rusttype font/glyph apis. It would honestly be a pain to generalise it. This is why I thought it would be good to get rusttype to support the font type. All the stuff needed to position glyphs should be implementable for any kind of font.

Texture

Texture management is mostly done by the rusttype::gpu_cache, it works with rusttype rasterization and manages an alpha-only texture that takes careful account of subpixel differences.

Colour bitmaps can never live on the same texture as the outline fonts, though colourless ones could. Subpixel rendering must be handled differently for outlines & bitmaps.

So here rusttype and bitmaps don't gel very well, and this makes me wonder if rusttype should be outline-only.

Vertex

This bit should be ok.

A way forward?

So maybe the rusttype drawing apis are the bit that don't fit.

  • Split out rusttype into the drawing bits, and the nondrawing bits. The drawing bits are only implemented for ttf. While both ttf & the new bitmap logic implements the non-drawing layout bits.
  • Add a new, much more static, texture-cache for bitmap glyphs. You can lookup the texture coords with a glyph id.
  • Use max 2 textures per GlyphBrush, 1 for outline, 1 for bitmaps. The former dynamically managed, the latter generated fully on initialization (I guess regenerated if you add a new bitmap font).

The first step is the hardest. What kind of formats are most commonly used for bitmap fonts. Do you guys have some good example fonts to prototype with?

alexheretic avatar Jun 07 '18 00:06 alexheretic

What kind of formats are most commonly used for bitmap fonts. Do you guys have some good example fonts to prototype with?

Unfortunately this is an area for which good general purpose multiplatform support is lacking. I don't know of any such formats.

Do you guys have some good example fonts to prototype with?

My best experience with this comes from XNA SpriteFonts. There's plenty of good examples of SpriteFont images here

Xaeroxe avatar Jun 07 '18 17:06 Xaeroxe

I can suggest ron for use alongside these images if nothing else.

Xaeroxe avatar Jun 07 '18 17:06 Xaeroxe

Thinking about this more... it's annoying because it feels like it should be easy, since bitmap fonts are just a degenerate case of exactly what gfx_glyph and such is doing anyway.

I wouldn't even try to deal with file formats, since as @Xaeroxe says, there aren't really any standards. It's one of those areas where it's so "simple" everyone rolls their own. Instead take a texture and a bunch of (character, glyph_offset_and_dimensions) pairs and use that as your mapping. Users can load whatever file format they care to and turn it into that form.

In terms of the pipeline described above, I believe this means that all the layout step work has already been done for you, by whoever made the bitmap font. The texture stage is trickier, I suppose; I don't know enough about how the internals work to comment yet.

That said, for ggez it's not too hard to write our own bitmap font stuff using instanced textures anyway. That might be easiest since bitmap fonts have a lot of properties that make them simple: they don't change, often all the glyphs are the same size, all the rendering has been done for you already, etc. That might be the easiest option all around.

Also for reference, the rusttype issue on the matter has meandered over to https://gitlab.redox-os.org/redox-os/rusttype/issues/78

icefoxen avatar Jun 21 '18 15:06 icefoxen