Browse Source

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.
pull/641/head
Vladimír Vondruš 2 years ago
parent
commit
ae2dc091d4
  1. 1
      src/Magnum/Text/AbstractShaper.cpp
  2. 65
      src/Magnum/Text/AbstractShaper.h
  3. 66
      src/Magnum/Text/Feature.h
  4. 84
      src/Magnum/Text/Test/AbstractShaperTest.cpp
  5. 84
      src/Magnum/Text/Test/FeatureTest.cpp

1
src/Magnum/Text/AbstractShaper.cpp

@ -29,6 +29,7 @@
#include <Corrade/Containers/StringView.h> #include <Corrade/Containers/StringView.h>
#include "Magnum/Text/Direction.h" #include "Magnum/Text/Direction.h"
#include "Magnum/Text/Feature.h"
#include "Magnum/Text/Script.h" #include "Magnum/Text/Script.h"
namespace Magnum { namespace Text { namespace Magnum { namespace Text {

65
src/Magnum/Text/AbstractShaper.h

@ -26,7 +26,7 @@
*/ */
/** @file /** @file
* @brief Class @ref Magnum::Text::AbstractShaper, @ref Magnum::Text::FeatureRange * @brief Class @ref Magnum::Text::AbstractShaper
* @m_since_latest * @m_since_latest
*/ */
@ -39,69 +39,6 @@
namespace Magnum { namespace Text { 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 @brief Base for text shapers
@m_since_latest @m_since_latest

66
src/Magnum/Text/Feature.h

@ -26,17 +26,81 @@
*/ */
/** @file /** @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 * @m_since_latest
*/ */
#include <Corrade/Utility/Endianness.h> #include <Corrade/Utility/Endianness.h>
#include "Magnum/Magnum.h" #include "Magnum/Magnum.h"
#include "Magnum/Text/Text.h"
#include "Magnum/Text/visibility.h" #include "Magnum/Text/visibility.h"
namespace Magnum { namespace Text { 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 @brief OpenType typographic feature
@m_since_latest @m_since_latest

84
src/Magnum/Text/Test/AbstractShaperTest.cpp

@ -42,9 +42,6 @@ namespace Magnum { namespace Text { namespace Test { namespace {
struct AbstractShaperTest: TestSuite::Tester { struct AbstractShaperTest: TestSuite::Tester {
explicit AbstractShaperTest(); explicit AbstractShaperTest();
void featureRangeConstruct();
void featureRangeConstructBeginEnd();
void construct(); void construct();
void constructCopy(); void constructCopy();
void constructMove(); void constructMove();
@ -72,10 +69,7 @@ struct AbstractShaperTest: TestSuite::Tester {
}; };
AbstractShaperTest::AbstractShaperTest() { AbstractShaperTest::AbstractShaperTest() {
addTests({&AbstractShaperTest::featureRangeConstruct, addTests({&AbstractShaperTest::construct,
&AbstractShaperTest::featureRangeConstructBeginEnd,
&AbstractShaperTest::construct,
&AbstractShaperTest::constructCopy, &AbstractShaperTest::constructCopy,
&AbstractShaperTest::constructMove, &AbstractShaperTest::constructMove,
@ -100,82 +94,6 @@ AbstractShaperTest::AbstractShaperTest() {
&AbstractShaperTest::glyphsIntoInvalidViewSizes}); &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<AbstractFont*>(std::size_t{0xdeadbeef}); AbstractFont& FakeFont = *reinterpret_cast<AbstractFont*>(std::size_t{0xdeadbeef});
struct DummyShaper: AbstractShaper { struct DummyShaper: AbstractShaper {

84
src/Magnum/Text/Test/FeatureTest.cpp

@ -35,6 +35,9 @@ namespace Magnum { namespace Text { namespace Test { namespace {
struct FeatureTest: TestSuite::Tester { struct FeatureTest: TestSuite::Tester {
explicit FeatureTest(); explicit FeatureTest();
void rangeConstruct();
void rangeConstructBeginEnd();
void debug(); void debug();
void fromFourCC(); void fromFourCC();
@ -43,13 +46,92 @@ struct FeatureTest: TestSuite::Tester {
}; };
FeatureTest::FeatureTest() { FeatureTest::FeatureTest() {
addTests({&FeatureTest::debug, addTests({&FeatureTest::rangeConstruct,
&FeatureTest::rangeConstructBeginEnd,
&FeatureTest::debug,
&FeatureTest::fromFourCC, &FeatureTest::fromFourCC,
&FeatureTest::fromString, &FeatureTest::fromString,
&FeatureTest::fromStringInvalid}); &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() { void FeatureTest::debug() {
std::ostringstream out; std::ostringstream out;
Debug{&out} << Feature::StandardLigatures << Text::feature('m', 'a', '\xab', 'g'); Debug{&out} << Feature::StandardLigatures << Text::feature('m', 'a', '\xab', 'g');

Loading…
Cancel
Save