From ae2dc091d41f335a53e4e4fb4dc7931844d1f0aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Thu, 20 Jun 2024 14:06:51 +0200 Subject: [PATCH] Text: move FeatureRange to Feature.h. 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. --- src/Magnum/Text/AbstractShaper.cpp | 1 + src/Magnum/Text/AbstractShaper.h | 65 +--------------- src/Magnum/Text/Feature.h | 66 +++++++++++++++- src/Magnum/Text/Test/AbstractShaperTest.cpp | 84 +-------------------- src/Magnum/Text/Test/FeatureTest.cpp | 84 ++++++++++++++++++++- 5 files changed, 151 insertions(+), 149 deletions(-) diff --git a/src/Magnum/Text/AbstractShaper.cpp b/src/Magnum/Text/AbstractShaper.cpp index 9c11276a2..e50160194 100644 --- a/src/Magnum/Text/AbstractShaper.cpp +++ b/src/Magnum/Text/AbstractShaper.cpp @@ -29,6 +29,7 @@ #include #include "Magnum/Text/Direction.h" +#include "Magnum/Text/Feature.h" #include "Magnum/Text/Script.h" namespace Magnum { namespace Text { diff --git a/src/Magnum/Text/AbstractShaper.h b/src/Magnum/Text/AbstractShaper.h index 3de26838e..dfdc9cb23 100644 --- a/src/Magnum/Text/AbstractShaper.h +++ b/src/Magnum/Text/AbstractShaper.h @@ -26,7 +26,7 @@ */ /** @file - * @brief Class @ref Magnum::Text::AbstractShaper, @ref Magnum::Text::FeatureRange + * @brief Class @ref Magnum::Text::AbstractShaper * @m_since_latest */ @@ -39,69 +39,6 @@ namespace Magnum { namespace Text { -/** -@brief OpenType feature for a text range -@m_since_latest - -@see @ref AbstractShaper::shape() -*/ -class FeatureRange { - public: - /** - * @brief Constructor - * @param feature Feature to control - * @param begin Beginning byte in the input text - * @param end (One byte after) the end byte in the input text - * @param value Feature value to set - */ - constexpr /*implicit*/ FeatureRange(Feature feature, UnsignedInt begin, UnsignedInt end, UnsignedInt value = true): _feature{feature}, _value{value}, _begin{begin}, _end{end} {} - - /** - * @brief Construct for the whole text - * - * Equivalent to calling @ref FeatureRange(Feature, UnsignedInt, UnsignedInt, UnsignedInt) - * with @p begin set to @cpp 0 @ce and @p end to @cpp 0xffffffffu @ce. - */ - constexpr /*implicit*/ FeatureRange(Feature feature, UnsignedInt value = true): _feature{feature}, _value{value}, _begin{0}, _end{~UnsignedInt{}} {} - - /** @brief Feature to control */ - constexpr Feature feature() const { return _feature; } - - /** - * @brief Whether to enable the feature - * - * Returns @cpp false @ce if @ref value() is @cpp 0 @ce, @cpp true @ce - * otherwise. - */ - constexpr bool isEnabled() const { return _value; } - - /** @brief Feature value to set */ - constexpr UnsignedInt value() const { return _value; } - - /** - * @brief Beginning byte in the input text - * - * If the feature is set for the whole text, this is @cpp 0 @ce. - */ - constexpr UnsignedInt begin() const { return _begin; } - - /** - * @brief (One byte after) the end byte in the input text - * - * If the feature is set for the whole text, this is - * @cpp 0xffffffffu @ce. - */ - constexpr UnsignedInt end() const { return _end; } - - private: - friend AbstractShaper; - - Feature _feature; - UnsignedInt _value; - UnsignedInt _begin; - UnsignedInt _end; -}; - /** @brief Base for text shapers @m_since_latest diff --git a/src/Magnum/Text/Feature.h b/src/Magnum/Text/Feature.h index af3a8c2f3..b2d94ff19 100644 --- a/src/Magnum/Text/Feature.h +++ b/src/Magnum/Text/Feature.h @@ -26,17 +26,81 @@ */ /** @file - * @brief Enum @ref Magnum::Text::Feature, function @ref Magnum::Text::feature() + * @brief Class @ref Magnum::Text::FeatureRange, enum @ref Magnum::Text::Feature, function @ref Magnum::Text::feature() * @m_since_latest */ #include #include "Magnum/Magnum.h" +#include "Magnum/Text/Text.h" #include "Magnum/Text/visibility.h" namespace Magnum { namespace Text { +/** +@brief OpenType feature for a text range +@m_since_latest + +@see @ref AbstractShaper::shape() +*/ +class FeatureRange { + public: + /** + * @brief Constructor + * @param feature Feature to control + * @param begin Beginning byte in the input text + * @param end (One byte after) the end byte in the input text + * @param value Feature value to set + */ + constexpr /*implicit*/ FeatureRange(Feature feature, UnsignedInt begin, UnsignedInt end, UnsignedInt value = true): _feature{feature}, _value{value}, _begin{begin}, _end{end} {} + + /** + * @brief Construct for the whole text + * + * Equivalent to calling @ref FeatureRange(Feature, UnsignedInt, UnsignedInt, UnsignedInt) + * with @p begin set to @cpp 0 @ce and @p end to @cpp 0xffffffffu @ce. + */ + constexpr /*implicit*/ FeatureRange(Feature feature, UnsignedInt value = true): _feature{feature}, _value{value}, _begin{0}, _end{~UnsignedInt{}} {} + + /** @brief Feature to control */ + constexpr Feature feature() const { return _feature; } + + /** + * @brief Whether to enable the feature + * + * Returns @cpp false @ce if @ref value() is @cpp 0 @ce, @cpp true @ce + * otherwise. + */ + constexpr bool isEnabled() const { return _value; } + + /** @brief Feature value to set */ + constexpr UnsignedInt value() const { return _value; } + + /** + * @brief Beginning byte in the input text + * + * If the feature is set for the whole text, this is @cpp 0 @ce. + */ + constexpr UnsignedInt begin() const { return _begin; } + + /** + * @brief (One byte after) the end byte in the input text + * + * If the feature is set for the whole text, this is + * @cpp 0xffffffffu @ce. + */ + constexpr UnsignedInt end() const { return _end; } + + private: + friend AbstractShaper; + + Feature _feature; + UnsignedInt _value; + UnsignedInt _begin; + UnsignedInt _end; +}; + /** @brief OpenType typographic feature @m_since_latest diff --git a/src/Magnum/Text/Test/AbstractShaperTest.cpp b/src/Magnum/Text/Test/AbstractShaperTest.cpp index 2d353254e..e582f9eb7 100644 --- a/src/Magnum/Text/Test/AbstractShaperTest.cpp +++ b/src/Magnum/Text/Test/AbstractShaperTest.cpp @@ -42,9 +42,6 @@ namespace Magnum { namespace Text { namespace Test { namespace { struct AbstractShaperTest: TestSuite::Tester { explicit AbstractShaperTest(); - void featureRangeConstruct(); - void featureRangeConstructBeginEnd(); - void construct(); void constructCopy(); void constructMove(); @@ -72,10 +69,7 @@ struct AbstractShaperTest: TestSuite::Tester { }; AbstractShaperTest::AbstractShaperTest() { - addTests({&AbstractShaperTest::featureRangeConstruct, - &AbstractShaperTest::featureRangeConstructBeginEnd, - - &AbstractShaperTest::construct, + addTests({&AbstractShaperTest::construct, &AbstractShaperTest::constructCopy, &AbstractShaperTest::constructMove, @@ -100,82 +94,6 @@ AbstractShaperTest::AbstractShaperTest() { &AbstractShaperTest::glyphsIntoInvalidViewSizes}); } -void AbstractShaperTest::featureRangeConstruct() { - FeatureRange a{Feature::Kerning}; - FeatureRange b{Feature::StandardLigatures, false}; - FeatureRange c{Feature::AccessAllAlternates, 13}; - CORRADE_COMPARE(a.feature(), Feature::Kerning); - CORRADE_COMPARE(b.feature(), Feature::StandardLigatures); - CORRADE_COMPARE(c.feature(), Feature::AccessAllAlternates); - CORRADE_VERIFY(a.isEnabled()); - CORRADE_VERIFY(!b.isEnabled()); - CORRADE_COMPARE(a.value(), 1); - CORRADE_COMPARE(b.value(), 0); - CORRADE_COMPARE(c.value(), 13); - CORRADE_COMPARE(a.begin(), 0); - CORRADE_COMPARE(b.begin(), 0); - CORRADE_COMPARE(c.begin(), 0); - CORRADE_COMPARE(a.end(), ~UnsignedInt{}); - CORRADE_COMPARE(b.end(), ~UnsignedInt{}); - CORRADE_COMPARE(c.end(), ~UnsignedInt{}); - - constexpr FeatureRange ca{Feature::Kerning}; - constexpr FeatureRange cb{Feature::StandardLigatures, false}; - constexpr FeatureRange cc{Feature::AccessAllAlternates, 13}; - CORRADE_COMPARE(ca.feature(), Feature::Kerning); - CORRADE_COMPARE(cb.feature(), Feature::StandardLigatures); - CORRADE_COMPARE(cc.feature(), Feature::AccessAllAlternates); - CORRADE_VERIFY(ca.isEnabled()); - CORRADE_VERIFY(!cb.isEnabled()); - CORRADE_COMPARE(ca.value(), 1); - CORRADE_COMPARE(cb.value(), 0); - CORRADE_COMPARE(cc.value(), 13); - CORRADE_COMPARE(ca.begin(), 0); - CORRADE_COMPARE(cb.begin(), 0); - CORRADE_COMPARE(cc.begin(), 0); - CORRADE_COMPARE(ca.end(), ~UnsignedInt{}); - CORRADE_COMPARE(cb.end(), ~UnsignedInt{}); - CORRADE_COMPARE(cc.end(), ~UnsignedInt{}); -} - -void AbstractShaperTest::featureRangeConstructBeginEnd() { - FeatureRange a{Feature::Kerning, 7, 26}; - FeatureRange b{Feature::StandardLigatures, 7, 26, false}; - FeatureRange c{Feature::AccessAllAlternates, 7, 26, 13}; - CORRADE_COMPARE(a.feature(), Feature::Kerning); - CORRADE_COMPARE(b.feature(), Feature::StandardLigatures); - CORRADE_COMPARE(c.feature(), Feature::AccessAllAlternates); - CORRADE_VERIFY(a.isEnabled()); - CORRADE_VERIFY(!b.isEnabled()); - CORRADE_COMPARE(a.value(), 1); - CORRADE_COMPARE(b.value(), 0); - CORRADE_COMPARE(c.value(), 13); - CORRADE_COMPARE(a.begin(), 7); - CORRADE_COMPARE(b.begin(), 7); - CORRADE_COMPARE(c.begin(), 7); - CORRADE_COMPARE(a.end(), 26); - CORRADE_COMPARE(b.end(), 26); - CORRADE_COMPARE(c.end(), 26); - - constexpr FeatureRange ca{Feature::Kerning, 7, 26}; - constexpr FeatureRange cb{Feature::StandardLigatures, 7, 26, false}; - constexpr FeatureRange cc{Feature::AccessAllAlternates, 7, 26, 13}; - CORRADE_COMPARE(ca.feature(), Feature::Kerning); - CORRADE_COMPARE(cb.feature(), Feature::StandardLigatures); - CORRADE_COMPARE(cc.feature(), Feature::AccessAllAlternates); - CORRADE_VERIFY(ca.isEnabled()); - CORRADE_VERIFY(!cb.isEnabled()); - CORRADE_COMPARE(ca.value(), 1); - CORRADE_COMPARE(cb.value(), 0); - CORRADE_COMPARE(cc.value(), 13); - CORRADE_COMPARE(ca.begin(), 7); - CORRADE_COMPARE(cb.begin(), 7); - CORRADE_COMPARE(cc.begin(), 7); - CORRADE_COMPARE(ca.end(), 26); - CORRADE_COMPARE(cb.end(), 26); - CORRADE_COMPARE(cc.end(), 26); -} - AbstractFont& FakeFont = *reinterpret_cast(std::size_t{0xdeadbeef}); struct DummyShaper: AbstractShaper { diff --git a/src/Magnum/Text/Test/FeatureTest.cpp b/src/Magnum/Text/Test/FeatureTest.cpp index d8b700d4e..9fe429ef3 100644 --- a/src/Magnum/Text/Test/FeatureTest.cpp +++ b/src/Magnum/Text/Test/FeatureTest.cpp @@ -35,6 +35,9 @@ namespace Magnum { namespace Text { namespace Test { namespace { struct FeatureTest: TestSuite::Tester { explicit FeatureTest(); + void rangeConstruct(); + void rangeConstructBeginEnd(); + void debug(); void fromFourCC(); @@ -43,13 +46,92 @@ struct FeatureTest: TestSuite::Tester { }; FeatureTest::FeatureTest() { - addTests({&FeatureTest::debug, + addTests({&FeatureTest::rangeConstruct, + &FeatureTest::rangeConstructBeginEnd, + + &FeatureTest::debug, &FeatureTest::fromFourCC, &FeatureTest::fromString, &FeatureTest::fromStringInvalid}); } +void FeatureTest::rangeConstruct() { + FeatureRange a{Feature::Kerning}; + FeatureRange b{Feature::StandardLigatures, false}; + FeatureRange c{Feature::AccessAllAlternates, 13}; + CORRADE_COMPARE(a.feature(), Feature::Kerning); + CORRADE_COMPARE(b.feature(), Feature::StandardLigatures); + CORRADE_COMPARE(c.feature(), Feature::AccessAllAlternates); + CORRADE_VERIFY(a.isEnabled()); + CORRADE_VERIFY(!b.isEnabled()); + CORRADE_COMPARE(a.value(), 1); + CORRADE_COMPARE(b.value(), 0); + CORRADE_COMPARE(c.value(), 13); + CORRADE_COMPARE(a.begin(), 0); + CORRADE_COMPARE(b.begin(), 0); + CORRADE_COMPARE(c.begin(), 0); + CORRADE_COMPARE(a.end(), ~UnsignedInt{}); + CORRADE_COMPARE(b.end(), ~UnsignedInt{}); + CORRADE_COMPARE(c.end(), ~UnsignedInt{}); + + constexpr FeatureRange ca{Feature::Kerning}; + constexpr FeatureRange cb{Feature::StandardLigatures, false}; + constexpr FeatureRange cc{Feature::AccessAllAlternates, 13}; + CORRADE_COMPARE(ca.feature(), Feature::Kerning); + CORRADE_COMPARE(cb.feature(), Feature::StandardLigatures); + CORRADE_COMPARE(cc.feature(), Feature::AccessAllAlternates); + CORRADE_VERIFY(ca.isEnabled()); + CORRADE_VERIFY(!cb.isEnabled()); + CORRADE_COMPARE(ca.value(), 1); + CORRADE_COMPARE(cb.value(), 0); + CORRADE_COMPARE(cc.value(), 13); + CORRADE_COMPARE(ca.begin(), 0); + CORRADE_COMPARE(cb.begin(), 0); + CORRADE_COMPARE(cc.begin(), 0); + CORRADE_COMPARE(ca.end(), ~UnsignedInt{}); + CORRADE_COMPARE(cb.end(), ~UnsignedInt{}); + CORRADE_COMPARE(cc.end(), ~UnsignedInt{}); +} + +void FeatureTest::rangeConstructBeginEnd() { + FeatureRange a{Feature::Kerning, 7, 26}; + FeatureRange b{Feature::StandardLigatures, 7, 26, false}; + FeatureRange c{Feature::AccessAllAlternates, 7, 26, 13}; + CORRADE_COMPARE(a.feature(), Feature::Kerning); + CORRADE_COMPARE(b.feature(), Feature::StandardLigatures); + CORRADE_COMPARE(c.feature(), Feature::AccessAllAlternates); + CORRADE_VERIFY(a.isEnabled()); + CORRADE_VERIFY(!b.isEnabled()); + CORRADE_COMPARE(a.value(), 1); + CORRADE_COMPARE(b.value(), 0); + CORRADE_COMPARE(c.value(), 13); + CORRADE_COMPARE(a.begin(), 7); + CORRADE_COMPARE(b.begin(), 7); + CORRADE_COMPARE(c.begin(), 7); + CORRADE_COMPARE(a.end(), 26); + CORRADE_COMPARE(b.end(), 26); + CORRADE_COMPARE(c.end(), 26); + + constexpr FeatureRange ca{Feature::Kerning, 7, 26}; + constexpr FeatureRange cb{Feature::StandardLigatures, 7, 26, false}; + constexpr FeatureRange cc{Feature::AccessAllAlternates, 7, 26, 13}; + CORRADE_COMPARE(ca.feature(), Feature::Kerning); + CORRADE_COMPARE(cb.feature(), Feature::StandardLigatures); + CORRADE_COMPARE(cc.feature(), Feature::AccessAllAlternates); + CORRADE_VERIFY(ca.isEnabled()); + CORRADE_VERIFY(!cb.isEnabled()); + CORRADE_COMPARE(ca.value(), 1); + CORRADE_COMPARE(cb.value(), 0); + CORRADE_COMPARE(cc.value(), 13); + CORRADE_COMPARE(ca.begin(), 7); + CORRADE_COMPARE(cb.begin(), 7); + CORRADE_COMPARE(cc.begin(), 7); + CORRADE_COMPARE(ca.end(), 26); + CORRADE_COMPARE(cb.end(), 26); + CORRADE_COMPARE(cc.end(), 26); +} + void FeatureTest::debug() { std::ostringstream out; Debug{&out} << Feature::StandardLigatures << Text::feature('m', 'a', '\xab', 'g');