diff --git a/doc/snippets/Text.cpp b/doc/snippets/Text.cpp index 213b9405f..4012a2c84 100644 --- a/doc/snippets/Text.cpp +++ b/doc/snippets/Text.cpp @@ -216,6 +216,36 @@ font->setFileCallback([](const std::string& filename, /* [AbstractFont-setFileCallback-template] */ } +{ +struct: Text::AbstractFont { + Text::FontFeatures doFeatures() const override { return {}; } + bool doIsOpened() const override { return false; } + void doClose() override {} + Properties doProperties() 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::Array _in; + +/* [AbstractFont-doOpenData-ownership] */ +void doOpenData(Containers::Array&& data, Text::DataFlags dataFlags, + Float size, UnsignedInt fontId) override +{ + /* Take over the existing array or copy the data if we can't */ + if(dataFlags & (Text::DataFlag::Owned|Text::DataFlag::ExternallyOwned)) + _in = std::move(data); + else + _in = Containers::Array{InPlaceInit, data}; + + DOXYGEN_ELLIPSIS(static_cast(size); static_cast(fontId);) +} +/* [AbstractFont-doOpenData-ownership] */ +} font; +} + + { /* -Wnonnull in GCC 11+ "helpfully" says "this is null" if I don't initialize the font pointer. I don't care, I just want you to check compilation errors, diff --git a/src/Magnum/Text/AbstractFont.cpp b/src/Magnum/Text/AbstractFont.cpp index 704dadaa5..9b2a1ab01 100644 --- a/src/Magnum/Text/AbstractFont.cpp +++ b/src/Magnum/Text/AbstractFont.cpp @@ -94,6 +94,28 @@ Debug& operator<<(Debug& debug, const FontFeatures value) { }); } +Debug& operator<<(Debug& debug, const DataFlag value) { + debug << "Text::DataFlag" << Debug::nospace; + + switch(value) { + /* LCOV_EXCL_START */ + #define _c(v) case DataFlag::v: return debug << "::" #v; + _c(Owned) + _c(ExternallyOwned) + #undef _c + /* LCOV_EXCL_STOP */ + } + + return debug << "(" << Debug::nospace << Debug::hex << UnsignedByte(value) << Debug::nospace << ")"; +} + +Debug& operator<<(Debug& debug, const DataFlags value) { + return Containers::enumSetDebugOutput(debug, value, "Text::DataFlags{}", { + DataFlag::Owned, + DataFlag::ExternallyOwned + }); +} + Containers::StringView AbstractFont::pluginInterface() { return MAGNUM_TEXT_ABSTRACTFONT_PLUGIN_INTERFACE ""_s; } @@ -181,7 +203,7 @@ bool AbstractFont::openData(const Containers::ArrayView data, const the check doesn't be done on the plugin side) because for some file formats it could be valid (MagnumFont in particular). */ close(); - doOpenData(Containers::arrayCast(data), size, fontId); + doOpenData(Containers::Array{const_cast(static_cast(data.data())), data.size(), [](char*, std::size_t) {}}, {}, size, fontId); /* If opening succeeded, cache reported font properties. If not, the values were reset to default-constructed values by close(). (OTOH, on @@ -203,7 +225,7 @@ bool AbstractFont::openData(const Containers::ArrayView data, const return false; } -void AbstractFont::doOpenData(const Containers::ArrayView data, const Float size, const UnsignedInt fontId) { +void AbstractFont::doOpenData(Containers::Array&& data, DataFlags, const Float size, const UnsignedInt fontId) { #ifndef MAGNUM_BUILD_DEPRECATED CORRADE_ASSERT_UNREACHABLE("Text::AbstractFont::openData(): feature advertised but not implemented", ); static_cast(data); @@ -238,6 +260,31 @@ auto AbstractFont::doOpenData(Containers::ArrayView, Float) -> Prope } #endif +bool AbstractFont::openMemory(Containers::ArrayView memory, const Float size, const UnsignedInt fontId) { + CORRADE_ASSERT(features() & FontFeature::OpenData, + "Text::AbstractFont::openData(): feature not supported", false); + + /* We accept empty data here (instead of checking for them and failing so + the check doesn't be done on the plugin side) because for some file + formats it could be valid (MagnumFont in particular). */ + close(); + doOpenData(Containers::Array{const_cast(static_cast(memory.data())), memory.size(), [](char*, std::size_t) {}}, DataFlag::ExternallyOwned, size, fontId); + + /* If opening succeeded, cache reported font properties. Same logic as in + openData() */ + if(isOpened()) { + const Properties properties = doProperties(); + _size = properties.size; + _ascent = properties.ascent; + _descent = properties.descent; + _lineHeight = properties.lineHeight; + _glyphCount = properties.glyphCount; + return true; + } + + return false; +} + Containers::Optional AbstractFont::fileFontCount(const Containers::StringView filename) { /* The logic here is mirroring what's in openFile(), just with delegating to different APIs. Comments are kept whole, just referring to different @@ -368,7 +415,7 @@ bool AbstractFont::openFile(const Containers::StringView filename, const Float s return isOpened(); } - doOpenData(*data, size, fontId); + doOpenData(Containers::Array{const_cast(data->data()), data->size(), [](char*, std::size_t) {}}, {}, size, fontId); _fileCallback(filename, InputFileCallbackPolicy::Close, _fileCallbackUserData); /* Shouldn't get here, the assert is fired already in setFileCallback() */ @@ -420,18 +467,18 @@ void AbstractFont::doOpenFile(const Containers::StringView filename, const Float return; } - doOpenData(*data, size, fontId); + doOpenData(Containers::Array{const_cast(data->data()), data->size(), [](char*, std::size_t) {}}, {}, size, fontId); _fileCallback(filename, InputFileCallbackPolicy::Close, _fileCallbackUserData); /* Otherwise open the file directly */ } else { - const Containers::Optional> data = Utility::Path::read(filename); + Containers::Optional> data = Utility::Path::read(filename); if(!data) { Error() << "Text::AbstractFont::openFile(): cannot open file" << filename; return; } - doOpenData(*data, size, fontId); + doOpenData(*Utility::move(data), DataFlag::Owned, size, fontId); } } diff --git a/src/Magnum/Text/AbstractFont.h b/src/Magnum/Text/AbstractFont.h index 3bbd71347..61ff45cf7 100644 --- a/src/Magnum/Text/AbstractFont.h +++ b/src/Magnum/Text/AbstractFont.h @@ -28,7 +28,7 @@ */ /** @file - * @brief Class @ref Magnum::Text::AbstractFont, enum @ref Magnum::Text::FontFeature, enum set @ref Magnum::Text::FontFeatures + * @brief Class @ref Magnum::Text::AbstractFont, enum @ref Magnum::Text::FontFeature, @ref Magnum::Text::DataFlag, enum set @ref Magnum::Text::FontFeatures, @ref Magnum::Text::DataFlags */ #include @@ -103,6 +103,55 @@ MAGNUM_TEXT_EXPORT Debug& operator<<(Debug& debug, FontFeature value); /** @debugoperatorenum{FontFeatures} */ MAGNUM_TEXT_EXPORT Debug& operator<<(Debug& debug, FontFeatures value); +/** +@brief Data flag +@m_since_latest + +@see @ref DataFlags, @ref AbstractFont::doOpenData(), @ref Trade::DataFlag +*/ +enum class DataFlag: UnsignedByte { + /** + * Data is owned by the instance, meaning it stays in scope for as long as + * the instance. If neither @ref DataFlag::Owned nor + * @ref DataFlag::ExternallyOwned is set, the data is considered to be just + * a temporary allocation and no assumptions about its lifetime can be + * made. + */ + Owned = 1 << 0, + + /** + * Data has an owner external to the instance, for example a memory-mapped + * file or a constant memory. In general the data lifetime exceeds lifetime + * of the instance wrapping it. If neither @ref DataFlag::Owned nor + * @ref DataFlag::ExternallyOwned is set, the data is considered to be just + * a temporary allocation and no assumptions about its lifetime can be + * made. + */ + ExternallyOwned = 1 << 1 +}; + +/** +@debugoperatorenum{DataFlag} +@m_since_latest +*/ +MAGNUM_TEXT_EXPORT Debug& operator<<(Debug& debug, DataFlag value); + +/** +@brief Data flags +@m_since_latest + +@see @ref AbstractFont::doOpenData(), @ref Trade::DataFlag +*/ +typedef Containers::EnumSet DataFlags; + +CORRADE_ENUMSET_OPERATORS(DataFlags) + +/** +@debugoperatorenum{DataFlags} +@m_since_latest +*/ +MAGNUM_TEXT_EXPORT Debug& operator<<(Debug& debug, DataFlags value); + /** @brief Base for font plugins @@ -189,10 +238,10 @@ all glyphs in the font: @section Text-AbstractFont-usage-callbacks Loading data from memory, using file callbacks Besides loading data directly from the filesystem using @ref openFile() like -shown above, it's possible to use @ref openData() to load fonts from memory -(for example from @relativeref{Corrade,Utility::Resource}). Note that the -particular font implementation has to support @ref FontFeature::OpenData for -this method to work: +shown above, it's possible to use @ref openData() / @ref openMemory() to load +fonts from memory (for example from @relativeref{Corrade,Utility::Resource}). +Note that the particular font implementation has to support +@ref FontFeature::OpenData for this method to work: @snippet Text.cpp AbstractFont-usage-data @@ -461,10 +510,14 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin { * @param size Size to open the font in, in points * @param fontId Font index * - * Closes previous file, if it was opened, and tries to open given - * raw data. Available only if @ref FontFeature::OpenData is supported. - * On failure prints a message to @relativeref{Magnum,Error} and - * returns @cpp false @ce. + * Closes previous file, if it was opened, and tries to open given raw + * data. Available only if @ref FontFeature::OpenData is supported. On + * failure prints a message to @relativeref{Magnum,Error} and returns + * @cpp false @ce. + * + * The @p data is not expected to be alive after the function exits. + * Using @ref openMemory() instead as can avoid unnecessary copies in + * exchange for stricter requirements on @p data lifetime. * * The function will fail if @p fontId is larger than the count of * fonts in given file. The total font count can be queried using @@ -477,6 +530,35 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin { */ bool openData(Containers::ArrayView data, Float size, UnsignedInt fontId = 0); + /** + * @brief Open a non-temporary memory + * @param memory Resident memory containing font data + * @param size Size to open the font in, in points + * @param fontId Font index + * @m_since_latest + * + * Closes previous file, if it was opened, and tries to open given raw + * data. Available only if @ref FontFeature::OpenData is supported. On + * failure prints a message to @relativeref{Magnum,Error} and returns + * @cpp false @ce. + * + * Unlike @ref openData(), this function expects @p memory to stay in + * scope until the font is destructed, @ref close() is called or + * another file is opened. This allows the implementation to directly + * operate on the provided memory, without having to allocate a local + * copy to extend its lifetime. + * + * The function will fail if @p fontId is larger than the count of + * fonts in given file. The total font count can be queried using + * @ref dataFontCount(), but as font rasterization libraries commonly + * require picking a concrete font index in order to open a file at + * all and don't allow changing it afterwards, it's faster to directly + * attempt to open a concrete index without checking it against + * @ref dataFontCount() first, and handle a potential failure. + * @see @ref features(), @ref openFile() + */ + bool openMemory(Containers::ArrayView memory, Float size, UnsignedInt fontId = 0); + /** * @brief Open a file * @param filename Font file @@ -864,18 +946,44 @@ class MAGNUM_TEXT_EXPORT AbstractFont: public PluginManager::AbstractPlugin { virtual Containers::Optional doDataFontCount(Containers::ArrayView data); /** - * @brief Implementation for @ref openData() + * @brief Implementation for @ref openData() and @ref openMemory() * @m_since_latest * * If the operation was successful, @ref doIsOpened() should return * @cpp true @ce after calling this function, @cpp false @ce otherwise. + * + * The @p data is mutable or owned depending on the value of + * @p dataFlags. This can be used for example to avoid allocating a + * local copy in order to preserve its lifetime. The following cases + * are possible: + * + * - If @p dataFlags is empty, @p data is a @cpp const @ce + * non-owning view. This happens when the function is called from + * @ref openData(). You have to assume the data go out of scope + * after the function exists, so if the font needs to access the + * data after, it has to allocate a local copy. + * - If @p dataFlags is @ref DataFlag::Owned, @p data is an owned + * (mutable) memory. This happens when the implementation is + * called from the default @ref doOpenFile() implementation --- it + * reads a file into a newly allocated array and passes it to this + * function. You can take ownership of the @p data instance + * instead of allocating a local copy. + * - If @p dataFlags is @ref DataFlag::ExternallyOwned, it can be + * assumed that @p data will stay in scope until @ref doClose() is + * called or the font is destructed. This happens when the + * function is called from @ref openMemory(). + * + * Example workflow in a plugin that needs to preserve access to the + * input data but wants to avoid allocating a copy if possible: + * + * @snippet Text.cpp AbstractFont-doOpenData-ownership */ - virtual void doOpenData(Containers::ArrayView data, Float size, UnsignedInt fontId); + virtual void doOpenData(Containers::Array&& data, DataFlags dataFlags, Float size, UnsignedInt fontId); #ifdef MAGNUM_BUILD_DEPRECATED /** * @brief Implementation for @ref openData() - * @m_deprecated_since_latest Implement @ref doOpenData(Containers::ArrayView, Float, UnsignedInt) + * @m_deprecated_since_latest Implement @ref doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) * and @ref doProperties() instead. * * If @ref doIsOpened() returns @cpp true @ce after calling this diff --git a/src/Magnum/Text/Test/AbstractFontTest.cpp b/src/Magnum/Text/Test/AbstractFontTest.cpp index 91a7a62e1..b571b4eb7 100644 --- a/src/Magnum/Text/Test/AbstractFontTest.cpp +++ b/src/Magnum/Text/Test/AbstractFontTest.cpp @@ -26,7 +26,7 @@ */ #include /** @todo remove once file callbacks are std::string-free */ -#include +#include #include #include #include @@ -60,6 +60,8 @@ struct AbstractFontTest: TestSuite::Tester { void debugFeaturePacked(); void debugFeatures(); void debugFeaturesPacked(); + void debugDataFlag(); + void debugDataFlags(); void construct(); @@ -77,12 +79,14 @@ struct AbstractFontTest: TestSuite::Tester { void fontCountInvalid(); void dataFontCountNotSupported(); - void openData(); + void openDataMemory(); #ifdef MAGNUM_BUILD_DEPRECATED void openDataDeprecated(); void openDataDeprecatedNonZeroFontId(); + /* No deprecated variants of openMemory(), as the behavior is the same as + with openData() there */ #endif - void openDataFailed(); + void openDataMemoryFailed(); #ifdef MAGNUM_BUILD_DEPRECATED void openDataFailedDeprecated(); #endif @@ -198,10 +202,26 @@ struct AbstractFontTest: TestSuite::Tester { const struct { const char* name; + bool openMemory; bool openedBefore; + DataFlags expectedFlags; /** @todo remove this once the deprecated APIs are gone */ UnsignedInt fontId; -} OpenDataFileData[]{ +} OpenDataMemoryData[]{ + {"open data", false, false, {}, 0}, + {"open data, opened before", false, true, {}, 0}, + {"open data, non-zero font ID", false, false, {}, 1}, + {"open memory", true, false, DataFlag::ExternallyOwned, 0}, + {"open memory, opened before", true, true, DataFlag::ExternallyOwned, 0}, + {"open memory, non-zero font ID", true, false, DataFlag::ExternallyOwned, 1} +}; + +const struct { + const char* name; + bool openedBefore; + /** @todo remove this once the deprecated APIs are gone */ + UnsignedInt fontId; +} OpenFileData[]{ {"", false, 0}, {"opened before", true, 0}, {"non-zero font ID", false, 1} @@ -242,6 +262,8 @@ AbstractFontTest::AbstractFontTest() { &AbstractFontTest::debugFeaturePacked, &AbstractFontTest::debugFeatures, &AbstractFontTest::debugFeaturesPacked, + &AbstractFontTest::debugDataFlag, + &AbstractFontTest::debugDataFlags, &AbstractFontTest::construct}); @@ -266,23 +288,23 @@ AbstractFontTest::AbstractFontTest() { &AbstractFontTest::fontCountInvalid, &AbstractFontTest::dataFontCountNotSupported}); - addInstancedTests({&AbstractFontTest::openData}, - Containers::arraySize(OpenDataFileData)); + addInstancedTests({&AbstractFontTest::openDataMemory}, + Containers::arraySize(OpenDataMemoryData)); #ifdef MAGNUM_BUILD_DEPRECATED addTests({&AbstractFontTest::openDataDeprecated, &AbstractFontTest::openDataDeprecatedNonZeroFontId}); #endif - addInstancedTests({&AbstractFontTest::openDataFailed}, - Containers::arraySize(OpenData)); + addInstancedTests({&AbstractFontTest::openDataMemoryFailed}, + Containers::arraySize(OpenDataMemoryData)); #ifdef MAGNUM_BUILD_DEPRECATED addTests({&AbstractFontTest::openDataFailedDeprecated}); #endif addInstancedTests({&AbstractFontTest::openFile}, - Containers::arraySize(OpenDataFileData)); + Containers::arraySize(OpenFileData)); #ifdef MAGNUM_BUILD_DEPRECATED addTests({&AbstractFontTest::openFileDeprecated, @@ -452,6 +474,18 @@ void AbstractFontTest::debugFeaturesPacked() { CORRADE_COMPARE(out, "OpenData|PreparedGlyphCache {} Text::FontFeature::FileCallback\n"); } +void AbstractFontTest::debugDataFlag() { + Containers::String out; + Debug{&out} << DataFlag::ExternallyOwned << DataFlag(0xf0); + CORRADE_COMPARE(out, "Text::DataFlag::ExternallyOwned Text::DataFlag(0xf0)\n"); +} + +void AbstractFontTest::debugDataFlags() { + Containers::String out; + Debug{&out} << (DataFlag::Owned|DataFlag(0xa0)) << DataFlags{}; + CORRADE_COMPARE(out, "Text::DataFlag::Owned|Text::DataFlag(0xa0) Text::DataFlags{}\n"); +} + void AbstractFontTest::construct() { struct: AbstractFont { FontFeatures doFeatures() const override { return {}; } @@ -493,7 +527,7 @@ void AbstractFontTest::dataFontCount() { return 37; } - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -535,7 +569,7 @@ void AbstractFontTest::dataFontCountFailed() { return {}; } - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -713,7 +747,7 @@ void AbstractFontTest::fileFontCountAsData() { return 37; } - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -754,7 +788,7 @@ void AbstractFontTest::fileFontCountAsDataNotFound() { return {}; } - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -803,7 +837,7 @@ void AbstractFontTest::fileFontCountAsDataFailed() { return {}; } - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -910,8 +944,8 @@ void AbstractFontTest::dataFontCountNotSupported() { CORRADE_COMPARE(out, "Text::AbstractFont::dataFontCount(): feature not supported\n"); } -void AbstractFontTest::openData() { - auto&& data = OpenDataFileData[testCaseInstanceId()]; +void AbstractFontTest::openDataMemory() { + auto&& data = OpenDataMemoryData[testCaseInstanceId()]; setTestCaseDescription(data.name); struct: AbstractFont { @@ -922,11 +956,14 @@ void AbstractFontTest::openData() { opened = false; } - void doOpenData(Containers::ArrayView data, Float size, UnsignedInt fontId) override { + void doOpenData(Containers::Array&& data, DataFlags dataFlags, Float size, UnsignedInt fontId) override { CORRADE_VERIFY(!opened); CORRADE_COMPARE_AS(data, Containers::arrayView({'\xa5'}), TestSuite::Compare::Container); + CORRADE_COMPARE(dataFlags, expectedFlags); + /* The array should have a custom no-op deleter */ + CORRADE_VERIFY(data.deleter()); CORRADE_COMPARE(size, 13.0f); CORRADE_COMPARE(fontId, expectedFontId); opened = true; @@ -941,9 +978,11 @@ void AbstractFontTest::openData() { Vector2 doGlyphAdvance(UnsignedInt) override { return {}; } Containers::Pointer doCreateShaper() override { return {}; } + DataFlags expectedFlags; UnsignedInt expectedFontId; bool opened; } font; + font.expectedFlags = data.expectedFlags; font.expectedFontId = data.fontId; font.opened = data.openedBefore; CORRADE_COMPARE(font.isOpened(), data.openedBefore); @@ -953,7 +992,10 @@ void AbstractFontTest::openData() { doOpenData() overload */ /** @todo remove the instanced font ID once the deprecated APIs are gone, supply a constant instead */ - CORRADE_VERIFY(font.openData(a5, 13.0f, data.fontId)); + if(data.openMemory) + CORRADE_VERIFY(font.openMemory(a5, 13.0f, data.fontId)); + else + CORRADE_VERIFY(font.openData(a5, 13.0f, data.fontId)); CORRADE_VERIFY(font.isOpened()); CORRADE_COMPARE(font.size(), 31.0f); CORRADE_COMPARE(font.ascent(), 1.0f); @@ -1042,8 +1084,8 @@ void AbstractFontTest::openDataDeprecatedNonZeroFontId() { } #endif -void AbstractFontTest::openDataFailed() { - auto&& data = OpenData[testCaseInstanceId()]; +void AbstractFontTest::openDataMemoryFailed() { + auto&& data = OpenDataMemoryData[testCaseInstanceId()]; setTestCaseDescription(data.name); struct: AbstractFont { @@ -1051,7 +1093,7 @@ void AbstractFontTest::openDataFailed() { bool doIsOpened() const override { return false; } void doClose() override {} - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { called = true; } @@ -1074,7 +1116,10 @@ void AbstractFontTest::openDataFailed() { overload for font 0 */ /** @todo remove the instanced font ID once the deprecated APIs are gone, supply a constant instead */ - CORRADE_VERIFY(!font.openData(nullptr, 1.0f, data.fontId)); + if(data.openMemory) + CORRADE_VERIFY(!font.openMemory(nullptr, 1.0f, data.fontId)); + else + CORRADE_VERIFY(!font.openData(nullptr, 1.0f, data.fontId)); CORRADE_VERIFY(!font.isOpened()); CORRADE_VERIFY(font.called); CORRADE_COMPARE(out, ""); @@ -1114,7 +1159,7 @@ void AbstractFontTest::openDataFailedDeprecated() { #endif void AbstractFontTest::openFile() { - auto&& data = OpenDataFileData[testCaseInstanceId()]; + auto&& data = OpenFileData[testCaseInstanceId()]; setTestCaseDescription(data.name); struct: AbstractFont { @@ -1317,10 +1362,13 @@ void AbstractFontTest::openFileAsData() { bool doIsOpened() const override { return _opened; } void doClose() override {} - void doOpenData(Containers::ArrayView data, Float size, UnsignedInt fontId) override { + void doOpenData(Containers::Array&& data, DataFlags dataFlags, Float size, UnsignedInt fontId) override { CORRADE_COMPARE_AS(data, Containers::arrayView({'\xa5'}), TestSuite::Compare::Container); + CORRADE_COMPARE(dataFlags, DataFlag::Owned); + /* I.e., we can take over the array, it's not just a view */ + CORRADE_VERIFY(!data.deleter()); CORRADE_COMPARE(size, 13.0f); CORRADE_COMPARE(fontId, expectedFontId); _opened = true; @@ -1365,7 +1413,7 @@ void AbstractFontTest::openFileAsDataNotFound() { bool doIsOpened() const override { return false; } void doClose() override {} - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { CORRADE_FAIL("This should not be called"); } @@ -1476,7 +1524,7 @@ void AbstractFontTest::openFileAsDataFailed() { bool doIsOpened() const override { return false; } void doClose() override {} - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { called = true; } @@ -1663,7 +1711,7 @@ void AbstractFontTest::propertiesNotImplemented() { void doOpenFile(Containers::StringView, Float, UnsignedInt) override { _opened = true; } - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -1902,7 +1950,7 @@ void AbstractFontTest::setFileCallbackOpenFileDirectly() { _opened = true; } - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { CORRADE_FAIL("This should not be called"); } @@ -1964,7 +2012,7 @@ void AbstractFontTest::setFileCallbackOpenFileDirectlyDeprecated() { return {size, 1.0f, 2.0f, 3.0f, 15}; } - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { CORRADE_FAIL("This should not be called"); } Properties doOpenData(Containers::ArrayView, Float) override { @@ -2077,7 +2125,7 @@ void AbstractFontTest::setFileCallbackOpenFileDirectlyFailed() { openCalled = true; } - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { CORRADE_FAIL("This should not be called"); } @@ -2132,7 +2180,7 @@ void AbstractFontTest::setFileCallbackOpenFileDirectlyFailedDeprecated() { return {}; } - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { CORRADE_FAIL("This should not be called"); } Properties doOpenData(Containers::ArrayView, Float) override { @@ -2197,10 +2245,13 @@ void AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementation() { AbstractFont::doOpenFile(filename, size, fontId); } - void doOpenData(Containers::ArrayView data, Float size, UnsignedInt fontId) override { + void doOpenData(Containers::Array&& data, DataFlags dataFlags, Float size, UnsignedInt fontId) override { CORRADE_COMPARE_AS(data, Containers::arrayView({'\xb0'}), TestSuite::Compare::Container); + CORRADE_COMPARE(dataFlags, DataFlags{}); + /* The array should have a custom no-op deleter */ + CORRADE_VERIFY(data.deleter()); CORRADE_COMPARE(size, 42.0f); CORRADE_COMPARE(fontId, expectedFontId); _opened = true; @@ -2368,7 +2419,7 @@ void AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementationNotFound( AbstractFont::doOpenFile(filename, size, fontId); } - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { CORRADE_FAIL("This should not be called"); } @@ -2439,7 +2490,7 @@ void AbstractFontTest::setFileCallbackOpenFileThroughBaseImplementationFailed() AbstractFont::doOpenFile(filename, size, fontId); } - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { openDataCalled = true; } @@ -2593,10 +2644,13 @@ void AbstractFontTest::setFileCallbackOpenFileAsData() { CORRADE_FAIL("This should not be called"); } - void doOpenData(Containers::ArrayView data, Float size, UnsignedInt fontId) override { + void doOpenData(Containers::Array&& data, DataFlags dataFlags, Float size, UnsignedInt fontId) override { CORRADE_COMPARE_AS(data, Containers::arrayView({'\xb0'}), TestSuite::Compare::Container); + CORRADE_COMPARE(dataFlags, DataFlags{}); + /* The array should have a custom no-op deleter */ + CORRADE_VERIFY(data.deleter()); CORRADE_COMPARE(size, 13.0f); CORRADE_COMPARE(fontId, expectedFontId); _opened = true; @@ -2810,7 +2864,7 @@ void AbstractFontTest::setFileCallbackOpenFileAsDataNotFound() { CORRADE_FAIL("This should not be called"); } - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { CORRADE_FAIL("This should not be called"); } @@ -2873,7 +2927,7 @@ void AbstractFontTest::setFileCallbackOpenFileAsDataFailed() { CORRADE_FAIL("This should not be called"); } - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { openCalled = true; } @@ -3000,7 +3054,7 @@ void AbstractFontTest::properties() { bool doIsOpened() const override { return _opened; } void doClose() override {} - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -3062,7 +3116,7 @@ void AbstractFontTest::glyphId() { bool doIsOpened() const override { return _opened; } void doClose() override {} - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -3156,7 +3210,7 @@ void AbstractFontTest::glyphIdOutOfRange() { bool doIsOpened() const override { return _opened; } void doClose() override {} - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -3197,7 +3251,7 @@ void AbstractFontTest::glyphName() { bool doIsOpened() const override { return _opened; } void doClose() override {} - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -3235,7 +3289,7 @@ void AbstractFontTest::glyphNameNotImplemented() { bool doIsOpened() const override { return _opened; } void doClose() override {} - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -3293,7 +3347,7 @@ void AbstractFontTest::glyphNameOutOfRange() { bool doIsOpened() const override { return _opened; } void doClose() override {} - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -3329,7 +3383,7 @@ void AbstractFontTest::glyphSizeAdvance() { bool doIsOpened() const override { return _opened; } void doClose() override {} - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -3382,7 +3436,7 @@ void AbstractFontTest::glyphSizeAdvanceOutOfRange() { bool doIsOpened() const override { return _opened; } void doClose() override {} - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -3424,7 +3478,7 @@ void AbstractFontTest::fillGlyphCache() { bool doIsOpened() const override { return _opened; } void doClose() override {} - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -3479,7 +3533,7 @@ void AbstractFontTest::fillGlyphCacheOutOfRange() { bool doIsOpened() const override { return _opened; } void doClose() override {} - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -3519,7 +3573,7 @@ void AbstractFontTest::fillGlyphCacheNotUnique() { bool doIsOpened() const override { return _opened; } void doClose() override {} - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -3555,7 +3609,7 @@ void AbstractFontTest::fillGlyphCacheFromString() { bool doIsOpened() const override { return _opened; } void doClose() override {} - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -3626,7 +3680,7 @@ void AbstractFontTest::fillGlyphCacheFailed() { bool doIsOpened() const override { return _opened; } void doClose() override {} - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; } @@ -3704,7 +3758,7 @@ void AbstractFontTest::fillGlyphCacheNotImplemented() { bool doIsOpened() const override { return _opened; } void doClose() override {} - void doOpenData(Containers::ArrayView, Float, UnsignedInt) override { + void doOpenData(Containers::Array&&, DataFlags, Float, UnsignedInt) override { _opened = true; }