From a28ebaef847c48574cadb9a2b84128107436361f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sun, 24 Sep 2023 15:44:01 +0200 Subject: [PATCH] Text: add AbstractFont::glyphSize(). Together with glyphCount() quite useful for querying font properties. --- doc/changelog.dox | 3 +- doc/snippets/MagnumText.cpp | 1 + src/Magnum/Text/AbstractFont.cpp | 7 +++ src/Magnum/Text/AbstractFont.h | 23 +++++++ .../Text/Test/AbstractFontConverterTest.cpp | 1 + src/Magnum/Text/Test/AbstractFontTest.cpp | 63 ++++++++++++++++--- src/Magnum/Text/Test/RendererGLTest.cpp | 2 + src/MagnumPlugins/MagnumFont/MagnumFont.cpp | 30 ++++++--- src/MagnumPlugins/MagnumFont/MagnumFont.h | 1 + .../MagnumFont/Test/MagnumFontTest.cpp | 1 + .../Test/MagnumFontConverterTest.cpp | 3 + 11 files changed, 115 insertions(+), 20 deletions(-) diff --git a/doc/changelog.dox b/doc/changelog.dox index 24069f89d..99cc74a30 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -767,7 +767,8 @@ See also: @subsubsection changelog-latest-changes-text Text library -- Added @ref Text::AbstractFont::glyphCount() +- Added @ref Text::AbstractFont::glyphCount() and + @relativeref{Text::AbstractFont,glyphSize()} - Added @ref Text::Renderer::fontSize() @subsubsection changelog-latest-changes-trade Trade library diff --git a/doc/snippets/MagnumText.cpp b/doc/snippets/MagnumText.cpp index 155dfee05..b28831685 100644 --- a/doc/snippets/MagnumText.cpp +++ b/doc/snippets/MagnumText.cpp @@ -58,6 +58,7 @@ struct MyFont: Text::AbstractFont { bool doIsOpened() const override { return false; } void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const Text::AbstractGlyphCache&, Float, Containers::StringView) override { return {}; } }; diff --git a/src/Magnum/Text/AbstractFont.cpp b/src/Magnum/Text/AbstractFont.cpp index ebfea333d..45b539683 100644 --- a/src/Magnum/Text/AbstractFont.cpp +++ b/src/Magnum/Text/AbstractFont.cpp @@ -250,6 +250,13 @@ UnsignedInt AbstractFont::glyphId(const char32_t character) { return doGlyphId(character); } +Vector2 AbstractFont::glyphSize(const UnsignedInt glyph) { + CORRADE_ASSERT(isOpened(), "Text::AbstractFont::glyphSize(): no font opened", {}); + CORRADE_ASSERT(glyph < _glyphCount, "Text::AbstractFont::glyphSize(): index" << glyph << "out of range for" << _glyphCount << "glyphs", {}); + + return doGlyphSize(glyph); +} + Vector2 AbstractFont::glyphAdvance(const UnsignedInt glyph) { CORRADE_ASSERT(isOpened(), "Text::AbstractFont::glyphAdvance(): no font opened", {}); CORRADE_ASSERT(glyph < _glyphCount, "Text::AbstractFont::glyphAdvance(): index" << glyph << "out of range for" << _glyphCount << "glyphs", {}); diff --git a/src/Magnum/Text/AbstractFont.h b/src/Magnum/Text/AbstractFont.h index 0e5089155..8b8308610 100644 --- a/src/Magnum/Text/AbstractFont.h +++ b/src/Magnum/Text/AbstractFont.h @@ -457,6 +457,23 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin { */ UnsignedInt glyphId(char32_t character); + /** + * @brief Glyph size in pixels + * @param glyph Glyph ID + * @m_since_latest + * + * Size of the glyph image in pixels when rasterized. Some + * implementations may return fractional values, in which case + * @ref Math::ceil() should be used to get the actual integer pixel + * size. + * @note This function is meant to be used only for font observations + * and conversions. In performance-critical code the + * @ref fillGlyphCache() and @ref layout() functions should be + * used instead. + * @see @ref glyphId(), @ref size() + */ + Vector2 glyphSize(UnsignedInt glyph); + /** * @brief Glyph advance in pixels * @param glyph Glyph ID @@ -609,6 +626,12 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin { /** @brief Implementation for @ref glyphId() */ virtual UnsignedInt doGlyphId(char32_t character) = 0; + /** + * @brief Implementation for @ref glyphSize() + * @m_since_latest + */ + virtual Vector2 doGlyphSize(UnsignedInt glyph) = 0; + /** @brief Implementation for @ref glyphAdvance() */ virtual Vector2 doGlyphAdvance(UnsignedInt glyph) = 0; diff --git a/src/Magnum/Text/Test/AbstractFontConverterTest.cpp b/src/Magnum/Text/Test/AbstractFontConverterTest.cpp index 2415a0ff8..8280c111b 100644 --- a/src/Magnum/Text/Test/AbstractFontConverterTest.cpp +++ b/src/Magnum/Text/Test/AbstractFontConverterTest.cpp @@ -159,6 +159,7 @@ struct DummyFont: AbstractFont { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; diff --git a/src/Magnum/Text/Test/AbstractFontTest.cpp b/src/Magnum/Text/Test/AbstractFontTest.cpp index 1517b3538..688d6e185 100644 --- a/src/Magnum/Text/Test/AbstractFontTest.cpp +++ b/src/Magnum/Text/Test/AbstractFontTest.cpp @@ -75,9 +75,9 @@ struct AbstractFontTest: TestSuite::Tester { void glyphId(); void glyphIdNoFont(); - void glyphAdvance(); - void glyphAdvanceNoFont(); - void glyphAdvanceOutOfRange(); + void glyphSizeAdvance(); + void glyphSizeAdvanceNoFont(); + void glyphSizeAdvanceOutOfRange(); void layout(); void layoutNoFont(); @@ -129,9 +129,9 @@ AbstractFontTest::AbstractFontTest() { &AbstractFontTest::glyphId, &AbstractFontTest::glyphIdNoFont, - &AbstractFontTest::glyphAdvance, - &AbstractFontTest::glyphAdvanceNoFont, - &AbstractFontTest::glyphAdvanceOutOfRange, + &AbstractFontTest::glyphSizeAdvance, + &AbstractFontTest::glyphSizeAdvanceNoFont, + &AbstractFontTest::glyphSizeAdvanceOutOfRange, &AbstractFontTest::layout, &AbstractFontTest::layoutNoFont, @@ -162,6 +162,7 @@ void AbstractFontTest::construct() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -187,6 +188,7 @@ void AbstractFontTest::openData() { } UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -218,6 +220,7 @@ void AbstractFontTest::openFileAsData() { } UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -244,6 +247,7 @@ void AbstractFontTest::openFileAsDataNotFound() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -269,6 +273,7 @@ void AbstractFontTest::openFileNotImplemented() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -291,6 +296,7 @@ void AbstractFontTest::openDataNotSupported() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -312,6 +318,7 @@ void AbstractFontTest::openDataNotImplemented() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -334,6 +341,7 @@ void AbstractFontTest::setFileCallback() { } UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -360,6 +368,7 @@ void AbstractFontTest::setFileCallbackTemplate() { } UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -392,6 +401,7 @@ void AbstractFontTest::setFileCallbackTemplateNull() { } UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -417,6 +427,7 @@ void AbstractFontTest::setFileCallbackTemplateConst() { } UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -444,6 +455,7 @@ void AbstractFontTest::setFileCallbackFileOpened() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -466,6 +478,7 @@ void AbstractFontTest::setFileCallbackNotImplemented() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -491,6 +504,7 @@ void AbstractFontTest::setFileCallbackNotSupported() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -526,6 +540,7 @@ void AbstractFontTest::setFileCallbackOpenFileDirectly() { } UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -568,6 +583,7 @@ void AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementation() { } UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -622,6 +638,7 @@ void AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementationFailed() } UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -659,6 +676,7 @@ void AbstractFontTest::setFileCallbackOpenFileAsData() { } UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -714,6 +732,7 @@ void AbstractFontTest::setFileCallbackOpenFileAsDataFailed() { } UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -746,6 +765,7 @@ void AbstractFontTest::properties() { } UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -771,6 +791,7 @@ void AbstractFontTest::propertiesNoFont() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -799,6 +820,7 @@ void AbstractFontTest::glyphId() { void doClose() override {} UnsignedInt doGlyphId(char32_t a) override { return a*10; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -817,6 +839,7 @@ void AbstractFontTest::glyphIdNoFont() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -829,7 +852,7 @@ void AbstractFontTest::glyphIdNoFont() { CORRADE_COMPARE(out.str(), "Text::AbstractFont::glyphId(): no font opened\n"); } -void AbstractFontTest::glyphAdvance() { +void AbstractFontTest::glyphSizeAdvance() { struct MyFont: AbstractFont { FontFeatures doFeatures() const override { return FontFeature::OpenData; } bool doIsOpened() const override { return _opened; } @@ -840,6 +863,7 @@ void AbstractFontTest::glyphAdvance() { return {0.0f, 0.0f, 0.0f, 0.0f, 98}; } UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt a) override { return {a*2.0f, a/3.0f}; } Vector2 doGlyphAdvance(UnsignedInt a) override { return {a*10.0f, -Float(a)/10.0f}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -850,10 +874,11 @@ void AbstractFontTest::glyphAdvance() { /* Have to explicitly open in order to make glyphCount() non-zero */ CORRADE_VERIFY(font.openData(nullptr, 0.0f)); + CORRADE_COMPARE(font.glyphSize(33), (Vector2{66.0f, 11.0f})); CORRADE_COMPARE(font.glyphAdvance(97), (Vector2{970.0f, -9.7f})); } -void AbstractFontTest::glyphAdvanceNoFont() { +void AbstractFontTest::glyphSizeAdvanceNoFont() { CORRADE_SKIP_IF_NO_ASSERT(); struct MyFont: AbstractFont { @@ -862,6 +887,7 @@ void AbstractFontTest::glyphAdvanceNoFont() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -870,11 +896,14 @@ void AbstractFontTest::glyphAdvanceNoFont() { std::ostringstream out; Error redirectError{&out}; + font.glyphSize(33); font.glyphAdvance(97); - CORRADE_COMPARE(out.str(), "Text::AbstractFont::glyphAdvance(): no font opened\n"); + CORRADE_COMPARE(out.str(), + "Text::AbstractFont::glyphSize(): no font opened\n" + "Text::AbstractFont::glyphAdvance(): no font opened\n"); } -void AbstractFontTest::glyphAdvanceOutOfRange() { +void AbstractFontTest::glyphSizeAdvanceOutOfRange() { CORRADE_SKIP_IF_NO_ASSERT(); struct MyFont: AbstractFont { @@ -887,6 +916,7 @@ void AbstractFontTest::glyphAdvanceOutOfRange() { return {0.0f, 0.0f, 0.0f, 0.0f, 3}; } UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; @@ -900,8 +930,10 @@ void AbstractFontTest::glyphAdvanceOutOfRange() { std::ostringstream out; Error redirectError{&out}; + font.glyphSize(3); font.glyphAdvance(3); CORRADE_COMPARE(out.str(), + "Text::AbstractFont::glyphSize(): index 3 out of range for 3 glyphs\n" "Text::AbstractFont::glyphAdvance(): index 3 out of range for 3 glyphs\n"); } @@ -924,6 +956,7 @@ void AbstractFontTest::layout() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache& cache, Float size, Containers::StringView str) override { return Containers::pointer(UnsignedInt(cache.textureSize().x()*str.size()*size)); @@ -944,6 +977,7 @@ void AbstractFontTest::layoutNoFont() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; } } font; @@ -962,6 +996,7 @@ void AbstractFontTest::fillGlyphCache() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; } @@ -991,6 +1026,7 @@ void AbstractFontTest::fillGlyphCacheNotSupported() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; } } font; @@ -1011,6 +1047,7 @@ void AbstractFontTest::fillGlyphCacheNotImplemented() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; } } font; @@ -1031,6 +1068,7 @@ void AbstractFontTest::fillGlyphCacheNoFont() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; } } font; @@ -1051,6 +1089,7 @@ void AbstractFontTest::fillGlyphCacheInvalidUtf8() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; } } font; @@ -1069,6 +1108,7 @@ void AbstractFontTest::createGlyphCache() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; } @@ -1097,6 +1137,7 @@ void AbstractFontTest::createGlyphCacheNotSupported() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; } } font; @@ -1116,6 +1157,7 @@ void AbstractFontTest::createGlyphCacheNotImplemented() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; } } font; @@ -1135,6 +1177,7 @@ void AbstractFontTest::createGlyphCacheNoFont() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr; } } font; diff --git a/src/Magnum/Text/Test/RendererGLTest.cpp b/src/Magnum/Text/Test/RendererGLTest.cpp index 9834f0461..f188e448d 100644 --- a/src/Magnum/Text/Test/RendererGLTest.cpp +++ b/src/Magnum/Text/Test/RendererGLTest.cpp @@ -77,6 +77,7 @@ class TestFont: public AbstractFont { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return 0; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float size, Containers::StringView text) override { @@ -354,6 +355,7 @@ void RendererGLTest::multiline() { } UnsignedInt doGlyphId(char32_t) override { return 0; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView text) override { diff --git a/src/MagnumPlugins/MagnumFont/MagnumFont.cpp b/src/MagnumPlugins/MagnumFont/MagnumFont.cpp index 403165a6a..97f6dc0da 100644 --- a/src/MagnumPlugins/MagnumFont/MagnumFont.cpp +++ b/src/MagnumPlugins/MagnumFont/MagnumFont.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -52,18 +53,22 @@ struct MagnumFont::Data { Containers::Optional image; Containers::Optional filePath; std::unordered_map glyphId; - Containers::Array glyphAdvance; + struct Glyph { + Vector2i size; + Vector2 advance; + }; + Containers::Array glyphs; }; namespace { class MagnumFontLayouter: public AbstractLayouter { public: - explicit MagnumFontLayouter(Containers::ArrayView glyphAdvance, const AbstractGlyphCache& cache, Float fontSize, Float textSize, Containers::Array&& glyphs); + explicit MagnumFontLayouter(const Containers::StridedArrayView1D& glyphAdvance, const AbstractGlyphCache& cache, Float fontSize, Float textSize, Containers::Array&& glyphs); private: Containers::Triple doRenderGlyph(UnsignedInt i) override; - const Containers::ArrayView glyphAdvance; + const Containers::StridedArrayView1D glyphAdvance; const AbstractGlyphCache& cache; const Float fontSize, textSize; const Containers::Array glyphs; @@ -119,15 +124,18 @@ auto MagnumFont::doOpenData(const Containers::ArrayView data, const /* Glyph advances */ const std::vector glyphs = _opened->conf.groups("glyph"); - _opened->glyphAdvance = Containers::Array{NoInit, glyphs.size()}; + _opened->glyphs = Containers::Array{NoInit, glyphs.size()}; for(std::size_t i = 0; i != glyphs.size(); ++i) - _opened->glyphAdvance[i] = glyphs[i]->value("advance"); + _opened->glyphs[i] = { + glyphs[i]->value("rectangle").size(), + glyphs[i]->value("advance") + }; /* Fill character->glyph map */ const std::vector chars = _opened->conf.groups("char"); for(const Utility::ConfigurationGroup* const c: chars) { const UnsignedInt glyphId = c->value("glyph"); - CORRADE_INTERNAL_ASSERT(glyphId < _opened->glyphAdvance.size()); + CORRADE_INTERNAL_ASSERT(glyphId < _opened->glyphs.size()); _opened->glyphId.emplace(c->value("unicode"), glyphId); } @@ -150,8 +158,12 @@ UnsignedInt MagnumFont::doGlyphId(const char32_t character) { return it != _opened->glyphId.end() ? it->second : 0; } +Vector2 MagnumFont::doGlyphSize(const UnsignedInt glyph) { + return Vector2{_opened->glyphs[glyph].size}; +} + Vector2 MagnumFont::doGlyphAdvance(const UnsignedInt glyph) { - return _opened->glyphAdvance[glyph]; + return _opened->glyphs[glyph].advance; } Containers::Pointer MagnumFont::doCreateGlyphCache() { @@ -181,12 +193,12 @@ Containers::Pointer MagnumFont::doLayout(const AbstractGlyphCa i = codepointNext.second(); } - return Containers::pointer(_opened->glyphAdvance, cache, this->size(), size, Utility::move(glyphs)); + return Containers::pointer(stridedArrayView(_opened->glyphs).slice(&Data::Glyph::advance), cache, this->size(), size, Utility::move(glyphs)); } namespace { -MagnumFontLayouter::MagnumFontLayouter(Containers::ArrayView glyphAdvance, const AbstractGlyphCache& cache, const Float fontSize, const Float textSize, Containers::Array&& glyphs): AbstractLayouter{UnsignedInt(glyphs.size())}, glyphAdvance{glyphAdvance}, cache(cache), fontSize{fontSize}, textSize{textSize}, glyphs{Utility::move(glyphs)} {} +MagnumFontLayouter::MagnumFontLayouter(const Containers::StridedArrayView1D& glyphAdvance, const AbstractGlyphCache& cache, const Float fontSize, const Float textSize, Containers::Array&& glyphs): AbstractLayouter{UnsignedInt(glyphs.size())}, glyphAdvance{glyphAdvance}, cache(cache), fontSize{fontSize}, textSize{textSize}, glyphs{Utility::move(glyphs)} {} Containers::Triple MagnumFontLayouter::doRenderGlyph(const UnsignedInt i) { /* Position of the texture in the resulting glyph, texture coordinates */ diff --git a/src/MagnumPlugins/MagnumFont/MagnumFont.h b/src/MagnumPlugins/MagnumFont/MagnumFont.h index 1c1d56268..7b67a39f7 100644 --- a/src/MagnumPlugins/MagnumFont/MagnumFont.h +++ b/src/MagnumPlugins/MagnumFont/MagnumFont.h @@ -177,6 +177,7 @@ class MAGNUM_MAGNUMFONT_EXPORT MagnumFont: public AbstractFont { MAGNUM_MAGNUMFONT_LOCAL void doClose() override; MAGNUM_MAGNUMFONT_LOCAL UnsignedInt doGlyphId(char32_t character) override; + MAGNUM_MAGNUMFONT_LOCAL Vector2 doGlyphSize(UnsignedInt glyph) override; MAGNUM_MAGNUMFONT_LOCAL Vector2 doGlyphAdvance(UnsignedInt glyph) override; MAGNUM_MAGNUMFONT_LOCAL Containers::Pointer doCreateGlyphCache() override; MAGNUM_MAGNUMFONT_LOCAL Containers::Pointer doLayout(const AbstractGlyphCache& cache, Float size, Containers::StringView text) override; diff --git a/src/MagnumPlugins/MagnumFont/Test/MagnumFontTest.cpp b/src/MagnumPlugins/MagnumFont/Test/MagnumFontTest.cpp index 08ed71920..26fa0394c 100644 --- a/src/MagnumPlugins/MagnumFont/Test/MagnumFontTest.cpp +++ b/src/MagnumPlugins/MagnumFont/Test/MagnumFontTest.cpp @@ -94,6 +94,7 @@ void MagnumFontTest::properties() { CORRADE_COMPARE(font->descent(), -10.0f); CORRADE_COMPARE(font->lineHeight(), 39.7333f); CORRADE_COMPARE(font->glyphCount(), 3); + CORRADE_COMPARE(font->glyphSize(font->glyphId(U'W')), (Vector2{16.0f, 120.0f})); CORRADE_COMPARE(font->glyphAdvance(font->glyphId(U'W')), (Vector2{23.0f, 0.0f})); } diff --git a/src/MagnumPlugins/MagnumFontConverter/Test/MagnumFontConverterTest.cpp b/src/MagnumPlugins/MagnumFontConverter/Test/MagnumFontConverterTest.cpp index bd33d4e61..9cb521524 100644 --- a/src/MagnumPlugins/MagnumFontConverter/Test/MagnumFontConverterTest.cpp +++ b/src/MagnumPlugins/MagnumFontConverter/Test/MagnumFontConverterTest.cpp @@ -109,6 +109,8 @@ void MagnumFontConverterTest::exportFont() { return 0; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } + Vector2 doGlyphAdvance(const UnsignedInt glyph) override { switch(glyph) { case 0: return {8, 0}; @@ -166,6 +168,7 @@ void MagnumFontConverterTest::exportFontNoGlyphCacheImageDownload() { void doClose() override {} UnsignedInt doGlyphId(char32_t) override { return {}; } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doLayout(const AbstractGlyphCache&, Float, Containers::StringView) override { return nullptr;