From 6cd07a043fc36ae75f8f094414d110a5f5333dbf Mon Sep 17 00:00:00 2001 From: Vittorio Romeo Date: Tue, 21 Jun 2022 15:33:50 +0200 Subject: [PATCH] 'sf::Image::copy' returns a 'bool' to signal success/failure --- include/SFML/Graphics/Image.hpp | 14 ++++++++++++-- src/SFML/Graphics/Image.cpp | 10 ++++++---- test/Graphics/Image.cpp | 10 +++++----- 3 files changed, 23 insertions(+), 11 deletions(-) diff --git a/include/SFML/Graphics/Image.hpp b/include/SFML/Graphics/Image.hpp index d49ccd5f..161269b5 100644 --- a/include/SFML/Graphics/Image.hpp +++ b/include/SFML/Graphics/Image.hpp @@ -196,13 +196,22 @@ public: /// See https://en.wikipedia.org/wiki/Alpha_compositing for /// details on the \b over operator. /// + /// Note that this function can fail if either image is invalid + /// (i.e. zero-sized width or height), or if \a sourceRect is + /// not within the boundaries of the \a source parameter, or + /// if the destination area is invalid (i.e. negative coordinates). + /// + /// On failure, the destination image is left unchanged. + /// /// \param source Source image to copy /// \param dest Coordinates of the destination position /// \param sourceRect Sub-rectangle of the source image to copy /// \param applyAlpha Should the copy take into account the source transparency? /// + /// \return True if the operation was successful, false otherwise + /// //////////////////////////////////////////////////////////// - void copy(const Image& source, const Vector2u& dest, const IntRect& sourceRect = IntRect({0, 0}, {0, 0}), bool applyAlpha = false); + [[nodiscard]] bool copy(const Image& source, const Vector2u& dest, const IntRect& sourceRect = IntRect({0, 0}, {0, 0}), bool applyAlpha = false); //////////////////////////////////////////////////////////// /// \brief Change the color of a pixel @@ -311,7 +320,8 @@ private: /// image.create(20, 20, sf::Color::Black); /// /// // Copy image1 on image2 at position (10, 10) -/// image.copy(background, 10, 10); +/// if (!image.copy(background, 10, 10)) +/// return -1; /// /// // Make the top-left pixel transparent /// sf::Color color = image.getPixel(0, 0); diff --git a/src/SFML/Graphics/Image.cpp b/src/SFML/Graphics/Image.cpp index 2cec9000..0f003851 100644 --- a/src/SFML/Graphics/Image.cpp +++ b/src/SFML/Graphics/Image.cpp @@ -171,16 +171,16 @@ void Image::createMaskFromColor(const Color& color, Uint8 alpha) //////////////////////////////////////////////////////////// -void Image::copy(const Image& source, const Vector2u& dest, const IntRect& sourceRect, bool applyAlpha) +[[nodiscard]] bool Image::copy(const Image& source, const Vector2u& dest, const IntRect& sourceRect, bool applyAlpha) { // Make sure that both images are valid if ((source.m_size.x == 0) || (source.m_size.y == 0) || (m_size.x == 0) || (m_size.y == 0)) - return; + return false; // Make sure the sourceRect left & top and the {left, top} + {width, height} within bounds if (static_cast(sourceRect.left) >= source.m_size.x || static_cast(sourceRect.left + sourceRect.width) > source.m_size.x || static_cast(sourceRect.top) >= source.m_size.y || static_cast(sourceRect.top + sourceRect.height) > source.m_size.y) - return; + return false; // Adjust the source rectangle IntRect srcRect = sourceRect; @@ -207,7 +207,7 @@ void Image::copy(const Image& source, const Vector2u& dest, const IntRect& sourc // Make sure the destination area is valid if ((width <= 0) || (height <= 0)) - return; + return false; // Precompute as much as possible std::size_t pitch = static_cast(width) * 4; @@ -258,6 +258,8 @@ void Image::copy(const Image& source, const Vector2u& dest, const IntRect& sourc dstPixels += dstStride; } } + + return true; } diff --git a/test/Graphics/Image.cpp b/test/Graphics/Image.cpp index b05d9962..4d852108 100644 --- a/test/Graphics/Image.cpp +++ b/test/Graphics/Image.cpp @@ -96,7 +96,7 @@ TEST_CASE("sf::Image - [graphics]") sf::Image image2; image2.create(sf::Vector2u(10, 10)); - image2.copy(image1, sf::Vector2u(0, 0)); + CHECK(image2.copy(image1, sf::Vector2u(0, 0))); for (sf::Uint32 i = 0; i < 10; ++i) { @@ -114,7 +114,7 @@ TEST_CASE("sf::Image - [graphics]") sf::Image image2; image2.create(sf::Vector2u(10, 10)); - image2.copy(image1, sf::Vector2u(0, 0), sf::IntRect(sf::Vector2i(0, 0), sf::Vector2i(5, 5))); + CHECK(image2.copy(image1, sf::Vector2u(0, 0), sf::IntRect(sf::Vector2i(0, 0), sf::Vector2i(5, 5)))); for (sf::Uint32 i = 0; i < 10; ++i) { @@ -145,7 +145,7 @@ TEST_CASE("sf::Image - [graphics]") sf::Image image2; image2.create(sf::Vector2u(10, 10), source); - image1.copy(image2, sf::Vector2u(0, 0), sf::IntRect(sf::Vector2i(0, 0), sf::Vector2i(10, 10)), true); + CHECK(image1.copy(image2, sf::Vector2u(0, 0), sf::IntRect(sf::Vector2i(0, 0), sf::Vector2i(10, 10)), true)); for (sf::Uint32 i = 0; i < 10; ++i) { @@ -162,7 +162,7 @@ TEST_CASE("sf::Image - [graphics]") sf::Image image2; image2.create(sf::Vector2u(10, 10), sf::Color::Red); - image2.copy(image1, sf::Vector2u(0, 0), sf::IntRect(sf::Vector2i(0, 0), sf::Vector2i(9, 9))); + CHECK(!image2.copy(image1, sf::Vector2u(0, 0), sf::IntRect(sf::Vector2i(0, 0), sf::Vector2i(9, 9)))); for (sf::Uint32 i = 0; i < 10; ++i) { @@ -181,7 +181,7 @@ TEST_CASE("sf::Image - [graphics]") sf::Image image2; image2.create(sf::Vector2u(10, 10), sf::Color::Red); - image2.copy(image1, sf::Vector2u(0, 0), sf::IntRect(sf::Vector2i(5, 5), sf::Vector2i(9, 9))); + CHECK(!image2.copy(image1, sf::Vector2u(0, 0), sf::IntRect(sf::Vector2i(5, 5), sf::Vector2i(9, 9)))); for (sf::Uint32 i = 0; i < 10; ++i) {