[libcamera-devel] [PATCH v2] libcamera: geometry: Add Size members to clamp to a min/max
Kieran Bingham
kieran.bingham at ideasonboard.com
Tue Apr 12 15:26:14 CEST 2022
Provide two new operations to support clamping a Size to a given
minimum or maximum Size, or returning a const variant of the same
restriction.
Reviewed-by: Umang Jain <umang.jain at ideasonboard.com>
Signed-off-by: Kieran Bingham <kieran.bingham at ideasonboard.com>
---
include/libcamera/geometry.h | 16 ++++++++++++++++
src/libcamera/geometry.cpp | 23 +++++++++++++++++++++++
test/geometry.cpp | 24 ++++++++++++++++++++++--
3 files changed, 61 insertions(+), 2 deletions(-)
diff --git a/include/libcamera/geometry.h b/include/libcamera/geometry.h
index 7838b6793617..a447beb55965 100644
--- a/include/libcamera/geometry.h
+++ b/include/libcamera/geometry.h
@@ -93,6 +93,13 @@ public:
return *this;
}
+ Size &clamp(const Size &minimum, const Size &maximum)
+ {
+ width = std::clamp(width, minimum.width, maximum.width);
+ height = std::clamp(height, minimum.height, maximum.height);
+ return *this;
+ }
+
Size &growBy(const Size &margins)
{
width += margins.width;
@@ -141,6 +148,15 @@ public:
};
}
+ __nodiscard constexpr Size clampedTo(const Size &minimum,
+ const Size &maximum) const
+ {
+ return {
+ std::clamp(width, minimum.width, maximum.width),
+ std::clamp(height, minimum.height, maximum.height)
+ };
+ }
+
__nodiscard constexpr Size grownBy(const Size &margins) const
{
return {
diff --git a/src/libcamera/geometry.cpp b/src/libcamera/geometry.cpp
index cb3c2de18d5e..6689b3996741 100644
--- a/src/libcamera/geometry.cpp
+++ b/src/libcamera/geometry.cpp
@@ -173,6 +173,19 @@ const std::string Size::toString() const
* \return A reference to this object
*/
+/**
+ * \fn Size::clamp(const Size &minimum, const Size &maximum)
+ * \brief Clamp the size to be within the dimensions of both the \a minimum and
+ * \a maximum values.
+ * \param[in] minimum The minimum size
+ * \param[in] maximum The maximum size
+ *
+ * This function constrains and clamps the width and height of the size to be
+ * within the limits of the \a minimum and \a maximum sizes given.
+ *
+ * \return A reference to this object
+ */
+
/**
* \fn Size::growBy(const Size &margins)
* \brief Grow the size by \a margins in place
@@ -231,6 +244,16 @@ const std::string Size::toString() const
* height of this size and the \a expand size
*/
+/**
+ * \fn Size::clampedTo(const Size &minimum, const Size &maximum)
+ * \brief Clamp the size to be within the dimensions of both the \a minimum and
+ * \a maximum values
+ * \param[in] minimum The minimum size
+ * \param[in] maximum The maximum size
+ * \return A Size whose width and height are clamped to be within the limits of
+ * the \a minimum and \a maximum sizes given.
+ */
+
/**
* \fn Size::grownBy(const Size &margins)
* \brief Grow the size by \a margins
diff --git a/test/geometry.cpp b/test/geometry.cpp
index 5125692496b3..8d29245b2568 100644
--- a/test/geometry.cpp
+++ b/test/geometry.cpp
@@ -106,7 +106,7 @@ protected:
/*
* Test alignDownTo(), alignUpTo(), boundTo(), expandTo(),
- * growBy() and shrinkBy()
+ * clamp(), growBy() and shrinkBy()
*/
Size s(50, 50);
@@ -134,6 +134,18 @@ protected:
return TestFail;
}
+ s.clamp({ 80, 120 }, { 160, 240 });
+ if (s != Size(80, 120)) {
+ cout << "Size::clamp (minium) test failed" << endl;
+ return TestFail;
+ }
+
+ s.clamp({ 20, 30 }, { 50, 50 });
+ if (s != Size(50, 50)) {
+ cout << "Size::clamp (maximum) test failed" << endl;
+ return TestFail;
+ }
+
s.growBy({ 10, 20 });
if (s != Size(60, 70)) {
cout << "Size::growBy() test failed" << endl;
@@ -162,7 +174,7 @@ protected:
/*
* Test alignedDownTo(), alignedUpTo(), boundedTo(),
- * expandedTo(), grownBy() and shrunkBy()
+ * expandedTo(), clampedTo(), grownBy() and shrunkBy()
*/
if (Size(0, 0).alignedDownTo(16, 8) != Size(0, 0) ||
Size(1, 1).alignedDownTo(16, 8) != Size(0, 0) ||
@@ -192,6 +204,14 @@ protected:
return TestFail;
}
+ if (Size(0, 0).clampedTo({ 60, 40 }, { 80, 90 }) != Size(60, 40) ||
+ Size(100, 100).clampedTo({ 60, 40 }, { 80, 90 }) != Size(80, 90) ||
+ Size(30, 100).clampedTo({ 60, 40 }, { 80, 90 }) != Size(60, 90) ||
+ Size(100, 30).clampedTo({ 60, 40 }, { 80, 90 }) != Size(80, 40)) {
+ cout << "Size::clampedTo() test failed" << endl;
+ return TestFail;
+ }
+
if (Size(0, 0).grownBy({ 10, 20 }) != Size(10, 20) ||
Size(200, 50).grownBy({ 10, 20 }) != Size(210, 70)) {
cout << "Size::grownBy() test failed" << endl;
--
2.25.1
More information about the libcamera-devel
mailing list