From 737d8bef2425d0373a8890b49f9b0babb7f994db Mon Sep 17 00:00:00 2001
From: Matthias Melcher <fltk@matthiasm.com>
Date: Wed, 14 Mar 2018 21:46:01 +0000
Subject: [PATCH] Android: adding stress test for complex clipping.

Complex clipping is needed to allow popup dialogs and menu window while
still correctly rendering windows that are "below" those popups.

git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12745 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
---
 .../app/src/main/cpp/HelloAndroid.cxx         | 32 +++++++--
 .../Android/Fl_Android_Graphics_Driver.H      | 31 ++++-----
 .../Fl_Android_Graphics_Driver_region.cxx     | 68 +++++++++++++------
 3 files changed, 88 insertions(+), 43 deletions(-)

diff --git a/ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx b/ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx
index f22728c33..7e8d11b72 100644
--- a/ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx
+++ b/ide/AndroidStudio3/app/src/main/cpp/HelloAndroid.cxx
@@ -22,7 +22,7 @@
 #include <FL/fl_draw.H>
 
 
-Fl_Window *win;
+Fl_Window *win, *win1, *win2;
 Fl_Button *btn, *btn2;
 
 
@@ -52,21 +52,39 @@ void hello_cb(void*)
   Fl::remove_timeout(hello_cb, NULL);
 }
 
-void start_timer(Fl_Widget*, void*)
-{
-  Fl::add_timeout(1.0, hello_cb, NULL);
-}
 
 int main(int argc, char **argv)
 {
+  win1 = new Fl_Window(10, 10, 200, 200, "back");
+  win1->color(FL_RED);
+  win1->box(FL_DOWN_BOX);
+  Fl_Button *b1 = new Fl_Button(10, 10, 180, 180, "back");
+  win1->end();
+  win1->show();
+
   win = new Fl_Window(50, 150, 500, 400, "Hallo");
-  btn2 = new Fl_Button(10, 10, 50, 50, "-@circle;-");
+
+  btn2 = new Fl_Button(10, 10, 480, 100, "-@circle;-");
   btn2->color(FL_BLUE);
+
   btn = new MyButton((win->w()-280)/2, 200, 280, 35, "Hello, Android!");
   btn->color(FL_LIGHT2);
-  btn->callback(start_timer);
+  btn->callback(
+          [](Fl_Widget*, void*) {
+            Fl::add_timeout(1.0, hello_cb, NULL);
+          }
+  );
+
+  win->end();
   win->show(argc, argv);
 
+  win2 = new Fl_Window(390, 10, 200, 200, "front");
+  win2->color(FL_BLUE);
+  win2->box(FL_UP_BOX);
+  Fl_Button *b2 = new Fl_Button(10, 10, 180, 180, "front");
+  win2->end();
+  win2->show();
+
   Fl::run();
 
   return 0;
diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver.H b/src/drivers/Android/Fl_Android_Graphics_Driver.H
index fd23e95d6..d229180c3 100644
--- a/src/drivers/Android/Fl_Android_Graphics_Driver.H
+++ b/src/drivers/Android/Fl_Android_Graphics_Driver.H
@@ -79,7 +79,6 @@ private:
   Fl_Rect_Region&  operator = (const Fl_Rect_Region& other);
 };
 
-#if 0
 /**
  * The Fl_Complex_Region represents a clipping region of any shape.
  *
@@ -99,23 +98,23 @@ private:
 class Fl_Complex_Region : public Fl_Rect_Region
 {
 public:
-  Fl_Complex_Region() : Fl_Rect_Region(), pSubregion(0L), pNext(0L) { }
-  Fl_Complex_Region(int x, int y, int w, int h) : Fl_Rect_Region(x, y, w, h), pSubregion(0L), pNext(0L)  { }
-  ~Fl_Complex_Region();
-  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() { return pSubregion==0; }
-  char is_complex() { return pSubregion!=0; }
-  void print();
+  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(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; }
+  virtual void print(const char*) const override;
 protected:
-  void print_data(int indent);
-  Fl_Complex_Region *pSubregion;
-  Fl_Complex_Region *pNext;
+  void print_data(int indent) const;
+  Fl_Complex_Region *pSubregion = 0L;
+  Fl_Complex_Region *pParent = 0L;
+  Fl_Complex_Region *pNext = 0L;
 };
-#endif
 
 
 /**
diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx b/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx
index e3ffafc54..2e71cfb29 100644
--- a/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx
+++ b/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx
@@ -147,15 +147,62 @@ void Fl_Rect_Region::print(const char *label) const
   Fl_Android_Application::log_i("Rect %d %d %d %d", x(), y(), w(), h());
 }
 
+// -----------------------------------------------------------------------------
 
-#if 0
+/**
+ * Create an empty complex region.
+ */
+Fl_Complex_Region::Fl_Complex_Region() :
+        Fl_Rect_Region()
+{
+}
 
+/**
+ * Create a complex region with the same bounds as the give rect.
+ * @param r region size
+ */
+Fl_Complex_Region::Fl_Complex_Region(const Fl_Rect_Region &r) :
+        Fl_Rect_Region(r)
+{
+}
+
+/**
+ * Delete this region, all subregions recursively, and all following regions.
+ */
 Fl_Complex_Region::~Fl_Complex_Region()
 {
   delete pSubregion; // recursively delete all subregions
   delete pNext; // recursively delete all following regions
 }
 
+/**
+ * Print the entire content of this region recursively.
+ */
+void Fl_Complex_Region::print(const char *label) const
+{
+  Fl_Android_Application::log_i("---> Fl_Complex_Region: %s", label);
+  print_data(0);
+}
+
+/*
+ * Print the rectangular data only.
+ */
+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());
+    pSubregion->print_data(indent+1);
+  } else {
+    Fl_Android_Application::log_i("%sRect %d %d %d %d", space+16-indent, x(), y(), w(), h());
+  }
+  if (pNext) {
+    pNext->print_data(indent+1);
+  }
+}
+
+
+#if 0
 
 void Fl_Complex_Region::set(int x, int y, int w, int h)
 {
@@ -167,7 +214,6 @@ void Fl_Complex_Region::set(int x, int y, int w, int h)
   Fl_Rect_Region::set(x, y, w, h);
 }
 
-
 void Fl_Complex_Region::set(Fl_Rect *rect)
 {
   delete pSubregion;
@@ -198,13 +244,11 @@ void Fl_Complex_Region::subtract(Fl_Rect *r)
   int x = 3;
 }
 
-
 void Fl_Complex_Region::intersect(Fl_Rect*)
 {
   // FIXME: implement
 }
 
-
 void Fl_Complex_Region::clone(Fl_Complex_Region *r)
 {
   // FIXME: implement
@@ -220,22 +264,6 @@ void Fl_Complex_Region::clone(Fl_Complex_Region *r)
   }
 }
 
-
-void Fl_Complex_Region::print_data(int indent)
-{
-  static const char *space = "                ";
-  if (pSubregion) {
-    Fl_Android_Application::log_i("%sBBox %d %d %d %d", space+16-indent, x(), y(), w(), h());
-    pSubregion->print_data(indent+1);
-  } else {
-    Fl_Android_Application::log_i("%sRect %d %d %d %d", space+16-indent, x(), y(), w(), h());
-  }
-  if (pNext) {
-    pNext->print_data(indent+1);
-  }
-}
-
-
 void Fl_Complex_Region::print()
 {
   Fl_Android_Application::log_i("-------- begin region");