diff --git a/doc/snippets/Text.cpp b/doc/snippets/Text.cpp index f4e820005..2586182f3 100644 --- a/doc/snippets/Text.cpp +++ b/doc/snippets/Text.cpp @@ -69,7 +69,7 @@ struct MyFont: Text::AbstractFont { Text::FontFeatures doFeatures() const override { return {}; } bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return nullptr; } diff --git a/src/Magnum/Text/AbstractFont.cpp b/src/Magnum/Text/AbstractFont.cpp index f25ce80cd..3711fb03d 100644 --- a/src/Magnum/Text/AbstractFont.cpp +++ b/src/Magnum/Text/AbstractFont.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include /** @todo remove once file callbacks are -free */ #include @@ -43,7 +44,6 @@ #ifdef MAGNUM_BUILD_DEPRECATED #include #include -#include #include "Magnum/Math/Functions.h" #include "Magnum/Math/Range.h" @@ -253,9 +253,25 @@ UnsignedInt AbstractFont::glyphCount() const { } UnsignedInt AbstractFont::glyphId(const char32_t character) { - CORRADE_ASSERT(isOpened(), "Text::AbstractFont::glyphId(): no font opened", 0); + const char32_t characters[]{character}; + UnsignedInt glyphs[1]; + glyphIdsInto(characters, glyphs); + return *glyphs; +} - return doGlyphId(character); +void AbstractFont::glyphIdsInto(const Containers::StridedArrayView1D& characters, const Containers::StridedArrayView1D& glyphs) { + CORRADE_ASSERT(isOpened(), + "Text::AbstractFont::glyphIdsInto(): no font opened", ); + CORRADE_ASSERT(glyphs.size() == characters.size(), + "Text::AbstractFont::glyphIdsInto(): expected the characters and glyphs views to have the same size but got" << characters.size() << "and" << glyphs.size(), ); + + doGlyphIdsInto(characters, glyphs); + #ifndef CORRADE_NO_DEBUG_ASSERT + for(std::size_t i = 0; i != characters.size(); ++i) { + CORRADE_DEBUG_ASSERT(glyphs[i] < _glyphCount, + "Text::AbstractFont::glyphIdsInto(): implementation-returned index" << glyphs[i] << "for character" << characters[i] << "out of range for" << _glyphCount << "glyphs", ); + } + #endif } Vector2 AbstractFont::glyphSize(const UnsignedInt glyph) { diff --git a/src/Magnum/Text/AbstractFont.h b/src/Magnum/Text/AbstractFont.h index e65069b8d..7d01b41ad 100644 --- a/src/Magnum/Text/AbstractFont.h +++ b/src/Magnum/Text/AbstractFont.h @@ -452,14 +452,23 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin { /** * @brief Glyph ID for given character * - * Expects that a font is opened. - * @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. + * A convenience wrapper around @ref glyphIdsInto() for querying a + * glyph ID for a single character. Expects that a font is opened. */ UnsignedInt glyphId(char32_t character); + /** + * @brief Glyph IDs for given characters + * @param[in] characters Input characters + * @param[out] glyphs Output glyph IDs + * @m_since_latest + * + * Expects that a font is opened and that the @p characters and + * @p glyphs views have the same size. The glyph IDs are all guaranteed + * to be less than @ref glyphCount(). + */ + void glyphIdsInto(const Containers::StridedArrayView1D& characters, const Containers::StridedArrayView1D& glyphs); + /** * @brief Glyph size in pixels * @param glyph Glyph ID @@ -653,8 +662,14 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin { /** @brief Implementation for @ref close() */ virtual void doClose() = 0; - /** @brief Implementation for @ref glyphId() */ - virtual UnsignedInt doGlyphId(char32_t character) = 0; + /** + * @brief Implementation for @ref glyphIdsInto() + * @m_since_latest + * + * The implementation is expected to return all @p glyphs smaller than + * @ref glyphCount(). + */ + virtual void doGlyphIdsInto(const Containers::StridedArrayView1D& characters, const Containers::StridedArrayView1D& glyphs) = 0; /** * @brief Implementation for @ref glyphSize() diff --git a/src/Magnum/Text/Test/AbstractFontConverterTest.cpp b/src/Magnum/Text/Test/AbstractFontConverterTest.cpp index 19713d817..081f588b7 100644 --- a/src/Magnum/Text/Test/AbstractFontConverterTest.cpp +++ b/src/Magnum/Text/Test/AbstractFontConverterTest.cpp @@ -161,7 +161,7 @@ struct DummyFont: AbstractFont { bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return nullptr; } diff --git a/src/Magnum/Text/Test/AbstractFontTest.cpp b/src/Magnum/Text/Test/AbstractFontTest.cpp index 578cd8ed8..cedd8c153 100644 --- a/src/Magnum/Text/Test/AbstractFontTest.cpp +++ b/src/Magnum/Text/Test/AbstractFontTest.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include /** @todo remove once Debug is stream-free */ #include @@ -82,6 +83,8 @@ struct AbstractFontTest: TestSuite::Tester { void glyphId(); void glyphIdNoFont(); + void glyphIdInvalidSize(); + void glyphIdOutOfRange(); void glyphSizeAdvance(); void glyphSizeAdvanceNoFont(); @@ -146,6 +149,8 @@ AbstractFontTest::AbstractFontTest() { &AbstractFontTest::glyphId, &AbstractFontTest::glyphIdNoFont, + &AbstractFontTest::glyphIdInvalidSize, + &AbstractFontTest::glyphIdOutOfRange, &AbstractFontTest::glyphSizeAdvance, &AbstractFontTest::glyphSizeAdvanceNoFont, @@ -189,7 +194,7 @@ void AbstractFontTest::construct() { bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -213,7 +218,7 @@ void AbstractFontTest::openData() { return {size, 1.0f, 2.0f, 3.0f, 15}; } - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -243,7 +248,7 @@ void AbstractFontTest::openFileAsData() { return {size, 1.0f, 2.0f, 3.0f, 15}; } - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -268,7 +273,7 @@ void AbstractFontTest::openFileAsDataNotFound() { bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -292,7 +297,7 @@ void AbstractFontTest::openFileNotImplemented() { bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -313,7 +318,7 @@ void AbstractFontTest::openDataNotSupported() { bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -333,7 +338,7 @@ void AbstractFontTest::openDataNotImplemented() { bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -354,7 +359,7 @@ void AbstractFontTest::setFileCallback() { *static_cast(userData) = 1337; } - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -379,7 +384,7 @@ void AbstractFontTest::setFileCallbackTemplate() { called = true; } - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -410,7 +415,7 @@ void AbstractFontTest::setFileCallbackTemplateNull() { called = !callback && !userData; } - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -434,7 +439,7 @@ void AbstractFontTest::setFileCallbackTemplateConst() { called = true; } - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -460,7 +465,7 @@ void AbstractFontTest::setFileCallbackFileOpened() { bool doIsOpened() const override { return true; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -481,7 +486,7 @@ void AbstractFontTest::setFileCallbackNotImplemented() { bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -505,7 +510,7 @@ void AbstractFontTest::setFileCallbackNotSupported() { bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -539,7 +544,7 @@ void AbstractFontTest::setFileCallbackOpenFileDirectly() { return {}; } - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -580,7 +585,7 @@ void AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementation() { return {size, 1.0f, 2.0f, 3.0f, 15}; } - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -633,7 +638,7 @@ void AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementationFailed() return AbstractFont::doOpenFile(filename, size); } - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -669,7 +674,7 @@ void AbstractFontTest::setFileCallbackOpenFileAsData() { return {size, 1.0f, 2.0f, 3.0f, 15}; } - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -723,7 +728,7 @@ void AbstractFontTest::setFileCallbackOpenFileAsDataFailed() { return {}; } - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -754,7 +759,7 @@ void AbstractFontTest::properties() { return {size, 1.0f, 2.0f, 3.0f, 15}; } - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -778,7 +783,7 @@ void AbstractFontTest::propertiesNoFont() { bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -801,16 +806,41 @@ void AbstractFontTest::propertiesNoFont() { void AbstractFontTest::glyphId() { struct MyFont: AbstractFont { - FontFeatures doFeatures() const override { return {}; } - bool doIsOpened() const override { return true; } + FontFeatures doFeatures() const override { + return FontFeature::OpenData; + } + bool doIsOpened() const override { return _opened; } void doClose() override {} - UnsignedInt doGlyphId(char32_t a) override { return a*10; } + Properties doOpenData(Containers::ArrayView, Float) override { + _opened = true; + return {0.0f, 0.0f, 0.0f, 0.0f, 1280}; + } + + void doGlyphIdsInto(const Containers::StridedArrayView1D& characters, const Containers::StridedArrayView1D& glyphs) override { + for(std::size_t i = 0; i != characters.size(); ++i) + glyphs[i] = characters[i]*10; + } + Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } + + private: + bool _opened = false; } font; + /* Have to explicitly open in order to make glyphCount() non-zero */ + CORRADE_VERIFY(font.openData(nullptr, 0.0f)); + + const char32_t characters[]{U'a', U'W', U'!'}; + UnsignedInt glyphs[3]; + font.glyphIdsInto(characters, glyphs); + CORRADE_COMPARE_AS(Containers::arrayView(glyphs), Containers::arrayView({ + 970u, 870u, 330u + }), TestSuite::Compare::Container); + + /* Single-item convenience overload */ CORRADE_COMPARE(font.glyphId(U'a'), 970); } @@ -822,7 +852,7 @@ void AbstractFontTest::glyphIdNoFont() { bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -830,8 +860,76 @@ void AbstractFontTest::glyphIdNoFont() { std::ostringstream out; Error redirectError{&out}; + font.glyphIdsInto({}, {}); font.glyphId('a'); - CORRADE_COMPARE(out.str(), "Text::AbstractFont::glyphId(): no font opened\n"); + CORRADE_COMPARE(out.str(), + "Text::AbstractFont::glyphIdsInto(): no font opened\n" + /* Both delegate to the same function so the assert is the same */ + "Text::AbstractFont::glyphIdsInto(): no font opened\n"); +} + +void AbstractFontTest::glyphIdInvalidSize() { + CORRADE_SKIP_IF_NO_ASSERT(); + + struct MyFont: AbstractFont { + FontFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return true; } + void doClose() override {} + + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} + Vector2 doGlyphSize(UnsignedInt) override { return {}; } + Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } + Containers::Pointer doCreateShaper() override { return {}; } + } font; + + char32_t characters[3]; + UnsignedInt glyphs[4]; + + std::ostringstream out; + Error redirectError{&out}; + font.glyphIdsInto(characters, glyphs); + CORRADE_COMPARE(out.str(), "Text::AbstractFont::glyphIdsInto(): expected the characters and glyphs views to have the same size but got 3 and 4\n"); +} + +void AbstractFontTest::glyphIdOutOfRange() { + CORRADE_SKIP_IF_NO_DEBUG_ASSERT(); + + struct MyFont: AbstractFont { + FontFeatures doFeatures() const override { + return FontFeature::OpenData; + } + bool doIsOpened() const override { return _opened; } + void doClose() override {} + + Properties doOpenData(Containers::ArrayView, Float) override { + _opened = true; + return {0.0f, 0.0f, 0.0f, 0.0f, 4}; + } + + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D& glyphs) override { + for(std::size_t i = 0; i != glyphs.size(); ++i) + glyphs[i] = i; + } + + Vector2 doGlyphSize(UnsignedInt) override { return {}; } + Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } + Containers::Pointer doCreateShaper() override { return {}; } + + private: + bool _opened = false; + } font; + + const char32_t characters[6]{U'\x1234', U'\x5678', U'\xabcd', + U'\xef01', U'\x2345', U'\x6789'}; + UnsignedInt glyphs[6]; + + /* Have to explicitly open in order to make glyphCount() non-zero */ + CORRADE_VERIFY(font.openData(nullptr, 0.0f)); + + std::ostringstream out; + Error redirectError{&out}; + font.glyphIdsInto(characters, glyphs); + CORRADE_COMPARE(out.str(), "Text::AbstractFont::glyphIdsInto(): implementation-returned index 4 for character U+2345 out of range for 4 glyphs\n"); } void AbstractFontTest::glyphSizeAdvance() { @@ -844,7 +942,7 @@ void AbstractFontTest::glyphSizeAdvance() { _opened = true; return {0.0f, 0.0f, 0.0f, 0.0f, 98}; } - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} 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 doCreateShaper() override { return {}; } @@ -866,7 +964,7 @@ void AbstractFontTest::glyphSizeAdvanceNoFont() { bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -893,7 +991,7 @@ void AbstractFontTest::glyphSizeAdvanceOutOfRange() { _opened = true; return {0.0f, 0.0f, 0.0f, 0.0f, 3}; } - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -926,7 +1024,7 @@ void AbstractFontTest::fillGlyphCache() { bool doIsOpened() const override { return true; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -958,7 +1056,7 @@ void AbstractFontTest::fillGlyphCacheFailed() { bool doIsOpened() const override { return true; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -986,7 +1084,7 @@ void AbstractFontTest::fillGlyphCacheNotSupported() { bool doIsOpened() const override { return true; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -1007,7 +1105,7 @@ void AbstractFontTest::fillGlyphCacheNotImplemented() { bool doIsOpened() const override { return true; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -1028,7 +1126,7 @@ void AbstractFontTest::fillGlyphCacheNoFont() { bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -1049,7 +1147,7 @@ void AbstractFontTest::fillGlyphCacheInvalidUtf8() { bool doIsOpened() const override { return true; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -1068,7 +1166,7 @@ void AbstractFontTest::createGlyphCache() { bool doIsOpened() const override { return true; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -1092,7 +1190,7 @@ void AbstractFontTest::createGlyphCacheNotSupported() { bool doIsOpened() const override { return true; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -1112,7 +1210,7 @@ void AbstractFontTest::createGlyphCacheNotImplemented() { bool doIsOpened() const override { return true; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -1132,7 +1230,7 @@ void AbstractFontTest::createGlyphCacheNoFont() { bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -1161,7 +1259,7 @@ void AbstractFontTest::createShaper() { bool doIsOpened() const override { return true; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return Containers::pointer(*this); } @@ -1179,7 +1277,7 @@ void AbstractFontTest::createShaperNoFont() { bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -1199,7 +1297,7 @@ void AbstractFontTest::createShaperNullptr() { bool doIsOpened() const override { return true; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return nullptr; } @@ -1243,7 +1341,7 @@ void AbstractFontTest::layout() { return {0.5f, 0.0f, 0.0f, 0.0f, 666}; } - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { @@ -1323,7 +1421,7 @@ void AbstractFontTest::layoutArrayGlyphCache() { bool doIsOpened() const override { return true; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -1345,7 +1443,7 @@ void AbstractFontTest::layoutGlyphCacheFontNotFound() { bool doIsOpened() const override { return true; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } @@ -1388,7 +1486,7 @@ void AbstractFontTest::layoutGlyphOutOfRange() { bool doIsOpened() const override { return true; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { @@ -1427,7 +1525,7 @@ void AbstractFontTest::layoutNoFont() { bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } diff --git a/src/Magnum/Text/Test/RendererGLTest.cpp b/src/Magnum/Text/Test/RendererGLTest.cpp index 4093bb34b..fabaafba5 100644 --- a/src/Magnum/Text/Test/RendererGLTest.cpp +++ b/src/Magnum/Text/Test/RendererGLTest.cpp @@ -94,7 +94,10 @@ struct TestFont: AbstractFont { return {size, 4.5f, -2.5f, 10000.0f, 10}; } - UnsignedInt doGlyphId(char32_t) override { return 0; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D& glyphs) override { + for(UnsignedInt& i: glyphs) + i = 0; + } Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } diff --git a/src/Magnum/Text/Test/RendererTest.cpp b/src/Magnum/Text/Test/RendererTest.cpp index 348888ce3..07907023e 100644 --- a/src/Magnum/Text/Test/RendererTest.cpp +++ b/src/Magnum/Text/Test/RendererTest.cpp @@ -342,7 +342,10 @@ struct TestFont: AbstractFont { return {size, 4.5f, -2.5f, 10000.0f, 10}; } - UnsignedInt doGlyphId(char32_t) override { return 0; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D& glyphs) override { + for(UnsignedInt& i: glyphs) + i = 0; + } Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } @@ -1039,7 +1042,10 @@ void RendererTest::multiline() { return {size, 1.0f, -1.0f, 8.0f, 10}; } - UnsignedInt doGlyphId(char32_t) override { return 0; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D& glyphs) override { + for(UnsignedInt& i: glyphs) + i = 0; + } Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } diff --git a/src/MagnumPlugins/MagnumFont/MagnumFont.cpp b/src/MagnumPlugins/MagnumFont/MagnumFont.cpp index f0cef2b2b..6ecc83ad6 100644 --- a/src/MagnumPlugins/MagnumFont/MagnumFont.cpp +++ b/src/MagnumPlugins/MagnumFont/MagnumFont.cpp @@ -142,9 +142,11 @@ auto MagnumFont::doOpenFile(const Containers::StringView filename, const Float s return AbstractFont::doOpenFile(filename, size); } -UnsignedInt MagnumFont::doGlyphId(const char32_t character) { - auto it = _opened->glyphId.find(character); - return it != _opened->glyphId.end() ? it->second : 0; +void MagnumFont::doGlyphIdsInto(const Containers::StridedArrayView1D& characters, const Containers::StridedArrayView1D& glyphs) { + for(std::size_t i = 0; i != characters.size(); ++i) { + auto it = _opened->glyphId.find(characters[i]); + glyphs[i] = it != _opened->glyphId.end() ? it->second : 0; + } } Vector2 MagnumFont::doGlyphSize(const UnsignedInt glyph) { diff --git a/src/MagnumPlugins/MagnumFont/MagnumFont.h b/src/MagnumPlugins/MagnumFont/MagnumFont.h index 4725a7015..cb9b7fdca 100644 --- a/src/MagnumPlugins/MagnumFont/MagnumFont.h +++ b/src/MagnumPlugins/MagnumFont/MagnumFont.h @@ -177,7 +177,7 @@ class MAGNUM_MAGNUMFONT_EXPORT MagnumFont: public AbstractFont { MAGNUM_MAGNUMFONT_LOCAL Properties doOpenFile(Containers::StringView filename, Float) override; MAGNUM_MAGNUMFONT_LOCAL void doClose() override; - MAGNUM_MAGNUMFONT_LOCAL UnsignedInt doGlyphId(char32_t character) override; + MAGNUM_MAGNUMFONT_LOCAL void doGlyphIdsInto(const Containers::StridedArrayView1D& characters, const Containers::StridedArrayView1D& glyphs) override; MAGNUM_MAGNUMFONT_LOCAL Vector2 doGlyphSize(UnsignedInt glyph) override; MAGNUM_MAGNUMFONT_LOCAL Vector2 doGlyphAdvance(UnsignedInt glyph) override; MAGNUM_MAGNUMFONT_LOCAL Containers::Pointer doCreateGlyphCache() override; diff --git a/src/MagnumPlugins/MagnumFontConverter/Test/MagnumFontConverterTest.cpp b/src/MagnumPlugins/MagnumFontConverter/Test/MagnumFontConverterTest.cpp index c4cd90e2b..91d9bcc54 100644 --- a/src/MagnumPlugins/MagnumFontConverter/Test/MagnumFontConverterTest.cpp +++ b/src/MagnumPlugins/MagnumFontConverter/Test/MagnumFontConverterTest.cpp @@ -115,23 +115,31 @@ class MyFont: public Text::AbstractFont { FontFeatures doFeatures() const override { return {}; } Containers::Pointer doCreateShaper() override { return nullptr; } - UnsignedInt doGlyphId(const char32_t character) override { - switch(character) { - case U'W': return 2; - case U'e': return 1; - /* MSVC (but not clang-cl) doesn't support UTF-8 in char32_t - literals but it does it regular strings. Still a problem in - MSVC 2022, what a trash fire, can't you just give up on - those codepage insanities already, ffs?! */ - #if defined(CORRADE_TARGET_MSVC) && !defined(CORRADE_TARGET_CLANG) - case U'\u011B': - #else - case U'ě': - #endif - return 3; + void doGlyphIdsInto(const Containers::StridedArrayView1D& characters, const Containers::StridedArrayView1D& glyphs) override { + for(std::size_t i = 0; i != characters.size(); ++i) { + switch(characters[i]) { + case U'W': + glyphs[i] = 2; + break; + case U'e': + glyphs[i] = 1; + break; + /* MSVC (but not clang-cl) doesn't support UTF-8 in + char32_t literals but it does it regular strings. Still + a problem in MSVC 2022, what a trash fire, can't you + just give up on those codepage insanities already, + ffs?! */ + #if defined(CORRADE_TARGET_MSVC) && !defined(CORRADE_TARGET_CLANG) + case U'\u011B': + #else + case U'ě': + #endif + glyphs[i] = 3; + break; + default: + glyphs[i] = 0; + } } - - return 0; } Vector2 doGlyphSize(UnsignedInt) override { return {}; } @@ -423,7 +431,7 @@ void MagnumFontConverterTest::exportFontImageProcessingGlyphCacheNoDownload() { bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return nullptr; } @@ -451,7 +459,7 @@ void MagnumFontConverterTest::exportFontArrayCache() { bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return nullptr; } @@ -481,7 +489,7 @@ void MagnumFontConverterTest::exportFontNotFoundInCache() { bool doIsOpened() const override { return false; } void doClose() override {} - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return nullptr; } @@ -515,7 +523,7 @@ void MagnumFontConverterTest::exportFontImageConversionFailed() { return {16.0f, 25.0f, -10.0f, 39.7333f, 3}; } - UnsignedInt doGlyphId(char32_t) override { return {}; } + void doGlyphIdsInto(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&) override {} Vector2 doGlyphSize(UnsignedInt) override { return {}; } Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return nullptr; }