summaryrefslogtreecommitdiff
path: root/src/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'src/drivers')
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Driver.H63
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Driver.cxx26
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx71
3 files changed, 122 insertions, 38 deletions
diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver.H b/src/drivers/Android/Fl_Android_Graphics_Driver.H
index a55e39400..6e03e26da 100644
--- a/src/drivers/Android/Fl_Android_Graphics_Driver.H
+++ b/src/drivers/Android/Fl_Android_Graphics_Driver.H
@@ -30,18 +30,61 @@
#include <limits.h>
-struct Fl_Clip_Rect
+/**
+ * The Fl_Rect_Region is based on Fl_Rect with additional functionality for clipping.
+ */
+class Fl_Rect_Region : public Fl_Rect
{
- Fl_Clip_Rect() : pRect() {}
- Fl_Clip_Rect(int x, int y, int w, int h) : pRect(x, y, w, h) {}
- int x() { return pRect.x(); }
- int y() { return pRect.y(); }
- int w() { return pRect.w(); }
- int h() { return pRect.h(); }
- int intersect_with(Fl_Clip_Rect *r);
+public:
+ enum {
+ EMPTY = 0, SAME, LESS, MORE
+ };
+
+ /**
+ * Create an empty clipping region.
+ */
+ Fl_Rect_Region() {}
+
+ /**
+ * Create a clipping region based on position and size.
+ * @param x, y position
+ * @param w, h size
+ */
+ Fl_Rect_Region(int x, int y, int w, int h) : Fl_Rect(x, y, w, h) {}
+ int intersect_with(Fl_Rect_Region *r);
static int min(int a, int b) { return (a<b) ? a : b; }
static int max(int a, int b) { return (a>b) ? a : b; }
- Fl_Rect pRect;
+};
+
+
+/**
+ * The Fl_Complex_Region represents a clipping region of any shape.
+ *
+ * This class is organized in a tree-like structure. If the region is
+ * rectangular, is_simple() returns 1 and the rectangle can be used just
+ * as in Fl_Rect_Region.
+ *
+ * If a more complex representation is needed, the first list of
+ * subregions is organizen in horizontal strips. The root region rect
+ * will contain the outline of all subregions, and the subregions
+ * will either be simple rectangles, or they will contain a second
+ * level of subregions, subdividing the horizontal region into vertical
+ * columns.
+ *
+ * When reading, the tree can be easily walked using recursion.
+ */
+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();
+ void set(Fl_Rect *rect);
+ char is_simple() { return pSubregion==0; }
+ char is_complex() { return pSubregion!=0; }
+protected:
+ Fl_Complex_Region *pSubregion;
+ Fl_Complex_Region *pNext;
};
@@ -144,7 +187,7 @@ protected:
void restore_clip();
void clip_region(Fl_Region r);
Fl_Region clip_region();
- static Fl_Clip_Rect pClipRect;
+ static Fl_Complex_Region pWindowRegion;
#if 0
virtual Fl_Region scale_clip(float f);
// --- implementation is in src/fl_vertex.cxx which includes src/cfg_gfx/xxx_rect.cxx
diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver.cxx b/src/drivers/Android/Fl_Android_Graphics_Driver.cxx
index 1df52462a..2a0b62cc8 100644
--- a/src/drivers/Android/Fl_Android_Graphics_Driver.cxx
+++ b/src/drivers/Android/Fl_Android_Graphics_Driver.cxx
@@ -55,10 +55,32 @@ static uint16_t make565(Fl_Color crgba)
void Fl_Android_Graphics_Driver::rectf_unscaled(float x, float y, float w, float h) {
Fl_Android_Application::log_w("rectf %g %g %g %g", x, y, w, h);
- Fl_Clip_Rect r(x, y, w, h);
- if (r.intersect_with(&pClipRect)) {
+ Fl_Rect_Region r(x, y, w, h);
+ if (r.intersect_with(&pWindowRegion)) {
rectf_unclipped(r.x(), r.y(), r.w(), r.h());
}
+
+ /*
+ * rectf(x, y, w, h) {
+ * rectf(complex_window_region, drawing_rect(x, y, w, h))
+ * }
+ *
+ * rectf( complexRgn, drawRgn) {
+ * // B: start of iterator
+ * if (intersect(rect_of_complexRgn, drawRgn) {
+ * if (complexRgn->is_complex() {
+ * rectf(complexRgn->subregion, drawRect);
+ * } else {
+ * rawRect = intersection(rect_of_complexRgn, drawRgn);
+ * rawDrawRect(rawRect);
+ * }
+ * }
+ * // A: recursion
+ * if (complexRgn->next)
+ * rectf(complexRgn->next, drawRgn);
+ * // B: end of iterator
+ * }
+ */
}
void Fl_Android_Graphics_Driver::rectf_unclipped(float x, float y, float w, float h) {
diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx b/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx
index 107a6e708..27e105d89 100644
--- a/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx
+++ b/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx
@@ -23,37 +23,55 @@
#include <FL/platform.H>
-Fl_Clip_Rect Fl_Android_Graphics_Driver::pClipRect;
+Fl_Complex_Region Fl_Android_Graphics_Driver::pWindowRegion;
+
// return 0 for empty, 1 for same, 2 if intersecting
-int Fl_Clip_Rect::intersect_with(Fl_Clip_Rect *a)
+int Fl_Rect_Region::intersect_with(Fl_Rect_Region *a)
{
- if (pRect.is_empty()) {
- return 0;
+ if (is_empty()) {
+ return EMPTY;
}
- if (a->pRect.is_empty()) {
- pRect.clear();
- return 0;
+ if (a->is_empty()) {
+ clear();
+ return EMPTY;
}
- int x = max(pRect.x(), a->pRect.x());
- int y = max(pRect.y(), a->pRect.y());
- int r = min(pRect.r(), a->pRect.r());
- int b = min(pRect.b(), a->pRect.b());
- int w = r-x;
- int h = b-y;
- if (pRect.equals(x, y, w, h)) {
- return 1;
+ int lx = max(x(), a->x());
+ int ly = max(y(), a->y());
+ int lr = min(r(), a->r());
+ int lb = min(b(), a->b());
+ int lw = lr-lx;
+ int lh = lb-ly;
+ if (equals(lx, ly, lw, lh)) {
+ return SAME;
}
- pRect.set(x, y, w, h);
- if ( (pRect.w()<=0) || (pRect.h()<=0) ) {
- pRect.clear();
- return 0;
+ set(lx, ly, lw, lh);
+ if ( (w()<=0) || (h()<=0) ) {
+ clear();
+ return EMPTY;
}
- return 2;
+ return LESS;
+}
+
+
+
+Fl_Complex_Region::~Fl_Complex_Region()
+{
+ delete pSubregion; // recursively delete all subregions
+ delete pNext; // recursively delete all following regions
}
+void Fl_Complex_Region::set(Fl_Rect *rect)
+{
+ delete pSubregion;
+ pSubregion = 0L;
+ delete pNext;
+ pNext = 0L;
+ Fl_Rect_Region::set(rect);
+}
+
void Fl_Android_Graphics_Driver::clip_region(Fl_Region r)
{
@@ -73,27 +91,28 @@ void Fl_Android_Graphics_Driver::restore_clip()
{
fl_clip_state_number++;
Fl_Window *win = Fl_Window::current();
- Fl_Clip_Rect a(0, 0, win->w(), win->h());
+ Fl_Rect_Region a(0, 0, win->w(), win->h());
Fl_Region b = rstack[rstackptr];
if (b) {
// FIXME: scaling!
a.intersect_with(b);
}
- pClipRect = a;
+ pWindowRegion.set(b);
+ // FIXME: intersect with complex window region
}
void Fl_Android_Graphics_Driver::push_clip(int x, int y, int w, int h)
{
Fl_Region r;
if (w > 0 && h > 0) {
- r = new Fl_Clip_Rect(x,y,w,h);
+ r = new Fl_Rect_Region(x,y,w,h);
Fl_Region current = rstack[rstackptr];
if (current) {
r->intersect_with(current);
}
} else { // make empty clip region:
- r = new Fl_Clip_Rect();
+ r = new Fl_Rect_Region();
}
if (rstackptr < region_stack_max) rstack[++rstackptr] = r;
else Fl::warning("Fl_Android_Graphics_Driver::push_clip: clip stack overflow!\n");
@@ -136,7 +155,7 @@ int Fl_Android_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int
return 0;
}
- Fl_Clip_Rect a(x, y, w, h);
+ Fl_Rect_Region a(x, y, w, h);
int ret = a.intersect_with(r); // return 0 for empty, 1 for same, 2 if intersecting
X = a.x();
Y = a.y();
@@ -161,7 +180,7 @@ int Fl_Android_Graphics_Driver::not_clipped(int x, int y, int w, int h) {
Fl_Region r = rstack[rstackptr];
if (!r) return 1;
- Fl_Clip_Rect a(x, y, w, h); // return 0 for empty, 1 for same, 2 if intersecting
+ Fl_Rect_Region a(x, y, w, h); // return 0 for empty, 1 for same, 2 if intersecting
return a.intersect_with(r);
}