Android: added function to optimize complex regions
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12760 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
e0a15603dd
commit
b6858cef56
@ -69,6 +69,7 @@ public:
|
||||
void set_ltrb(int l, int t, int r, int b);
|
||||
virtual void set(const Fl_Rect_Region &r);
|
||||
virtual int intersect_with(const Fl_Rect_Region &r);
|
||||
void add_to_bbox(const Fl_Rect_Region &r);
|
||||
|
||||
virtual void print(const char*) const;
|
||||
|
||||
@ -87,14 +88,29 @@ private:
|
||||
* rectangular, is_simple() returns 1 and the rectangle can be used just
|
||||
* as in Fl_Rect_Region.
|
||||
*
|
||||
* If a more complex representation is needed, the first list of
|
||||
* subregions is organizen in horizontal strips. The root region rect
|
||||
* will contain the outline of all subregions, and the subregions
|
||||
* will either be simple rectangles, or they will contain a second
|
||||
* level of subregions, subdividing the horizontal region into vertical
|
||||
* columns.
|
||||
* If a more complex representation is needed, subregions are created which are
|
||||
* guaranteed to lie within the bounding box of the current region. Subregions
|
||||
* themselves can again contain sub-subregions to describe the entire clipping
|
||||
* region, effectively creating a tree where the leafs contain the rectangles
|
||||
* that together describe the clipping area.
|
||||
*
|
||||
* To make life easier, Fl_Complex_Region provides two types of iterator to
|
||||
* travers the entire tree.
|
||||
*
|
||||
* 1. Fl_Complex_Region itself is compatible to C++11 range-based loops and
|
||||
* can bewalked simply by writing ``for (auto &&it: rgn) { ... }``.
|
||||
*
|
||||
* 2. Fl_Complex_Region provides an alternative iterator that loop only through
|
||||
* leafs that intersects with a given rectangle. The returned object
|
||||
* provides access to the readily clipped rectangle.
|
||||
*
|
||||
* @code
|
||||
* Fl_Complex_Region rgn(something);
|
||||
* for (auto &&it: rgn.iterate(Fl_Rect_Region(0, 0, 100, 100)) {
|
||||
* draw_something(it->rect());
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* When reading, the tree can be easily walked using recursion.
|
||||
*/
|
||||
class Fl_Complex_Region : public Fl_Rect_Region
|
||||
{
|
||||
@ -156,6 +172,7 @@ protected:
|
||||
void print_data(int indent) const;
|
||||
int subtract_smaller_region(const Fl_Rect_Region &r);
|
||||
Fl_Complex_Region *add_subregion();
|
||||
void compress();
|
||||
|
||||
Fl_Complex_Region *pSubregion = 0L;
|
||||
Fl_Complex_Region *pParent = 0L;
|
||||
|
@ -167,6 +167,17 @@ int Fl_Rect_Region::intersect_with(const Fl_Rect_Region &r)
|
||||
return LESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use rectangle as a bounding box and add the outline of another rect.
|
||||
*/
|
||||
void Fl_Rect_Region::add_to_bbox(const Fl_Rect_Region &r)
|
||||
{
|
||||
if (r.pLeft<pLeft) pLeft = r.pLeft;
|
||||
if (r.pTop<pTop) pTop = r.pTop;
|
||||
if (r.pRight>pRight) pRight = r.pRight;
|
||||
if (r.pBottom>pBottom) pBottom = r.pBottom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the coordinates of the rect to the log.
|
||||
* @param label some text that is logged with this message.
|
||||
@ -237,8 +248,8 @@ void Fl_Complex_Region::print_data(int indent) const
|
||||
*/
|
||||
void Fl_Complex_Region::set(const Fl_Rect_Region &r)
|
||||
{
|
||||
delete pSubregion; pSubregion = 0;
|
||||
Fl_Rect_Region::set(r);
|
||||
delete pSubregion; pSubregion = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -307,9 +318,48 @@ int Fl_Complex_Region::subtract(const Fl_Rect_Region &r)
|
||||
pNext->subtract(r);
|
||||
}
|
||||
}
|
||||
compress();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compress the subregion of this region if possible and update the bounding
|
||||
* box of this region.
|
||||
*
|
||||
* Does not recurse down the tree!
|
||||
*/
|
||||
void Fl_Complex_Region::compress()
|
||||
{
|
||||
// Can't compress anything that does not have a subregion
|
||||
if (!pSubregion) return;
|
||||
|
||||
// remove all empty regions, because the really don't add anything (literally)
|
||||
Fl_Complex_Region *rgn = pSubregion, **rgnPtr = &pSubregion;
|
||||
while (rgn) {
|
||||
if (rgn->is_empty()) {
|
||||
*rgnPtr = rgn->pNext;
|
||||
delete rgn;
|
||||
}
|
||||
rgnPtr = &rgn->pNext;
|
||||
rgn = *rgnPtr;
|
||||
}
|
||||
if (!pSubregion) return;
|
||||
|
||||
// find rectangles that can be merged into a single new rectangle
|
||||
|
||||
// if there is only a single subregion left, merge it into this region
|
||||
if (pSubregion->pNext==nullptr) {
|
||||
set((Fl_Rect_Region&)*pSubregion); // deletes subregion for us
|
||||
}
|
||||
if (!pSubregion) return;
|
||||
|
||||
// finally, update the boudning box
|
||||
Fl_Rect_Region::set((Fl_Rect_Region&)*pSubregion);
|
||||
for (rgn=pSubregion->pNext; rgn; rgn=rgn->pNext) {
|
||||
add_to_bbox(*rgn);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Subtract a rect from another rect, potentially creating four new rectangles.
|
||||
* This assumes that the calling region is NOT complex.
|
||||
|
@ -544,6 +544,9 @@ void Fl_GDI_Graphics_Driver::set_current_() {
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
*/
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
|
Loading…
Reference in New Issue
Block a user