diff --git a/headers/private/interface/clipping.h b/headers/private/interface/clipping.h index 02d8e797a5..87790a66cb 100644 --- a/headers/private/interface/clipping.h +++ b/headers/private/interface/clipping.h @@ -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 diff --git a/src/kits/interface/Region.cpp b/src/kits/interface/Region.cpp index 3e6f8f4b86..58e591cd9d 100644 --- a/src/kits/interface/Region.cpp +++ b/src/kits/interface/Region.cpp @@ -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 -#include +#include // System Includes ------------------------------------------------------------- #include @@ -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(region), &newRegion); + or_region(this, const_cast(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(region), &newRegion); + sub_region(this, const_cast(region), &newRegion); copy_region(&newRegion, this); } @@ -384,7 +400,7 @@ BRegion::IntersectWith(const BRegion *region) { BRegion newRegion; - and_region(this, const_cast(region), &newRegion); + and_region(this, const_cast(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"); diff --git a/src/kits/interface/region_helpers.cpp b/src/kits/interface/region_helpers.cpp index fb1322c216..5d9b662ce2 100644 --- a/src/kits/interface/region_helpers.cpp +++ b/src/kits/interface/region_helpers.cpp @@ -1,8 +1,10 @@ -#include +#include + #include #include #include + #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 diff --git a/src/kits/interface/region_helpers.h b/src/kits/interface/region_helpers.h index c67090e26c..8d6e821a29 100644 --- a/src/kits/interface/region_helpers.h +++ b/src/kits/interface/region_helpers.h @@ -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*);