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
This commit is contained in:
parent
5900d824e9
commit
d252801a31
@ -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);
|
||||
|
@ -212,6 +212,19 @@ Fl_Complex_Region::Fl_Complex_Region(const Fl_Rect_Region &r) :
|
||||
* Delete this region, all subregions recursively, and all following regions.
|
||||
*/
|
||||
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
|
||||
@ -219,7 +232,7 @@ Fl_Complex_Region::~Fl_Complex_Region()
|
||||
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);
|
||||
Fl_Complex_Region *rgn = pSubregion;
|
||||
while (rgn) {
|
||||
rgn->intersect_with(r);
|
||||
rgn = rgn->next();
|
||||
}
|
||||
compress();
|
||||
} 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_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);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user