alexheretic / ab-glyph

Rust API for loading, scaling, positioning and rasterizing OpenType font glyphs
Apache License 2.0
372 stars 24 forks source link

Documentation on glyph_bounds Unclear #31

Closed anlumo closed 3 years ago

anlumo commented 3 years ago

The documentation for Font::glyph_bounds says

/// Returns the layout bounds of this glyph. These are different to the outline `px_bounds()`.
///
/// Horizontally: Glyph position +/- h_advance/h_side_bearing.
/// Vertically: Glyph position +/- ascent/descent.

As someone with no formal typesetting education, I don't know what this text is trying to tell me. So, the result is different to px_bounds, but how? Why?

I'm currently trying to use this function, but the result cuts off the text on the left and right. I guess this comment is supposed to explain why, but it's a mystery to me.

Frankly, this feels like a quick note by the author of that code to themselves, rather than something others should be able to interpret. Could you expand on that definition?

alexheretic commented 3 years ago

glyph_bounds are calculated from the font layout values, like advance. They work for pretty much any glyph. Those docs seem to define it pretty well as far as I can see.

h_advance, h_side_bearing, ascent & descent are all methods & use existing font terminology. Yes, currently it looks like you just need to know what these mean or work it out from examples. I'd welcome improvements to the docs.

Image support in rust docs would be quite helpful though...

The outline px_bounds are the "conservative whole number pixel bounding box" for an OutlinedGlyph. So they only exist for glyphs with an outline. It's more of a drawing concept that's needed when you're interested in rasterizing the glyphs into a pixel grid.

So, for example, a monospace font at a given scale will have uniform Font::glyph_bounds, but each glyph will probably have different outlines and so different OutlinedGlyph::px_bounds.

I'd guess your cut off text bug may have a different cause.

anlumo commented 3 years ago

I analyzed the implementation of px_bounds and found here that it just takes all points used in the path and calculates the bounding box based on those. When I do the same thing myself, it works out to be correct. I guess if you want to implement text selection highlighting, the glyph_bounds rectangle is more interesting, but I need the real bounding box for creating a bitmap to render into first.

The background is that I'm currently trying to move from the integrated rasterizer to a different one (HTML canvas via web-sys), so I have to reimplement all these pixel-based calculations.

alexheretic commented 3 years ago

That px_bounds calculation is just a fallback for malformed fonts. Generally the bbox is returned from ttf-parser as part of outlining the glyph.

Can you elaborate on why you can't use px_bounds and draw. Outlining & drawing in _abglyph isn't render API specific in any way. draw just tells you what alpha to set at a given coordinate.

anlumo commented 3 years ago

That px_bounds calculation is just a fallback for malformed fonts. Generally the bbox is returned from ttf-parser as part of outlining the glyph.

How can I access this information from the outside?

Can you elaborate on why you can't use px_bounds and draw. Outlining & drawing in _abglyph isn't render API specific in any way. draw just tells you what alpha to set at a given coordinate.

I have to render a text outline like this: image

Unless I implement some kind of pixel filter (tried that, it's problematic), I need the actual path outline, so I can stroke the path before filling it.

alexheretic commented 3 years ago

Right ok, so you want the outline. I would have thought you'd be using the Font::outline method then.

An Outline comes with the bounds (returned by ttf-parser) & it's own px_bounds method for scaling, so you don't need to work them out again.

anlumo commented 3 years ago

Oh, I somehow missed that function. Works and is much cleaner, thank you!

alexheretic commented 3 years ago

I don't this we have any more actions to take from this issue, so I'll close. Please let me know otherwise.