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

View File

@ -67,6 +67,7 @@ public:
void set_empty();
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 int intersect_with(const Fl_Rect_Region &r);
@ -102,6 +103,7 @@ public:
Fl_Complex_Region(const Fl_Rect_Region&);
virtual ~Fl_Complex_Region() 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;
int subtract(const Fl_Rect_Region &r);
@ -116,6 +118,8 @@ public:
Fl_Complex_Region *subregion() const { return pSubregion; }
Fl_Complex_Region *next() const { return pNext; }
Fl_Complex_Region *add_subregion();
virtual void print(const char*) const override;
protected:
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);
wTop = Fl::next_window(wTop);
}
pDesktopWindowRegion.print(" #### DESKTOP");
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.
#if 0
Fl_Rect_Region r(x, y, w, h);
#if 0
if (r.intersect_with(pClippingRegion)) {
rectf_unclipped(r.x(), r.y(), r.w(), r.h());
}
#else // proof of concept
// FIXME: write iterator over tree
r.print("---- fl_rectf");
pClippingRegion.print("clip to");
for (Fl_Complex_Region *cr = &pClippingRegion; cr; cr=cr->next()) {
if (cr->subregion()) {
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 {
Fl_Rect_Region r(x, y, w, h);
if (r.intersect_with(*cr)) {
r.print("---- fl_rectf");
pClippingRegion.print("clip to");
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)
{
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
{
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 = " ";
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);
} 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) {
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)
{
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()) {
pTop = r.bottom();
} 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;
}
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
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];
if (b) {
pClippingRegion.intersect_with(*b);
// FIXME: pClippingRegion.intersect_with(*b);
}
}