From patchwork Tue Apr 12 13:26:14 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Kieran Bingham X-Patchwork-Id: 15663 X-Patchwork-Delegate: kieran.bingham@ideasonboard.com Return-Path: X-Original-To: parsemail@patchwork.libcamera.org Delivered-To: parsemail@patchwork.libcamera.org Received: from lancelot.ideasonboard.com (lancelot.ideasonboard.com [92.243.16.209]) by patchwork.libcamera.org (Postfix) with ESMTPS id 56AC8C3256 for ; Tue, 12 Apr 2022 13:26:00 +0000 (UTC) Received: from lancelot.ideasonboard.com (localhost [IPv6:::1]) by lancelot.ideasonboard.com (Postfix) with ESMTP id B476D6563F; Tue, 12 Apr 2022 15:25:59 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=libcamera.org; s=mail; t=1649769959; bh=sYNK6Gfwefxw6d4bLHDLSqAPk/orYRM8WKTQPpQxYGI=; h=To:Date:Subject:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=0H579I/VQGpgm7yLtEVgDp2lQwXzfOq35Gp+8oVH1Nofl66DUNGX3utPC+OrXgiBb /2s90sxmFRp1WuW4PRUu4RH1H+YNutsSK4IjBK3X4O4346XJVfIikJIEBZV5QD7gJZ eblOw8tBWYfxDxCpck1gMdSDTrwNQnucaFzNEfWpMcvcRmAz5cITgmI/AOODZtPs+r tfe94EqefTF/PQdzVkNzePl6sciViEBpo99Inmv2WY/zAXa1DOpakg7WBQmwVX2wnM oQZkGM4exeCkVb14UD/j1lNO5OMJabIZ4odePJ9Qpy5Znfyp253kTssj1IqHP47d1n b6QuQDdKlGx1w== Received: from perceval.ideasonboard.com (perceval.ideasonboard.com [213.167.242.64]) by lancelot.ideasonboard.com (Postfix) with ESMTPS id C1968604B7 for ; Tue, 12 Apr 2022 15:25:57 +0200 (CEST) Authentication-Results: lancelot.ideasonboard.com; dkim=pass (1024-bit key; unprotected) header.d=ideasonboard.com header.i=@ideasonboard.com header.b="Es/BiKWy"; dkim-atps=neutral Received: from Q.ksquared.org.uk.beta.tailscale.net (unknown [178.237.134.231]) by perceval.ideasonboard.com (Postfix) with ESMTPSA id F1F72486; Tue, 12 Apr 2022 15:25:56 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ideasonboard.com; s=mail; t=1649769957; bh=sYNK6Gfwefxw6d4bLHDLSqAPk/orYRM8WKTQPpQxYGI=; h=From:To:Cc:Subject:Date:From; b=Es/BiKWyOPU9SHTKHLG6TG41BCnJ+qeptYRograIE6ZAuVLyFF71DR/mZoRVzhLJ4 Y31QE1lLV8MGQOaF+kCXUCZoRi46bo8UiSOxnZK4Iai5g8hBng0H2Siavyd0L2wmji xOhOInfGpdRhT2kyxIFhTkHE3HYZAv9UL1TU4P+Q= To: libcamera devel Date: Tue, 12 Apr 2022 15:26:14 +0200 Message-Id: <20220412132614.317745-1-kieran.bingham@ideasonboard.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Subject: [libcamera-devel] [PATCH v2] libcamera: geometry: Add Size members to clamp to a min/max X-BeenThere: libcamera-devel@lists.libcamera.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Kieran Bingham via libcamera-devel From: Kieran Bingham Reply-To: Kieran Bingham Errors-To: libcamera-devel-bounces@lists.libcamera.org Sender: "libcamera-devel" 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 Signed-off-by: Kieran Bingham --- 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;