Fixed a bug in BRegion copy constructor. If one constructed a BRegion with
BRegion region(region), the region would have been put into an unitialized state. Took the chance to cleanup a bit the code, using some methods of clipping.h. Changed the way offset_rect works, and changed its name too. Added a note to Region.cpp git-svn-id: file:///srv/svn/repos/haiku/trunk/current@4512 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
e4bd4b6b58
commit
8d1a0ee7c1
@ -42,6 +42,15 @@ sect_rect(clipping_rect r1, clipping_rect r2)
|
||||
return 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;
|
||||
}
|
||||
|
||||
|
||||
static inline BRect
|
||||
to_BRect(clipping_rect rect)
|
||||
@ -113,18 +122,4 @@ rect_height(clipping_rect rect)
|
||||
return rect.bottom - rect.top;
|
||||
}
|
||||
|
||||
|
||||
static inline clipping_rect
|
||||
rect_offset(clipping_rect rect, int32 x, int32 y)
|
||||
{
|
||||
clipping_rect offRect;
|
||||
|
||||
offRect.left = rect.left + x;
|
||||
offRect.top = rect.top + y;
|
||||
offRect.right = rect.right + x;
|
||||
offRect.bottom = rect.bottom + y;
|
||||
|
||||
return offRect;
|
||||
}
|
||||
|
||||
#endif // __CLIPPING_H
|
||||
|
@ -25,10 +25,22 @@
|
||||
//
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Notes: As now, memory is always allocated and never freed (except on destruction).
|
||||
// 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.
|
||||
|
||||
|
||||
// Standard Includes -----------------------------------------------------------
|
||||
#include <cstdlib>
|
||||
#include <string.h>
|
||||
#include <cstring>
|
||||
|
||||
// System Includes -------------------------------------------------------------
|
||||
#include <Debug.h>
|
||||
@ -38,14 +50,16 @@
|
||||
|
||||
#include "region_helpers.h"
|
||||
|
||||
|
||||
/*! \brief Initializes a region. The region will have no rects,
|
||||
and its bound will be invalid.
|
||||
*/
|
||||
BRegion::BRegion()
|
||||
:data_size(8),
|
||||
:
|
||||
data_size(8),
|
||||
data(NULL)
|
||||
{
|
||||
data = (clipping_rect*)malloc(data_size * sizeof(clipping_rect));
|
||||
data = (clipping_rect *)malloc(data_size * sizeof(clipping_rect));
|
||||
|
||||
zero_region(this);
|
||||
}
|
||||
@ -55,7 +69,9 @@ BRegion::BRegion()
|
||||
\param region The region to copy.
|
||||
*/
|
||||
BRegion::BRegion(const BRegion ®ion)
|
||||
:data(NULL)
|
||||
:
|
||||
data_size(8),
|
||||
data(NULL)
|
||||
{
|
||||
if (®ion != this) {
|
||||
bound = region.bound;
|
||||
@ -65,9 +81,13 @@ BRegion::BRegion(const BRegion ®ion)
|
||||
if (data_size <= 0)
|
||||
data_size = 1;
|
||||
|
||||
data = (clipping_rect*)malloc(data_size * sizeof(clipping_rect));
|
||||
data = (clipping_rect *)malloc(data_size * sizeof(clipping_rect));
|
||||
|
||||
memcpy(data, region.data, count * sizeof(clipping_rect));
|
||||
} else {
|
||||
|
||||
data = (clipping_rect *)malloc(data_size * sizeof(clipping_rect));
|
||||
zero_region(this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -76,10 +96,11 @@ BRegion::BRegion(const BRegion ®ion)
|
||||
\param rect The BRect to set the region to.
|
||||
*/
|
||||
BRegion::BRegion(const BRect rect)
|
||||
:data_size(8),
|
||||
:
|
||||
data_size(8),
|
||||
data(NULL)
|
||||
{
|
||||
data = (clipping_rect*)malloc(data_size * sizeof(clipping_rect));
|
||||
data = (clipping_rect *)malloc(data_size * sizeof(clipping_rect));
|
||||
|
||||
Set(rect);
|
||||
}
|
||||
@ -201,11 +222,11 @@ BRegion::Intersects(BRect rect) const
|
||||
bool
|
||||
BRegion::Intersects(clipping_rect rect) const
|
||||
{
|
||||
if (!valid_rect(sect_rect(rect, bound)))
|
||||
if (!rects_intersect(rect, bound))
|
||||
return false;
|
||||
|
||||
for (long c = 0; c < count; c++) {
|
||||
if (valid_rect(sect_rect(data[c], rect)))
|
||||
if (rects_intersect(data[c], rect))
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -276,16 +297,10 @@ void
|
||||
BRegion::OffsetBy(int32 dh, int32 dv)
|
||||
{
|
||||
if (count > 0) {
|
||||
for (long c = 0; c < count; c++) {
|
||||
data[c].left += dh;
|
||||
data[c].right += dh;
|
||||
data[c].top += dv;
|
||||
data[c].bottom += dv;
|
||||
}
|
||||
bound.left += dh;
|
||||
bound.right += dh;
|
||||
bound.top += dv;
|
||||
bound.bottom += dv;
|
||||
for (long c = 0; c < count; c++)
|
||||
offset_rect(data[c], dh, dv);
|
||||
|
||||
offset_rect(bound, dh, dv);
|
||||
}
|
||||
}
|
||||
|
||||
@ -333,7 +348,7 @@ BRegion::Include(const BRegion *region)
|
||||
{
|
||||
BRegion newRegion;
|
||||
|
||||
or_region(this, const_cast<BRegion*>(region), &newRegion);
|
||||
or_region(this, const_cast<BRegion *>(region), &newRegion);
|
||||
copy_region(&newRegion, this);
|
||||
}
|
||||
|
||||
@ -358,6 +373,7 @@ BRegion::Exclude(clipping_rect rect)
|
||||
BRegion newRegion;
|
||||
|
||||
region.Set(rect);
|
||||
|
||||
sub_region(this, ®ion, &newRegion);
|
||||
copy_region(&newRegion, this);
|
||||
}
|
||||
@ -371,7 +387,7 @@ BRegion::Exclude(const BRegion *region)
|
||||
{
|
||||
BRegion newRegion;
|
||||
|
||||
sub_region(this, const_cast<BRegion*>(region), &newRegion);
|
||||
sub_region(this, const_cast<BRegion *>(region), &newRegion);
|
||||
copy_region(&newRegion, this);
|
||||
}
|
||||
|
||||
@ -384,7 +400,7 @@ BRegion::IntersectWith(const BRegion *region)
|
||||
{
|
||||
BRegion newRegion;
|
||||
|
||||
and_region(this, const_cast<BRegion*>(region), &newRegion);
|
||||
and_region(this, const_cast<BRegion *>(region), &newRegion);
|
||||
copy_region(&newRegion, this);
|
||||
}
|
||||
|
||||
@ -405,7 +421,7 @@ BRegion::operator=(const BRegion ®ion)
|
||||
if (data_size <= 0)
|
||||
data_size = 1;
|
||||
|
||||
data = (clipping_rect*)malloc(data_size * sizeof(clipping_rect));
|
||||
data = (clipping_rect *)malloc(data_size * sizeof(clipping_rect));
|
||||
|
||||
memcpy(data, region.data, count * sizeof(clipping_rect));
|
||||
}
|
||||
@ -423,46 +439,43 @@ BRegion::operator=(const BRegion ®ion)
|
||||
void
|
||||
BRegion::_AddRect(clipping_rect rect)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
ASSERT(count >= 0);
|
||||
ASSERT(data_size >= 0);
|
||||
|
||||
// Should we just reallocate the memory and
|
||||
// copy the rect ?
|
||||
bool add = false;
|
||||
bool addRect = true;
|
||||
|
||||
if (count <= 0)
|
||||
// Yeah, we don't have any rect here..
|
||||
add = true;
|
||||
else {
|
||||
// Wait! We could merge "rect" with one of the
|
||||
// existing rectangles...
|
||||
if (count > 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.
|
||||
long last = count - 1;
|
||||
if (rect.top == data[last].bottom + 1
|
||||
&& rect.left == data[last].left
|
||||
&& rect.right == data[last].right) {
|
||||
if (rect.left == data[last].left && rect.right == data[last].right
|
||||
&& rect.top == data[last].bottom + 1) {
|
||||
|
||||
data[last].bottom = rect.bottom;
|
||||
addRect = false;
|
||||
|
||||
} else if (rect.top == data[last].top && rect.bottom == data[last].bottom) {
|
||||
|
||||
if (rect.left == data[last].right + 1)
|
||||
} else if (rect.top == data[last].top && rect.bottom == data[last].bottom) {
|
||||
if (rect.left == data[last].right + 1) {
|
||||
|
||||
data[last].right = rect.right;
|
||||
|
||||
else if (rect.right == data[last].left - 1)
|
||||
addRect = false;
|
||||
|
||||
} else if (rect.right == data[last].left - 1) {
|
||||
|
||||
data[last].left = rect.left;
|
||||
|
||||
else
|
||||
add = true; //no luck... just add the rect
|
||||
|
||||
} else
|
||||
add = true; //just add the rect
|
||||
addRect = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We weren't lucky.... just add the rect as a new one
|
||||
if (add) {
|
||||
if (addRect) {
|
||||
if (data_size <= count)
|
||||
set_size(data_size + 16);
|
||||
set_size(count + 16);
|
||||
|
||||
data[count] = rect;
|
||||
|
||||
@ -470,16 +483,16 @@ BRegion::_AddRect(clipping_rect rect)
|
||||
}
|
||||
|
||||
// Recalculate bounds
|
||||
if (rect.top <= bound.top)
|
||||
if (rect.top < bound.top)
|
||||
bound.top = rect.top;
|
||||
|
||||
if (rect.left <= bound.left)
|
||||
if (rect.left < bound.left)
|
||||
bound.left = rect.left;
|
||||
|
||||
if (rect.right >= bound.right)
|
||||
if (rect.right > bound.right)
|
||||
bound.right = rect.right;
|
||||
|
||||
if (rect.bottom >= bound.bottom)
|
||||
if (rect.bottom > bound.bottom)
|
||||
bound.bottom = rect.bottom;
|
||||
}
|
||||
|
||||
@ -493,7 +506,7 @@ BRegion::set_size(long new_size)
|
||||
if (new_size <= 0)
|
||||
new_size = data_size + 16;
|
||||
|
||||
data = (clipping_rect*)realloc(data, new_size * sizeof(clipping_rect));
|
||||
data = (clipping_rect *)realloc(data, new_size * sizeof(clipping_rect));
|
||||
|
||||
if (data == NULL)
|
||||
debugger("BRegion::set_size realloc error\n");
|
||||
|
@ -1,8 +1,10 @@
|
||||
#include <string.h>
|
||||
#include <cstring>
|
||||
|
||||
#include <Debug.h>
|
||||
#include <Region.h>
|
||||
|
||||
#include <clipping.h>
|
||||
|
||||
#include "region_helpers.h"
|
||||
|
||||
static const int32 kMaxPoints = 1024;
|
||||
@ -17,8 +19,6 @@ static const int32 kMaxVerticalExtent = 0x10000000;
|
||||
void
|
||||
zero_region(BRegion *region)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
|
||||
region->count = 0;
|
||||
region->bound.left = 0x7ffffffd;
|
||||
region->bound.top = 0x7ffffffd;
|
||||
@ -30,7 +30,6 @@ zero_region(BRegion *region)
|
||||
void
|
||||
clear_region(BRegion *region)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
region->count = 0;
|
||||
region->bound.left = 0xfffffff;
|
||||
region->bound.top = 0xfffffff;
|
||||
@ -45,8 +44,6 @@ clear_region(BRegion *region)
|
||||
void
|
||||
cleanup_region_1(BRegion *region)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
|
||||
clipping_rect testRect =
|
||||
{
|
||||
1, 1,
|
||||
@ -85,7 +82,6 @@ cleanup_region_1(BRegion *region)
|
||||
void
|
||||
cleanup_region(BRegion *region)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
long oldCount;
|
||||
|
||||
do {
|
||||
@ -102,7 +98,6 @@ cleanup_region(BRegion *region)
|
||||
void
|
||||
sort_rects(clipping_rect *rects, long count)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
bool again; //flag that tells we changed rects positions
|
||||
|
||||
if (count == 2) {
|
||||
@ -130,7 +125,6 @@ sort_rects(clipping_rect *rects, long count)
|
||||
void
|
||||
sort_trans(long *lptr1, long *lptr2, long count)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
bool again; //flag that tells we changed trans positions
|
||||
|
||||
if (count == 2) {
|
||||
@ -169,8 +163,6 @@ sort_trans(long *lptr1, long *lptr2, long count)
|
||||
void
|
||||
cleanup_region_horizontal(BRegion *region)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
|
||||
clipping_rect testRect =
|
||||
{
|
||||
1, 1,
|
||||
@ -204,7 +196,6 @@ cleanup_region_horizontal(BRegion *region)
|
||||
void
|
||||
copy_region(BRegion *source, BRegion *dest)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
ASSERT(source);
|
||||
ASSERT(dest);
|
||||
ASSERT(source != dest);
|
||||
@ -213,7 +204,7 @@ copy_region(BRegion *source, BRegion *dest)
|
||||
if (dest->data_size < source->count) {
|
||||
free(dest->data);
|
||||
dest->data_size = source->count + 8;
|
||||
dest->data = (clipping_rect*)malloc(dest->data_size * sizeof(clipping_rect));
|
||||
dest->data = (clipping_rect *)malloc(dest->data_size * sizeof(clipping_rect));
|
||||
}
|
||||
|
||||
dest->count = source->count;
|
||||
@ -232,7 +223,6 @@ copy_region(BRegion *source, BRegion *dest)
|
||||
void
|
||||
copy_region_n(BRegion *source, BRegion *dest, long count)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
ASSERT(source);
|
||||
ASSERT(dest);
|
||||
ASSERT(source != dest);
|
||||
@ -241,7 +231,7 @@ copy_region_n(BRegion *source, BRegion *dest, long count)
|
||||
if (dest->data_size < source->count) {
|
||||
free(dest->data);
|
||||
dest->data_size = source->count + count;
|
||||
dest->data = (clipping_rect*)malloc(dest->data_size * sizeof(clipping_rect));
|
||||
dest->data = (clipping_rect *)malloc(dest->data_size * sizeof(clipping_rect));
|
||||
}
|
||||
|
||||
dest->count = source->count;
|
||||
@ -262,7 +252,6 @@ copy_region_n(BRegion *source, BRegion *dest, long count)
|
||||
void
|
||||
and_region_complex(BRegion *first, BRegion *second, BRegion *dest)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
ASSERT(first);
|
||||
ASSERT(second);
|
||||
ASSERT(dest);
|
||||
@ -292,7 +281,6 @@ and_region_complex(BRegion *first, BRegion *second, BRegion *dest)
|
||||
void
|
||||
and_region_1_to_n(BRegion *first, BRegion *second, BRegion *dest)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
ASSERT(first);
|
||||
ASSERT(second);
|
||||
ASSERT(dest);
|
||||
@ -329,7 +317,6 @@ and_region_1_to_n(BRegion *first, BRegion *second, BRegion *dest)
|
||||
void
|
||||
and_region(BRegion *first, BRegion *second, BRegion *dest)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
ASSERT(first);
|
||||
ASSERT(second);
|
||||
ASSERT(dest);
|
||||
@ -367,7 +354,6 @@ and_region(BRegion *first, BRegion *second, BRegion *dest)
|
||||
void
|
||||
append_region(BRegion *first, BRegion *second, BRegion *dest)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
ASSERT(first);
|
||||
ASSERT(second);
|
||||
ASSERT(dest);
|
||||
@ -382,8 +368,6 @@ append_region(BRegion *first, BRegion *second, BRegion *dest)
|
||||
void
|
||||
r_or(long top, long bottom, BRegion *first, BRegion *second, BRegion *dest, long *indexA, long *indexB)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
|
||||
int32 lefts[kMaxPoints];
|
||||
int32 rights[kMaxPoints];
|
||||
|
||||
@ -469,7 +453,6 @@ r_or(long top, long bottom, BRegion *first, BRegion *second, BRegion *dest, long
|
||||
void
|
||||
or_region_complex(BRegion *first, BRegion *second, BRegion *dest)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
long a = 0, b = 0;
|
||||
|
||||
int32 top;
|
||||
@ -518,7 +501,6 @@ or_region_complex(BRegion *first, BRegion *second, BRegion *dest)
|
||||
void
|
||||
or_region_1_to_n(BRegion *first, BRegion *second, BRegion *dest)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
ASSERT(first);
|
||||
ASSERT(second);
|
||||
ASSERT(dest);
|
||||
@ -546,7 +528,6 @@ or_region_1_to_n(BRegion *first, BRegion *second, BRegion *dest)
|
||||
void
|
||||
or_region_no_x(BRegion *first, BRegion *second, BRegion *dest)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
ASSERT(first);
|
||||
ASSERT(second);
|
||||
ASSERT(dest);
|
||||
@ -600,7 +581,6 @@ or_region_no_x(BRegion *first, BRegion *second, BRegion *dest)
|
||||
void
|
||||
or_region(BRegion *first, BRegion *second, BRegion *dest)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
ASSERT(first);
|
||||
ASSERT(second);
|
||||
ASSERT(dest);
|
||||
@ -652,7 +632,6 @@ or_region(BRegion *first, BRegion *second, BRegion *dest)
|
||||
void
|
||||
sub_region_complex(BRegion *first, BRegion *second, BRegion *dest)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
long a = 0, b = 0;
|
||||
|
||||
int32 top;
|
||||
@ -693,8 +672,6 @@ sub_region_complex(BRegion *first, BRegion *second, BRegion *dest)
|
||||
void
|
||||
r_sub(long top, long bottom, BRegion *first, BRegion *second, BRegion *dest, long *indexA, long *indexB)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
|
||||
int32 leftsA[kMaxPoints / 2];
|
||||
int32 rightsA[kMaxPoints / 2];
|
||||
int32 leftsB[kMaxPoints / 2];
|
||||
@ -802,9 +779,9 @@ r_sub(long top, long bottom, BRegion *first, BRegion *second, BRegion *dest, lon
|
||||
|
||||
} while (f < foundA);
|
||||
|
||||
//Last rect: we take the right coordinate of the last minuend rect
|
||||
//as left coordinate of the rect to intersect, and the maximum possible
|
||||
//value as the right coordinate.
|
||||
// Last rect: we take the right coordinate of the last minuend rect
|
||||
// as left coordinate of the rect to intersect, and the maximum possible
|
||||
// value as the right coordinate.
|
||||
minuendRect.left = rightsA[foundA - 1] + 1;
|
||||
minuendRect.right = 0x7ffffffd;
|
||||
|
||||
@ -837,7 +814,6 @@ r_sub(long top, long bottom, BRegion *first, BRegion *second, BRegion *dest, lon
|
||||
void
|
||||
sub_region(BRegion *first, BRegion *second, BRegion *dest)
|
||||
{
|
||||
PRINT(("%s\n", __PRETTY_FUNCTION__));
|
||||
ASSERT(first);
|
||||
ASSERT(second);
|
||||
ASSERT(dest);
|
||||
@ -845,7 +821,7 @@ sub_region(BRegion *first, BRegion *second, BRegion *dest)
|
||||
if (first->count == 0)
|
||||
zero_region(dest);
|
||||
|
||||
else if (second->count == 0 || !valid_rect(sect_rect(first->bound, second->bound)))
|
||||
else if (second->count == 0 || !rects_intersect(first->bound, second->bound))
|
||||
copy_region(first, dest);
|
||||
|
||||
else
|
||||
|
@ -19,7 +19,6 @@ void or_region_complex(BRegion*, BRegion*, BRegion*);
|
||||
void or_region_1_to_n(BRegion*, BRegion*, BRegion*);
|
||||
void or_region_no_x(BRegion*, BRegion*, BRegion*);
|
||||
void or_region(BRegion*, BRegion*, BRegion*);
|
||||
//void sub(long, long, BRegion*, BRegion*, BRegion*, long*, long*);
|
||||
void sub_region_complex(BRegion*, BRegion*, BRegion*);
|
||||
void r_sub(long , long, BRegion*, BRegion*, BRegion*, long*, long*);
|
||||
void sub_region(BRegion*, BRegion*, BRegion*);
|
||||
|
Loading…
Reference in New Issue
Block a user