diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2018-03-18 14:58:25 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2018-03-18 14:58:25 +0000 |
| commit | d252801a319deb371bba3bdf1adb760f50514ac9 (patch) | |
| tree | 018b0ef0669bf95c8245e4077aee0c1e4fc2759a /src/drivers/Android/Fl_Android_Graphics_Clipping.cxx | |
| parent | 5900d824e93be44a852741ca093d88023e2a516a (diff) | |
Android: Fixed another bug when deleting complex clipping areas
Better complex region cleanup - should be compete now...
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12772 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/drivers/Android/Fl_Android_Graphics_Clipping.cxx')
| -rw-r--r-- | src/drivers/Android/Fl_Android_Graphics_Clipping.cxx | 112 |
1 files changed, 52 insertions, 60 deletions
diff --git a/src/drivers/Android/Fl_Android_Graphics_Clipping.cxx b/src/drivers/Android/Fl_Android_Graphics_Clipping.cxx index 1ea7cdb08..f25f61976 100644 --- a/src/drivers/Android/Fl_Android_Graphics_Clipping.cxx +++ b/src/drivers/Android/Fl_Android_Graphics_Clipping.cxx @@ -213,13 +213,26 @@ Fl_Complex_Region::Fl_Complex_Region(const Fl_Rect_Region &r) : */ Fl_Complex_Region::~Fl_Complex_Region() { + delete_all_subregions(); +} + +/** + * Delete all subregions of this region. + * The pSubregion pointer should always be seen as a list of subregions, rather + * than a single region and some pNext pointer. So everything we do, we should + * probably do for every object in that list. + * + * Also note, that the top level region never has pNext pointing to anything. + */ +void Fl_Complex_Region::delete_all_subregions() +{ // Do NOT delete the chain in pNext! The caller has to that job. // A top-level coplex region has pNext always set to NULL, and it does // delete all subregions chained via the subregion pNext. while (pSubregion) { Fl_Complex_Region *rgn = pSubregion; pSubregion = rgn->pNext; - delete rgn; + delete rgn; rgn = 0; } } @@ -256,7 +269,7 @@ void Fl_Complex_Region::print_data(int indent) const void Fl_Complex_Region::set(const Fl_Rect_Region &r) { Fl_Rect_Region::set(r); - delete pSubregion; pSubregion = 0; + delete_all_subregions(); } /** @@ -266,17 +279,21 @@ void Fl_Complex_Region::set(const Fl_Rect_Region &r) */ void Fl_Complex_Region::set(const Fl_Complex_Region &r) { - // outline: - // clear this region and copy the coordinates from r - delete pSubregion; pSubregion = 0; Fl_Rect_Region::set((const Fl_Rect_Region&)r); - if (r.pSubregion) { - pSubregion = new Fl_Complex_Region(); - pSubregion->set(*r.subregion()); - } - if (r.pNext) { - pNext = new Fl_Complex_Region(); - pNext->set(*r.next()); + delete_all_subregions(); + + Fl_Complex_Region *srcRgn = r.pSubregion; + if (srcRgn) { + // copy first subregion + Fl_Complex_Region *dstRgn = pSubregion = new Fl_Complex_Region(); + pSubregion->set(*srcRgn); + // copy rest of list + while (srcRgn) { + dstRgn->pNext = new Fl_Complex_Region(); + dstRgn = dstRgn->next(); + dstRgn->set(*srcRgn); + srcRgn = srcRgn->next(); + } } } @@ -288,28 +305,15 @@ void Fl_Complex_Region::set(const Fl_Complex_Region &r) int Fl_Complex_Region::intersect_with(const Fl_Rect_Region &r) { if (pSubregion) { - pSubregion->intersect_with(r); - } else { - int intersects = Fl_Rect_Region::intersect_with(r); - switch (intersects) { - case EMPTY: - // Will be deleted by compress() - break; - case SAME: - // nothing to do - break; - case LESS: - // nothing to do - break; - default: - Fl_Android_Application::log_e("Invalid case in %s:%d", __FUNCTION__, __LINE__); - break; - } - if (pNext) { - pNext->intersect_with(r); + Fl_Complex_Region *rgn = pSubregion; + while (rgn) { + rgn->intersect_with(r); + rgn = rgn->next(); } + compress(); + } else { + Fl_Rect_Region::intersect_with(r); } - compress(); return 0; } @@ -321,7 +325,12 @@ int Fl_Complex_Region::intersect_with(const Fl_Rect_Region &r) int Fl_Complex_Region::subtract(const Fl_Rect_Region &r) { if (pSubregion) { - pSubregion->subtract(r); + Fl_Complex_Region *rgn = pSubregion; + while (rgn) { + rgn->subtract(r); + rgn = rgn->next(); + } + compress(); } else { // Check if we overlap at all Fl_Rect_Region s(r); @@ -341,11 +350,8 @@ int Fl_Complex_Region::subtract(const Fl_Rect_Region &r) Fl_Android_Application::log_e("Invalid case in %s:%d", __FUNCTION__, __LINE__); break; } - if (pNext) { - pNext->subtract(r); - } + if (pSubregion) compress(); // because intersecting this may have created subregions } - compress(); return 0; } @@ -365,41 +371,27 @@ void Fl_Complex_Region::compress() Fl_Complex_Region *rgn = pSubregion; while (rgn && rgn->is_empty()) { pSubregion = rgn->next(); - delete rgn; - rgn = pSubregion; - } - - -#if 0 - // FIXME: remove emty rectangles and lift single rectangles - // TODO: merging rectangles may take much too much time with little benefit - print("compress"); - while (rgn && rgn->is_empty()) { - pSubregion = rgn->next(); - delete rgn; - rgn = pSubregion; + delete rgn; rgn = pSubregion; } if (!pSubregion) return; + rgn = pSubregion; while (rgn) { - Fl_Complex_Region *nextRgn = rgn->next(); - if (nextRgn && nextRgn->is_empty()) { - rgn->pNext = nextRgn->next(); - delete nextRgn; - nextRgn = rgn->pNext; + while (rgn->pNext && rgn->pNext->is_empty()) { + Fl_Complex_Region *nextNext = rgn->pNext->pNext; + delete rgn->pNext; rgn->pNext = nextNext; } rgn = rgn->next(); } - if (!pSubregion) return; // find rectangles that can be merged into a single new rectangle + // (Too much work for much too little benefit) // 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; -#endif // finally, update the boudning box Fl_Rect_Region::set((Fl_Rect_Region&)*pSubregion); @@ -484,7 +476,7 @@ Fl_Complex_Region::Iterator Fl_Complex_Region::begin() */ Fl_Complex_Region::Iterator Fl_Complex_Region::end() { - return Iterator(0L); + return Iterator(nullptr); } /** @@ -574,7 +566,7 @@ Fl_Complex_Region::Overlapping::OverlappingIterator Fl_Complex_Region::Overlappi */ Fl_Complex_Region::Overlapping::OverlappingIterator Fl_Complex_Region::Overlapping::end() { - return OverlappingIterator(0L); + return OverlappingIterator(nullptr); } /** @@ -630,7 +622,7 @@ bool Fl_Complex_Region::Overlapping::find_next() } else { pRegion = pRegion->parent(); // can be NULL } - return (pRegion != 0L); + return (pRegion != nullptr); } // ----------------------------------------------------------------------------- |
