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
This commit is contained in:
Vadim Zeitlin
2005-02-04 11:04:43 +00:00
parent 48714f7495
commit 8673a12505
3 changed files with 75 additions and 26 deletions

View File

@@ -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}

View File

@@ -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;
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;
}
// 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*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;
}

View File

@@ -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