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:
Matthias Melcher 2018-03-16 17:39:16 +00:00
parent e0a15603dd
commit b6858cef56
3 changed files with 78 additions and 8 deletions

View File

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

View File

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

View File

@ -544,6 +544,9 @@ void Fl_GDI_Graphics_Driver::set_current_() {
#endif
/*
*/
//
// End of "$Id$".