diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/drivers/Android/Fl_Android_Graphics_Driver.H | 63 | ||||
| -rw-r--r-- | src/drivers/Android/Fl_Android_Graphics_Driver.cxx | 26 | ||||
| -rw-r--r-- | src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx | 71 |
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); } |
