Added a test for the bug found by Pahtz, and fixed the bug. Simplified a bit the code in BRegion::Support::RSub()
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7533 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -41,8 +41,10 @@
|
||||
#include <RegionSupport.h>
|
||||
|
||||
// Constants --------------------------------------------------------------------
|
||||
const int32 kMaxPoints = 1024;
|
||||
const int32 kMaxVerticalExtent = 0x10000000;
|
||||
static const int32 kMaxPoints = 1024;
|
||||
static const int32 kMaxVerticalExtent = 0x10000000;
|
||||
static const int32 kMaxPositive = 0x7ffffffd;
|
||||
static const int32 kMaxNegative = 0x80000003;
|
||||
|
||||
|
||||
#define TRACE_REGION 0
|
||||
@@ -67,10 +69,10 @@ BRegion::Support::ZeroRegion(BRegion *region)
|
||||
CALLED();
|
||||
|
||||
region->count = 0;
|
||||
region->bound.left = 0x7ffffffd;
|
||||
region->bound.top = 0x7ffffffd;
|
||||
region->bound.right = 0x80000003;
|
||||
region->bound.bottom = 0x80000003;
|
||||
region->bound.left = kMaxPositive;
|
||||
region->bound.top = kMaxPositive;
|
||||
region->bound.right = kMaxNegative;
|
||||
region->bound.bottom = kMaxNegative;
|
||||
}
|
||||
|
||||
|
||||
@@ -794,11 +796,34 @@ BRegion::Support::SubRegionComplex(BRegion *first, BRegion *second, BRegion *des
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Converts the empty spaces between rectangles to rectangles,
|
||||
and the rectangles to empty spaces.
|
||||
|
||||
Watch out!!! We write 1 element more than count, so be sure that the passed
|
||||
arrays have the needed space
|
||||
*/
|
||||
static void
|
||||
InvertRectangles(long *lefts, long *rights, long count)
|
||||
{
|
||||
long tmpLeft, tmpRight = kMaxNegative;
|
||||
|
||||
for (int i = 0; i <= count; i++) {
|
||||
tmpLeft = lefts[i] - 1;
|
||||
|
||||
lefts[i] = (i == 0) ? kMaxNegative : tmpRight;
|
||||
tmpRight = rights[i] + 1;
|
||||
|
||||
rights[i] = (i == count) ? kMaxPositive : tmpLeft;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BRegion::Support::RSub(long top, long bottom, BRegion *first, BRegion *second, BRegion *dest, long *indexA, long *indexB)
|
||||
{
|
||||
CALLED();
|
||||
|
||||
// TODO: review heap management
|
||||
int32 stackLeftsA[kMaxPoints / 2];
|
||||
int32 stackLeftsB[kMaxPoints / 2];
|
||||
int32 stackRightsA[kMaxPoints / 2];
|
||||
@@ -836,8 +861,7 @@ BRegion::Support::RSub(long top, long bottom, BRegion *first, BRegion *second, B
|
||||
}
|
||||
|
||||
// Store left and right points to the appropriate array
|
||||
for (x = i1; x < first->count; x++) {
|
||||
|
||||
for (x = i1; x < first->count; x++) {
|
||||
// Look if this rect can be used next time we are called,
|
||||
// thus correctly maintaining the "index" parameters.
|
||||
if (first->data[x].bottom >= top && *indexA == -1)
|
||||
@@ -850,12 +874,6 @@ BRegion::Support::RSub(long top, long bottom, BRegion *first, BRegion *second, B
|
||||
} else if (first->data[x].top > bottom)
|
||||
break;
|
||||
}
|
||||
|
||||
if (*indexA == -1)
|
||||
*indexA = i1;
|
||||
|
||||
if (foundA > 1)
|
||||
SortTrans(leftsA, rightsA, foundA);
|
||||
|
||||
for (x = i2; x < second->count; x++) {
|
||||
if (second->data[x].bottom >= top && *indexB == -1)
|
||||
@@ -869,83 +887,42 @@ BRegion::Support::RSub(long top, long bottom, BRegion *first, BRegion *second, B
|
||||
break;
|
||||
}
|
||||
|
||||
if (*indexA == -1)
|
||||
*indexA = i1;
|
||||
if (*indexB == -1)
|
||||
*indexB = i2;
|
||||
|
||||
|
||||
if (foundA > 1)
|
||||
SortTrans(leftsA, rightsA, foundA);
|
||||
|
||||
if (foundB > 1)
|
||||
SortTrans(leftsB, rightsB, foundB);
|
||||
|
||||
|
||||
// No minuend's rect, just add all the subtraend's rects.
|
||||
if (foundA == 0)
|
||||
if (foundA == 0) {
|
||||
for (x = 0; x < foundB; x++) {
|
||||
clipping_rect rect = { leftsB[x], top, rightsB[x], bottom };
|
||||
dest->_AddRect(rect);
|
||||
}
|
||||
else if (foundB > 0) {
|
||||
long f = 0, s = 0;
|
||||
} else if (foundB > 0) {
|
||||
|
||||
clipping_rect minuendRect;
|
||||
minuendRect.top = top;
|
||||
minuendRect.bottom = bottom;
|
||||
minuendRect.left = 0x80000003;
|
||||
InvertRectangles(leftsA, rightsA, foundA);
|
||||
|
||||
clipping_rect subRect;
|
||||
subRect.top = top;
|
||||
subRect.bottom = bottom;
|
||||
|
||||
// We take the empty spaces between the minuend rects, and intersect
|
||||
// these with the subtraend rects. We then add their intersection
|
||||
// to the destination region.
|
||||
do {
|
||||
subRect.left = leftsB[s];
|
||||
subRect.right = rightsB[s];
|
||||
|
||||
if (f != 0)
|
||||
minuendRect.left = rightsA[f - 1] + 1;
|
||||
|
||||
minuendRect.right = leftsA[f] - 1;
|
||||
clipping_rect A, B;
|
||||
A.top = B.top = top;
|
||||
A.bottom = B.bottom = bottom;
|
||||
|
||||
for (long f = 0; f <= foundA; f++) {
|
||||
for (long s = 0; s < foundB; s++) {
|
||||
A.left = leftsA[f];
|
||||
A.right = rightsA[f];
|
||||
|
||||
if (leftsB[s] > minuendRect.right) {
|
||||
if (++f > foundA)
|
||||
break;
|
||||
else
|
||||
continue;
|
||||
B.left = leftsB[s];
|
||||
B.right = rightsB[s];
|
||||
if (rects_intersect(A, B))
|
||||
dest->_AddRect(sect_rect(A, B));
|
||||
}
|
||||
|
||||
clipping_rect intersection = sect_rect(minuendRect, subRect);
|
||||
|
||||
if (valid_rect(intersection))
|
||||
dest->_AddRect(intersection);
|
||||
|
||||
if (rightsB[s] < minuendRect.left)
|
||||
s++;
|
||||
|
||||
if (s >= foundB)
|
||||
break;
|
||||
|
||||
f++;
|
||||
|
||||
} while (f < foundA);
|
||||
|
||||
// Last rect: we take the right coordinate of the last minuend rect
|
||||
// as left coordinate of the rect to intersect, and the maximum possible
|
||||
// value as the right coordinate.
|
||||
minuendRect.left = rightsA[foundA - 1] + 1;
|
||||
minuendRect.right = 0x7ffffffd;
|
||||
|
||||
// Skip the subtraend rects that could never intersect.
|
||||
while (s < foundB && rightsB[s] < minuendRect.left)
|
||||
s++;
|
||||
|
||||
for (long c = s; c < foundB; c++) {
|
||||
subRect.left = leftsB[c];
|
||||
subRect.right = rightsB[c];
|
||||
|
||||
clipping_rect intersection = sect_rect(minuendRect, subRect);
|
||||
|
||||
if (valid_rect(intersection))
|
||||
dest->_AddRect(intersection);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (allocatedBuffer) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
$Id: RegionTestcase.cpp,v 1.2 2004/03/31 06:53:40 jackburton Exp $
|
||||
$Id: RegionTestcase.cpp,v 1.3 2004/05/12 06:37:18 jackburton Exp $
|
||||
|
||||
This file implements a base class for all tests of the OpenBeOS
|
||||
BRegion code.
|
||||
@@ -21,10 +21,9 @@
|
||||
RegionTestcase::RegionTestcase(std::string name) :
|
||||
TestCase(name)
|
||||
{
|
||||
const int numTestRegions = 8;
|
||||
const int numRectsPerRegion = 3;
|
||||
|
||||
float theRegions[numTestRegions][numRectsPerRegion][4] =
|
||||
float theRegions[][numRectsPerRegion][4] =
|
||||
{
|
||||
{
|
||||
{10.0, 10.0, 50.0, 50.0},
|
||||
@@ -67,8 +66,23 @@ RegionTestcase::RegionTestcase(std::string name) :
|
||||
{15.0, 25.0, 75.0, 80.0},
|
||||
{30.0, 15.0, 80.0, 45.0},
|
||||
{60.0, 20.0, 95.0, 225.0}
|
||||
},
|
||||
// These two regions were added to test our implementation
|
||||
// against the "Pahtz matrix test" (see interface kit
|
||||
// mailing list archives (April 2004) for more info)
|
||||
{
|
||||
{0.0, 50.0, 47.0, 50.0},
|
||||
{99.0, 50.0, 399.0, 50.0},
|
||||
{-100.0, -20.0, 100.0, -20.0}
|
||||
},
|
||||
{
|
||||
{0.0, 50.0, 47.0, 50.0},
|
||||
{100.0, 50.0, 399.0, 50.0},
|
||||
{-100.0, -20.0, 100.0, -20.0}
|
||||
}
|
||||
};
|
||||
|
||||
const int numTestRegions = sizeof(theRegions) / sizeof(theRegions[0]);
|
||||
|
||||
listOfRegions.AddItem(new BRegion);
|
||||
for(int regionNum = 0; regionNum < numTestRegions; regionNum++) {
|
||||
|
||||
Reference in New Issue
Block a user