From ce5371cbf00e504e1e1b08a417c9d254be487da1 Mon Sep 17 00:00:00 2001 From: Matthias Melcher Date: Thu, 15 Mar 2018 21:50:27 +0000 Subject: Android: clipping code cleanup, xy and yx lines are clipped git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12755 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- src/drivers/Android/Fl_Android_Graphics_Driver.H | 32 ++++--- src/drivers/Android/Fl_Android_Graphics_Driver.cxx | 101 +++++---------------- .../Android/Fl_Android_Graphics_Driver_region.cxx | 93 +------------------ 3 files changed, 45 insertions(+), 181 deletions(-) diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver.H b/src/drivers/Android/Fl_Android_Graphics_Driver.H index e20f02a19..53118dc15 100644 --- a/src/drivers/Android/Fl_Android_Graphics_Driver.H +++ b/src/drivers/Android/Fl_Android_Graphics_Driver.H @@ -118,7 +118,7 @@ class Fl_Complex_Region : public Fl_Rect_Region Overlapping *pOv; }; public: - Overlapping(Fl_Complex_Region *rgn, Fl_Rect_Region &rect); + Overlapping(Fl_Complex_Region *rgn, const Fl_Rect_Region &rect); OverlappingIterator begin(); OverlappingIterator end(); Fl_Rect_Region &clipped_rect(); @@ -151,7 +151,7 @@ public: Iterator begin(); Iterator end(); - Overlapping overlapping(Fl_Rect_Region &r); + Overlapping overlapping(const Fl_Rect_Region &r); protected: void print_data(int indent) const; @@ -189,7 +189,7 @@ protected: #endif public: Fl_Android_Graphics_Driver(); - ~Fl_Android_Graphics_Driver(); + virtual ~Fl_Android_Graphics_Driver() override; #if 0 Fl_GDI_Graphics_Driver() {mask_bitmap_ = NULL; gc_ = NULL; p_size = 0; p = NULL; depth = -1; origins = NULL;} virtual ~Fl_GDI_Graphics_Driver() { if (p) free(p); delete[] origins;} @@ -202,7 +202,7 @@ public: Fl_Bitmask create_bitmask(int w, int h, const uchar *array); void delete_bitmask(Fl_Bitmask bm); #endif - virtual void draw_unscaled(const char* str, int n, int x, int y); + virtual void draw_unscaled(const char* str, int n, int x, int y) override; #if 0 virtual void draw_unscaled(int angle, const char *str, int n, int x, int y); virtual void rtl_draw_unscaled(const char* str, int n, int x, int y); @@ -244,14 +244,16 @@ protected: void rect_unscaled(float x, float y, float w, float h); void focus_rect(int x, int y, int w, int h); #endif - void rectf_unscaled(float x, float y, float w, float h); + virtual void rectf_unscaled(float x, float y, float w, float h) override; void rectf_unclipped(float x, float y, float w, float h); #if 0 virtual void line_unscaled(float x, float y, float x1, float y1); virtual void line_unscaled(float x, float y, float x1, float y1, float x2, float y2); #endif - virtual void xyline_unscaled(float x, float y, float x1); - virtual void yxline_unscaled(float x, float y, float y1); + virtual void xyline_unscaled(float x, float y, float x1) override; + void xyline_unclipped(float x, float y, float x1); + virtual void yxline_unscaled(float x, float y, float y1) override; + void yxline_unclipped(float x, float y, float y1); #if 0 virtual void loop_unscaled(float x0, float y0, float x1, float y1, float x2, float y2); virtual void loop_unscaled(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3); @@ -259,14 +261,14 @@ protected: virtual void polygon_unscaled(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3); #endif // --- clipping - void push_clip(int x, int y, int w, int h); - int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H); - int not_clipped(int x, int y, int w, int h); - void push_no_clip(); - void pop_clip(); - void restore_clip(); - void clip_region(Fl_Region r); - Fl_Region clip_region(); + virtual void push_clip(int x, int y, int w, int h) override; + virtual int clip_box(int x, int y, int w, int h, int &X, int &Y, int &W, int &H) override; + virtual int not_clipped(int x, int y, int w, int h) override; + virtual void push_no_clip() override; + virtual void pop_clip() override; + virtual void restore_clip() override; + virtual void clip_region(Fl_Region r) override; + virtual Fl_Region clip_region() override; #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 aa2bcd937..e3dde7d06 100644 --- a/src/drivers/Android/Fl_Android_Graphics_Driver.cxx +++ b/src/drivers/Android/Fl_Android_Graphics_Driver.cxx @@ -61,7 +61,6 @@ void Fl_Android_Graphics_Driver::make_current(Fl_Window *win) pWindowRegion.intersect_with(Fl_Rect_Region(0, 0, win->w(), win->h())); 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 @@ -72,9 +71,7 @@ void Fl_Android_Graphics_Driver::make_current(Fl_Window *win) pDesktopWindowRegion.subtract(r); wTop = Fl::next_window(wTop); } - pDesktopWindowRegion.print(" #### DESKTOP"); pClippingRegion.set(pDesktopWindowRegion); - pClippingRegion.print("#### CLIPPING"); } @@ -95,88 +92,20 @@ static uint16_t make565(Fl_Color crgba) ((crgba >>11) & 0x001f) ); } + void Fl_Android_Graphics_Driver::rectf_unscaled(float x, float y, float w, float h) { -#if 1 - - Fl_Rect_Region r(x, y, w, h); - for (const auto &it: pClippingRegion.overlapping(r)) { -#if 1 + for (const auto &it: pClippingRegion.overlapping(Fl_Rect_Region(x, y, w, h))) { Fl_Rect_Region s(it->clipped_rect()); rectf_unclipped(s.x(), s.y(), s.w(), s.h()); -#else - if (it->is_simple()) { - Fl_Rect_Region r(x, y, w, h); - if (r.intersect_with(*it)) { - rectf_unclipped(r.x(), r.y(), r.w(), r.h()); - } - } -#endif - } - -#elif 0 - - // This is elegant code, but it is not efficient. It walks the entire tree - // and checks for intersetion, even if the parent region indicated that there - // is no intersection. - // - // Maybe we can add a parameter somewhere so that the iterator runs the tree - // based on a give rectangle. - - for (const auto &it: pClippingRegion) { - // TODO: if region is complex, but doesn't intersect, can we somehow manipulate the iterator? - if (it->is_simple()) { - Fl_Rect_Region r(x, y, w, h); - if (r.intersect_with(*it)) { - rectf_unclipped(r.x(), r.y(), r.w(), r.h()); - } - } - } - -#else - - // This code is massiv and ugly and has the same problem in that it does not - // optimize the number of tests for intersections. - - r.print("---- fl_rectf"); - pClippingRegion.print("clip to"); - - 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)) { - rectf_unclipped(r.x(), r.y(), r.w(), r.h()); - } - } } - -#endif } + void Fl_Android_Graphics_Driver::rectf_unclipped(float x, float y, float w, float h) { if (w<=0 || h<=0) return; -// TODO: clip the rectangle to the window outline -// TODO: clip the rectangle to all parts of the window region -// TODo: clip the rectangle to all parts of the current clipping region - uint16_t cc = make565(color()); int32_t ss = pStride; uint16_t *bits = pBits; @@ -192,9 +121,9 @@ void Fl_Android_Graphics_Driver::rectf_unclipped(float x, float y, float w, floa } } + void Fl_Android_Graphics_Driver::xyline_unscaled(float x, float y, float x1) { - uint16_t cc = make565(color()); float w; if (x1>x) { w = x1-x; @@ -202,6 +131,17 @@ void Fl_Android_Graphics_Driver::xyline_unscaled(float x, float y, float x1) w = x-x1; x = x1; } + for (const auto &it: pClippingRegion.overlapping(Fl_Rect_Region(x, y, w, 1))) { + Fl_Rect_Region s(it->clipped_rect()); + xyline_unclipped(s.x(), s.y(), s.right()); + } +} + + +void Fl_Android_Graphics_Driver::xyline_unclipped(float x, float y, float x1) +{ + uint16_t cc = make565(color()); + float w = x1-x; int32_t ss = pStride; uint16_t *bits = pBits; uint32_t xx = (uint32_t)x; @@ -215,7 +155,6 @@ void Fl_Android_Graphics_Driver::xyline_unscaled(float x, float y, float x1) void Fl_Android_Graphics_Driver::yxline_unscaled(float x, float y, float y1) { - uint16_t cc = make565(color()); float h; if (y1>y) { h = y1-y; @@ -223,6 +162,16 @@ void Fl_Android_Graphics_Driver::yxline_unscaled(float x, float y, float y1) h = y-y1; y = y1; } + for (const auto &it: pClippingRegion.overlapping(Fl_Rect_Region(x, y, 1, h))) { + Fl_Rect_Region s(it->clipped_rect()); + yxline_unclipped(s.x(), s.y(), s.bottom()); + } +} + +void Fl_Android_Graphics_Driver::yxline_unclipped(float x, float y, float y1) +{ + uint16_t cc = make565(color()); + float h = y1-y; int32_t ss = pStride; uint16_t *bits = pBits; uint32_t xx = (uint32_t)x; diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx b/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx index 1763a8d0f..1271ec66e 100644 --- a/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx +++ b/src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx @@ -220,11 +220,6 @@ void Fl_Complex_Region::set(const Fl_Rect_Region &r) void Fl_Complex_Region::set(const Fl_Complex_Region &r) { -#if 0 - Fl_Android_Application::log_e("Not yet implemented!"); - delete pSubregion; pSubregion = 0; - Fl_Rect_Region::set(r); -#else // outline: // clear this region and copy the coordinates from r delete pSubregion; pSubregion = 0; @@ -237,7 +232,6 @@ void Fl_Complex_Region::set(const Fl_Complex_Region &r) pNext = new Fl_Complex_Region(); pNext->set(*r.next()); } -#endif } @@ -252,14 +246,11 @@ int Fl_Complex_Region::intersect_with(const Fl_Rect_Region &r) 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: @@ -287,9 +278,7 @@ int Fl_Complex_Region::subtract(const Fl_Rect_Region &r) 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(""); + // FIXME: make sure that the bbox of the parent region is shrunk to the size of all children // 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 @@ -320,8 +309,6 @@ int Fl_Complex_Region::subtract_smaller_region(const Fl_Rect_Region &r) Fl_Complex_Region *s = add_subregion(); s->set_ltrb(r.right(), r.top(), pRight, r.bottom()); } - //Fl_Android_Application::log_w("Regions too complex. Not yet implemented"); - print("-- added subregions"); } return 0; } @@ -383,14 +370,14 @@ Fl_Complex_Region *Fl_Complex_Region::Iterator::operator*() const // ----------------------------------------------------------------------------- -Fl_Complex_Region::Overlapping Fl_Complex_Region::overlapping(Fl_Rect_Region &r) +Fl_Complex_Region::Overlapping Fl_Complex_Region::overlapping(const Fl_Rect_Region &r) { return Overlapping(this, r); } Fl_Complex_Region::Overlapping::Overlapping(Fl_Complex_Region *rgn, - Fl_Rect_Region &rect) : + const Fl_Rect_Region &rect) : pRegion(rgn), pOriginalRect(rect), pClippedRect(rect) @@ -428,9 +415,6 @@ bool Fl_Complex_Region::Overlapping::find_intersecting() for (;;) { if (!pRegion) return false; pClippedRect.set(pOriginalRect); - pRegion->print("find intersetion"); - pClippedRect.print("with"); - pOriginalRect.print("with"); if (intersects()) { if (!pRegion->subregion()) { return true; @@ -493,77 +477,6 @@ Fl_Complex_Region::Overlapping::OverlappingIterator::operator*() const // ============================================================================= -#if 0 - -void Fl_Complex_Region::set(int x, int y, int w, int h) -{ - // TODO: refactor the next four lines out, repeating - delete pSubregion; - pSubregion = 0L; - delete pNext; - pNext = 0L; - Fl_Rect_Region::set(x, y, w, h); -} - -void Fl_Complex_Region::set(Fl_Rect *rect) -{ - delete pSubregion; - pSubregion = 0L; - delete pNext; - pNext = 0L; - Fl_Rect_Region::set(rect); -} - -/** - * Subtract a rectangle from this region. - * - * This operation may create multiple new subregions, but possibly also remove - * subregions. - * - * @param x, y, w, h rectangular region that will be subtracted - */ -void Fl_Complex_Region::subtract(Fl_Rect *r) -{ - Fl_Android_Application::log_i("------------ subtract"); - this->print(); - Fl_Android_Application::log_i("--------"); - Fl_Android_Application::log_i("Rect %d %d %d %d", r->x(), r->y(), r->w(), r->h()); - // ---- - this->print(); - Fl_Android_Application::log_i("------------ subtract done"); - // FIXME: implement - int x = 3; -} - -void Fl_Complex_Region::intersect(Fl_Rect*) -{ - // FIXME: implement -} - -void Fl_Complex_Region::clone(Fl_Complex_Region *r) -{ - // FIXME: implement - // make this region simple and copy the bounding box - set(r); - if (r->pSubregion) { - pSubregion = new Fl_Complex_Region(); - pSubregion->clone(r->pSubregion); - } - if (r->pNext) { - pNext = new Fl_Complex_Region(); - pNext->clone(r->pNext); - } -} - -void Fl_Complex_Region::print() -{ - Fl_Android_Application::log_i("-------- begin region"); - print_data(0); -} - -#endif - - void Fl_Android_Graphics_Driver::restore_clip() { -- cgit v1.2.3