Android: implemented complex clipping at the first level.
Clipping areas are calculated for overlapping windows, named "Desktop Windows". The first level implementation works if the resulting complex region is just a rectangle. Higher complexity (sub-rectangles) is next. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12746 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
737d8bef24
commit
1bb5eea696
@ -55,7 +55,7 @@ void hello_cb(void*)
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
win1 = new Fl_Window(10, 10, 200, 200, "back");
|
||||
win1 = new Fl_Window(10+50, 10, 200, 200, "back");
|
||||
win1->color(FL_RED);
|
||||
win1->box(FL_DOWN_BOX);
|
||||
Fl_Button *b1 = new Fl_Button(10, 10, 180, 180, "back");
|
||||
@ -78,7 +78,7 @@ int main(int argc, char **argv)
|
||||
win->end();
|
||||
win->show(argc, argv);
|
||||
|
||||
win2 = new Fl_Window(390, 10, 200, 200, "front");
|
||||
win2 = new Fl_Window(390-50, 10, 200, 200, "front");
|
||||
win2->color(FL_BLUE);
|
||||
win2->box(FL_UP_BOX);
|
||||
Fl_Button *b2 = new Fl_Button(10, 10, 180, 180, "front");
|
||||
|
@ -67,8 +67,8 @@ public:
|
||||
|
||||
void set_empty();
|
||||
void set(int x, int y, int w, int h);
|
||||
void set(const Fl_Rect_Region &r);
|
||||
int intersect_with(const Fl_Rect_Region &r);
|
||||
virtual void set(const Fl_Rect_Region &r);
|
||||
virtual int intersect_with(const Fl_Rect_Region &r);
|
||||
|
||||
virtual void print(const char*) const;
|
||||
|
||||
@ -101,16 +101,25 @@ public:
|
||||
Fl_Complex_Region();
|
||||
Fl_Complex_Region(const Fl_Rect_Region&);
|
||||
virtual ~Fl_Complex_Region() override;
|
||||
// virtual void set(int x, int y, int w, int h);
|
||||
virtual void set(const Fl_Rect_Region &r) override;
|
||||
virtual int intersect_with(const Fl_Rect_Region &r) override;
|
||||
int subtract(const Fl_Rect_Region &r);
|
||||
|
||||
// virtual void set(int x, int y, int w, int h);
|
||||
// virtual void set(Fl_Rect_Region*);
|
||||
// void subtract(Fl_Rect_Region*);
|
||||
// void intersect(Fl_Rect_Region*);
|
||||
// void clone(Fl_Complex_Region*);
|
||||
char is_simple() const { return pSubregion==0; }
|
||||
char is_complex() const { return pSubregion!=0; }
|
||||
|
||||
Fl_Complex_Region *subregion() const { return pSubregion; }
|
||||
Fl_Complex_Region *next() const { return pNext; }
|
||||
|
||||
virtual void print(const char*) const override;
|
||||
protected:
|
||||
void print_data(int indent) const;
|
||||
int subtract_smaller_region(const Fl_Rect_Region &r);
|
||||
Fl_Complex_Region *pSubregion = 0L;
|
||||
Fl_Complex_Region *pParent = 0L;
|
||||
Fl_Complex_Region *pNext = 0L;
|
||||
@ -262,8 +271,13 @@ protected:
|
||||
int32_t pStride;
|
||||
uint16_t *pBits;
|
||||
|
||||
// Clipping region of the current window in window coordinates (see: pStride and pBits)
|
||||
Fl_Rect_Region pWindowRegion;
|
||||
Fl_Rect_Region pClippingRegion;
|
||||
|
||||
Fl_Complex_Region pDesktopWindowRegion;
|
||||
|
||||
// Final clipping region for all graphics calls to this class.
|
||||
Fl_Complex_Region pClippingRegion;
|
||||
};
|
||||
|
||||
|
||||
|
@ -60,19 +60,19 @@ void Fl_Android_Graphics_Driver::make_current(Fl_Window *win)
|
||||
pWindowRegion.set(-win->x(), -win->y(), 600, 800);
|
||||
pWindowRegion.intersect_with(Fl_Rect_Region(0, 0, win->w(), win->h()));
|
||||
|
||||
#if 0
|
||||
pDesktopWindowRegion.set(pWindowRegion);
|
||||
pDesktopWindowRegion.print(win->label());
|
||||
|
||||
// remove all window rectangles that are positioned on top of this window
|
||||
// TODO: this region is expensive to calculate. Cache it for each window and recalculate when windows move, show, hide, or change order
|
||||
Fl_Window *wTop = Fl::first_window();
|
||||
while (wTop) {
|
||||
if (wTop==win) break;
|
||||
Fl_Rect r(wTop->x(), wTop->y(), wTop->w(), wTop->h());
|
||||
pDesktopRegion->subtract(&r);
|
||||
Fl_Rect_Region r(wTop->x()-win->x(), wTop->y()-win->y(), wTop->w(), wTop->h());
|
||||
pDesktopWindowRegion.subtract(r);
|
||||
wTop = Fl::next_window(wTop);
|
||||
}
|
||||
#endif
|
||||
|
||||
pClippingRegion.set(pWindowRegion);
|
||||
pClippingRegion.set(pDesktopWindowRegion);
|
||||
}
|
||||
|
||||
|
||||
@ -95,10 +95,47 @@ static uint16_t make565(Fl_Color crgba)
|
||||
|
||||
void Fl_Android_Graphics_Driver::rectf_unscaled(float x, float y, float w, float h)
|
||||
{
|
||||
// FIXME: r must be a complex region, like pClippingRegion.
|
||||
|
||||
#if 0
|
||||
Fl_Rect_Region r(x, y, w, h);
|
||||
if (r.intersect_with(pClippingRegion)) {
|
||||
rectf_unclipped(r.x(), r.y(), r.w(), r.h());
|
||||
}
|
||||
#else // proof of concept
|
||||
// FIXME: write iterator over tree
|
||||
for (Fl_Complex_Region *cr = &pClippingRegion; cr; cr=cr->next()) {
|
||||
if (cr->subregion()) {
|
||||
for (Fl_Complex_Region *cr1 = cr->subregion(); cr1; cr1=cr1->next()) {
|
||||
if (cr1->subregion()) {
|
||||
for (Fl_Complex_Region *cr2 = cr1->subregion(); cr2; cr2 = cr2->next()) {
|
||||
Fl_Rect_Region r(x, y, w, h);
|
||||
if (r.intersect_with(*cr2)) {
|
||||
rectf_unclipped(r.x(), r.y(), r.w(), r.h());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Fl_Rect_Region r(x, y, w, h);
|
||||
if (r.intersect_with(*cr1)) {
|
||||
rectf_unclipped(r.x(), r.y(), r.w(), r.h());
|
||||
}
|
||||
}
|
||||
}
|
||||
} 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// TODO: create a complex region by intersecting r with the pClippingRegion
|
||||
// TODO: walk the region and draw all rectangles
|
||||
|
||||
|
@ -202,6 +202,83 @@ void Fl_Complex_Region::print_data(int indent) const
|
||||
}
|
||||
|
||||
|
||||
void Fl_Complex_Region::set(const Fl_Rect_Region &r)
|
||||
{
|
||||
delete pSubregion; pSubregion = 0;
|
||||
Fl_Rect_Region::set(r);
|
||||
}
|
||||
|
||||
|
||||
int Fl_Complex_Region::intersect_with(const Fl_Rect_Region &r)
|
||||
{
|
||||
delete pSubregion; pSubregion = 0;
|
||||
// FIXME: handle complex regions!
|
||||
int ret = Fl_Rect_Region::intersect_with(r);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int Fl_Complex_Region::subtract(const Fl_Rect_Region &r)
|
||||
{
|
||||
// FIXME: write me.
|
||||
if (pSubregion) {
|
||||
pSubregion->subtract(r);
|
||||
} else {
|
||||
// Check if we overlap at all
|
||||
Fl_Rect_Region s(r);
|
||||
this->print("---- subtract");
|
||||
s.print("");
|
||||
int intersects = s.intersect_with(*this);
|
||||
switch (intersects) {
|
||||
case EMPTY:
|
||||
// nothing to do
|
||||
break;
|
||||
case SAME:
|
||||
set_empty(); // FIXME: delete this Rect!
|
||||
break;
|
||||
case LESS:
|
||||
// split this rect into 1, 2, 3, or 4 new ones
|
||||
subtract_smaller_region(s);
|
||||
break;
|
||||
default:
|
||||
Fl_Android_Application::log_e("Invalid case in %s:%d", __FUNCTION__, __LINE__);
|
||||
break;
|
||||
}
|
||||
if (pNext) {
|
||||
pNext->subtract(r);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int Fl_Complex_Region::subtract_smaller_region(const Fl_Rect_Region &r)
|
||||
{
|
||||
// subtract a smaller rect from a larger rect and create subrects as needed
|
||||
|
||||
print("subtract_smaller_region");
|
||||
r.print("");
|
||||
// if there is only one single coordinte different, we can reuse this container
|
||||
if (left()==r.left() && top()==r.top() && right()==r.right() && bottom()==r.bottom()) {
|
||||
// this should not happen
|
||||
set_empty();
|
||||
} else if (left()!=r.left() && top()==r.top() && right()==r.right() && bottom()==r.bottom()) {
|
||||
pRight = r.left();
|
||||
} else if (left()==r.left() && top()!=r.top() && right()==r.right() && bottom()==r.bottom()) {
|
||||
pBottom = r.top();
|
||||
} else if (left()==r.left() && top()==r.top() && right()!=r.right() && bottom()==r.bottom()) {
|
||||
pLeft = r.right();
|
||||
} 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");
|
||||
}
|
||||
print("subtract_smaller_region");
|
||||
r.print("");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
|
||||
void Fl_Complex_Region::set(int x, int y, int w, int h)
|
||||
@ -278,7 +355,8 @@ void Fl_Android_Graphics_Driver::restore_clip()
|
||||
{
|
||||
fl_clip_state_number++;
|
||||
|
||||
pClippingRegion.set(pWindowRegion);
|
||||
pClippingRegion.set(pDesktopWindowRegion);
|
||||
|
||||
|
||||
Fl_Region b = rstack[rstackptr];
|
||||
if (b) {
|
||||
|
Loading…
Reference in New Issue
Block a user