summaryrefslogtreecommitdiff
path: root/src/drivers/Android
diff options
context:
space:
mode:
authorMatthias Melcher <fltk@matthiasm.com>2018-03-18 14:58:25 +0000
committerMatthias Melcher <fltk@matthiasm.com>2018-03-18 14:58:25 +0000
commitd252801a319deb371bba3bdf1adb760f50514ac9 (patch)
tree018b0ef0669bf95c8245e4077aee0c1e4fc2759a /src/drivers/Android
parent5900d824e93be44a852741ca093d88023e2a516a (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')
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Clipping.H1
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Clipping.cxx112
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Font.cxx12
-rw-r--r--src/drivers/Android/Fl_Android_Screen_Driver.cxx12
4 files changed, 65 insertions, 72 deletions
diff --git a/src/drivers/Android/Fl_Android_Graphics_Clipping.H b/src/drivers/Android/Fl_Android_Graphics_Clipping.H
index 7f6d43f96..349be87e1 100644
--- a/src/drivers/Android/Fl_Android_Graphics_Clipping.H
+++ b/src/drivers/Android/Fl_Android_Graphics_Clipping.H
@@ -149,6 +149,7 @@ public:
Fl_Complex_Region();
Fl_Complex_Region(const Fl_Rect_Region&);
virtual ~Fl_Complex_Region() override;
+ void delete_all_subregions();
virtual void set(const Fl_Rect_Region &r) override;
void set(const Fl_Complex_Region &r);
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);
}
// -----------------------------------------------------------------------------
diff --git a/src/drivers/Android/Fl_Android_Graphics_Font.cxx b/src/drivers/Android/Fl_Android_Graphics_Font.cxx
index 55136e73e..53021c063 100644
--- a/src/drivers/Android/Fl_Android_Graphics_Font.cxx
+++ b/src/drivers/Android/Fl_Android_Graphics_Font.cxx
@@ -69,7 +69,7 @@ static const char *old_font_names[] = {
* Create an empty Bytemap.
*/
Fl_Android_Bytemap::Fl_Android_Bytemap() :
- pBytes(0L)
+ pBytes(nullptr)
{
}
@@ -90,7 +90,7 @@ Fl_Android_Bytemap::~Fl_Android_Bytemap()
* @param fnum the index into the fl_fonts table
*/
Fl_Android_Font_Source::Fl_Android_Font_Source(const char *fname, Fl_Font fnum) :
- pFileBuffer(0L),
+ pFileBuffer(nullptr),
pName(fname),
pFontIndex(fnum),
pError(false)
@@ -133,7 +133,7 @@ bool Fl_Android_Font_Source::load_font_asset(const char *name)
errno = 0;
AAssetManager *aMgr = Fl_Android_Application::get_asset_manager();
AAsset *aFile = AAssetManager_open(aMgr, name, AASSET_MODE_STREAMING);
- if (aFile == NULL) {
+ if (aFile == nullptr) {
Fl_Android_Application::log_w("Can't open font asset at '%s': ",
name, strerror(errno));
return false;
@@ -173,7 +173,7 @@ bool Fl_Android_Font_Source::load_font_file(const char *name)
strcpy(buf, name);
}
FILE *f = fopen(buf, "rb");
- if (f == NULL) {
+ if (f == nullptr) {
Fl_Android_Application::log_w("Can't open font file at '%s': ",
name, strerror(errno));
return false;
@@ -242,7 +242,7 @@ void Fl_Android_Font_Source::load_font()
Fl_Android_Bytemap *Fl_Android_Font_Source::get_bytemap(uint32_t c, int size)
{
if (pFileBuffer==0) load_font();
- if (pError) return 0L;
+ if (pError) return nullptr;
Fl_Android_Bytemap *bm = new Fl_Android_Bytemap();
@@ -330,7 +330,7 @@ Fl_Android_Font_Descriptor::~Fl_Android_Font_Descriptor()
{
// Life is easy in C++11.
for (auto &i: pBytemapTable) {
- delete i.second;
+ delete i.second; i.second = nullptr;
}
}
diff --git a/src/drivers/Android/Fl_Android_Screen_Driver.cxx b/src/drivers/Android/Fl_Android_Screen_Driver.cxx
index e9458c9c7..e713f5b95 100644
--- a/src/drivers/Android/Fl_Android_Screen_Driver.cxx
+++ b/src/drivers/Android/Fl_Android_Screen_Driver.cxx
@@ -77,7 +77,7 @@ int Fl_Android_Screen_Driver::handle_app_command()
// call all registered FLTK system handlers
Fl::e_number = ((uint32_t)(cmd-Fl_Android_Application::APP_CMD_INPUT_CHANGED)) + FL_ANDROID_EVENT_INPUT_CHANGED;
- fl_send_system_handlers(0L);
+ fl_send_system_handlers(nullptr);
// fixup and finalize application wide command handling
Fl_Android_Application::post_exec_cmd(cmd);
@@ -87,7 +87,7 @@ int Fl_Android_Screen_Driver::handle_app_command()
int Fl_Android_Screen_Driver::handle_input_event()
{
AInputQueue *queue = Fl_Android_Application::input_event_queue();
- AInputEvent *event = NULL;
+ AInputEvent *event = nullptr;
if (AInputQueue_getEvent(queue, &event) >= 0) {
if (AInputQueue_preDispatchEvent(queue, event)==0) {
@@ -179,7 +179,7 @@ int Fl_Android_Screen_Driver::handle_queued_events(double time_to_wait)
struct android_poll_source *source;
for (;;) {
- ident = ALooper_pollAll(Fl::damage() ? 0 : -1, NULL, &events, (void **) &source);
+ ident = ALooper_pollAll(Fl::damage() ? 0 : -1, nullptr, &events, (void **) &source);
switch (ident) {
// FIXME: ALOOPER_POLL_WAKE = -1, ALOOPER_POLL_CALLBACK = -2, ALOOPER_POLL_TIMEOUT = -3, ALOOPER_POLL_ERROR = -4
case Fl_Android_Application::LOOPER_ID_MAIN:
@@ -718,7 +718,7 @@ struct TimerData
bool triggered;
struct itimerspec timeout;
};
-static TimerData* timerData = 0L;
+static TimerData* timerData = nullptr;
static int NTimerData = 0;
static int nTimerData = 0;
@@ -818,7 +818,7 @@ void Fl_Android_Screen_Driver::repeat_timeout(double time, Fl_Timeout_Handler cb
{ 0, 0 },
{ (time_t)floor(time), (long)(modf(time, &ff)*1000000000) }
};
- ret = timer_settime(t.handle, 0, &t.timeout, 0L);
+ ret = timer_settime(t.handle, 0, &t.timeout, nullptr);
if (ret==-1) {
Fl_Android_Application::log_e("Can't launch timer: %s", strerror(errno));
return;
@@ -843,7 +843,7 @@ void Fl_Android_Screen_Driver::remove_timeout(Fl_Timeout_Handler cb, void *data)
{
for (int i = 0; i < nTimerData; ++i) {
TimerData& t = timerData[i];
- if ( t.used && (t.callback==cb) && ( (t.data==data) || (data==NULL) ) ) {
+ if ( t.used && (t.callback==cb) && ( (t.data==data) || (data==nullptr) ) ) {
if (t.used)
timer_delete(t.handle);
t.triggered = t.used = false;