Don't ask me how, but I apparently fixed the weird bug I had introduced.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15583 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini
2005-12-19 11:06:20 +00:00
parent 70da1fab92
commit cbe65c2e73
4 changed files with 75 additions and 16 deletions
@@ -16,11 +16,22 @@ const static int32 kMaxNegative = 0x80000003;
const static int32 kInitialDataSize = 8; const static int32 kInitialDataSize = 8;
class DebugHelper {
public:
DebugHelper() { printf("Entering...\n"); }
~DebugHelper() { printf("Exiting...\n"); }
};
#define DEBUG_ENTER_FUNCTION ;//printf("%s\n", __PRETTY_FUNCTION__); DebugHelper helper;
ClipRegion::ClipRegion() ClipRegion::ClipRegion()
: :
fDataSize(0), fDataSize(0),
fData(NULL) fData(NULL)
{ {
DEBUG_ENTER_FUNCTION
_Resize(kInitialDataSize); _Resize(kInitialDataSize);
_Invalidate(); _Invalidate();
} }
@@ -31,6 +42,7 @@ ClipRegion::ClipRegion(const ClipRegion &region)
fDataSize(0), fDataSize(0),
fData(NULL) fData(NULL)
{ {
DEBUG_ENTER_FUNCTION
*this = region; *this = region;
} }
@@ -40,6 +52,7 @@ ClipRegion::ClipRegion(const clipping_rect &rect)
fDataSize(0), fDataSize(0),
fData(NULL) fData(NULL)
{ {
DEBUG_ENTER_FUNCTION
Set(rect); Set(rect);
} }
@@ -49,6 +62,7 @@ ClipRegion::ClipRegion(const BRect &rect)
fDataSize(0), fDataSize(0),
fData(NULL) fData(NULL)
{ {
DEBUG_ENTER_FUNCTION
Set(rect); Set(rect);
} }
@@ -58,12 +72,14 @@ ClipRegion::ClipRegion(const clipping_rect *rects, const int32 &count)
fDataSize(0), fDataSize(0),
fData(NULL) fData(NULL)
{ {
DEBUG_ENTER_FUNCTION
Set(rects, count); Set(rects, count);
} }
ClipRegion::~ClipRegion() ClipRegion::~ClipRegion()
{ {
DEBUG_ENTER_FUNCTION
free(fData); free(fData);
} }
@@ -71,6 +87,7 @@ ClipRegion::~ClipRegion()
void void
ClipRegion::Set(const clipping_rect &rect) ClipRegion::Set(const clipping_rect &rect)
{ {
DEBUG_ENTER_FUNCTION
if (!valid_rect(rect) || (fDataSize <= 1 && !_Resize(kInitialDataSize))) if (!valid_rect(rect) || (fDataSize <= 1 && !_Resize(kInitialDataSize)))
_Invalidate(); _Invalidate();
else { else {
@@ -83,6 +100,7 @@ ClipRegion::Set(const clipping_rect &rect)
void void
ClipRegion::Set(const BRect &rect) ClipRegion::Set(const BRect &rect)
{ {
DEBUG_ENTER_FUNCTION
Set(to_clipping_rect(rect)); Set(to_clipping_rect(rect));
} }
@@ -90,6 +108,7 @@ ClipRegion::Set(const BRect &rect)
void void
ClipRegion::Set(const clipping_rect *rects, const int32 &count) ClipRegion::Set(const clipping_rect *rects, const int32 &count)
{ {
DEBUG_ENTER_FUNCTION
_Invalidate(); _Invalidate();
_Append(rects, count); _Append(rects, count);
} }
@@ -98,6 +117,7 @@ ClipRegion::Set(const clipping_rect *rects, const int32 &count)
bool bool
ClipRegion::Intersects(const clipping_rect &rect) const ClipRegion::Intersects(const clipping_rect &rect) const
{ {
DEBUG_ENTER_FUNCTION
if (!rects_intersect(rect, fBound)) if (!rects_intersect(rect, fBound))
return false; return false;
@@ -113,6 +133,7 @@ ClipRegion::Intersects(const clipping_rect &rect) const
bool bool
ClipRegion::Intersects(const BRect &rect) const ClipRegion::Intersects(const BRect &rect) const
{ {
DEBUG_ENTER_FUNCTION
return Intersects(to_clipping_rect(rect)); return Intersects(to_clipping_rect(rect));
} }
@@ -120,6 +141,7 @@ ClipRegion::Intersects(const BRect &rect) const
bool bool
ClipRegion::Contains(const BPoint &pt) const ClipRegion::Contains(const BPoint &pt) const
{ {
DEBUG_ENTER_FUNCTION
// If the point doesn't lie within the region's bounds, // If the point doesn't lie within the region's bounds,
// don't even try it against the region's rects. // don't even try it against the region's rects.
if (!point_in(fBound, pt)) if (!point_in(fBound, pt))
@@ -137,6 +159,7 @@ ClipRegion::Contains(const BPoint &pt) const
void void
ClipRegion::OffsetBy(const int32 &dh, const int32 &dv) ClipRegion::OffsetBy(const int32 &dh, const int32 &dv)
{ {
DEBUG_ENTER_FUNCTION
if (dh == 0 && dv == 0) if (dh == 0 && dv == 0)
return; return;
@@ -152,6 +175,7 @@ ClipRegion::OffsetBy(const int32 &dh, const int32 &dv)
void void
ClipRegion::OffsetBy(const BPoint &point) ClipRegion::OffsetBy(const BPoint &point)
{ {
DEBUG_ENTER_FUNCTION
return OffsetBy((int32)point.x, (int32)point.y); return OffsetBy((int32)point.x, (int32)point.y);
} }
@@ -159,6 +183,7 @@ ClipRegion::OffsetBy(const BPoint &point)
void void
ClipRegion::IntersectWith(const clipping_rect &rect) ClipRegion::IntersectWith(const clipping_rect &rect)
{ {
DEBUG_ENTER_FUNCTION
if (!rects_intersect(rect, fBound)) if (!rects_intersect(rect, fBound))
_Invalidate(); _Invalidate();
else else
@@ -169,6 +194,7 @@ ClipRegion::IntersectWith(const clipping_rect &rect)
void void
ClipRegion::IntersectWith(const BRect &rect) ClipRegion::IntersectWith(const BRect &rect)
{ {
DEBUG_ENTER_FUNCTION
IntersectWith(to_clipping_rect(rect)); IntersectWith(to_clipping_rect(rect));
} }
@@ -176,6 +202,7 @@ ClipRegion::IntersectWith(const BRect &rect)
void void
ClipRegion::IntersectWith(const ClipRegion &region) ClipRegion::IntersectWith(const ClipRegion &region)
{ {
DEBUG_ENTER_FUNCTION
clipping_rect intersection = sect_rect(fBound, region.fBound); clipping_rect intersection = sect_rect(fBound, region.fBound);
if (fCount == 0 || region.fCount == 0 || !valid_rect(intersection)) if (fCount == 0 || region.fCount == 0 || !valid_rect(intersection))
@@ -200,6 +227,7 @@ ClipRegion::IntersectWith(const ClipRegion &region)
void void
ClipRegion::Include(const clipping_rect &rect) ClipRegion::Include(const clipping_rect &rect)
{ {
DEBUG_ENTER_FUNCTION
// The easy case first: if the rectangle completely contains // The easy case first: if the rectangle completely contains
// ourself, the union is the rectangle itself. // ourself, the union is the rectangle itself.
if (rect_contains(fBound, rect)) if (rect_contains(fBound, rect))
@@ -214,6 +242,7 @@ ClipRegion::Include(const clipping_rect &rect)
void void
ClipRegion::Include(const BRect &rect) ClipRegion::Include(const BRect &rect)
{ {
DEBUG_ENTER_FUNCTION
Include(to_clipping_rect(rect)); Include(to_clipping_rect(rect));
} }
@@ -221,6 +250,7 @@ ClipRegion::Include(const BRect &rect)
void void
ClipRegion::Include(const ClipRegion &region) ClipRegion::Include(const ClipRegion &region)
{ {
DEBUG_ENTER_FUNCTION
if (region.fCount == 0) if (region.fCount == 0)
return; return;
@@ -245,7 +275,7 @@ ClipRegion::Include(const ClipRegion &region)
Include(region.fBound); Include(region.fBound);
else if (fCount == 1) { else if (fCount == 1) {
ClipRegion dest = region; ClipRegion dest(region);
dest.Include(fBound); dest.Include(fBound);
_Adopt(dest); _Adopt(dest);
} else } else
@@ -256,6 +286,7 @@ ClipRegion::Include(const ClipRegion &region)
void void
ClipRegion::Exclude(const clipping_rect &rect) ClipRegion::Exclude(const clipping_rect &rect)
{ {
DEBUG_ENTER_FUNCTION
const ClipRegion region(rect); const ClipRegion region(rect);
Exclude(region); Exclude(region);
} }
@@ -264,6 +295,7 @@ ClipRegion::Exclude(const clipping_rect &rect)
void void
ClipRegion::Exclude(const BRect &rect) ClipRegion::Exclude(const BRect &rect)
{ {
DEBUG_ENTER_FUNCTION
const ClipRegion region(rect); const ClipRegion region(rect);
Exclude(region); Exclude(region);
} }
@@ -272,6 +304,7 @@ ClipRegion::Exclude(const BRect &rect)
void void
ClipRegion::Exclude(const ClipRegion &region) ClipRegion::Exclude(const ClipRegion &region)
{ {
DEBUG_ENTER_FUNCTION
if (fCount == 0 || region.fCount == 0 || !rects_intersect(fBound, region.fBound)) if (fCount == 0 || region.fCount == 0 || !rects_intersect(fBound, region.fBound))
return; return;
@@ -279,9 +312,21 @@ ClipRegion::Exclude(const ClipRegion &region)
} }
void
ClipRegion::GetRects(clipping_rect **rects, int32 *count)
{
if (fCount > 0) {
*rects = new clipping_rect[fCount];
memcpy(*rects, fData, fCount);
}
*count = fCount;
}
ClipRegion & ClipRegion &
ClipRegion::operator=(const ClipRegion &region) ClipRegion::operator=(const ClipRegion &region)
{ {
DEBUG_ENTER_FUNCTION
const int32 size = region.fDataSize > 0 ? region.fDataSize : kInitialDataSize; const int32 size = region.fDataSize > 0 ? region.fDataSize : kInitialDataSize;
if (_Resize(size, false)) { if (_Resize(size, false)) {
fBound = region.fBound; fBound = region.fBound;
@@ -331,6 +376,7 @@ topComparator(const void *a, const void *b)
void void
ClipRegion::_IntersectWithComplex(const ClipRegion &region) ClipRegion::_IntersectWithComplex(const ClipRegion &region)
{ {
DEBUG_ENTER_FUNCTION
ClipRegion dest; ClipRegion dest;
for (int32 f = 0; f < fCount; f++) { for (int32 f = 0; f < fCount; f++) {
@@ -351,6 +397,7 @@ ClipRegion::_IntersectWithComplex(const ClipRegion &region)
void void
ClipRegion::_IntersectWith(const clipping_rect &rect) ClipRegion::_IntersectWith(const clipping_rect &rect)
{ {
DEBUG_ENTER_FUNCTION
ASSERT(rects_intersect(rect, fBound)); ASSERT(rects_intersect(rect, fBound));
// The easy case first: We already know that the region intersects, // The easy case first: We already know that the region intersects,
@@ -375,6 +422,7 @@ ClipRegion::_IntersectWith(const clipping_rect &rect)
void void
ClipRegion::_IncludeNoIntersection(const ClipRegion &region) ClipRegion::_IncludeNoIntersection(const ClipRegion &region)
{ {
DEBUG_ENTER_FUNCTION
ASSERT(fCount != 0 || region.fCount != 0); ASSERT(fCount != 0 || region.fCount != 0);
ASSERT(!rects_intersect(region.fBound, fBound)); ASSERT(!rects_intersect(region.fBound, fBound));
@@ -409,6 +457,7 @@ ClipRegion::_IncludeNoIntersection(const ClipRegion &region)
void void
ClipRegion::_IncludeComplex(const ClipRegion &region) ClipRegion::_IncludeComplex(const ClipRegion &region)
{ {
DEBUG_ENTER_FUNCTION
int32 bottom = min_c(fBound.top, region.fBound.top) - 1; int32 bottom = min_c(fBound.top, region.fBound.top) - 1;
int32 a = 0, b = 0; int32 a = 0, b = 0;
ClipRegion dest; ClipRegion dest;
@@ -434,12 +483,7 @@ ClipRegion::_IncludeComplex(const ClipRegion &region)
} }
} }
// TODO: For some reason, I had to add those two qsort calls.
// They wasn't needed in the old implementation, so I obviously
// introduced a bug somewhere. Fix the bug and then remove those calls
qsort(dest.fData, dest.fCount, sizeof(clipping_rect), leftComparator);
dest._Coalesce(); dest._Coalesce();
qsort(dest.fData, dest.fCount, sizeof(clipping_rect), topComparator);
_Adopt(dest); _Adopt(dest);
@@ -490,6 +534,7 @@ ClipRegion::_ExcludeComplex(const ClipRegion &region)
void void
ClipRegion::_AddRect(const clipping_rect &rect) ClipRegion::_AddRect(const clipping_rect &rect)
{ {
DEBUG_ENTER_FUNCTION
ASSERT(fCount >= 0); ASSERT(fCount >= 0);
ASSERT(fDataSize >= 0); ASSERT(fDataSize >= 0);
ASSERT(valid_rect(rect)); ASSERT(valid_rect(rect));
@@ -540,6 +585,7 @@ ClipRegion::_AddRect(const clipping_rect &rect)
void void
ClipRegion::_RecalculateBounds(const clipping_rect &rect) ClipRegion::_RecalculateBounds(const clipping_rect &rect)
{ {
DEBUG_ENTER_FUNCTION
ASSERT(fCount > 0); ASSERT(fCount > 0);
if (rect.top < fBound.top) if (rect.top < fBound.top)
@@ -556,6 +602,7 @@ ClipRegion::_RecalculateBounds(const clipping_rect &rect)
int32 int32
ClipRegion::_FindSmallestBottom(const int32 &top, const int32 &oldBottom, const int32 &startIndex) const ClipRegion::_FindSmallestBottom(const int32 &top, const int32 &oldBottom, const int32 &startIndex) const
{ {
DEBUG_ENTER_FUNCTION
int32 bottom = oldBottom; int32 bottom = oldBottom;
for (int32 i = startIndex; i < fCount; i++) { for (int32 i = startIndex; i < fCount; i++) {
const int32 n = fData[i].top - 1; const int32 n = fData[i].top - 1;
@@ -572,6 +619,7 @@ ClipRegion::_FindSmallestBottom(const int32 &top, const int32 &oldBottom, const
int32 int32
ClipRegion::_ExtractStripRects(const int32 &top, const int32 &bottom, clipping_rect *rects, int32 *inOutIndex) const ClipRegion::_ExtractStripRects(const int32 &top, const int32 &bottom, clipping_rect *rects, int32 *inOutIndex) const
{ {
DEBUG_ENTER_FUNCTION
int32 currentIndex = *inOutIndex; int32 currentIndex = *inOutIndex;
*inOutIndex = -1; *inOutIndex = -1;
@@ -607,6 +655,7 @@ ClipRegion::_ExtractStripRects(const int32 &top, const int32 &bottom, clipping_r
void void
ClipRegion::_Append(const ClipRegion &region, const bool &aboveThis) ClipRegion::_Append(const ClipRegion &region, const bool &aboveThis)
{ {
DEBUG_ENTER_FUNCTION
if (aboveThis) { if (aboveThis) {
ClipRegion dest = region; ClipRegion dest = region;
for (int32 c = 0; c < fCount; c++) for (int32 c = 0; c < fCount; c++)
@@ -622,6 +671,7 @@ ClipRegion::_Append(const ClipRegion &region, const bool &aboveThis)
void void
ClipRegion::_Append(const clipping_rect *rects, const int32 &count, const bool &aboveThis) ClipRegion::_Append(const clipping_rect *rects, const int32 &count, const bool &aboveThis)
{ {
DEBUG_ENTER_FUNCTION
if (aboveThis) { if (aboveThis) {
ClipRegion dest; ClipRegion dest;
dest.Set(rects, count); dest.Set(rects, count);
@@ -638,6 +688,7 @@ ClipRegion::_Append(const clipping_rect *rects, const int32 &count, const bool &
void void
ClipRegion::_MergeAndInclude(clipping_rect *rects, const int32 &count) ClipRegion::_MergeAndInclude(clipping_rect *rects, const int32 &count)
{ {
DEBUG_ENTER_FUNCTION
// rects share the top and bottom coordinates, // rects share the top and bottom coordinates,
// so we can get those from the first one and ignore the others // so we can get those from the first one and ignore the others
clipping_rect rect; clipping_rect rect;
@@ -659,7 +710,6 @@ ClipRegion::_MergeAndInclude(clipping_rect *rects, const int32 &count)
next++; next++;
} }
//to_BRect(rect).PrintToStream();
_AddRect(rect); _AddRect(rect);
current = next; current = next;
} }
@@ -669,6 +719,7 @@ ClipRegion::_MergeAndInclude(clipping_rect *rects, const int32 &count)
inline void inline void
ClipRegion::_Coalesce() ClipRegion::_Coalesce()
{ {
DEBUG_ENTER_FUNCTION
if (fCount > 1) { if (fCount > 1) {
while (_CoalesceVertical() || _CoalesceHorizontal()) while (_CoalesceVertical() || _CoalesceHorizontal())
; ;
@@ -679,14 +730,15 @@ ClipRegion::_Coalesce()
bool bool
ClipRegion::_CoalesceVertical() ClipRegion::_CoalesceVertical()
{ {
int32 oldCount = fCount; DEBUG_ENTER_FUNCTION
const int32 oldCount = fCount;
clipping_rect testRect = { 1, 1, -1, -1 }; clipping_rect testRect = { 1, 1, -1, -1 };
int32 newCount = -1; int32 newCount = -1;
// First, try coalescing rects vertically // First, try coalescing rects vertically
for (int32 x = 0; x < fCount; x++) { for (int32 x = 0; x < fCount; x++) {
clipping_rect &rect = fData[x]; const clipping_rect &rect = fData[x];
if (rect.left == testRect.left && rect.right == testRect.right if (rect.left == testRect.left && rect.right == testRect.right
&& rect.top == testRect.bottom + 1) && rect.top == testRect.bottom + 1)
@@ -707,13 +759,14 @@ ClipRegion::_CoalesceVertical()
bool bool
ClipRegion::_CoalesceHorizontal() ClipRegion::_CoalesceHorizontal()
{ {
int32 oldCount = fCount; DEBUG_ENTER_FUNCTION
const int32 oldCount = fCount;
clipping_rect testRect = { 1, 1, -1, -1 }; clipping_rect testRect = { 1, 1, -1, -1 };
int32 newCount = -1; int32 newCount = -1;
for (int32 x = 0; x < fCount; x++) { for (int32 x = 0; x < fCount; x++) {
clipping_rect &rect = fData[x]; const clipping_rect &rect = fData[x];
if (rect.top == testRect.top && rect.bottom == testRect.bottom if (rect.top == testRect.top && rect.bottom == testRect.bottom
&& rect.left == testRect.right + 1) && rect.left == testRect.right + 1)
@@ -734,6 +787,7 @@ ClipRegion::_CoalesceHorizontal()
void void
ClipRegion::_Invalidate() ClipRegion::_Invalidate()
{ {
DEBUG_ENTER_FUNCTION
fCount = 0; fCount = 0;
fBound.left = kMaxPositive; fBound.left = kMaxPositive;
fBound.top = kMaxPositive; fBound.top = kMaxPositive;
@@ -745,6 +799,7 @@ ClipRegion::_Invalidate()
bool bool
ClipRegion::_Resize(const int32 &newSize, const bool &keepOld) ClipRegion::_Resize(const int32 &newSize, const bool &keepOld)
{ {
DEBUG_ENTER_FUNCTION
if (!keepOld) { if (!keepOld) {
free(fData); free(fData);
fData = (clipping_rect *)malloc(newSize * sizeof(clipping_rect)); fData = (clipping_rect *)malloc(newSize * sizeof(clipping_rect));
@@ -763,6 +818,7 @@ ClipRegion::_Resize(const int32 &newSize, const bool &keepOld)
void void
ClipRegion::_Adopt(ClipRegion &region) ClipRegion::_Adopt(ClipRegion &region)
{ {
DEBUG_ENTER_FUNCTION
free(fData); free(fData);
fData = region.fData; fData = region.fData;
fDataSize = region.fDataSize; fDataSize = region.fDataSize;
@@ -16,7 +16,7 @@ public:
ClipRegion(const clipping_rect &rect); ClipRegion(const clipping_rect &rect);
ClipRegion(const BRect &rect); ClipRegion(const BRect &rect);
ClipRegion(const clipping_rect *rects, const int32 &count); ClipRegion(const clipping_rect *rects, const int32 &count);
~ClipRegion(); ~ClipRegion();
clipping_rect Frame() const { return fBound; } clipping_rect Frame() const { return fBound; }
@@ -49,6 +49,8 @@ public:
void IntersectWith(const BRect &rect); void IntersectWith(const BRect &rect);
void IntersectWith(const ClipRegion &region); void IntersectWith(const ClipRegion &region);
void GetRects(clipping_rect **rects, int32 *count);
ClipRegion &operator=(const ClipRegion &region); ClipRegion &operator=(const ClipRegion &region);
status_t ReadFromLink(BPrivate::ServerLink &link); status_t ReadFromLink(BPrivate::ServerLink &link);
@@ -251,7 +251,7 @@ BRegion::OffsetBy(int32 dh, int32 dv)
void void
BRegion::MakeEmpty() BRegion::MakeEmpty()
{ {
clipping_rect invalid = { 0, 0, -1, -1 }; const clipping_rect invalid = { 0, 0, -1, -1 };
Set(invalid); Set(invalid);
} }
+4 -3
View File
@@ -9,8 +9,8 @@ int main()
BRegion other(BRect(15, 15, 50, 19)); BRegion other(BRect(15, 15, 50, 19));
other.IntersectWith(&region); other.IntersectWith(&region);
if (region.Intersects(other.Frame())) //if (region.Intersects(other.Frame()))
printf("Okay!\n"); // printf("Okay!\n");
BRegion c; BRegion c;
@@ -18,7 +18,8 @@ int main()
other.Include(&c); other.Include(&c);
region.Include(&c); region.Include(&c);
region.PrintToStream(); region.PrintToStream();
other.PrintToStream();
} }