From b5325ab0ac2e2e394b5e58b92cab759e506ea13b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 14 Feb 2025 18:58:47 +0100 Subject: [PATCH] TextureTools: return the filled range from AtlasLandfill::add(). Because otherwise the users likely have to do something similar on their end to perform a texture upload etc., which means they'll either take the easy path and upload everything including the unused area, or they introduce various bugs in the process, leading to random artifacts, especially when it comes to padding. Which is exactly what I think is causing random test failures in the Ui library text rendering, because the glyph cache filling process in plugins is calculating the rectangle too tight, without considering padding. Gonna fix that now. --- doc/snippets/TextureTools.cpp | 1 + src/Magnum/Text/AbstractGlyphCache.cpp | 2 +- src/Magnum/TextureTools/Atlas.cpp | 49 +++++++++------ src/Magnum/TextureTools/Atlas.h | 38 ++++++------ src/Magnum/TextureTools/Test/AtlasTest.cpp | 72 +++++++++++++--------- 5 files changed, 94 insertions(+), 68 deletions(-) diff --git a/doc/snippets/TextureTools.cpp b/doc/snippets/TextureTools.cpp index b71c206ef..6393cadb2 100644 --- a/doc/snippets/TextureTools.cpp +++ b/doc/snippets/TextureTools.cpp @@ -36,6 +36,7 @@ #include "Magnum/Math/Color.h" #include "Magnum/Math/FunctionsBatch.h" #include "Magnum/Math/Matrix3.h" +#include "Magnum/Math/Range.h" #include "Magnum/MeshTools/Transform.h" #include "Magnum/TextureTools/Atlas.h" #include "Magnum/Trade/MaterialData.h" diff --git a/src/Magnum/Text/AbstractGlyphCache.cpp b/src/Magnum/Text/AbstractGlyphCache.cpp index 3e1cfbb1c..9f7977672 100644 --- a/src/Magnum/Text/AbstractGlyphCache.cpp +++ b/src/Magnum/Text/AbstractGlyphCache.cpp @@ -302,7 +302,7 @@ std::vector AbstractGlyphCache::reserve(const std::vector& s for(std::size_t i = 0; i != sizes.size(); ++i) out[i].max() = sizes[i]; - const bool succeeded = state.atlas.add( + const bool succeeded = !!state.atlas.add( Containers::stridedArrayView(out).slice(&Range2Di::max), Containers::stridedArrayView(out).slice(&Range2Di::min)); diff --git a/src/Magnum/TextureTools/Atlas.cpp b/src/Magnum/TextureTools/Atlas.cpp index 76dd24536..23c66b45a 100644 --- a/src/Magnum/TextureTools/Atlas.cpp +++ b/src/Magnum/TextureTools/Atlas.cpp @@ -31,17 +31,17 @@ #include #include #include +#include #include #include #include "Magnum/Math/Matrix3.h" #include "Magnum/Math/Functions.h" #include "Magnum/Math/FunctionsBatch.h" +#include "Magnum/Math/Range.h" #ifdef MAGNUM_BUILD_DEPRECATED #include - -#include "Magnum/Math/Range.h" #endif namespace Magnum { namespace TextureTools { @@ -96,7 +96,7 @@ struct AtlasLandfillState { namespace { -bool atlasLandfillAddSortedFlipped(Implementation::AtlasLandfillState& state, const Int slice, const Containers::StridedArrayView1D> sortedFlippedSizes, const Containers::StridedArrayView1D offsets, const Containers::StridedArrayView1D zOffsets, const Containers::BitArrayView rotations) { +Containers::Optional atlasLandfillAddSortedFlipped(Implementation::AtlasLandfillState& state, const Int slice, const Containers::StridedArrayView1D> sortedFlippedSizes, const Containers::StridedArrayView1D offsets, const Containers::StridedArrayView1D zOffsets, const Containers::BitArrayView rotations) { /* Add a new slice if not there yet, extend the yOffsets array */ if(UnsignedInt(slice) >= state.slices.size()) { CORRADE_INTERNAL_ASSERT(UnsignedInt(slice) == state.slices.size()); @@ -117,6 +117,7 @@ bool atlasLandfillAddSortedFlipped(Implementation::AtlasLandfillState& state, co if(sliceState.direction == -1) sliceYOffsets = sliceYOffsets.flipped<0>(); + Range3Di range; std::size_t i; for(i = 0; i != sortedFlippedSizes.size(); ++i) { const Vector2i size = sortedFlippedSizes[i].first(); @@ -161,11 +162,15 @@ bool atlasLandfillAddSortedFlipped(Implementation::AtlasLandfillState& state, co /* Save the position (X-flip it in case we're in reverse direction), add the (appropriately rotated) padding to it so it points to the original unpadded size */ - offsets[index] = padding + Vector2i{ + const Vector2i offset{ sliceState.direction > 0 ? sliceState.xOffset : state.size.x() - sliceState.xOffset - size.x(), - placementYOffset - }; + placementYOffset}; + offsets[index] = padding + offset; + + /* Add this item to the range spanning all added items, including the + (potentially rotated) padding */ + range = join(range, Range3Di::fromSize({offset, slice}, {size, 1})); /* Advance to the next X offset */ sliceState.xOffset += size.x(); @@ -179,13 +184,18 @@ bool atlasLandfillAddSortedFlipped(Implementation::AtlasLandfillState& state, co /* If there are items that didn't fit, recurse to the next slice. This should only happen if the Y size is bounded. */ if(i < sortedFlippedSizes.size()) { + /* If there are no more slices, fail */ if(slice + 1 == state.size.z()) - return false; - return atlasLandfillAddSortedFlipped(state, slice + 1, sortedFlippedSizes.exceptPrefix(i), offsets, zOffsets, rotations); + return {}; + /* If the recursion succeeded, return the two ranges joined */ + if(const Containers::Optional out = atlasLandfillAddSortedFlipped(state, slice + 1, sortedFlippedSizes.exceptPrefix(i), offsets, zOffsets, rotations)) + return Range3Di{join(range, *out)}; + /* If it didn't, fail */ + return {}; } /* Everything fit, success */ - return true; + return range; } } @@ -252,7 +262,7 @@ AtlasLandfill& AtlasLandfill::setFlags(AtlasLandfillFlags flags) { namespace { -bool atlasLandfillAdd(Implementation::AtlasLandfillState& state, const Containers::StridedArrayView1D sizes, const Containers::StridedArrayView1D offsets, const Containers::StridedArrayView1D zOffsets, const Containers::MutableBitArrayView rotations) { +Containers::Optional atlasLandfillAdd(Implementation::AtlasLandfillState& state, const Containers::StridedArrayView1D sizes, const Containers::StridedArrayView1D offsets, const Containers::StridedArrayView1D zOffsets, const Containers::MutableBitArrayView rotations) { CORRADE_ASSERT(offsets.size() == sizes.size(), "TextureTools::AtlasLandfill::add(): expected sizes and offsets views to have the same size, got" << sizes.size() << "and" << offsets.size(), {}); CORRADE_ASSERT((!(state.flags & (AtlasLandfillFlag::RotatePortrait|AtlasLandfillFlag::RotateLandscape)) && rotations.isEmpty()) || rotations.size() == sizes.size(), @@ -342,41 +352,42 @@ bool atlasLandfillAdd(Implementation::AtlasLandfillState& state, const Container } -bool AtlasLandfill::add(const Containers::StridedArrayView1D& sizes, const Containers::StridedArrayView1D& offsets, Containers::MutableBitArrayView flips) { +Containers::Optional AtlasLandfill::add(const Containers::StridedArrayView1D& sizes, const Containers::StridedArrayView1D& offsets, Containers::MutableBitArrayView flips) { return atlasLandfillAdd(*_state, sizes, offsets.slice(&Vector3i::xy), offsets.slice(&Vector3i::z), flips); } -bool AtlasLandfill::add(const std::initializer_list sizes, const Containers::StridedArrayView1D& offsets, Containers::MutableBitArrayView flips) { +Containers::Optional AtlasLandfill::add(const std::initializer_list sizes, const Containers::StridedArrayView1D& offsets, Containers::MutableBitArrayView flips) { return add(Containers::stridedArrayView(sizes), offsets, flips); } -bool AtlasLandfill::add(const Containers::StridedArrayView1D& sizes, const Containers::StridedArrayView1D& offsets) { +Containers::Optional AtlasLandfill::add(const Containers::StridedArrayView1D& sizes, const Containers::StridedArrayView1D& offsets) { CORRADE_ASSERT(!(_state->flags & (AtlasLandfillFlag::RotatePortrait|AtlasLandfillFlag::RotateLandscape)), "TextureTools::AtlasLandfill::add():" << (_state->flags & (AtlasLandfillFlag::RotatePortrait|AtlasLandfillFlag::RotateLandscape)) << "set, expected a rotations view", {}); return add(sizes, offsets, nullptr); } -bool AtlasLandfill::add(const std::initializer_list sizes, const Containers::StridedArrayView1D& offsets) { +Containers::Optional AtlasLandfill::add(const std::initializer_list sizes, const Containers::StridedArrayView1D& offsets) { return add(Containers::stridedArrayView(sizes), offsets); } -bool AtlasLandfill::add(const Containers::StridedArrayView1D& sizes, const Containers::StridedArrayView1D& offsets, Containers::MutableBitArrayView flips) { +Containers::Optional AtlasLandfill::add(const Containers::StridedArrayView1D& sizes, const Containers::StridedArrayView1D& offsets, Containers::MutableBitArrayView flips) { CORRADE_ASSERT(_state->size.z() == 1, "TextureTools::AtlasLandfill::add(): use the three-component overload for an array atlas", {}); - return atlasLandfillAdd(*_state, sizes, offsets, nullptr, flips); + const Containers::Optional out = atlasLandfillAdd(*_state, sizes, offsets, nullptr, flips); + return out ? Containers::optional(out->xy()) : Containers::NullOpt; } -bool AtlasLandfill::add(const std::initializer_list sizes, const Containers::StridedArrayView1D& offsets, Containers::MutableBitArrayView flips) { +Containers::Optional AtlasLandfill::add(const std::initializer_list sizes, const Containers::StridedArrayView1D& offsets, Containers::MutableBitArrayView flips) { return add(Containers::stridedArrayView(sizes), offsets, flips); } -bool AtlasLandfill::add(const Containers::StridedArrayView1D& sizes, const Containers::StridedArrayView1D& offsets) { +Containers::Optional AtlasLandfill::add(const Containers::StridedArrayView1D& sizes, const Containers::StridedArrayView1D& offsets) { CORRADE_ASSERT(!(_state->flags & (AtlasLandfillFlag::RotatePortrait|AtlasLandfillFlag::RotateLandscape)), "TextureTools::AtlasLandfill::add():" << (_state->flags & (AtlasLandfillFlag::RotatePortrait|AtlasLandfillFlag::RotateLandscape)) << "set, expected a rotations view", {}); return add(sizes, offsets, nullptr); } -bool AtlasLandfill::add(const std::initializer_list sizes, const Containers::StridedArrayView1D& offsets) { +Containers::Optional AtlasLandfill::add(const std::initializer_list sizes, const Containers::StridedArrayView1D& offsets) { return add(Containers::stridedArrayView(sizes), offsets); } diff --git a/src/Magnum/TextureTools/Atlas.h b/src/Magnum/TextureTools/Atlas.h index d9c483531..f9c69f5f4 100644 --- a/src/Magnum/TextureTools/Atlas.h +++ b/src/Magnum/TextureTools/Atlas.h @@ -345,6 +345,8 @@ class MAGNUM_TEXTURETOOLS_EXPORT AtlasLandfill { * @param[in] sizes Texture sizes * @param[out] offsets Resulting offsets in the atlas * @param[out] rotations Which textures got rotated + * @return Range spanning all added items including padding or + * @relativeref{Corrade,Containers::NullOpt} if they didn't fit * * The @p sizes, @p offsets and @p rotations views are expected to have * the same size. The @p sizes are all expected to be not larger than @@ -364,17 +366,18 @@ class MAGNUM_TEXTURETOOLS_EXPORT AtlasLandfill { * height are treated as any others to make sure they don't overlap * other items. * - * On success returns @cpp true @ce and updates @ref filledSize(). If - * @ref size() is bounded, can return @cpp false @ce if the items - * didn't fit, in which case the internals and contents of @p offsets - * and @p rotations are left in an undefined state. For an unbounded - * @ref size() returns @cpp true @ce always. + * On success updates @ref filledSize() and returns a range spanning + * all added items including padding, which can be used for example to + * perform a partial GPU texture upload. If @ref size() is bounded, can + * return @relativeref{Corrade,Containers::NullOpt} if the items didn't + * fit, in which case the internals and contents of @p offsets and + * @p rotations are left in an undefined state. For an unbounded + * @ref size() the function never fails. * @see @ref setFlags(), @ref setPadding() */ - bool add(const Containers::StridedArrayView1D& sizes, const Containers::StridedArrayView1D& offsets, Containers::MutableBitArrayView rotations); - + Containers::Optional add(const Containers::StridedArrayView1D& sizes, const Containers::StridedArrayView1D& offsets, Containers::MutableBitArrayView rotations); /** @overload */ - bool add(std::initializer_list sizes, const Containers::StridedArrayView1D& offsets, Containers::MutableBitArrayView rotations); + Containers::Optional add(std::initializer_list sizes, const Containers::StridedArrayView1D& offsets, Containers::MutableBitArrayView rotations); /** * @brief Add textures to the atlas with rotations disabled @@ -385,20 +388,20 @@ class MAGNUM_TEXTURETOOLS_EXPORT AtlasLandfill { * @relativeref{AtlasLandfillFlag,RotateLandscape} is set. * @see @ref clearFlags() */ - bool add(const Containers::StridedArrayView1D& sizes, const Containers::StridedArrayView1D& offsets); - + Containers::Optional add(const Containers::StridedArrayView1D& sizes, const Containers::StridedArrayView1D& offsets); /** @overload */ - bool add(std::initializer_list sizes, const Containers::StridedArrayView1D& offsets); + Containers::Optional add(std::initializer_list sizes, const Containers::StridedArrayView1D& offsets); /** * @brief Add textures to a non-array atlas * - * Can be called only if @ref size() depth is @cpp 1 @ce. + * Like @ref add(const Containers::StridedArrayView1D&, const Containers::StridedArrayView1D&, Containers::MutableBitArrayView), + * but omitting the third dimension. Can be called only if @ref size() + * depth is @cpp 1 @ce. */ - bool add(const Containers::StridedArrayView1D& sizes, const Containers::StridedArrayView1D& offsets, Containers::MutableBitArrayView rotations); - + Containers::Optional add(const Containers::StridedArrayView1D& sizes, const Containers::StridedArrayView1D& offsets, Containers::MutableBitArrayView rotations); /** @overload */ - bool add(std::initializer_list sizes, const Containers::StridedArrayView1D& offsets, Containers::MutableBitArrayView rotations); + Containers::Optional add(std::initializer_list sizes, const Containers::StridedArrayView1D& offsets, Containers::MutableBitArrayView rotations); /** * @brief Add textures to a non-array atlas with rotations disabled @@ -410,10 +413,9 @@ class MAGNUM_TEXTURETOOLS_EXPORT AtlasLandfill { * @relativeref{AtlasLandfillFlag,RotateLandscape} is set. * @see @ref clearFlags() */ - bool add(const Containers::StridedArrayView1D& sizes, const Containers::StridedArrayView1D& offsets); - + Containers::Optional add(const Containers::StridedArrayView1D& sizes, const Containers::StridedArrayView1D& offsets); /** @overload */ - bool add(std::initializer_list sizes, const Containers::StridedArrayView1D& offsets); + Containers::Optional add(std::initializer_list sizes, const Containers::StridedArrayView1D& offsets); private: Containers::Pointer _state; diff --git a/src/Magnum/TextureTools/Test/AtlasTest.cpp b/src/Magnum/TextureTools/Test/AtlasTest.cpp index 0d1ccd9ba..541ed0ae3 100644 --- a/src/Magnum/TextureTools/Test/AtlasTest.cpp +++ b/src/Magnum/TextureTools/Test/AtlasTest.cpp @@ -25,9 +25,10 @@ */ #include +#include +#include #include #include -#include #include #include #include @@ -35,12 +36,11 @@ #include #include "Magnum/Math/Matrix3.h" +#include "Magnum/Math/Range.h" #include "Magnum/TextureTools/Atlas.h" #ifdef MAGNUM_BUILD_DEPRECATED #include - -#include "Magnum/Math/Range.h" #endif namespace Magnum { namespace TextureTools { namespace Test { namespace { @@ -584,12 +584,12 @@ void AtlasTest::landfillFullFit() { UnsignedByte rotationData[1]; Containers::MutableBitArrayView rotations{rotationData, 0, 4}; /* Testing the init list overload here as all others test the view */ - CORRADE_VERIFY(atlas.add({ + CORRADE_COMPARE(atlas.add({ {2, 4}, /* 0 */ {2, 3}, /* 1 */ {2, 3}, /* 2 */ {2, 2}, /* 3 */ - }, offsets, rotations)); + }, offsets, rotations), (Range2Di{{}, {4, 6}})); CORRADE_COMPARE(atlas.filledSize(), (Vector3i{4, 6, 1})); CORRADE_COMPARE_AS(rotations, Containers::stridedArrayView({ false, false, false, false @@ -626,9 +626,9 @@ void AtlasTest::landfill() { /* Test the rotations-less overload if no rotations are enabled */ if(!(data.flags & (AtlasLandfillFlag::RotatePortrait|AtlasLandfillFlag::RotateLandscape))) - CORRADE_VERIFY(atlas.add(LandfillSizes, offsets)); + CORRADE_COMPARE(atlas.add(LandfillSizes, offsets), (Range2Di{{}, data.filledSize})); else - CORRADE_VERIFY(atlas.add(LandfillSizes, offsets, rotations)); + CORRADE_COMPARE(atlas.add(LandfillSizes, offsets, rotations), (Range2Di{{}, data.filledSize})); CORRADE_COMPARE(atlas.filledSize(), (Vector3i{data.filledSize, 1})); CORRADE_COMPARE_AS(rotations, @@ -672,22 +672,25 @@ void AtlasTest::landfillIncremental() { AtlasLandfill atlas{{11, 8}}; CORRADE_COMPARE(atlas.filledSize(), (Vector3i{11, 0, 1})); - CORRADE_VERIFY(atlas.add( + /* The first addition spans a range that begins at the origin and ends at + filledSize() */ + CORRADE_COMPARE(atlas.add( sizes.prefix(5), offsets.prefix(5), - rotations.prefix(5))); + rotations.prefix(5)), (Range2Di{{}, {11, 6}})); CORRADE_COMPARE(atlas.filledSize(), (Vector3i{11, 6, 1})); - CORRADE_VERIFY(atlas.add( + /* Following additions are just incremental */ + CORRADE_COMPARE(atlas.add( sizes.slice(5, 9), offsets.slice(5, 9), - rotations.slice(5, 9))); + rotations.slice(5, 9)), (Range2Di{{0, 4}, {8, 8}})); CORRADE_COMPARE(atlas.filledSize(), (Vector3i{11, 8, 1})); - CORRADE_VERIFY(atlas.add( + CORRADE_COMPARE(atlas.add( sizes.exceptPrefix(9), offsets.exceptPrefix(9), - rotations.exceptPrefix(9))); + rotations.exceptPrefix(9)), (Range2Di{{7, 6}, {11, 8}})); CORRADE_COMPARE(atlas.filledSize(), (Vector3i{11, 8, 1})); CORRADE_COMPARE_AS(rotations, Containers::stridedArrayView({ @@ -728,7 +731,10 @@ void AtlasTest::landfillPadded() { Vector2i offsets[8]; UnsignedByte rotationData[1]; Containers::MutableBitArrayView rotations{rotationData, 0, 8}; - CORRADE_VERIFY(atlas.add({ + + /* The filled size includes the padding as well, since that's what is + likely desirable to get copied as well */ + CORRADE_COMPARE(atlas.add({ {6, 2}, /* 0, padded to {8, 6}, flipped */ {1, 3}, /* 1, padded to {3, 7} */ {4, 1}, /* 2, padded to {6, 5}, flipped */ @@ -737,7 +743,7 @@ void AtlasTest::landfillPadded() { {1, 1}, /* 5, padded to {3, 5} */ {3, 0}, /* 6 (zero height), padded to {5, 4}, flipped */ {0, 2}, /* 7 (zero width), padded to {2, 6} */ - }, offsets, rotations)); + }, offsets, rotations), (Range2Di{{}, {17, 13}})); CORRADE_COMPARE(atlas.filledSize(), (Vector3i{17, 13, 1})); CORRADE_COMPARE_AS(rotations, Containers::stridedArrayView({ @@ -780,7 +786,7 @@ void AtlasTest::landfillNoFit() { Vector2i offsets[Containers::arraySize(LandfillSizes)]; UnsignedByte rotationData[2]; Containers::MutableBitArrayView rotations{rotationData, 0, Containers::arraySize(LandfillSizes)}; - CORRADE_VERIFY(!atlas.add(LandfillSizes, offsets, rotations)); + CORRADE_COMPARE(atlas.add(LandfillSizes, offsets, rotations), Containers::NullOpt); } void AtlasTest::landfillCopy() { @@ -822,14 +828,14 @@ void AtlasTest::landfillArrayFullFit() { UnsignedByte rotationData[1]; Containers::MutableBitArrayView rotations{rotationData, 0, 6}; /* Testing the init list overload as all others test the view */ - CORRADE_VERIFY(atlas.add({ + CORRADE_COMPARE(atlas.add({ {3, 5}, /* 0 */ {1, 5}, /* 1 */ {3, 3}, /* 2 */ {1, 3}, /* 3 */ {2, 2}, /* 4 */ {2, 2}, /* 5 */ - }, offsets, rotations)); + }, offsets, rotations), (Range3Di{{}, {4, 5, 2}})); CORRADE_COMPARE(atlas.filledSize(), (Vector3i{4, 5, 2})); CORRADE_COMPARE_AS(rotations, Containers::stridedArrayView({ false, false, false, false, false, false @@ -867,9 +873,9 @@ void AtlasTest::landfillArray() { /* Test the rotations-less overload if no rotations are enabled */ if(!(data.flags & (AtlasLandfillFlag::RotatePortrait|AtlasLandfillFlag::RotateLandscape))) - CORRADE_VERIFY(atlas.add(LandfillArraySizes, offsets)); + CORRADE_COMPARE(atlas.add(LandfillArraySizes, offsets), (Range3Di{{}, data.filledSize})); else - CORRADE_VERIFY(atlas.add(LandfillArraySizes, offsets, rotations)); + CORRADE_COMPARE(atlas.add(LandfillArraySizes, offsets, rotations), (Range3Di{{}, data.filledSize})); CORRADE_COMPARE(atlas.filledSize(), data.filledSize); CORRADE_COMPARE_AS(rotations, @@ -909,22 +915,28 @@ void AtlasTest::landfillArrayIncremental() { AtlasLandfill atlas{{11, 6, 2}}; CORRADE_COMPARE(atlas.filledSize(), (Vector3i{11, 6, 0})); - CORRADE_VERIFY(atlas.add( + /* The first addition spans a range that begins at the origin and ends at + filledSize(). Well, almost, because the first four items don't make use + of the rightmost column. */ + CORRADE_COMPARE(atlas.add( sizes.prefix(4), offsets.prefix(4), - rotations.prefix(4))); + rotations.prefix(4)), (Range3Di{{}, {10, 6, 1}})); CORRADE_COMPARE(atlas.filledSize(), (Vector3i{11, 6, 1})); - CORRADE_VERIFY(atlas.add( + /* Following additions are incremental ... well, in this case it overflows + to the next slice, which means it covers basically the whole area */ + CORRADE_COMPARE(atlas.add( sizes.slice(4, 7), offsets.slice(4, 7), - rotations.slice(4, 7))); + rotations.slice(4, 7)), (Range3Di{{}, {11, 6, 2}})); CORRADE_COMPARE(atlas.filledSize(), (Vector3i{11, 6, 2})); - CORRADE_VERIFY(atlas.add( + /* The last addition is then just a tiny bit of the second slice */ + CORRADE_COMPARE(atlas.add( sizes.exceptPrefix(7), offsets.exceptPrefix(7), - rotations.exceptPrefix(7))); + rotations.exceptPrefix(7)), (Range3Di{{2, 0, 1}, {7, 2, 2}})); CORRADE_COMPARE(atlas.filledSize(), (Vector3i{11, 6, 2})); CORRADE_COMPARE_AS(rotations, Containers::stridedArrayView({ @@ -961,7 +973,7 @@ void AtlasTest::landfillArrayPadded() { Vector3i offsets[8]; UnsignedByte rotationData[1]; Containers::MutableBitArrayView rotations{rotationData, 0, 8}; - CORRADE_VERIFY(atlas.add({ + CORRADE_COMPARE(atlas.add({ {6, 2}, /* 0, padded to {8, 6}, flipped */ {1, 3}, /* 1, padded to {3, 7} */ {4, 1}, /* 2, padded to {6, 5}, flipped */ @@ -970,7 +982,7 @@ void AtlasTest::landfillArrayPadded() { {1, 1}, /* 5, padded to {3, 5} */ {3, 0}, /* 6 (zero height), padded to {5, 4}, flipped */ {0, 2}, /* 7 (zero width), padded to {2, 6} */ - }, offsets, rotations)); + }, offsets, rotations), (Range3Di{{}, {16, 12, 2}})); CORRADE_COMPARE(atlas.filledSize(), (Vector3i{16, 12, 2})); CORRADE_COMPARE_AS(rotations, Containers::stridedArrayView({ @@ -1011,7 +1023,7 @@ void AtlasTest::landfillArrayNoFit() { Vector3i offsets[Containers::arraySize(LandfillArraySizes)]; UnsignedByte rotationData[2]; Containers::MutableBitArrayView rotations{rotationData, 0, Containers::arraySize(LandfillArraySizes)}; - CORRADE_VERIFY(!atlas.add(LandfillArraySizes, offsets, rotations)); + CORRADE_COMPARE(atlas.add(LandfillArraySizes, offsets, rotations), Containers::NullOpt); /* Sanity check that with one more slice it works */ } { @@ -1019,7 +1031,7 @@ void AtlasTest::landfillArrayNoFit() { Vector3i offsets[Containers::arraySize(LandfillArraySizes)]; UnsignedByte rotationData[2]; Containers::MutableBitArrayView rotations{rotationData, 0, Containers::arraySize(LandfillArraySizes)}; - CORRADE_VERIFY(atlas.add(LandfillArraySizes, offsets, rotations)); + CORRADE_COMPARE(atlas.add(LandfillArraySizes, offsets, rotations), (Range3Di{{}, {6, 6, 3}})); } }