Essential for text selection and editing in cases where mapping from the
input text to the actual shaped glyphs is nontrivial. I.e., in case of
HarfBuzzFont; both FreeTypeFont and StbTrueTypeFont perform a 1:1
translation from input (UTF-8) characters to glyphs so there it isn't
as important.
Having it next to AbstractShaper didn't make sense, as there's various
use cases where font features are specified but the caller code doesn't
even know there's any shaper involved. Such as in the UI library.
Based on the actual text direction (either explicitly set or detected),
these resolve to either *Left or *Right. For the Text::Renderer it's
done automatically inside (and there's no way to actually set the
direction from outside due to the API being ancient and limited), for
the align*() utils the alignment has to be explicitly resolved using a
new alignmentForDirection() utility.
There shouldn't be any other values passed to these. Compilers, don't
even attempt to say that the alignment value is now maybe uninitialized,
I'm watching you!
This is going to get called from fillGlyphCache() that takes a string,
and thus should be better than one virtual call per character. The
single-character variant still stays, as it's a nice convenience API.
Eventually glyphSize() will get a similar treatment as well.
Took me quite a while to realize what was going on, but in retrospect
it's obvious -- the rasterizer just *rounds* the sub-pixel-positioned
glyph quads to nearest pixels. Which then can cause the neighboring
glyph data to leak to it (because the texture is then sampled not
directly on the edge pixel, but slightly outside of it), or it can also
cut away the edge, when it gets rounded in the other direction.
This was a problem with the original -- laughably inefficient -- atlas
packer as well, but because that packer had excessive padding around
everything, only the second edge-cutting artifact manifested, and that
one is rather subtle unless you know what to look for.
This means the packing is now slightly worse than before and sizes that
previously worked may no longer fit anymore. But since the new atlas
packer is relatively new (well, from September, time sure flies
different here), and the improvement compared to the original packer is
still quite massive, I don't think this is a problem.
Want to construct them without a GL context present, and Optional is too
wasteful. Also adding it to the AbstractGlyphCache base, where it skips
also allocating the internal PIMPL state, because it's not going to get
used for anything in a NoCreate'd instance anyway.
If Magnum and Corrade get installed into the same directory,
target_include_directories() or target_link_libraries() with Corrade
before Magnum will result in the (usually stale) installed Magnum
headers being picked over the local ones. Which is unwanted, so try to
always put the local Magnum include path first.
Tested manually by installing to an arbitrary location and editing
configure.h to contain an #error. That failed for the Text library, and
with these changes it now doesn't fail anymore, but that's not a
guarantee that I managed to fix all such cases.
Especially given that nullptr causes an assert. All call sites basically
ended up passing a &font and all that extra annoyance just doesn't make
sense.
Given this API is still relatively recent, I'm not bothering with
backwards compatibility.
Which also allows the internals to be a bit simpler / potentially more
efficient, as the implementation can now access the glyph cache contents
directly, without a getter.
The new API makes it possible to alias storage for the glyph offsets,
advances and IDs (20 bytes per glyph) directly with the output positions
+ texcoords (16 bytes per glyph, times four) by splitting the retrieval
in two steps.
I wonder how long will it take before this bites back, heh.
In basically all cases it's two independent operations so forcing them
to be done together doesn't really bring any potential efficiency
advantages. On the other hand, splitting them allows allows the caller
to better make use of available memory, as the new
renderGlyphQuadsInto() allows the input and output arrays to be aliased.
Bumping AbstractFont plugin interface versions as this is a breaking
change.
The awful original STL-heavy public API is kept the same for now, it's
just the internals being now implemented using brand new APIs that are
actually usable with multiple fonts, font sizes and runs with different
scripts/languages/directions. There's also preparation for configurable
vertical text layouting, although for now the functionality asserts that
horizontal text is used.
This also makes Renderer.h header available on non-GL builds, as the new
APIs don't rely on a class full of GL objects anymore. The class will
get eventually renamed and moved to a dedicated RendererGL.h header, but
for now this partial update has to suffice.
To be used as a placeholder argument in the reworked renderer APIs. No
intention to deal with the complexities of this right now, just taking
it to not have to deprecate & replace the API when this feature actually
gets implemented.
So it's possible to shape the text even before having all glyphs ready.
That's one reason, second reason is that this is a more common behavior
-- it usually doesn't make sense to make the text jump based on whether
it's "zaxaca", "KEKEKE" or "yqpyq".
The original alignment based on glyph bounds is now moved into dedicated
`*GlyphBounds` variants. Additionally the `*LeftGlyphBounds` were
changed to subtract the initial glyph offset as well, `*Integer` now
rounds only in the direction where it's needed because a division by 2
happened, and there's a set of `*Bottom*` values that somehow weren't
there before.
Still not good enough regression testing for the changes I need to make.
This was absolutely not verifying correct behavior of the other vertical
alignment values for multiline text.
Otherwise the assertion from TextureTools::DistanceField fires only
later during image upload, which can cause great confusion, not being
sure what's to blame, etc.