Android: implemented good complex clipping, but unoptimized.

fl_rectf is so far the only function that uses the complex clipping
region successfully. Code is slow, but works.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12747 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
Matthias Melcher 2018-03-15 00:07:53 +00:00
parent 1bb5eea696
commit 630fc8e983
4 changed files with 78 additions and 11 deletions

View File

@ -59,6 +59,7 @@ int main(int argc, char **argv)
win1->color(FL_RED); win1->color(FL_RED);
win1->box(FL_DOWN_BOX); win1->box(FL_DOWN_BOX);
Fl_Button *b1 = new Fl_Button(10, 10, 180, 180, "back"); Fl_Button *b1 = new Fl_Button(10, 10, 180, 180, "back");
b1->color(FL_DARK_RED);
win1->end(); win1->end();
win1->show(); win1->show();
@ -82,6 +83,7 @@ int main(int argc, char **argv)
win2->color(FL_BLUE); win2->color(FL_BLUE);
win2->box(FL_UP_BOX); win2->box(FL_UP_BOX);
Fl_Button *b2 = new Fl_Button(10, 10, 180, 180, "front"); Fl_Button *b2 = new Fl_Button(10, 10, 180, 180, "front");
b2->color(FL_DARK_BLUE);
win2->end(); win2->end();
win2->show(); win2->show();

View File

@ -67,6 +67,7 @@ public:
void set_empty(); void set_empty();
void set(int x, int y, int w, int h); void set(int x, int y, int w, int h);
void set_ltrb(int l, int t, int r, int b);
virtual void set(const Fl_Rect_Region &r); virtual void set(const Fl_Rect_Region &r);
virtual int intersect_with(const Fl_Rect_Region &r); virtual int intersect_with(const Fl_Rect_Region &r);
@ -102,6 +103,7 @@ public:
Fl_Complex_Region(const Fl_Rect_Region&); Fl_Complex_Region(const Fl_Rect_Region&);
virtual ~Fl_Complex_Region() override; virtual ~Fl_Complex_Region() override;
virtual void set(const Fl_Rect_Region &r) override; virtual void set(const Fl_Rect_Region &r) override;
void set(const Fl_Complex_Region &r);
virtual int intersect_with(const Fl_Rect_Region &r) override; virtual int intersect_with(const Fl_Rect_Region &r) override;
int subtract(const Fl_Rect_Region &r); int subtract(const Fl_Rect_Region &r);
@ -116,6 +118,8 @@ public:
Fl_Complex_Region *subregion() const { return pSubregion; } Fl_Complex_Region *subregion() const { return pSubregion; }
Fl_Complex_Region *next() const { return pNext; } Fl_Complex_Region *next() const { return pNext; }
Fl_Complex_Region *add_subregion();
virtual void print(const char*) const override; virtual void print(const char*) const override;
protected: protected:
void print_data(int indent) const; void print_data(int indent) const;

View File

@ -72,7 +72,9 @@ void Fl_Android_Graphics_Driver::make_current(Fl_Window *win)
pDesktopWindowRegion.subtract(r); pDesktopWindowRegion.subtract(r);
wTop = Fl::next_window(wTop); wTop = Fl::next_window(wTop);
} }
pDesktopWindowRegion.print(" #### DESKTOP");
pClippingRegion.set(pDesktopWindowRegion); pClippingRegion.set(pDesktopWindowRegion);
pClippingRegion.print("#### CLIPPING");
} }
@ -97,13 +99,17 @@ void Fl_Android_Graphics_Driver::rectf_unscaled(float x, float y, float w, float
{ {
// FIXME: r must be a complex region, like pClippingRegion. // FIXME: r must be a complex region, like pClippingRegion.
#if 0
Fl_Rect_Region r(x, y, w, h); Fl_Rect_Region r(x, y, w, h);
#if 0
if (r.intersect_with(pClippingRegion)) { if (r.intersect_with(pClippingRegion)) {
rectf_unclipped(r.x(), r.y(), r.w(), r.h()); rectf_unclipped(r.x(), r.y(), r.w(), r.h());
} }
#else // proof of concept #else // proof of concept
// FIXME: write iterator over tree // FIXME: write iterator over tree
r.print("---- fl_rectf");
pClippingRegion.print("clip to");
for (Fl_Complex_Region *cr = &pClippingRegion; cr; cr=cr->next()) { for (Fl_Complex_Region *cr = &pClippingRegion; cr; cr=cr->next()) {
if (cr->subregion()) { if (cr->subregion()) {
for (Fl_Complex_Region *cr1 = cr->subregion(); cr1; cr1=cr1->next()) { for (Fl_Complex_Region *cr1 = cr->subregion(); cr1; cr1=cr1->next()) {
@ -124,8 +130,6 @@ void Fl_Android_Graphics_Driver::rectf_unscaled(float x, float y, float w, float
} else { } else {
Fl_Rect_Region r(x, y, w, h); Fl_Rect_Region r(x, y, w, h);
if (r.intersect_with(*cr)) { if (r.intersect_with(*cr)) {
r.print("---- fl_rectf");
pClippingRegion.print("clip to");
rectf_unclipped(r.x(), r.y(), r.w(), r.h()); rectf_unclipped(r.x(), r.y(), r.w(), r.h());
} }
} }

View File

@ -98,6 +98,15 @@ void Fl_Rect_Region::set(int x, int y, int w, int h)
} }
void Fl_Rect_Region::set_ltrb(int l, int t, int r, int b)
{
pLeft = l;
pTop = t;
pRight = r;
pBottom = b;
}
void Fl_Rect_Region::set(const Fl_Rect_Region &r) void Fl_Rect_Region::set(const Fl_Rect_Region &r)
{ {
pLeft = r.pLeft; pLeft = r.pLeft;
@ -144,7 +153,7 @@ int Fl_Rect_Region::intersect_with(const Fl_Rect_Region &r)
void Fl_Rect_Region::print(const char *label) const void Fl_Rect_Region::print(const char *label) const
{ {
Fl_Android_Application::log_i("---> Fl_Rect_Region: %s", label); Fl_Android_Application::log_i("---> Fl_Rect_Region: %s", label);
Fl_Android_Application::log_i("Rect %d %d %d %d", x(), y(), w(), h()); Fl_Android_Application::log_i("Rect l:%d t:%d r:%d b:%d", left(), top(), right(), bottom());
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -191,13 +200,13 @@ void Fl_Complex_Region::print_data(int indent) const
{ {
static const char *space = " "; static const char *space = " ";
if (pSubregion) { if (pSubregion) {
Fl_Android_Application::log_i("%sBBox %d %d %d %d", space+16-indent, x(), y(), w(), h()); Fl_Android_Application::log_i("%sBBox l:%d t:%d r:%d b:%d", space+16-indent, left(), top(), right(), bottom());
pSubregion->print_data(indent+1); pSubregion->print_data(indent+1);
} else { } else {
Fl_Android_Application::log_i("%sRect %d %d %d %d", space+16-indent, x(), y(), w(), h()); Fl_Android_Application::log_i("%sRect l:%d t:%d r:%d b:%d", space+16-indent, left(), top(), right(), bottom());
} }
if (pNext) { if (pNext) {
pNext->print_data(indent+1); pNext->print_data(indent);
} }
} }
@ -209,6 +218,29 @@ void Fl_Complex_Region::set(const Fl_Rect_Region &r)
} }
void Fl_Complex_Region::set(const Fl_Complex_Region &r)
{
#if 0
Fl_Android_Application::log_e("Not yet implemented!");
delete pSubregion; pSubregion = 0;
Fl_Rect_Region::set(r);
#else
// 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());
}
#endif
}
int Fl_Complex_Region::intersect_with(const Fl_Rect_Region &r) int Fl_Complex_Region::intersect_with(const Fl_Rect_Region &r)
{ {
delete pSubregion; pSubregion = 0; delete pSubregion; pSubregion = 0;
@ -271,14 +303,39 @@ int Fl_Complex_Region::subtract_smaller_region(const Fl_Rect_Region &r)
} else if (left()==r.left() && top()==r.top() && right()==r.right() && bottom()!=r.bottom()) { } else if (left()==r.left() && top()==r.top() && right()==r.right() && bottom()!=r.bottom()) {
pTop = r.bottom(); pTop = r.bottom();
} else { } else {
Fl_Android_Application::log_w("Regions too complex. Not yet implemented"); // create multiple regions
if (pTop!=r.top()) {
Fl_Complex_Region *s = add_subregion();
s->set_ltrb(pLeft, pTop, pRight, r.top());
}
if (pBottom!=r.bottom()) {
Fl_Complex_Region *s = add_subregion();
s->set_ltrb(pLeft, r.bottom(), pRight, pBottom);
}
if (pLeft!=r.left()) {
Fl_Complex_Region *s = add_subregion();
s->set_ltrb(pLeft, r.top(), r.left(), r.bottom());
}
if (pRight!=r.right()) {
Fl_Complex_Region *s = add_subregion();
s->set_ltrb(r.right(), r.top(), pRight, r.bottom());
}
//Fl_Android_Application::log_w("Regions too complex. Not yet implemented");
print("-- added subregions");
} }
print("subtract_smaller_region");
r.print("");
return 0; return 0;
} }
Fl_Complex_Region *Fl_Complex_Region::add_subregion()
{
Fl_Complex_Region *r = new Fl_Complex_Region();
r->pNext = pSubregion;
pSubregion = r;
return r;
}
#if 0 #if 0
void Fl_Complex_Region::set(int x, int y, int w, int h) void Fl_Complex_Region::set(int x, int y, int w, int h)
@ -360,7 +417,7 @@ void Fl_Android_Graphics_Driver::restore_clip()
Fl_Region b = rstack[rstackptr]; Fl_Region b = rstack[rstackptr];
if (b) { if (b) {
pClippingRegion.intersect_with(*b); // FIXME: pClippingRegion.intersect_with(*b);
} }
} }