diff options
Diffstat (limited to 'src/drivers/Android')
| -rw-r--r-- | src/drivers/Android/Fl_Android_Graphics_Driver.H | 22 | ||||
| -rw-r--r-- | src/drivers/Android/Fl_Android_Graphics_Driver.cxx | 49 | ||||
| -rw-r--r-- | src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx | 80 |
3 files changed, 140 insertions, 11 deletions
diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver.H b/src/drivers/Android/Fl_Android_Graphics_Driver.H index d229180c3..eca76be9b 100644 --- a/src/drivers/Android/Fl_Android_Graphics_Driver.H +++ b/src/drivers/Android/Fl_Android_Graphics_Driver.H @@ -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; }; diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver.cxx b/src/drivers/Android/Fl_Android_Graphics_Driver.cxx index 817b5c0d1..4e3be5d14 100644 --- a/src/drivers/Android/Fl_Android_Graphics_Driver.cxx +++ b/src/drivers/Android/Fl_Android_Graphics_Driver.cxx @@ -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 diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx b/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx index 2e71cfb29..a7c417b97 100644 --- a/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx +++ b/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx @@ -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) { |
