Deleted useless new(old) region implementation
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22760 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
795a2888e7
commit
c20e6cca18
@ -1,833 +0,0 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "clipping.h"
|
||||
#include "ClipRegion.h"
|
||||
//#include <ServerLink.h>
|
||||
|
||||
#include <Debug.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
const static int32 kMaxPoints = 512;
|
||||
const static int32 kMaxVerticalExtent = 0x10000000;
|
||||
const static int32 kMaxPositive = 0x7ffffffd;
|
||||
const static int32 kMaxNegative = 0x80000003;
|
||||
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()
|
||||
:
|
||||
fDataSize(0),
|
||||
fData(NULL)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
_Resize(kInitialDataSize);
|
||||
_Invalidate();
|
||||
}
|
||||
|
||||
|
||||
ClipRegion::ClipRegion(const ClipRegion ®ion)
|
||||
:
|
||||
fDataSize(0),
|
||||
fData(NULL)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
*this = region;
|
||||
}
|
||||
|
||||
|
||||
ClipRegion::ClipRegion(const clipping_rect &rect)
|
||||
:
|
||||
fDataSize(0),
|
||||
fData(NULL)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
Set(rect);
|
||||
}
|
||||
|
||||
|
||||
ClipRegion::ClipRegion(const BRect &rect)
|
||||
:
|
||||
fDataSize(0),
|
||||
fData(NULL)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
Set(rect);
|
||||
}
|
||||
|
||||
|
||||
ClipRegion::ClipRegion(const clipping_rect *rects, const int32 &count)
|
||||
:
|
||||
fDataSize(0),
|
||||
fData(NULL)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
Set(rects, count);
|
||||
}
|
||||
|
||||
|
||||
ClipRegion::~ClipRegion()
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
free(fData);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::Set(const clipping_rect &rect)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
if (!valid_rect(rect) || (fDataSize <= 1 && !_Resize(kInitialDataSize)))
|
||||
_Invalidate();
|
||||
else {
|
||||
fCount = 1;
|
||||
fData[0] = fBound = rect;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::Set(const BRect &rect)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
Set(to_clipping_rect(rect));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::Set(const clipping_rect *rects, const int32 &count)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
_Invalidate();
|
||||
_Append(rects, count);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ClipRegion::Intersects(const clipping_rect &rect) const
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
if (!rects_intersect(rect, fBound))
|
||||
return false;
|
||||
|
||||
for (int32 c = 0; c < fCount; c++) {
|
||||
if (rects_intersect(fData[c], rect))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ClipRegion::Intersects(const BRect &rect) const
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
return Intersects(to_clipping_rect(rect));
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ClipRegion::Contains(const BPoint &pt) const
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
// If the point doesn't lie within the region's bounds,
|
||||
// don't even try it against the region's rects.
|
||||
if (!point_in(fBound, pt))
|
||||
return false;
|
||||
|
||||
for (int32 c = 0; c < fCount; c++) {
|
||||
if (point_in(fData[c], pt))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::OffsetBy(const int32 &dh, const int32 &dv)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
if (dh == 0 && dv == 0)
|
||||
return;
|
||||
|
||||
if (fCount > 0) {
|
||||
for (int32 c = 0; c < fCount; c++)
|
||||
offset_rect(fData[c], dh, dv);
|
||||
|
||||
offset_rect(fBound, dh, dv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::OffsetBy(const BPoint &point)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
return OffsetBy((int32)point.x, (int32)point.y);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::IntersectWith(const clipping_rect &rect)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
if (!rects_intersect(rect, fBound))
|
||||
_Invalidate();
|
||||
else
|
||||
_IntersectWith(rect);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::IntersectWith(const BRect &rect)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
IntersectWith(to_clipping_rect(rect));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::IntersectWith(const ClipRegion ®ion)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
clipping_rect intersection = sect_rect(fBound, region.fBound);
|
||||
|
||||
if (fCount == 0 || region.fCount == 0 || !valid_rect(intersection))
|
||||
_Invalidate();
|
||||
|
||||
else if (fCount == 1 && region.fCount == 1)
|
||||
Set(intersection);
|
||||
|
||||
else if (fCount > 1 && region.fCount == 1)
|
||||
_IntersectWith(region.fBound);
|
||||
|
||||
else if (fCount == 1 && region.fCount > 1) {
|
||||
ClipRegion dest = region;
|
||||
dest._IntersectWith(fBound);
|
||||
_Adopt(dest);
|
||||
|
||||
} else
|
||||
_IntersectWithComplex(region);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::Include(const clipping_rect &rect)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
// The easy case first: if the rectangle completely contains
|
||||
// ourself, the union is the rectangle itself.
|
||||
if (rect_contains(fBound, rect))
|
||||
Set(rect);
|
||||
else {
|
||||
const ClipRegion region(rect);
|
||||
_IncludeComplex(region);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::Include(const BRect &rect)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
Include(to_clipping_rect(rect));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::Include(const ClipRegion ®ion)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
if (region.fCount == 0)
|
||||
return;
|
||||
|
||||
if (fCount == 0)
|
||||
*this = region;
|
||||
|
||||
else if (region.fBound.top > fBound.bottom)
|
||||
_Append(region);
|
||||
|
||||
else if (fBound.top > region.fBound.bottom)
|
||||
_Append(region, true);
|
||||
|
||||
else if (fBound.left > region.fBound.right) {
|
||||
ClipRegion dest(region);
|
||||
dest._IncludeNoIntersection(*this);
|
||||
_Adopt(dest);
|
||||
|
||||
} else if (region.fBound.left > fBound.right)
|
||||
_IncludeNoIntersection(region);
|
||||
|
||||
else if (region.fCount == 1)
|
||||
Include(region.fBound);
|
||||
|
||||
else if (fCount == 1) {
|
||||
ClipRegion dest(region);
|
||||
dest.Include(fBound);
|
||||
_Adopt(dest);
|
||||
} else
|
||||
_IncludeComplex(region);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::Exclude(const clipping_rect &rect)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
const ClipRegion region(rect);
|
||||
Exclude(region);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::Exclude(const BRect &rect)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
const ClipRegion region(rect);
|
||||
Exclude(region);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::Exclude(const ClipRegion ®ion)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
if (fCount == 0 || region.fCount == 0 || !rects_intersect(fBound, region.fBound))
|
||||
return;
|
||||
|
||||
_ExcludeComplex(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::operator=(const ClipRegion ®ion)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
const int32 size = region.fDataSize > 0 ? region.fDataSize : kInitialDataSize;
|
||||
if (_Resize(size, false)) {
|
||||
fBound = region.fBound;
|
||||
fCount = region.fCount;
|
||||
memcpy(fData, region.fData, fCount * sizeof(clipping_rect));
|
||||
} else
|
||||
_Invalidate();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
#if 0
|
||||
status_t
|
||||
ClipRegion::ReadFromLink(BPrivate::ServerLink &link)
|
||||
{
|
||||
link.Read(&fCount, sizeof(fCount));
|
||||
link.Read(&fBound, sizeof(fBound));
|
||||
_Resize(fCount + 1);
|
||||
return link.Read(fData, fCount * sizeof(clipping_rect));
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ClipRegion::WriteToLink(BPrivate::ServerLink &link)
|
||||
{
|
||||
link.Attach(&fCount, sizeof(fCount));
|
||||
link.Attach(&fBound, sizeof(fBound));
|
||||
return link.Attach(fData, fCount * sizeof(clipping_rect));
|
||||
}
|
||||
#endif
|
||||
|
||||
// private methods
|
||||
static int
|
||||
leftComparator(const void *a, const void *b)
|
||||
{
|
||||
return ((clipping_rect *)(a))->left - ((clipping_rect *)(b))->left;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
topComparator(const void *a, const void *b)
|
||||
{
|
||||
return ((clipping_rect *)(a))->top - ((clipping_rect *)(b))->top;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::_IntersectWithComplex(const ClipRegion ®ion)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
ClipRegion dest;
|
||||
|
||||
for (int32 f = 0; f < fCount; f++) {
|
||||
for (int32 s = 0; s < region.fCount; s++) {
|
||||
clipping_rect intersection = sect_rect(fData[f], region.fData[s]);
|
||||
if (valid_rect(intersection))
|
||||
dest._AddRect(intersection);
|
||||
}
|
||||
}
|
||||
|
||||
if (dest.fCount > 1)
|
||||
qsort(dest.fData, dest.fCount, sizeof(clipping_rect), topComparator);
|
||||
|
||||
_Adopt(dest);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::_IntersectWith(const clipping_rect &rect)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
ASSERT(rects_intersect(rect, fBound));
|
||||
|
||||
// The easy case first: We already know that the region intersects,
|
||||
// with the passed rect, so we check if the rect completely contains
|
||||
// the region.
|
||||
// If it's the case, the intersection is exactly the region itself.
|
||||
if (rect_contains(rect, fBound))
|
||||
return;
|
||||
|
||||
// Otherwise, we add the intersections of the region's rects
|
||||
// with the passed rect
|
||||
ClipRegion dest;
|
||||
for (int32 x = 0; x < fCount; x++) {
|
||||
clipping_rect testRect = sect_rect(rect, fData[x]);
|
||||
if (valid_rect(testRect))
|
||||
dest._AddRect(testRect);
|
||||
}
|
||||
_Adopt(dest);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::_IncludeNoIntersection(const ClipRegion ®ion)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
ASSERT(fCount != 0 || region.fCount != 0);
|
||||
ASSERT(!rects_intersect(region.fBound, fBound));
|
||||
|
||||
int32 first = 0, second = 0;
|
||||
|
||||
ClipRegion dest;
|
||||
// Add the rects in the right order, so that
|
||||
// they are kept sorted by their top coordinate
|
||||
while (first < fCount && second < region.fCount) {
|
||||
if (fData[first].top < region.fData[second].top)
|
||||
dest._AddRect(fData[first++]);
|
||||
else
|
||||
dest._AddRect(region.fData[second++]);
|
||||
}
|
||||
|
||||
if (first == fCount) {
|
||||
while (second < region.fCount)
|
||||
dest._AddRect(region.fData[second++]);
|
||||
|
||||
} else if (second == region.fCount) {
|
||||
while (first < fCount)
|
||||
dest._AddRect(fData[first++]);
|
||||
}
|
||||
|
||||
_Adopt(dest);
|
||||
|
||||
ASSERT(first == fCount && second == region.fCount);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::_IncludeComplex(const ClipRegion ®ion)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
int32 bottom = min_c(fBound.top, region.fBound.top) - 1;
|
||||
int32 a = 0, b = 0;
|
||||
ClipRegion dest;
|
||||
while (true) {
|
||||
int32 top = bottom + 1;
|
||||
bottom = kMaxVerticalExtent;
|
||||
bottom = _FindSmallestBottom(top, bottom, a);
|
||||
bottom = region._FindSmallestBottom(top, bottom, b);
|
||||
|
||||
if (bottom == kMaxVerticalExtent)
|
||||
break;
|
||||
|
||||
clipping_rect rects[kMaxPoints];
|
||||
|
||||
int32 rectsCount = _ExtractStripRects(top, bottom, rects, &a);
|
||||
rectsCount += region._ExtractStripRects(top, bottom, &rects[rectsCount], &b);
|
||||
|
||||
if (rectsCount > 0) {
|
||||
if (rectsCount > 1)
|
||||
qsort(&rects, rectsCount, sizeof(clipping_rect), leftComparator);
|
||||
|
||||
dest._MergeAndInclude(rects, rectsCount);
|
||||
}
|
||||
}
|
||||
|
||||
dest._Coalesce();
|
||||
|
||||
_Adopt(dest);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::_ExcludeComplex(const ClipRegion ®ion)
|
||||
{
|
||||
/*
|
||||
int32 bottom = min_c(fBound.top, region.fBound.top) - 1;
|
||||
int32 a = 0, b = 0;
|
||||
ClipRegion dest;
|
||||
while (true) {
|
||||
int32 top = bottom + 1;
|
||||
bottom = region._FindSmallestBottom(_FindSmallestBottom(top, a), b);
|
||||
|
||||
if (bottom == kMaxVerticalExtent)
|
||||
break;
|
||||
|
||||
clipping_rect rectsA[kMaxPoints];
|
||||
rectsA[0].top = top;
|
||||
rectsA[0].bottom = bottom;
|
||||
|
||||
clipping_rect rectsB[kMaxPoints];
|
||||
rectsB[0].top = top;
|
||||
rectsB[0].bottom = bottom;
|
||||
|
||||
int32 foundA = _ExtractStripRects(top, bottom, rectsA, &a);
|
||||
int32 foundB = region._ExtractStripRects(top, bottom, rectsB, &b);
|
||||
|
||||
if (foundA > 1)
|
||||
qsort(rectsA, foundA, sizeof(clipping_rect), leftComparator);
|
||||
|
||||
if (foundB > 1)
|
||||
qsort(rectsB, foundB, sizeof(clipping_rect), leftComparator);
|
||||
|
||||
// TODO: Do the actual exclusion
|
||||
|
||||
}
|
||||
|
||||
dest._Coalesce();
|
||||
_Adopt(dest);
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::_AddRect(const clipping_rect &rect)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
ASSERT(fCount >= 0);
|
||||
ASSERT(fDataSize >= 0);
|
||||
ASSERT(valid_rect(rect));
|
||||
|
||||
// Should we just reallocate the memory and
|
||||
// copy the rect ?
|
||||
bool addRect = true;
|
||||
|
||||
if (fCount > 0) {
|
||||
// Wait! We could merge the rect with one of the
|
||||
// existing rectangles, if it's adiacent.
|
||||
// We just check it against the last rectangle, since
|
||||
// we are keeping them sorted by their "top" coordinates.
|
||||
const int32 last = fCount - 1;
|
||||
if (rect.left == fData[last].left && rect.right == fData[last].right
|
||||
&& rect.top == fData[last].bottom + 1) {
|
||||
|
||||
fData[last].bottom = rect.bottom;
|
||||
addRect = false;
|
||||
|
||||
} else if (rect.top == fData[last].top && rect.bottom == fData[last].bottom) {
|
||||
if (rect.left == fData[last].right + 1) {
|
||||
|
||||
fData[last].right = rect.right;
|
||||
addRect = false;
|
||||
|
||||
} else if (rect.right == fData[last].left - 1) {
|
||||
|
||||
fData[last].left = rect.left;
|
||||
addRect = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We weren't lucky.... just add the rect as a new one
|
||||
if (addRect) {
|
||||
if (fDataSize <= fCount && !_Resize(fCount + 16))
|
||||
return;
|
||||
|
||||
fData[fCount] = rect;
|
||||
fCount++;
|
||||
}
|
||||
|
||||
_RecalculateBounds(rect);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::_RecalculateBounds(const clipping_rect &rect)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
ASSERT(fCount > 0);
|
||||
|
||||
if (rect.top < fBound.top)
|
||||
fBound.top = rect.top;
|
||||
if (rect.left < fBound.left)
|
||||
fBound.left = rect.left;
|
||||
if (rect.right > fBound.right)
|
||||
fBound.right = rect.right;
|
||||
if (rect.bottom > fBound.bottom)
|
||||
fBound.bottom = rect.bottom;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
ClipRegion::_FindSmallestBottom(const int32 &top, const int32 &oldBottom, const int32 &startIndex) const
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
int32 bottom = oldBottom;
|
||||
for (int32 i = startIndex; i < fCount; i++) {
|
||||
const int32 n = fData[i].top - 1;
|
||||
if (n >= top && n < bottom)
|
||||
bottom = n;
|
||||
if (fData[i].bottom >= top && fData[i].bottom < bottom)
|
||||
bottom = fData[i].bottom;
|
||||
}
|
||||
|
||||
return bottom;
|
||||
}
|
||||
|
||||
|
||||
int32
|
||||
ClipRegion::_ExtractStripRects(const int32 &top, const int32 &bottom, clipping_rect *rects, int32 *inOutIndex) const
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
int32 currentIndex = *inOutIndex;
|
||||
*inOutIndex = -1;
|
||||
|
||||
int32 foundCount = 0;
|
||||
// Store left and right points to the appropriate array
|
||||
for (int32 x = currentIndex; x < fCount; x++) {
|
||||
// Look if this rect can be used next time we are called,
|
||||
// thus correctly maintaining the "index" parameters.
|
||||
if (fData[x].bottom >= top && *inOutIndex == -1)
|
||||
*inOutIndex = x;
|
||||
|
||||
if (fData[x].top <= top && fData[x].bottom >= bottom) {
|
||||
rects[foundCount].left = fData[x].left;
|
||||
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++;
|
||||
} else if (fData[x].top > bottom)
|
||||
break;
|
||||
}
|
||||
|
||||
if (*inOutIndex == -1)
|
||||
*inOutIndex = currentIndex;
|
||||
|
||||
return foundCount;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::_Append(const ClipRegion ®ion, const bool &aboveThis)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
if (aboveThis) {
|
||||
ClipRegion dest = region;
|
||||
for (int32 c = 0; c < fCount; c++)
|
||||
dest._AddRect(fData[c]);
|
||||
_Adopt(dest);
|
||||
} else {
|
||||
for (int32 c = 0; c < region.fCount; c++)
|
||||
_AddRect(region.fData[c]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::_Append(const clipping_rect *rects, const int32 &count, const bool &aboveThis)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
if (aboveThis) {
|
||||
ClipRegion dest;
|
||||
dest.Set(rects, count);
|
||||
for (int32 c = 0; c < fCount; c++)
|
||||
dest._AddRect(fData[c]);
|
||||
_Adopt(dest);
|
||||
} else {
|
||||
for (int32 c = 0; c < count; c++)
|
||||
_AddRect(rects[c]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::_MergeAndInclude(clipping_rect *rects, const int32 &count)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
// rects share the top and bottom coordinates,
|
||||
// so we can get those from the first one and ignore the others
|
||||
clipping_rect rect;
|
||||
rect.top = rects[0].top;
|
||||
rect.bottom = rects[0].bottom;
|
||||
|
||||
// Check if a rect intersects with the next one.
|
||||
// If so, merge the two rects, if not, just add the rect.
|
||||
int32 current = 0;
|
||||
while (current < count) {
|
||||
int32 next = current + 1;
|
||||
|
||||
rect.left = rects[current].left;
|
||||
rect.right = rects[current].right;
|
||||
|
||||
while (next < count && rect.right >= rects[next].left) {
|
||||
if (rect.right < rects[next].right)
|
||||
rect.right = rects[next].right;
|
||||
next++;
|
||||
}
|
||||
|
||||
_AddRect(rect);
|
||||
current = next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
inline void
|
||||
ClipRegion::_Coalesce()
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
if (fCount > 1) {
|
||||
while (_CoalesceVertical() || _CoalesceHorizontal())
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ClipRegion::_CoalesceVertical()
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
const int32 oldCount = fCount;
|
||||
|
||||
clipping_rect testRect = { 1, 1, -1, -1 };
|
||||
int32 newCount = -1;
|
||||
|
||||
// First, try coalescing rects vertically
|
||||
for (int32 x = 0; x < fCount; x++) {
|
||||
const clipping_rect &rect = fData[x];
|
||||
|
||||
if (rect.left == testRect.left && rect.right == testRect.right
|
||||
&& rect.top == testRect.bottom + 1)
|
||||
fData[newCount].bottom = rect.bottom;
|
||||
else {
|
||||
newCount++;
|
||||
fData[newCount] = fData[x];
|
||||
}
|
||||
testRect = fData[newCount];
|
||||
}
|
||||
|
||||
fCount = newCount + 1;
|
||||
|
||||
return fCount < oldCount;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ClipRegion::_CoalesceHorizontal()
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
const int32 oldCount = fCount;
|
||||
|
||||
clipping_rect testRect = { 1, 1, -1, -1 };
|
||||
int32 newCount = -1;
|
||||
|
||||
for (int32 x = 0; x < fCount; x++) {
|
||||
const clipping_rect &rect = fData[x];
|
||||
|
||||
if (rect.top == testRect.top && rect.bottom == testRect.bottom
|
||||
&& rect.left == testRect.right + 1)
|
||||
fData[newCount].right = rect.right;
|
||||
else {
|
||||
newCount++;
|
||||
fData[newCount] = rect;
|
||||
}
|
||||
testRect = fData[newCount];
|
||||
}
|
||||
|
||||
fCount = newCount + 1;
|
||||
|
||||
return fCount < oldCount;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::_Invalidate()
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
fCount = 0;
|
||||
fBound.left = kMaxPositive;
|
||||
fBound.top = kMaxPositive;
|
||||
fBound.right = kMaxNegative;
|
||||
fBound.bottom = kMaxNegative;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ClipRegion::_Resize(const int32 &newSize, const bool &keepOld)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
if (!keepOld) {
|
||||
free(fData);
|
||||
fData = (clipping_rect *)malloc(newSize * sizeof(clipping_rect));
|
||||
} else
|
||||
fData = (clipping_rect *)realloc(fData, newSize * sizeof(clipping_rect));
|
||||
|
||||
if (fData == NULL)
|
||||
return false;
|
||||
|
||||
fDataSize = newSize;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ClipRegion::_Adopt(ClipRegion ®ion)
|
||||
{
|
||||
DEBUG_ENTER_FUNCTION
|
||||
free(fData);
|
||||
fData = region.fData;
|
||||
fDataSize = region.fDataSize;
|
||||
fCount = region.fCount;
|
||||
fBound = region.fBound;
|
||||
|
||||
region._Invalidate();
|
||||
region.fDataSize = 0;
|
||||
region.fData = NULL;
|
||||
}
|
||||
|
||||
|
@ -1,103 +0,0 @@
|
||||
#ifndef __CLIPREGION_H
|
||||
#define __CLIPREGION_H
|
||||
|
||||
#include "Region.h" // for clipping_rect
|
||||
|
||||
namespace BPrivate {
|
||||
class ServerLink;
|
||||
};
|
||||
|
||||
|
||||
class ClipRegion {
|
||||
public:
|
||||
ClipRegion();
|
||||
ClipRegion(const ClipRegion ®ion);
|
||||
ClipRegion(const BRegion ®ion);
|
||||
ClipRegion(const clipping_rect &rect);
|
||||
ClipRegion(const BRect &rect);
|
||||
ClipRegion(const clipping_rect *rects, const int32 &count);
|
||||
|
||||
~ClipRegion();
|
||||
|
||||
clipping_rect Frame() const { return fBound; }
|
||||
clipping_rect RectAt(const int32 &index) const;
|
||||
|
||||
int32 CountRects() const { return fCount; }
|
||||
|
||||
void Set(const clipping_rect &rect);
|
||||
void Set(const BRect &rect);
|
||||
void Set(const clipping_rect *rects, const int32 &count);
|
||||
|
||||
bool Intersects(const clipping_rect &rect) const;
|
||||
bool Intersects(const BRect &rect) const;
|
||||
bool Intersects(const ClipRegion ®ion) const;
|
||||
|
||||
bool Contains(const BPoint &point) const;
|
||||
|
||||
void OffsetBy(const int32 &dx, const int32 &dy);
|
||||
void OffsetBy(const BPoint &point);
|
||||
|
||||
void Include(const clipping_rect &rect);
|
||||
void Include(const BRect &rect);
|
||||
void Include(const ClipRegion ®ion);
|
||||
|
||||
void Exclude(const clipping_rect &rect);
|
||||
void Exclude(const BRect &rect);
|
||||
void Exclude(const ClipRegion ®ion);
|
||||
|
||||
void IntersectWith(const clipping_rect &rect);
|
||||
void IntersectWith(const BRect &rect);
|
||||
void IntersectWith(const ClipRegion ®ion);
|
||||
|
||||
void GetRects(clipping_rect **rects, int32 *count);
|
||||
|
||||
ClipRegion &operator=(const ClipRegion ®ion);
|
||||
|
||||
status_t ReadFromLink(BPrivate::ServerLink &link);
|
||||
status_t WriteToLink(BPrivate::ServerLink &link);
|
||||
|
||||
private:
|
||||
int32 fCount;
|
||||
int32 fDataSize;
|
||||
clipping_rect fBound;
|
||||
clipping_rect *fData;
|
||||
|
||||
void _Append(const ClipRegion ®ion, const bool &aboveThis = false);
|
||||
void _Append(const clipping_rect *rects, const int32 &count, const bool &aboveThis = false);
|
||||
|
||||
void _IntersectWithComplex(const ClipRegion ®ion);
|
||||
void _IntersectWith(const clipping_rect &rect);
|
||||
void _IncludeNoIntersection(const ClipRegion ®ion);
|
||||
void _IncludeComplex(const ClipRegion ®ion);
|
||||
void _ExcludeComplex(const ClipRegion ®ion);
|
||||
|
||||
void _AddRect(const clipping_rect &rect);
|
||||
void _RecalculateBounds(const clipping_rect &newRect);
|
||||
|
||||
int32 _FindSmallestBottom(const int32 &top, const int32 &oldBottom,
|
||||
const int32 &startIndex) const;
|
||||
int32 _ExtractStripRects(const int32 &top, const int32 &bottom,
|
||||
clipping_rect *rects, int32 *inOutIndex) const;
|
||||
|
||||
void _MergeAndInclude(clipping_rect *rects, const int32 &count);
|
||||
|
||||
void _Coalesce();
|
||||
bool _CoalesceVertical();
|
||||
bool _CoalesceHorizontal();
|
||||
|
||||
void _Invalidate();
|
||||
bool _Resize(const int32 &newSize, const bool &keepOld = true);
|
||||
void _Adopt(ClipRegion ®ion);
|
||||
};
|
||||
|
||||
|
||||
inline clipping_rect
|
||||
ClipRegion::RectAt(const int32 &index) const
|
||||
{
|
||||
if (index >= 0 && index < fCount)
|
||||
return fData[index];
|
||||
clipping_rect rect = { 0, 0, -1, -1 };
|
||||
return rect;
|
||||
}
|
||||
|
||||
#endif // __CLIPREGION_H
|
@ -1,503 +0,0 @@
|
||||
/*
|
||||
* Copyright 2003-2005, Haiku Inc.
|
||||
* Authors:
|
||||
* Stefano Ceccherini (burton666@libero.it).
|
||||
* Carwyn Jones (turok2@currantbun.com)
|
||||
*
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
|
||||
|
||||
#include <DirectWindow.h>
|
||||
#include <Screen.h>
|
||||
|
||||
#include <clipping.h>
|
||||
#include <AppServerLink.h>
|
||||
#include <ClipRegion.h>
|
||||
#include <DirectWindowPrivate.h>
|
||||
#include <ServerProtocol.h>
|
||||
|
||||
|
||||
// We don't need this kind of locking, since the directDaemonFunc
|
||||
// doesn't access critical shared data.
|
||||
#define DW_NEEDS_LOCKING 0
|
||||
|
||||
enum dw_status_bits {
|
||||
DW_STATUS_AREA_CLONED = 0x1,
|
||||
DW_STATUS_THREAD_STARTED = 0x2,
|
||||
DW_STATUS_SEM_CREATED = 0x4
|
||||
};
|
||||
|
||||
|
||||
BDirectWindow::BDirectWindow(BRect frame, const char *title, window_type type,
|
||||
uint32 flags, uint32 workspace)
|
||||
: BWindow(frame, title, type, flags, workspace)
|
||||
{
|
||||
InitData();
|
||||
}
|
||||
|
||||
|
||||
BDirectWindow::BDirectWindow(BRect frame, const char *title, window_look look,
|
||||
window_feel feel, uint32 flags, uint32 workspace)
|
||||
: BWindow(frame, title, look, feel, flags, workspace)
|
||||
{
|
||||
InitData();
|
||||
}
|
||||
|
||||
|
||||
BDirectWindow::~BDirectWindow()
|
||||
{
|
||||
DisposeData();
|
||||
}
|
||||
|
||||
|
||||
// start of regular BWindow API
|
||||
BArchivable *
|
||||
BDirectWindow::Instantiate(BMessage *data)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BDirectWindow::Archive(BMessage *data, bool deep) const
|
||||
{
|
||||
return inherited::Archive(data, deep);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::Quit()
|
||||
{
|
||||
inherited::Quit();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::DispatchMessage(BMessage *message, BHandler *handler)
|
||||
{
|
||||
inherited::DispatchMessage(message, handler);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::MessageReceived(BMessage *message)
|
||||
{
|
||||
inherited::MessageReceived(message);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::FrameMoved(BPoint new_position)
|
||||
{
|
||||
inherited::FrameMoved(new_position);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::WorkspacesChanged(uint32 old_ws, uint32 new_ws)
|
||||
{
|
||||
inherited::WorkspacesChanged(old_ws, new_ws);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::WorkspaceActivated(int32 ws, bool state)
|
||||
{
|
||||
inherited::WorkspaceActivated(ws, state);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::FrameResized(float new_width, float new_height)
|
||||
{
|
||||
inherited::FrameResized(new_width, new_height);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::Minimize(bool minimize)
|
||||
{
|
||||
inherited::Minimize(minimize);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::Zoom(BPoint rec_position, float rec_width, float rec_height)
|
||||
{
|
||||
inherited::Zoom(rec_position, rec_width, rec_height);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::ScreenChanged(BRect screen_size, color_space depth)
|
||||
{
|
||||
inherited::ScreenChanged(screen_size, depth);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::MenusBeginning()
|
||||
{
|
||||
inherited::MenusBeginning();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::MenusEnded()
|
||||
{
|
||||
inherited::MenusEnded();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::WindowActivated(bool state)
|
||||
{
|
||||
inherited::WindowActivated(state);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::Show()
|
||||
{
|
||||
inherited::Show();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::Hide()
|
||||
{
|
||||
inherited::Hide();
|
||||
}
|
||||
|
||||
|
||||
BHandler *
|
||||
BDirectWindow::ResolveSpecifier(BMessage *msg, int32 index,
|
||||
BMessage *specifier, int32 form, const char *property)
|
||||
{
|
||||
return inherited::ResolveSpecifier(msg, index, specifier, form, property);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BDirectWindow::GetSupportedSuites(BMessage *data)
|
||||
{
|
||||
return inherited::GetSupportedSuites(data);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BDirectWindow::Perform(perform_code d, void *arg)
|
||||
{
|
||||
return inherited::Perform(d, arg);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::task_looper()
|
||||
{
|
||||
inherited::task_looper();
|
||||
}
|
||||
|
||||
|
||||
BMessage *
|
||||
BDirectWindow::ConvertToMessage(void *raw, int32 code)
|
||||
{
|
||||
return inherited::ConvertToMessage(raw, code);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - BDirectWindow specific API
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::DirectConnected(direct_buffer_info *info)
|
||||
{
|
||||
// implemented in subclasses
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BDirectWindow::GetClippingRegion(BRegion *region, BPoint *origin) const
|
||||
{
|
||||
if (region == NULL)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
if (IsLocked() || !LockDirect())
|
||||
return B_ERROR;
|
||||
|
||||
if (in_direct_connect) {
|
||||
UnlockDirect();
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// BPoint's coordinates are floats. We can only work
|
||||
// with integers.
|
||||
int32 originX, originY;
|
||||
if (origin == NULL) {
|
||||
originX = 0;
|
||||
originY = 0;
|
||||
} else {
|
||||
originX = (int32)origin->x;
|
||||
originY = (int32)origin->y;
|
||||
}
|
||||
|
||||
#ifndef HAIKU_TARGET_PLATFORM_DANO
|
||||
// Since we are friend of BRegion, we can access its private members.
|
||||
// Otherwise, we would need to call BRegion::Include(clipping_rect)
|
||||
// for every clipping_rect in our clip_list, and that would be much
|
||||
// more overkill than this (tested ).
|
||||
region->fRegion->Set(buffer_desc->clip_list, buffer_desc->clip_list_count);
|
||||
|
||||
// adjust bounds by the given origin point
|
||||
region->OffsetBy(-originX, -originY);
|
||||
#endif
|
||||
|
||||
UnlockDirect();
|
||||
|
||||
return B_OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BDirectWindow::SetFullScreen(bool enable)
|
||||
{
|
||||
status_t status = B_ERROR;
|
||||
if (Lock()) {
|
||||
fLink->StartMessage(AS_DIRECT_WINDOW_SET_FULLSCREEN);
|
||||
fLink->Attach<bool>(enable);
|
||||
|
||||
if (fLink->FlushWithReply(status) == B_OK
|
||||
&& status == B_OK)
|
||||
full_screen_enable = enable;
|
||||
Unlock();
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BDirectWindow::IsFullScreen() const
|
||||
{
|
||||
return full_screen_enable;
|
||||
}
|
||||
|
||||
|
||||
/*static*/
|
||||
bool
|
||||
BDirectWindow::SupportsWindowMode(screen_id id)
|
||||
{
|
||||
display_mode mode;
|
||||
status_t status = BScreen(id).GetMode(&mode);
|
||||
if (status == B_OK)
|
||||
return mode.flags & B_PARALLEL_ACCESS;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark - Private methods
|
||||
|
||||
|
||||
int32
|
||||
BDirectWindow::DirectDaemonFunc(void *arg)
|
||||
{
|
||||
BDirectWindow *object = static_cast<BDirectWindow *>(arg);
|
||||
|
||||
while (!object->daemon_killer) {
|
||||
// This sem is released by the app_server when our
|
||||
// clipping region changes, or when our window is moved,
|
||||
// resized, etc. etc.
|
||||
status_t status;
|
||||
do {
|
||||
status = acquire_sem(object->disable_sem);
|
||||
} while (status == B_INTERRUPTED);
|
||||
|
||||
if (status < B_OK)
|
||||
return -1;
|
||||
|
||||
if (object->LockDirect()) {
|
||||
if ((object->buffer_desc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_START)
|
||||
object->connection_enable = true;
|
||||
|
||||
object->in_direct_connect = true;
|
||||
object->DirectConnected(object->buffer_desc);
|
||||
object->in_direct_connect = false;
|
||||
|
||||
if ((object->buffer_desc->buffer_state & B_DIRECT_MODE_MASK) == B_DIRECT_STOP)
|
||||
object->connection_enable = false;
|
||||
|
||||
object->UnlockDirect();
|
||||
}
|
||||
|
||||
// The app_server then waits (with a timeout) on this sem.
|
||||
// If we aren't quick enough to release this sem, our app
|
||||
// will be terminated by the app_server
|
||||
if (release_sem(object->disable_sem_ack) != B_OK)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// LockDirect() and UnlockDirect() are no-op on R5. I tried to call (R5's) LockDirect()
|
||||
// repeatedly, from the same thread and from different threads, nothing happened.
|
||||
// I implemented them anyway, as they were the first methods I wrote
|
||||
// in this class (As you can see, I even needed to cast away their constness
|
||||
// to make them do something useful).
|
||||
// They're not needed though, as the direct_daemon_thread doesn't change
|
||||
// any shared data. They are probably here for future enhancements (see also the
|
||||
// comment in DriverSetup()
|
||||
bool
|
||||
BDirectWindow::LockDirect() const
|
||||
{
|
||||
status_t status = B_OK;
|
||||
|
||||
#if DW_NEEDS_LOCKING
|
||||
BDirectWindow *casted = const_cast<BDirectWindow *>(this);
|
||||
|
||||
if (atomic_add(&casted->direct_lock, 1) > 0) {
|
||||
do {
|
||||
status = acquire_sem(direct_sem);
|
||||
} while (status == B_INTERRUPTED);
|
||||
}
|
||||
|
||||
if (status == B_OK) {
|
||||
casted->direct_lock_owner = find_thread(NULL);
|
||||
casted->direct_lock_count++;
|
||||
}
|
||||
#endif
|
||||
|
||||
return status == B_OK;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::UnlockDirect() const
|
||||
{
|
||||
#if DW_NEEDS_LOCKING
|
||||
BDirectWindow *casted = const_cast<BDirectWindow *>(this);
|
||||
|
||||
if (atomic_add(&casted->direct_lock, -1) > 1)
|
||||
release_sem(direct_sem);
|
||||
|
||||
casted->direct_lock_count--;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::InitData()
|
||||
{
|
||||
connection_enable = false;
|
||||
full_screen_enable = false;
|
||||
in_direct_connect = false;
|
||||
|
||||
dw_init_status = 0;
|
||||
|
||||
direct_driver_ready = false;
|
||||
direct_driver_type = 0;
|
||||
direct_driver_token = 0;
|
||||
direct_driver = NULL;
|
||||
|
||||
if (!Lock())
|
||||
return;
|
||||
|
||||
struct direct_window_sync_data syncData;
|
||||
|
||||
fLink->StartMessage(AS_DIRECT_WINDOW_GET_SYNC_DATA);
|
||||
|
||||
status_t status = B_ERROR;
|
||||
if (fLink->FlushWithReply(status) == B_OK
|
||||
&& status == B_OK) {
|
||||
fLink->Read<direct_window_sync_data>(&syncData);
|
||||
}
|
||||
|
||||
Unlock();
|
||||
|
||||
if (status < B_OK)
|
||||
return;
|
||||
|
||||
#if DW_NEEDS_LOCKING
|
||||
direct_lock = 0;
|
||||
direct_lock_count = 0;
|
||||
direct_lock_owner = -1;
|
||||
direct_lock_stack = NULL;
|
||||
direct_sem = create_sem(1, "direct sem");
|
||||
if (direct_sem > 0)
|
||||
dw_init_status |= DW_STATUS_SEM_CREATED;
|
||||
#endif
|
||||
|
||||
source_clipping_area = syncData.area;
|
||||
disable_sem = syncData.disable_sem;
|
||||
disable_sem_ack = syncData.disable_sem_ack;
|
||||
|
||||
cloned_clipping_area = clone_area("Clone direct area", (void**)&buffer_desc,
|
||||
B_ANY_ADDRESS, B_READ_AREA, source_clipping_area);
|
||||
|
||||
if (cloned_clipping_area > 0) {
|
||||
dw_init_status |= DW_STATUS_AREA_CLONED;
|
||||
|
||||
direct_daemon_id = spawn_thread(DirectDaemonFunc, "direct daemon",
|
||||
B_DISPLAY_PRIORITY, this);
|
||||
|
||||
if (direct_daemon_id > 0) {
|
||||
daemon_killer = false;
|
||||
if (resume_thread(direct_daemon_id) == B_OK)
|
||||
dw_init_status |= DW_STATUS_THREAD_STARTED;
|
||||
else
|
||||
kill_thread(direct_daemon_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
BDirectWindow::DisposeData()
|
||||
{
|
||||
// wait until the connection terminates: we can't destroy
|
||||
// the object until the client receives the B_DIRECT_STOP
|
||||
// notification, or bad things will happen
|
||||
while (connection_enable)
|
||||
snooze(50000);
|
||||
|
||||
LockDirect();
|
||||
|
||||
if (dw_init_status & DW_STATUS_THREAD_STARTED) {
|
||||
daemon_killer = true;
|
||||
// Release this sem, otherwise the Direct daemon thread
|
||||
// will wait forever on it
|
||||
release_sem(disable_sem);
|
||||
status_t retVal;
|
||||
wait_for_thread(direct_daemon_id, &retVal);
|
||||
}
|
||||
|
||||
#if DW_NEEDS_LOCKING
|
||||
if (dw_init_status & DW_STATUS_SEM_CREATED)
|
||||
delete_sem(direct_sem);
|
||||
#endif
|
||||
|
||||
if (dw_init_status & DW_STATUS_AREA_CLONED)
|
||||
delete_area(cloned_clipping_area);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BDirectWindow::DriverSetup() const
|
||||
{
|
||||
// Unimplemented in R5.
|
||||
// This function is probably here because they wanted, in a future time,
|
||||
// to implement graphic acceleration within BDirectWindow
|
||||
// (in fact, there is also a BDirectDriver member in BDirectWindow,
|
||||
// though it's not used).
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
void BDirectWindow::_ReservedDirectWindow1() {}
|
||||
void BDirectWindow::_ReservedDirectWindow2() {}
|
||||
void BDirectWindow::_ReservedDirectWindow3() {}
|
||||
void BDirectWindow::_ReservedDirectWindow4() {}
|
@ -1,11 +0,0 @@
|
||||
SubDir HAIKU_TOP src tests kits interface NewRegion ;
|
||||
|
||||
UsePrivateHeaders interface ;
|
||||
|
||||
SimpleTest NewRegionTest
|
||||
: Region.cpp
|
||||
ClipRegion.cpp
|
||||
main.cpp
|
||||
: root be
|
||||
;
|
||||
|
@ -1,348 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) 2003-2005, Haiku, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// File Name: Region.cpp
|
||||
// Author: Stefano Ceccherini (burton666@libero.it)
|
||||
// Description: Region class consisting of multiple rectangles
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Notes: As now, memory is always allocated and never freed (except on destruction,
|
||||
// or sometimes when a copy is made).
|
||||
// This let us be a bit faster since we don't do many reallocations.
|
||||
// But that means that even an empty region could "waste" much space, if it contained
|
||||
// many rects before being emptied.
|
||||
// I.E: a region which contains 24 rects allocates more than 24 * 4 * sizeof(int32)
|
||||
// = 96 * sizeof(int32) bytes. If we call MakeEmpty(), that region will contain no rects,
|
||||
// but it will still keep the allocated memory.
|
||||
// This shouldnt' be an issue, since usually BRegions are just used for calculations,
|
||||
// and don't last so long.
|
||||
// Anyway, we can change that behaviour if we want, but BeOS's BRegion seems to behave exactly
|
||||
// like this.
|
||||
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <Debug.h>
|
||||
#include "Region.h"
|
||||
|
||||
#include "clipping.h"
|
||||
#include "ClipRegion.h"
|
||||
|
||||
|
||||
|
||||
/*! \brief Initializes a region. The region will have no rects,
|
||||
and its bound will be invalid.
|
||||
*/
|
||||
BRegion::BRegion()
|
||||
:
|
||||
fRegion(new (nothrow) ClipRegion)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Initializes a region to be a copy of another.
|
||||
\param region The region to copy.
|
||||
*/
|
||||
BRegion::BRegion(const BRegion ®ion)
|
||||
:
|
||||
fRegion(new (nothrow) ClipRegion(*region.fRegion))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Initializes a region to contain a BRect.
|
||||
\param rect The BRect to set the region to.
|
||||
*/
|
||||
BRegion::BRegion(const BRect rect)
|
||||
:
|
||||
fRegion(new (nothrow) ClipRegion(to_clipping_rect(rect)))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Frees the allocated memory.
|
||||
*/
|
||||
BRegion::~BRegion()
|
||||
{
|
||||
delete fRegion;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the bounds of the region.
|
||||
\return A BRect which represents the bounds of the region.
|
||||
*/
|
||||
BRect
|
||||
BRegion::Frame() const
|
||||
{
|
||||
return fRegion ? to_BRect(fRegion->Frame()) : BRect();
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the bounds of the region as a clipping_rect (which has integer coordinates).
|
||||
\return A clipping_rect which represents the bounds of the region.
|
||||
*/
|
||||
clipping_rect
|
||||
BRegion::FrameInt() const
|
||||
{
|
||||
return fRegion ? fRegion->Frame() : to_clipping_rect(BRect());
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the regions's BRect at the given index.
|
||||
\param index The index (zero based) of the wanted rectangle.
|
||||
\return If the given index is valid, it returns the BRect at that index,
|
||||
otherwise, it returns an invalid BRect.
|
||||
*/
|
||||
BRect
|
||||
BRegion::RectAt(int32 index)
|
||||
{
|
||||
return fRegion ? to_BRect(fRegion->RectAt(index)) : BRect();
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Returns the regions's clipping_rect at the given index.
|
||||
\param index The index (zero based) of the wanted rectangle.
|
||||
\return If the given index is valid, it returns the clipping_rect at that index,
|
||||
otherwise, it returns an invalid clipping_rect.
|
||||
*/
|
||||
clipping_rect
|
||||
BRegion::RectAtInt(int32 index)
|
||||
{
|
||||
return fRegion ? fRegion->RectAt(index) : to_clipping_rect(BRect());
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Counts the region rects.
|
||||
\return An int32 which is the total number of rects in the region.
|
||||
*/
|
||||
int32
|
||||
BRegion::CountRects()
|
||||
{
|
||||
return fRegion ? fRegion->CountRects() : 0;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Set the region to contain just the given BRect.
|
||||
\param newBounds A BRect.
|
||||
*/
|
||||
void
|
||||
BRegion::Set(BRect newBounds)
|
||||
{
|
||||
Set(to_clipping_rect(newBounds));
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Set the region to contain just the given clipping_rect.
|
||||
\param newBounds A clipping_rect.
|
||||
*/
|
||||
void
|
||||
BRegion::Set(clipping_rect newBounds)
|
||||
{
|
||||
if (fRegion)
|
||||
fRegion->Set(newBounds);
|
||||
else
|
||||
fRegion = new (nothrow) ClipRegion(newBounds);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Check if the region has any area in common with the given BRect.
|
||||
\param rect The BRect to check the region against to.
|
||||
\return \ctrue if the region has any area in common with the BRect, \cfalse if not.
|
||||
*/
|
||||
bool
|
||||
BRegion::Intersects(BRect rect) const
|
||||
{
|
||||
return fRegion ? fRegion->Intersects(to_clipping_rect(rect)) : false;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Check if the region has any area in common with the given clipping_rect.
|
||||
\param rect The clipping_rect to check the region against to.
|
||||
\return \ctrue if the region has any area in common with the clipping_rect, \cfalse if not.
|
||||
*/
|
||||
bool
|
||||
BRegion::Intersects(clipping_rect rect) const
|
||||
{
|
||||
return fRegion ? fRegion->Intersects(rect) : false;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Check if the region contains the given BPoint.
|
||||
\param pt The BPoint to be checked.
|
||||
\return \ctrue if the region contains the BPoint, \cfalse if not.
|
||||
*/
|
||||
bool
|
||||
BRegion::Contains(BPoint pt) const
|
||||
{
|
||||
return fRegion ? fRegion->Contains(pt) : false;
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Check if the region contains the given coordinates.
|
||||
\param x The \cx coordinate of the point to be checked.
|
||||
\param y The \cy coordinate of the point to be checked.
|
||||
\return \ctrue if the region contains the point, \cfalse if not.
|
||||
*/
|
||||
bool
|
||||
BRegion::Contains(int32 x, int32 y)
|
||||
{
|
||||
if (fRegion == NULL)
|
||||
return false;
|
||||
|
||||
const BPoint pt(x, y);
|
||||
return fRegion->Contains(pt);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Prints the BRegion to stdout.
|
||||
*/
|
||||
void
|
||||
BRegion::PrintToStream() const
|
||||
{
|
||||
if (fRegion == NULL)
|
||||
return;
|
||||
|
||||
Frame().PrintToStream();
|
||||
|
||||
for (int32 c = 0; c < fRegion->CountRects(); c++) {
|
||||
clipping_rect rect = fRegion->RectAt(c);
|
||||
printf("data = BRect(l:%ld.0, t:%ld.0, r:%ld.0, b:%ld.0)\n",
|
||||
rect.left, rect.top, rect.right, rect.bottom);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Offsets all region's rects, and bounds by the given values.
|
||||
\param dh The horizontal offset.
|
||||
\param dv The vertical offset.
|
||||
*/
|
||||
void
|
||||
BRegion::OffsetBy(int32 dh, int32 dv)
|
||||
{
|
||||
if (fRegion != NULL)
|
||||
fRegion->OffsetBy(dh, dv);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Empties the region, so that it doesn't include any rect, and invalidates its bounds.
|
||||
*/
|
||||
void
|
||||
BRegion::MakeEmpty()
|
||||
{
|
||||
const clipping_rect invalid = { 0, 0, -1, -1 };
|
||||
Set(invalid);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Modifies the region, so that it includes the given BRect.
|
||||
\param rect The BRect to be included by the region.
|
||||
*/
|
||||
void
|
||||
BRegion::Include(BRect rect)
|
||||
{
|
||||
Include(to_clipping_rect(rect));
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Modifies the region, so that it includes the given clipping_rect.
|
||||
\param rect The clipping_rect to be included by the region.
|
||||
*/
|
||||
void
|
||||
BRegion::Include(clipping_rect rect)
|
||||
{
|
||||
if (fRegion != NULL)
|
||||
fRegion->Include(rect);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Modifies the region, so that it includes the area of the given region.
|
||||
\param region The region to be included.
|
||||
*/
|
||||
void
|
||||
BRegion::Include(const BRegion *region)
|
||||
{
|
||||
if (fRegion != NULL)
|
||||
fRegion->Include(*region->fRegion);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Modifies the region, excluding the area represented by the given BRect.
|
||||
\param rect The BRect to be excluded.
|
||||
*/
|
||||
void
|
||||
BRegion::Exclude(BRect rect)
|
||||
{
|
||||
if (fRegion)
|
||||
fRegion->Exclude(to_clipping_rect(rect));
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Modifies the region, excluding the area represented by the given clipping_rect.
|
||||
\param rect The clipping_rect to be excluded.
|
||||
*/
|
||||
void
|
||||
BRegion::Exclude(clipping_rect rect)
|
||||
{
|
||||
if (fRegion)
|
||||
fRegion->Exclude(rect);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Modifies the region, excluding the area contained in the given BRegion.
|
||||
\param region The BRegion to be excluded.
|
||||
*/
|
||||
void
|
||||
BRegion::Exclude(const BRegion *region)
|
||||
{
|
||||
if (fRegion)
|
||||
fRegion->Exclude(*region->fRegion);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Modifies the region, so that it will contain just the area in common with the given BRegion.
|
||||
\param region the BRegion to intersect to.
|
||||
*/
|
||||
void
|
||||
BRegion::IntersectWith(const BRegion *region)
|
||||
{
|
||||
if (fRegion)
|
||||
fRegion->IntersectWith(*region->fRegion);
|
||||
}
|
||||
|
||||
|
||||
/*! \brief Modifies the region to be a copy of the given BRegion.
|
||||
\param region the BRegion to copy.
|
||||
\return This function always returns \c *this.
|
||||
*/
|
||||
BRegion &
|
||||
BRegion::operator=(const BRegion ®ion)
|
||||
{
|
||||
if (®ion != this) {
|
||||
delete fRegion;
|
||||
fRegion = new (nothrow) ClipRegion(*region.fRegion);
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
@ -1,75 +0,0 @@
|
||||
/*******************************************************************************
|
||||
/
|
||||
/ File: Region.h
|
||||
/
|
||||
/ Description: BRegion represents an area that's composed of individual
|
||||
/ rectangles.
|
||||
/
|
||||
/ Copyright 1992-98, Be Incorporated, All Rights Reserved
|
||||
/
|
||||
*******************************************************************************/
|
||||
|
||||
#ifndef _REGION_H
|
||||
#define _REGION_H
|
||||
|
||||
#include <BeBuild.h>
|
||||
#include <Rect.h>
|
||||
|
||||
|
||||
/* Integer rect used to define a cliping rectangle. All bounds are included */
|
||||
/* Moved from DirectWindow.h */
|
||||
typedef struct {
|
||||
int32 left;
|
||||
int32 top;
|
||||
int32 right;
|
||||
int32 bottom;
|
||||
} clipping_rect;
|
||||
|
||||
namespace BPrivate {
|
||||
class ServerLink;
|
||||
};
|
||||
|
||||
/*----- BRegion class --------------------------------------------*/
|
||||
class ClipRegion;
|
||||
class BDirectWindow;
|
||||
class BRegion {
|
||||
public:
|
||||
BRegion();
|
||||
BRegion(const BRegion ®ion);
|
||||
BRegion(const BRect rect);
|
||||
virtual ~BRegion();
|
||||
|
||||
BRegion &operator=(const BRegion &from);
|
||||
|
||||
BRect Frame() const;
|
||||
clipping_rect FrameInt() const;
|
||||
BRect RectAt(int32 index);
|
||||
clipping_rect RectAtInt(int32 index);
|
||||
int32 CountRects();
|
||||
void Set(BRect newBounds);
|
||||
void Set(clipping_rect newBounds);
|
||||
bool Intersects(BRect r) const;
|
||||
bool Intersects(clipping_rect r) const;
|
||||
bool Contains(BPoint pt) const;
|
||||
bool Contains(int32 x, int32 y);
|
||||
void PrintToStream() const;
|
||||
void OffsetBy(int32 dh, int32 dv);
|
||||
void MakeEmpty();
|
||||
void Include(BRect r);
|
||||
void Include(clipping_rect r);
|
||||
void Include(const BRegion*);
|
||||
void Exclude(BRect r);
|
||||
void Exclude(clipping_rect r);
|
||||
void Exclude(const BRegion*);
|
||||
void IntersectWith(const BRegion*);
|
||||
|
||||
/*----- Private or reserved -----------------------------------------*/
|
||||
private:
|
||||
friend class BPrivate::ServerLink;
|
||||
friend class BDirectWindow;
|
||||
|
||||
ClipRegion *fRegion;
|
||||
char padding[24];
|
||||
};
|
||||
|
||||
#endif /* _REGION_H */
|
@ -1,93 +0,0 @@
|
||||
/*
|
||||
* Copyright 2001-2005, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Pahtz <pahtz@yahoo.com.au>
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
*/
|
||||
|
||||
/** Class for low-overhead port-based messaging */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <new>
|
||||
#include <Region.h>
|
||||
#include <Shape.h>
|
||||
|
||||
#include <ClipRegion.h>
|
||||
#include <ServerLink.h>
|
||||
#include <ServerProtocol.h>
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
ServerLink::ServerLink()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ServerLink::~ServerLink()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ServerLink::ReadRegion(BRegion *region)
|
||||
{
|
||||
return region->fRegion->ReadFromLink(*this);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ServerLink::AttachRegion(const BRegion ®ion)
|
||||
{
|
||||
return region.fRegion->WriteToLink(*this);
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ServerLink::ReadShape(BShape *shape)
|
||||
{
|
||||
int32 opCount, ptCount;
|
||||
fReceiver->Read(&opCount, sizeof(int32));
|
||||
fReceiver->Read(&ptCount, sizeof(int32));
|
||||
|
||||
uint32 opList[opCount];
|
||||
fReceiver->Read(opList, opCount * sizeof(uint32));
|
||||
|
||||
BPoint ptList[ptCount];
|
||||
fReceiver->Read(ptList, ptCount * sizeof(BPoint));
|
||||
|
||||
shape->SetData(opCount, ptCount, opList, ptList);
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ServerLink::AttachShape(BShape &shape)
|
||||
{
|
||||
int32 opCount, ptCount;
|
||||
uint32 *opList;
|
||||
BPoint *ptList;
|
||||
|
||||
shape.GetData(&opCount, &ptCount, &opList, &ptList);
|
||||
|
||||
fSender->Attach(&opCount, sizeof(int32));
|
||||
fSender->Attach(&ptCount, sizeof(int32));
|
||||
fSender->Attach(opList, opCount * sizeof(uint32));
|
||||
return fSender->Attach(ptList, ptCount * sizeof(BPoint));
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
ServerLink::FlushWithReply(int32 &code)
|
||||
{
|
||||
status_t status = Flush(B_INFINITE_TIMEOUT, true);
|
||||
if (status < B_OK)
|
||||
return status;
|
||||
|
||||
return GetNextMessage(code);
|
||||
}
|
||||
|
||||
} // namespace BPrivate
|
@ -1,180 +0,0 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// Copyright (c) 2001-2004, Haiku, Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||
// copy of this software and associated documentation files (the "Software"),
|
||||
// to deal in the Software without restriction, including without limitation
|
||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
// and/or sell copies of the Software, and to permit persons to whom the
|
||||
// Software is furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
// File Name: clipping.h
|
||||
// Author: Stefano Ceccherini (burton666@libero.it)
|
||||
// Description: Helper methods to manipulate clipping_rects
|
||||
//------------------------------------------------------------------------------
|
||||
#ifndef __CLIPPING_H
|
||||
#define __CLIPPING_H
|
||||
|
||||
#include <Region.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
|
||||
/* Some methods to manipulate clipping_rects.
|
||||
basically you can do almost everything you do with
|
||||
BRects, just that clipping_rects can only have integer
|
||||
coordinates (a thing that makes these perfect for drawing
|
||||
calculations).
|
||||
*/
|
||||
|
||||
|
||||
// Returns the union of the given rects.
|
||||
static inline clipping_rect
|
||||
union_rect(const clipping_rect &r1, const clipping_rect &r2)
|
||||
{
|
||||
clipping_rect rect;
|
||||
|
||||
rect.left = min_c(r1.left, r2.left);
|
||||
rect.top = min_c(r1.top, r2.top);
|
||||
rect.right = max_c(r1.right, r2.right);
|
||||
rect.bottom = max_c(r1.bottom, r2.bottom);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
||||
// Returns the intersection of the given rects.
|
||||
// The caller should check if the returned rect is valid. If it isn't valid,
|
||||
// then the two rectangles don't intersect.
|
||||
static inline clipping_rect
|
||||
sect_rect(const clipping_rect &r1, const clipping_rect &r2)
|
||||
{
|
||||
clipping_rect rect;
|
||||
|
||||
rect.left = max_c(r1.left, r2.left);
|
||||
rect.top = max_c(r1.top, r2.top);
|
||||
rect.right = min_c(r1.right, r2.right);
|
||||
rect.bottom = min_c(r1.bottom, r2.bottom);
|
||||
|
||||
return rect;
|
||||
}
|
||||
|
||||
|
||||
// Adds the given offsets to the given rect.
|
||||
static inline void
|
||||
offset_rect(clipping_rect &rect, int32 x, int32 y)
|
||||
{
|
||||
rect.left += x;
|
||||
rect.top += y;
|
||||
rect.right += x;
|
||||
rect.bottom += y;
|
||||
}
|
||||
|
||||
|
||||
// Converts the given clipping_rect to a BRect
|
||||
static inline BRect
|
||||
to_BRect(const clipping_rect &rect)
|
||||
{
|
||||
return BRect((float)rect.left, (float)rect.top, (float)rect.right, (float)rect.bottom);
|
||||
}
|
||||
|
||||
|
||||
// Converts the given BRect to a clipping_rect.
|
||||
static inline clipping_rect
|
||||
to_clipping_rect(const BRect &rect)
|
||||
{
|
||||
clipping_rect clipRect;
|
||||
|
||||
clipRect.left = (int32)floor(rect.left);
|
||||
clipRect.top = (int32)floor(rect.top);
|
||||
clipRect.right = (int32)ceil(rect.right);
|
||||
clipRect.bottom = (int32)ceil(rect.bottom);
|
||||
|
||||
return clipRect;
|
||||
}
|
||||
|
||||
|
||||
// Checks if the given point lies in the given rect's area
|
||||
static inline bool
|
||||
point_in(const clipping_rect &rect, int32 px, int32 py)
|
||||
{
|
||||
if (px >= rect.left && px <= rect.right
|
||||
&& py >= rect.top && py <= rect.bottom)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Same as above, but it accepts a BPoint parameter
|
||||
static inline bool
|
||||
point_in(const clipping_rect &rect, const BPoint &pt)
|
||||
{
|
||||
if (pt.x >= rect.left && pt.x <= rect.right
|
||||
&& pt.y >= rect.top && pt.y <= rect.bottom)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static inline bool
|
||||
rect_contains(const clipping_rect &rect, const clipping_rect &testRect)
|
||||
{
|
||||
return rect.top <= testRect.top && rect.bottom >= testRect.bottom
|
||||
&& rect.left <= testRect.left && rect.right >= testRect.right;
|
||||
}
|
||||
|
||||
|
||||
// Checks if the rect is valid
|
||||
static inline bool
|
||||
valid_rect(const clipping_rect &rect)
|
||||
{
|
||||
if (rect.left <= rect.right && rect.top <= rect.bottom)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Checks if the two rects intersect.
|
||||
static inline bool
|
||||
rects_intersect(const clipping_rect &rectA, const clipping_rect &rectB)
|
||||
{
|
||||
// We behave like BRect::Intersects() does:
|
||||
// we return false if one of the two rects is not valid
|
||||
if (!valid_rect(rectA) || !valid_rect(rectB))
|
||||
return false;
|
||||
|
||||
// TODO: Is there a better algorithm ?
|
||||
// the one we used is faster than
|
||||
// ' return valid_rect(sect_rect(rectA, rectB)); ', though.
|
||||
|
||||
return !(rectA.left > rectB.right || rectA.top > rectB.bottom
|
||||
|| rectA.right < rectB.left || rectA.bottom < rectB.top);
|
||||
}
|
||||
|
||||
|
||||
// Returns the width of the given rect.
|
||||
static inline int32
|
||||
rect_width(const clipping_rect &rect)
|
||||
{
|
||||
return rect.right - rect.left;
|
||||
}
|
||||
|
||||
|
||||
// Returns the height of the given rect.
|
||||
static inline int32
|
||||
rect_height(const clipping_rect &rect)
|
||||
{
|
||||
return rect.bottom - rect.top;
|
||||
}
|
||||
|
||||
#endif // __CLIPPING_H
|
@ -1,25 +0,0 @@
|
||||
#include "clipping.h"
|
||||
#include "Region.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
int main()
|
||||
{
|
||||
BRegion region(BRect(10, 10, 20, 20));
|
||||
|
||||
BRegion other(BRect(15, 15, 50, 19));
|
||||
other.IntersectWith(®ion);
|
||||
//if (region.Intersects(other.Frame()))
|
||||
// printf("Okay!\n");
|
||||
|
||||
|
||||
BRegion c;
|
||||
c.Set(BRect(10, 20, 15, 56));
|
||||
|
||||
other.Include(&c);
|
||||
region.Include(&c);
|
||||
|
||||
region.PrintToStream();
|
||||
other.PrintToStream();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user