From 8673a125052b480c4a79772c310586e5eff05bf8 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 4 Feb 2005 11:04:43 +0000 Subject: [PATCH] fixed Inflate() to not move the rectangle (patch 1114622) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@31750 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/rect.tex | 41 ++++++++++++++++++++++++++++---------- src/common/gdicmn.cpp | 44 +++++++++++++++++++++++++---------------- tests/geometry/rect.cpp | 18 +++++++++++++++++ 3 files changed, 76 insertions(+), 27 deletions(-) diff --git a/docs/latex/wx/rect.tex b/docs/latex/wx/rect.tex index 729b214952..44239884dd 100644 --- a/docs/latex/wx/rect.tex +++ b/docs/latex/wx/rect.tex @@ -76,14 +76,11 @@ Height member. \constfunc{wxRect}{Deflate}{\param{wxCoord }{dx}, \param{wxCoord }{dy}} -Decrease the rectangle size by {\it dx} in x direction and {\it dy} in y -direction. Both (or one of) parameters may be negative to increase the -rectngle size. This method is the opposite of \helpref{Inflate}{wxrectinflate}. +Decrease the rectangle size. -The second form uses the same {\it diff} for both {\it dx} and {\it dy}. - -The first two versions modify the rectangle in place, the last one returns a -new rectangle leaving this one unchanged. +This method is the opposite from \helpref{Inflate}{wxrectinflate}: +Deflate(a, b) is equivalent to Inflate(-a, -b). +Please refer to \helpref{Inflate}{wxrectinflate} for full description. \wxheading{See also} @@ -182,15 +179,39 @@ Gets the y member. \constfunc{wxRect}{Inflate}{\param{wxCoord }{dx}, \param{wxCoord }{dy}} -Increase the rectangle size by {\it dx} in x direction and {\it dy} in y -direction. Both (or one of) parameters may be negative to decrease the -rectangle size. +Increases the size of the rectangle. The second form uses the same {\it diff} for both {\it dx} and {\it dy}. The first two versions modify the rectangle in place, the last one returns a new rectangle leaving this one unchanged. +The left border is moved farther left and the right border is moved farther +right by {\it dx}. The upper border is moved farther up and the bottom border +is moved farther down by {\it dy}. (Note the the width and height of the +rectangle thus change by 2*{\it dx} and 2*{\it dy}, respectively.) If one or +both of {\it dx} and {\it dy} are negative, the opposite happens: the rectangle +size decreases in the respective direction. + +Inflating and deflating behaves ``naturally''. Defined more precisely, that +means: +\begin{enumerate} + \item ``Real'' inflates (that is, {\it dx} and/or {\it dy} >= 0) are not + constrained. Thus inflating a rectangle can cause its upper left corner + to move into the negative numbers. (the versions prior to 2.5.4 forced + the top left coordinate to not fall below (0, 0), which implied a + forced move of the rectangle.) + + \item Deflates are clamped to not reduce the width or height of the + rectangle below zero. In such cases, the top-left corner is nonetheless + handled properly. For example, a rectangle at (10, 10) with size (20, + 40) that is inflated by (-15, -15) will become located at (20, 25) at + size (0, 10). Finally, observe that the width and height are treated + independently. In the above example, the width is reduced by 20, + whereas the height is reduced by the full 30 (rather than also stopping + at 20, when the width reached zero). +\end{enumerate} + \wxheading{See also} \helpref{Deflate}{wxrectdeflate} diff --git a/src/common/gdicmn.cpp b/src/common/gdicmn.cpp index 5de95ee422..ecf3f6b21a 100644 --- a/src/common/gdicmn.cpp +++ b/src/common/gdicmn.cpp @@ -163,23 +163,33 @@ wxRect& wxRect::Union(const wxRect& rect) wxRect& wxRect::Inflate(wxCoord dx, wxCoord dy) { - x -= dx; - y -= dy; - width += 2*dx; - height += 2*dy; - - // check that we didn't make the rectangle invalid by accident (you almost - // never want to have negative coords and never want negative size) - if ( x < 0 ) - x = 0; - if ( y < 0 ) - y = 0; - - // what else can we do? - if ( width < 0 ) - width = 0; - if ( height < 0 ) - height = 0; + if (-2*dx>width) + { + // Don't allow deflate to eat more width than we have, + // a well-defined rectangle cannot have negative width. + x+=width/2; + width=0; + } + else + { + // The inflate is valid. + x-=dx; + width+=2*dx; + } + + if (-2*dy>height) + { + // Don't allow deflate to eat more height than we have, + // a well-defined rectangle cannot have negative height. + y+=height/2; + height=0; + } + else + { + // The inflate is valid. + y-=dy; + height+=2*dy; + } return *this; } diff --git a/tests/geometry/rect.cpp b/tests/geometry/rect.cpp index 21568366f4..c7d73971f6 100644 --- a/tests/geometry/rect.cpp +++ b/tests/geometry/rect.cpp @@ -32,10 +32,12 @@ public: private: CPPUNIT_TEST_SUITE( RectTestCase ); + CPPUNIT_TEST( InflateDeflate ); CPPUNIT_TEST( Operators ); CPPUNIT_TEST( Union ); CPPUNIT_TEST_SUITE_END(); + void InflateDeflate(); void Operators(); void Union(); @@ -48,6 +50,22 @@ CPPUNIT_TEST_SUITE_REGISTRATION( RectTestCase ); // also include in it's own registry so that these tests can be run alone CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( RectTestCase, "RectTestCase" ); +void RectTestCase::InflateDeflate() +{ + // This is the rectangle from the example in the documentation of wxRect::Inflate(). + const wxRect r1(10, 10, 20, 40); + + CPPUNIT_ASSERT(r1.Inflate( 10, 10)==wxRect( 0, 0, 40, 60)); + CPPUNIT_ASSERT(r1.Inflate( 20, 30)==wxRect(-10, -20, 60, 100)); + CPPUNIT_ASSERT(r1.Inflate(-10, -10)==wxRect( 20, 20, 0, 20)); + CPPUNIT_ASSERT(r1.Inflate(-15, -15)==wxRect( 20, 25, 0, 10)); + + CPPUNIT_ASSERT(r1.Inflate( 10, 10)==r1.Deflate(-10, -10)); + CPPUNIT_ASSERT(r1.Inflate( 20, 30)==r1.Deflate(-20, -30)); + CPPUNIT_ASSERT(r1.Inflate(-10, -10)==r1.Deflate( 10, 10)); + CPPUNIT_ASSERT(r1.Inflate(-15, -15)==r1.Deflate( 15, 15)); +} + void RectTestCase::Operators() { // test + operator which works like Union but does not ignore empty rectangles -- 2.47.2