summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Driver.H22
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Driver.cxx49
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx80
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) {