From 90e342773c4bab0da9afbf6e9f1ad514469056e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Wed, 3 Jul 2024 17:13:36 +0200 Subject: [PATCH] MagnumFont: adapt to AbstractShaper changes. The returned cluster IDs are UTF-8 character positions in the input text. --- src/MagnumPlugins/MagnumFont/MagnumFont.cpp | 13 +++++-- .../MagnumFont/Test/MagnumFontTest.cpp | 39 ++++++++++++++++--- 2 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/MagnumPlugins/MagnumFont/MagnumFont.cpp b/src/MagnumPlugins/MagnumFont/MagnumFont.cpp index 6ecc83ad6..a6ae8af42 100644 --- a/src/MagnumPlugins/MagnumFont/MagnumFont.cpp +++ b/src/MagnumPlugins/MagnumFont/MagnumFont.cpp @@ -203,7 +203,9 @@ Containers::Pointer MagnumFont::doCreateShaper() { for(std::size_t i = 0; i != text.size(); ) { const Containers::Pair codepointNext = Utility::Unicode::nextChar(text, i); const auto it = fontData.glyphId.find(codepointNext.first()); - arrayAppend(_glyphs, it == fontData.glyphId.end() ? 0 : it->second); + arrayAppend(_glyphs, InPlaceInit, + it == fontData.glyphId.end() ? 0 : it->second, + begin + UnsignedInt(i)); i = codepointNext.second(); } @@ -211,19 +213,22 @@ Containers::Pointer MagnumFont::doCreateShaper() { } void doGlyphIdsInto(const Containers::StridedArrayView1D& ids) const override { - Utility::copy(_glyphs, ids); + Utility::copy(stridedArrayView(_glyphs).slice(&Containers::Pair::first), ids); } void doGlyphOffsetsAdvancesInto(const Containers::StridedArrayView1D& offsets, const Containers::StridedArrayView1D& advances) const override { const Data& fontData = *static_cast(font())._opened; for(std::size_t i = 0; i != _glyphs.size(); ++i) { /* There's no glyph offsets in addition to advances */ offsets[i] = {}; - advances[i] = fontData.glyphs[_glyphs[i]].advance; + advances[i] = fontData.glyphs[_glyphs[i].first()].advance; } } + void doGlyphClustersInto(const Containers::StridedArrayView1D& clusters) const override { + Utility::copy(stridedArrayView(_glyphs).slice(&Containers::Pair::second), clusters); + } Containers::StridedArrayView1D _glyphAdvance; - Containers::Array _glyphs; + Containers::Array> _glyphs; }; return Containers::pointer(*this); diff --git a/src/MagnumPlugins/MagnumFont/Test/MagnumFontTest.cpp b/src/MagnumPlugins/MagnumFont/Test/MagnumFontTest.cpp index e4842a26f..c78d49c95 100644 --- a/src/MagnumPlugins/MagnumFont/Test/MagnumFontTest.cpp +++ b/src/MagnumPlugins/MagnumFont/Test/MagnumFontTest.cpp @@ -68,13 +68,13 @@ struct MagnumFontTest: TestSuite::Tester { const struct { const char* name; const char* string; - UnsignedInt eGlyphId; + UnsignedInt eGlyphId, eGlyphClusterExtraSize; UnsignedInt begin, end; } ShapeData[]{ - {"", "Weave", 1, 0, ~UnsignedInt{}}, - {"substring", "haWeavesfefe", 1, 2, 7}, - {"UTF-8", "Wěave", 3, 0, ~UnsignedInt{}}, - {"UTF-8 substring", "haWěavefefe", 3, 2, 8}, + {"", "Weave", 1, 0, 0, ~UnsignedInt{}}, + {"substring", "haWeavesfefe", 1, 0, 2, 7}, + {"UTF-8", "Wěave", 3, 1, 0, ~UnsignedInt{}}, + {"UTF-8 substring", "haWěavefefe", 3, 1, 2, 8}, }; MagnumFontTest::MagnumFontTest() { @@ -152,8 +152,10 @@ void MagnumFontTest::shape() { UnsignedInt ids[5]; Vector2 offsets[5]; Vector2 advances[5]; + UnsignedInt clusters[5]; shaper->glyphIdsInto(ids); shaper->glyphOffsetsAdvancesInto(offsets, advances); + shaper->glyphClustersInto(clusters); CORRADE_COMPARE_AS(Containers::arrayView(ids), Containers::arrayView({ 2u, /* 'W' */ data.eGlyphId, /* 'e' or 'ě' */ @@ -172,6 +174,13 @@ void MagnumFontTest::shape() { {8.0f, 0.0f}, {12.f, 0.0f}, }), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(Containers::arrayView(clusters), Containers::arrayView({ + data.begin + 0u, + data.begin + 1u, + data.begin + 2u + data.eGlyphClusterExtraSize, + data.begin + 3u + data.eGlyphClusterExtraSize, + data.begin + 4u + data.eGlyphClusterExtraSize, + }), TestSuite::Compare::Container); } void MagnumFontTest::shapeEmpty() { @@ -200,8 +209,10 @@ void MagnumFontTest::shaperReuse() { UnsignedInt ids[2]; Vector2 offsets[2]; Vector2 advances[2]; + UnsignedInt clusters[2]; shaper->glyphIdsInto(ids); shaper->glyphOffsetsAdvancesInto(offsets, advances); + shaper->glyphClustersInto(clusters); CORRADE_COMPARE_AS(Containers::arrayView(ids), Containers::arrayView({ 2u, /* 'W' */ 1u /* 'e' */ @@ -213,6 +224,10 @@ void MagnumFontTest::shaperReuse() { {23.0f, 0.0f}, {12.f, 0.0f} }), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(Containers::arrayView(clusters), Containers::arrayView({ + 0u, + 1u + }), TestSuite::Compare::Container); /* Long text, same as in shape(), should enlarge the array for it */ } { @@ -220,8 +235,10 @@ void MagnumFontTest::shaperReuse() { UnsignedInt ids[5]; Vector2 offsets[5]; Vector2 advances[5]; + UnsignedInt clusters[5]; shaper->glyphIdsInto(ids); shaper->glyphOffsetsAdvancesInto(offsets, advances); + shaper->glyphClustersInto(clusters); CORRADE_COMPARE_AS(Containers::arrayView(ids), Containers::arrayView({ 2u, /* 'W' */ 3u, /* 'ě' */ @@ -239,6 +256,13 @@ void MagnumFontTest::shaperReuse() { {8.0f, 0.0f}, {12.f, 0.0f} }), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(Containers::arrayView(clusters), Containers::arrayView({ + 0u, + 1u, + 3u, + 4u, + 5u + }), TestSuite::Compare::Container); /* Short text again, should not leave the extra glyphs there */ } { @@ -246,8 +270,10 @@ void MagnumFontTest::shaperReuse() { UnsignedInt ids[3]; Vector2 offsets[3]; Vector2 advances[3]; + UnsignedInt clusters[3]; shaper->glyphIdsInto(ids); shaper->glyphOffsetsAdvancesInto(offsets, advances); + shaper->glyphClustersInto(clusters); CORRADE_COMPARE_AS(Containers::arrayView(ids), Containers::arrayView({ 0u, /* 'a' (not found) */ 0u, /* 'v' (not found) */ @@ -261,6 +287,9 @@ void MagnumFontTest::shaperReuse() { {8.0f, 0.0f}, {12.f, 0.0f} }), TestSuite::Compare::Container); + CORRADE_COMPARE_AS(Containers::arrayView(clusters), Containers::arrayView({ + 0u, 1u, 2u + }), TestSuite::Compare::Container); } }