diff options
| author | Matthias Melcher <fltk@matthiasm.com> | 2018-03-12 12:57:28 +0000 |
|---|---|---|
| committer | Matthias Melcher <fltk@matthiasm.com> | 2018-03-12 12:57:28 +0000 |
| commit | 1b52ead802e1f3b24c33cadacb8d67dbfb209253 (patch) | |
| tree | 9db02c4ee0d18a9c937f28bb9fa80fc6584cbff2 /src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx | |
| parent | 371cfd1476de37c4741b6455af77bfc9a07cd9c1 (diff) | |
Android: Reinstated working simple cliping functionality based on an
improved Fl_Rect_Region class instead of Fl_Rect. Commented out
complex clipping.
Android lib and apps now use C++11 because they can (and I like it).
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12741 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx')
| -rw-r--r-- | src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx | 228 |
1 files changed, 130 insertions, 98 deletions
diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx b/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx index 30131cf05..e3ffafc54 100644 --- a/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx +++ b/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx @@ -23,41 +23,132 @@ #include <FL/platform.H> -// return 0 for empty, 1 for same, 2 if intersecting -int Fl_Rect_Region::intersect_with(Fl_Rect_Region *a) +/** + * Create an empty clipping region. + */ +Fl_Rect_Region::Fl_Rect_Region() : + pLeft(0), pTop(0), pRight(0), pBottom(0) +{ +} + +/** + * Create a clipping region based on position and size. + * @param x, y position + * @param w, h size + */ +Fl_Rect_Region::Fl_Rect_Region(int x, int y, int w, int h) : + pLeft(x), pTop(y), pRight(x+w), pBottom(y+h) +{ +} + +/** + * Clone a clipping rectangle. + */ +Fl_Rect_Region::Fl_Rect_Region(const Fl_Rect_Region &r) : + pLeft(r.pLeft), pTop(r.pTop), + pRight(r.pRight), pBottom(r.pBottom) +{ +} + +/** + * Clone a clipping rectangle. + * The pointer can be NULL if an empty rectangle is needed. + */ +Fl_Rect_Region::Fl_Rect_Region(enum Type what) +{ + if (what==INFINITE) { + pLeft = pTop = INT_MIN; + pRight = pBottom = INT_MAX; + } else { + pLeft = pTop = pRight = pBottom = 0; + } +} + +/** + * If the rectangle has no width or height, it's considered empty. + * @return true, if everything will be clipped and there is nothing to draw + */ +bool Fl_Rect_Region::is_empty() const +{ + return (pRight<=pLeft || pBottom<=pTop); +} + +/** + * Return true, if the rectangle is of unlimited size and nothing should be clipped. + * @return treu, if there is no clipping + */ +bool Fl_Rect_Region::is_infinite() const +{ + return (pLeft==INT_MIN); +} + + +void Fl_Rect_Region::set_empty() +{ + pLeft = pTop = pRight = pBottom = 0; +} + + +void Fl_Rect_Region::set(int x, int y, int w, int h) +{ + pLeft = x; + pTop = y; + pRight = x+w; + pBottom = y+h; +} + + +void Fl_Rect_Region::set(const Fl_Rect_Region &r) +{ + pLeft = r.pLeft; + pTop = r.pTop; + pRight = r.pRight; + pBottom = r.pBottom; +} + + +int Fl_Rect_Region::intersect_with(const Fl_Rect_Region &r) { if (is_empty()) { return EMPTY; } - if (a->is_empty()) { - clear(); + if (r.is_empty()) { + set_empty(); return EMPTY; } - 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; + bool same = true; + if ( pLeft != r.pLeft ) { + same = false; + if ( r.pLeft > pLeft ) pLeft = r.pLeft; } - set(lx, ly, lw, lh); - if ( (w()<=0) || (h()<=0) ) { - clear(); - return EMPTY; + if ( pTop != r.pTop ) { + same = false; + if ( r.pTop > pTop ) pTop = r.pTop; + } + if ( pRight != r.pRight ) { + same = false; + if ( r.pRight < pRight ) pRight = r.pRight; + } + if ( pBottom != r.pBottom ) { + same = false; + if ( r.pBottom < pBottom ) pBottom = r.pBottom; } + if (same) + return SAME; + if (is_empty()) + return EMPTY; return LESS; } -void Fl_Rect_Region::print() +void Fl_Rect_Region::print(const char *label) const { - Fl_Android_Application::log_i("-------- begin rect"); + Fl_Android_Application::log_i("---> Fl_Rect_Region: %s", label); Fl_Android_Application::log_i("Rect %d %d %d %d", x(), y(), w(), h()); } +#if 0 Fl_Complex_Region::~Fl_Complex_Region() { @@ -151,6 +242,7 @@ void Fl_Complex_Region::print() print_data(0); } +#endif @@ -158,18 +250,12 @@ void Fl_Android_Graphics_Driver::restore_clip() { fl_clip_state_number++; - // TODO: we can optimize this by using some "copy on write" system - Fl_Android_Application::log_i("------------ restore_clip"); - pDesktopRegion->print(); - //pClippingRegion->set(pWindowRegion); - pClippingRegion->clone(pDesktopRegion); + pClippingRegion.set(pWindowRegion); Fl_Region b = rstack[rstackptr]; if (b) { - pClippingRegion->intersect_with(b); - pClippingRegion->print(); + pClippingRegion.intersect_with(*b); } - Fl_Android_Application::log_i("------------ restore_clip done"); } @@ -193,10 +279,10 @@ 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_Rect_Region(x,y,w,h); + r = new Fl_Rect_Region(x, y, w, h); Fl_Region current = rstack[rstackptr]; if (current) { - r->intersect_with(current); + r->intersect_with(*current); } } else { // make empty clip region: r = new Fl_Rect_Region(); @@ -239,19 +325,18 @@ void Fl_Android_Graphics_Driver::pop_clip() int Fl_Android_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H) { Fl_Region r = rstack[rstackptr]; - if (!r) { + if (r) { + Fl_Rect_Region a(x, y, w, h); + int ret = a.intersect_with(*r); + X = a.x(); + Y = a.y(); + W = a.w(); + H = a.h(); + return (ret!=Fl_Rect_Region::SAME); + } else { X = x; Y = y; W = w; H = h; return 0; } - - 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(); - W = a.w(); - H = a.h(); - - return (ret!=1); } /* @@ -264,72 +349,19 @@ int Fl_Android_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int Under X this returns 2 if the rectangle is partially clipped, and 1 if it is entirely inside the clip region. */ -int Fl_Android_Graphics_Driver::not_clipped(int x, int y, int w, int h) { - if (x+w <= 0 || y+h <= 0) return 0; - Fl_Region r = rstack[rstackptr]; - if (!r) return 1; - - Fl_Rect_Region a(x, y, w, h); // return 0 for empty, 1 for same, 2 if intersecting - return a.intersect_with(r); -} - -#if 0 - -// --- clipping - -int Fl_GDI_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){ - X = x; Y = y; W = w; H = h; - Fl_Region r = rstack[rstackptr]; - if (!r) return 0; - // The win32 API makes no distinction between partial and complete - // intersection, so we have to check for partial intersection ourselves. - // However, given that the regions may be composite, we have to do - // some voodoo stuff... - Fl_Region rr = XRectangleRegion(x,y,w,h); - Fl_Region temp = CreateRectRgn(0,0,0,0); - int ret; - if (CombineRgn(temp, rr, r, RGN_AND) == NULLREGION) { // disjoint - W = H = 0; - ret = 2; - } else if (EqualRgn(temp, rr)) { // complete - ret = 0; - } else { // partial intersection - RECT rect; - GetRgnBox(temp, &rect); - if (Fl_Surface_Device::surface() != Fl_Display_Device::display_device()) { // if print context, convert coords from device to logical - POINT pt[2] = { {rect.left, rect.top}, {rect.right, rect.bottom} }; - DPtoLP(gc_, pt, 2); - X = pt[0].x; Y = pt[0].y; W = pt[1].x - X; H = pt[1].y - Y; - } - else { - X = rect.left; Y = rect.top; W = rect.right - X; H = rect.bottom - Y; - } - ret = 1; - } - DeleteObject(temp); - DeleteObject(rr); - return ret; -} - -int Fl_GDI_Graphics_Driver::not_clipped(int x, int y, int w, int h) { - if (x+w <= 0 || y+h <= 0) return 0; +int Fl_Android_Graphics_Driver::not_clipped(int x, int y, int w, int h) +{ + if (w <= 0 || h <= 0) return 0; Fl_Region r = rstack[rstackptr]; - if (!r) return 1; - RECT rect; - if (Fl_Surface_Device::surface() != Fl_Display_Device::display_device()) { // in case of print context, convert coords from logical to device - POINT pt[2] = { {x, y}, {x + w, y + h} }; - LPtoDP(gc_, pt, 2); - rect.left = pt[0].x; rect.top = pt[0].y; rect.right = pt[1].x; rect.bottom = pt[1].y; + if (r) { + Fl_Rect_Region a(x, y, w, h); // return 0 for empty, 1 for same, 2 if intersecting + return a.intersect_with(*r); } else { - rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h; + return 1; } - return RectInRegion(r,&rect); } -#endif - - // // End of "$Id$". // |
