Tested the new implementation, corrected a ton of bugs and wrong code, now Include and IntersectWith methods work. Exclude is still not working, and there are still a couple of hacks to remove

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15422 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Stefano Ceccherini 2005-12-08 14:57:54 +00:00
parent 72994381f2
commit 70206143d0
2 changed files with 39 additions and 21 deletions

View File

@ -137,6 +137,9 @@ ClipRegion::Contains(const BPoint &pt) const
void void
ClipRegion::OffsetBy(const int32 &dh, const int32 &dv) ClipRegion::OffsetBy(const int32 &dh, const int32 &dv)
{ {
if (dh == 0 && dv == 0)
return;
if (fCount > 0) { if (fCount > 0) {
for (int32 c = 0; c < fCount; c++) for (int32 c = 0; c < fCount; c++)
offset_rect(fData[c], dh, dv); offset_rect(fData[c], dh, dv);
@ -314,14 +317,14 @@ ClipRegion::WriteToLink(BPrivate::ServerLink &link)
static int static int
leftComparator(const void *a, const void *b) leftComparator(const void *a, const void *b)
{ {
return ((clipping_rect *)(a))->left > ((clipping_rect *)(b))->left; return ((clipping_rect *)(a))->left - ((clipping_rect *)(b))->left;
} }
static int static int
topComparator(const void *a, const void *b) topComparator(const void *a, const void *b)
{ {
return ((clipping_rect *)(a))->top > ((clipping_rect *)(b))->top; return ((clipping_rect *)(a))->top - ((clipping_rect *)(b))->top;
} }
@ -339,7 +342,7 @@ ClipRegion::_IntersectWithComplex(const ClipRegion &region)
} }
if (dest.fCount > 1) if (dest.fCount > 1)
qsort(dest.fData, sizeof(clipping_rect), dest.fCount, topComparator); qsort(dest.fData, dest.fCount, sizeof(clipping_rect), topComparator);
_Adopt(dest); _Adopt(dest);
} }
@ -411,26 +414,33 @@ ClipRegion::_IncludeComplex(const ClipRegion &region)
ClipRegion dest; ClipRegion dest;
while (true) { while (true) {
int32 top = bottom + 1; int32 top = bottom + 1;
bottom = region._FindSmallestBottom(_FindSmallestBottom(top, a), b); bottom = kMaxVerticalExtent;
bottom = _FindSmallestBottom(top, bottom, a);
bottom = region._FindSmallestBottom(top, bottom, b);
if (bottom == kMaxVerticalExtent) if (bottom == kMaxVerticalExtent)
break; break;
clipping_rect rects[kMaxPoints]; clipping_rect rects[kMaxPoints];
rects[0].top = top;
rects[0].bottom = bottom;
int32 rectsCount = _ExtractStripRects(top, bottom, rects, &a) int32 rectsCount = _ExtractStripRects(top, bottom, rects, &a);
+ region._ExtractStripRects(top, bottom, &rects[rectsCount], &b); rectsCount += region._ExtractStripRects(top, bottom, &rects[rectsCount], &b);
if (rectsCount > 0) { if (rectsCount > 0) {
if (rectsCount > 1) if (rectsCount > 1)
qsort(rects, sizeof(clipping_rect), rectsCount, leftComparator); qsort(&rects, rectsCount, sizeof(clipping_rect), leftComparator);
dest._MergeAndInclude(rects, rectsCount); dest._MergeAndInclude(rects, rectsCount);
} }
} }
// 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);
} }
@ -462,10 +472,10 @@ ClipRegion::_ExcludeComplex(const ClipRegion &region)
int32 foundB = region._ExtractStripRects(top, bottom, rectsB, &b); int32 foundB = region._ExtractStripRects(top, bottom, rectsB, &b);
if (foundA > 1) if (foundA > 1)
qsort(rectsA, sizeof(clipping_rect), foundA, leftComparator); qsort(rectsA, foundA, sizeof(clipping_rect), leftComparator);
if (foundB > 1) if (foundB > 1)
qsort(rectsB, sizeof(clipping_rect), foundB, leftComparator); qsort(rectsB, foundB, sizeof(clipping_rect), leftComparator);
// TODO: Do the actual exclusion // TODO: Do the actual exclusion
@ -544,9 +554,9 @@ ClipRegion::_RecalculateBounds(const clipping_rect &rect)
int32 int32
ClipRegion::_FindSmallestBottom(const int32 &top, const int32 &startIndex) const ClipRegion::_FindSmallestBottom(const int32 &top, const int32 &oldBottom, const int32 &startIndex) const
{ {
int32 bottom = kMaxVerticalExtent; 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;
if (n >= top && n < bottom) if (n >= top && n < bottom)
@ -576,6 +586,12 @@ ClipRegion::_ExtractStripRects(const int32 &top, const int32 &bottom, clipping_r
if (fData[x].top <= top && fData[x].bottom >= bottom) { if (fData[x].top <= top && fData[x].bottom >= bottom) {
rects[foundCount].left = fData[x].left; rects[foundCount].left = fData[x].left;
rects[foundCount].right = fData[x].right; rects[foundCount].right = fData[x].right;
// TODO: top and bottom are the same for every rect,
// maybe we could extract only the left and right coordinates,
// as we did in the old implementation
rects[foundCount].top = top;
rects[foundCount].bottom = bottom;
foundCount++; foundCount++;
} else if (fData[x].top > bottom) } else if (fData[x].top > bottom)
break; break;
@ -643,6 +659,7 @@ ClipRegion::_MergeAndInclude(clipping_rect *rects, const int32 &count)
next++; next++;
} }
//to_BRect(rect).PrintToStream();
_AddRect(rect); _AddRect(rect);
current = next; current = next;
} }

View File

@ -72,7 +72,8 @@ private:
void _AddRect(const clipping_rect &rect); void _AddRect(const clipping_rect &rect);
void _RecalculateBounds(const clipping_rect &newRect); void _RecalculateBounds(const clipping_rect &newRect);
int32 _FindSmallestBottom(const int32 &top, const int32 &startIndex) const; int32 _FindSmallestBottom(const int32 &top, const int32 &oldBottom,
const int32 &startIndex) const;
int32 _ExtractStripRects(const int32 &top, const int32 &bottom, int32 _ExtractStripRects(const int32 &top, const int32 &bottom,
clipping_rect *rects, int32 *inOutIndex) const; clipping_rect *rects, int32 *inOutIndex) const;