16296Siignatyev/*
211833Sctornqvi	$Id: RegionTestcase.cpp 7533 2004-05-12 06:37:18Z jackburton $
36296Siignatyev
46296Siignatyev	This file implements a base class for all tests of the OpenBeOS
56296Siignatyev	BRegion code.
66296Siignatyev
76296Siignatyev	*/
86296Siignatyev
96296Siignatyev
106296Siignatyev#include "RegionTestcase.h"
116296Siignatyev#include <Region.h>
126296Siignatyev#include <Rect.h>
136296Siignatyev#include <math.h>
146296Siignatyev
156296Siignatyev
166296Siignatyev/*
176296Siignatyev *  Method:  RegionTestcase::RegionTestcase()
186296Siignatyev *   Descr:  This is the constructor for this class.
196296Siignatyev */
206296Siignatyev
216296SiignatyevRegionTestcase::RegionTestcase(std::string name) :
226296Siignatyev	TestCase(name)
236296Siignatyev{
246296Siignatyev	const int numRectsPerRegion = 3;
256296Siignatyev
266296Siignatyev	float theRegions[][numRectsPerRegion][4] =
276296Siignatyev		{
286296Siignatyev			{
2911833Sctornqvi				{10.0, 10.0, 50.0, 50.0},
3010551Schegar				{25.0, 10.0, 75.0, 40.0},
318013Sykantser				{70.0, 100.0, 90.0, 120.0}
3211707Stpivovarova			},
3311833Sctornqvi			{
3411534Siignatyev				{15.0, 15.0, 45.0, 45.0},
3511534Siignatyev				{30.0, 15.0, 70.0, 35.0},
366296Siignatyev				{75.0, 105.0, 85.0, 115.0}
376296Siignatyev			},
3811707Stpivovarova			{
396296Siignatyev				{15.0, 15.0, 55.0, 55.0},
406296Siignatyev				{30.0, 15.0, 80.0, 45.0},
4111707Stpivovarova				{75.0, 105.0, 95.0, 125.0}
4211707Stpivovarova			},
4311534Siignatyev			{
4412074Sgoetz				{210.0, 210.0, 250.0, 250.0},
4511534Siignatyev				{225.0, 210.0, 275.0, 240.0},
4611707Stpivovarova				{270.0, 300.0, 290.0, 320.0}
4711707Stpivovarova			},
486296Siignatyev			{
496296Siignatyev				{-50.0, -50.0, -10.0, -10.0},
506296Siignatyev				{-75.0, -40.0, -25.0, -10.0},
516296Siignatyev				{-90.0, -120.0, -70.0, -100.0}
5212074Sgoetz			},
536296Siignatyev			{
546296Siignatyev				{-50.0, -30.0, 100.0, 120.0},
556296Siignatyev				{-140.0, 120.0, 340.0, 905.0},
566296Siignatyev				{-90.0, -120.0, 90.0, 120.0}
576296Siignatyev			},
586296Siignatyev			{
596296Siignatyev				// A test to see if our BRegion can handle non integers
606296Siignatyev				// rects coordinates (as R5 do)
617588Seistepan				{10.3, 10.8, 50.2, 50.9},
627588Seistepan				{25.1, 10.7, 75.8, 40.4},
637588Seistepan				{70.6, 100.6, 90.1, 120.3}
646296Siignatyev			},
656943Skvn			{
666296Siignatyev				{15.0, 25.0, 75.0, 80.0},
676296Siignatyev				{30.0, 15.0, 80.0, 45.0},
686296Siignatyev				{60.0, 20.0, 95.0, 225.0}
696296Siignatyev			},
707588Seistepan			// These two regions were added to test our implementation
717588Seistepan			// against the "Pahtz matrix test" (see interface kit
727588Seistepan			// mailing list archives (April 2004) for more info)
737588Seistepan			{
746296Siignatyev				{0.0, 50.0, 47.0, 50.0},
756943Skvn				{99.0, 50.0, 399.0, 50.0},
766296Siignatyev				{-100.0, -20.0, 100.0, -20.0}
776296Siignatyev			},
786296Siignatyev			{
796296Siignatyev				{0.0, 50.0, 47.0, 50.0},
807588Seistepan				{100.0, 50.0, 399.0, 50.0},
817588Seistepan				{-100.0, -20.0, 100.0, -20.0}
827588Seistepan			}
836296Siignatyev		};
846943Skvn
856296Siignatyev	const int numTestRegions = sizeof(theRegions) / sizeof(theRegions[0]);
866296Siignatyev
876296Siignatyev	listOfRegions.AddItem(new BRegion);
886296Siignatyev	for(int regionNum = 0; regionNum < numTestRegions; regionNum++) {
896296Siignatyev		BRegion *tempRegion = new BRegion;
906296Siignatyev		for(int rectNum = 0; rectNum < numRectsPerRegion; rectNum++) {
916296Siignatyev			tempRegion->Include(BRect(theRegions[regionNum][rectNum][0],
926296Siignatyev			                          theRegions[regionNum][rectNum][1],
93			                          theRegions[regionNum][rectNum][2],
94			                          theRegions[regionNum][rectNum][3]));
95		}
96		listOfRegions.AddItem(tempRegion);
97	}
98}
99
100
101/*
102 *  Method:  RegionTestcase::~RegionTestcase()
103 *   Descr:  This is the destructor for this class.
104 */
105
106RegionTestcase::~RegionTestcase()
107{
108	while(!listOfRegions.IsEmpty()) {
109		delete static_cast<BRegion *>(listOfRegions.RemoveItem((long int)0));
110	}
111}
112
113
114/*
115 *  Method:  RegionTestcase::GetPointsInRect()
116 *   Descr:  This member function returns an array of BPoints on the edge and
117 *           inside the passed in BRect.  It also returns the number of points
118 *           in the array.
119 */
120
121int RegionTestcase::GetPointsInRect(BRect theRect, BPoint **pointArrayPtr)
122{
123	*pointArrayPtr = pointArray;
124	if (!theRect.IsValid()) {
125		return(0);
126	}
127
128	float xIncrement = (theRect.Width() + 1.0) / (numPointsPerSide - 1);
129	float yIncrement = (theRect.Height() + 1.0) / (numPointsPerSide - 1);
130
131	int numPoints = 0;
132
133	for(int i = 0; i < numPointsPerSide; i++) {
134		float xCoord = theRect.left + (i * xIncrement);
135		if (i == numPointsPerSide - 1) {
136			xCoord = theRect.right;
137		}
138		for(int j = 0; j < numPointsPerSide; j++) {
139			float yCoord = theRect.top + (j * yIncrement);
140			if (j == numPointsPerSide - 1) {
141				yCoord = theRect.bottom;
142			}
143			pointArray[numPoints].Set(floor(xCoord), floor(yCoord));
144			assert(theRect.Contains(pointArray[numPoints]));
145			numPoints++;
146		}
147	}
148	return(numPoints);
149}
150
151
152/*
153 *  Method:  RegionTestcase::CheckFrame()
154 *   Descr:  This member function checks that the BRegion's frame matches
155 *           the regions contents.
156 */
157
158void RegionTestcase::CheckFrame(BRegion *theRegion)
159{
160	BRect theFrame = theRegion->Frame();
161	if (theFrame.IsValid()) {
162		assert(!RegionIsEmpty(theRegion));
163
164		BRect testFrame = theRegion->RectAt(0);
165		assert(theFrame.Contains(testFrame));
166
167		for(int i = 1; i < theRegion->CountRects(); i++) {
168			BRect tempRect = theRegion->RectAt(i);
169			assert(theFrame.Contains(tempRect));
170			testFrame = testFrame | tempRect;
171		}
172		assert(testFrame == theFrame);
173	} else {
174		assert(RegionIsEmpty(theRegion));
175	}
176}
177
178
179/*
180 *  Method:  RegionTestcase::RegionsAreEqual()
181 *   Descr:  This member function returns true if the two BRegion's passed
182 *           in are the same, otherwise it returns false.
183 */
184
185bool RegionTestcase::RegionsAreEqual(BRegion *regionA, BRegion *regionB)
186{
187	bool result = false;
188
189	if (regionA->CountRects() == regionB->CountRects()) {
190		bool gotAMatch = true;
191		for(int i = 0; i < regionA->CountRects(); i++) {
192			gotAMatch = false;
193			for(int j = 0; j < regionB->CountRects(); j++) {
194				if (regionA->RectAt(i) == regionB->RectAt(j)) {
195					gotAMatch = true;
196					break;
197				}
198			}
199			if (!gotAMatch) {
200				break;
201			}
202		}
203		if (gotAMatch) {
204			result = true;
205		}
206	}
207
208	if (!result) {
209		BRegion tempRegion(*regionA);
210
211		tempRegion.Exclude(regionB);
212		if (RegionIsEmpty(&tempRegion)) {
213			tempRegion = *regionB;
214			tempRegion.Exclude(regionA);
215			if (RegionIsEmpty(&tempRegion)) {
216				result = true;
217			}
218		}
219	}
220
221	if (result) {
222		assert(regionA->Frame() == regionB->Frame());
223		if (regionA->CountRects() == 0) {
224			assert(RegionIsEmpty(regionA));
225			assert(RegionIsEmpty(regionB));
226		}
227	}
228	return(result);
229}
230
231
232/*
233 *  Method:  RegionTestcase::RegionsIsEmpty()
234 *   Descr:  This member function returns true if the BRegion passed
235 *           in is an empty region, otherwise it returns false.
236 */
237
238bool RegionTestcase::RegionIsEmpty(BRegion *theRegion)
239{
240	if (theRegion->CountRects() == 0) {
241		assert(!theRegion->Frame().IsValid());
242		return(true);
243	}
244	assert(theRegion->Frame().IsValid());
245	return(false);
246}
247
248
249/*
250 *  Method:  RegionTestcase::PerformTest()
251 *   Descr:  This member function iterates over the set of BRegion's for
252 *           testing and calls testOneRegion() for each region.  Then it
253 *           calls testTwoRegions() for each pair of regions (including
254 *           when the two regions are the same).
255 */
256
257void RegionTestcase::PerformTest(void)
258{
259	int numItems = listOfRegions.CountItems();
260
261	for(int i = 0; i < numItems; i++) {
262		BRegion *testRegion = static_cast<BRegion *>(listOfRegions.ItemAt(i));
263
264		CheckFrame(testRegion);
265		testOneRegion(testRegion);
266	}
267	for(int i = 0; i < numItems; i++) {
268		BRegion *testRegionA = static_cast<BRegion *>(listOfRegions.ItemAt(i));
269
270		for(int j = 0; j < numItems; j++) {
271			BRegion *testRegionB = static_cast<BRegion *>(listOfRegions.ItemAt(j));
272
273			testTwoRegions(testRegionA, testRegionB);
274		}
275	}
276}
277