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:
Stefano Ceccherini 2007-10-29 10:49:03 +00:00
parent 795a2888e7
commit c20e6cca18
9 changed files with 0 additions and 2171 deletions

View File

@ -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 &region)
:
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 &region)
{
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 &region)
{
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 &region)
{
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 &region)
{
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 &region)
{
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 &region)
{
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 &region)
{
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 &region)
{
/*
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 &region, 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 &region)
{
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;
}

View File

@ -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 &region);
ClipRegion(const BRegion &region);
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 &region) 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 &region);
void Exclude(const clipping_rect &rect);
void Exclude(const BRect &rect);
void Exclude(const ClipRegion &region);
void IntersectWith(const clipping_rect &rect);
void IntersectWith(const BRect &rect);
void IntersectWith(const ClipRegion &region);
void GetRects(clipping_rect **rects, int32 *count);
ClipRegion &operator=(const ClipRegion &region);
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 &region, const bool &aboveThis = false);
void _Append(const clipping_rect *rects, const int32 &count, const bool &aboveThis = false);
void _IntersectWithComplex(const ClipRegion &region);
void _IntersectWith(const clipping_rect &rect);
void _IncludeNoIntersection(const ClipRegion &region);
void _IncludeComplex(const ClipRegion &region);
void _ExcludeComplex(const ClipRegion &region);
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 &region);
};
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

View File

@ -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() {}

View File

@ -1,11 +0,0 @@
SubDir HAIKU_TOP src tests kits interface NewRegion ;
UsePrivateHeaders interface ;
SimpleTest NewRegionTest
: Region.cpp
ClipRegion.cpp
main.cpp
: root be
;

View File

@ -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 &region)
:
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 &region)
{
if (&region != this) {
delete fRegion;
fRegion = new (nothrow) ClipRegion(*region.fRegion);
}
return *this;
}

View File

@ -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 &region);
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 */

View File

@ -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 &region)
{
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

View File

@ -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

View File

@ -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(&region);
//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();
}