summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt2
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Driver.H75
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Driver.cxx28
-rw-r--r--src/drivers/Android/Fl_Android_Graphics_Driver_region.cxx228
4 files changed, 187 insertions, 146 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 072fe0604..6534baea4 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -296,6 +296,8 @@ elseif (ANDROID)
# Android
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+
set (DRIVER_FILES
drivers/Android/Fl_Android_Application.cxx
drivers/Android/Fl_Android_System_Driver.cxx
diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver.H b/src/drivers/Android/Fl_Android_Graphics_Driver.H
index cbcf8eb37..fd23e95d6 100644
--- a/src/drivers/Android/Fl_Android_Graphics_Driver.H
+++ b/src/drivers/Android/Fl_Android_Graphics_Driver.H
@@ -26,7 +26,6 @@
#define FL_ANDROID_GRAPHICS_DRIVER_H
#include <FL/Fl_Graphics_Driver.H>
-#include <FL/Fl_Rect.H>
#include <limits.h>
@@ -34,34 +33,53 @@ class Fl_Android_Window_Driver;
/**
- * The Fl_Rect_Region is based on Fl_Rect with additional functionality for clipping.
+ * The Fl_Rect_Region describes a rectangular clipping region.
+ *
+ * Contrary to common FLTK convention, rectangles are stored with coordinates
+ * instead of their width and height to accelerate calculations. The discreet
+ * constructor however uses the old convention for convenience.
*/
-class Fl_Rect_Region : public Fl_Rect
+class Fl_Rect_Region
{
public:
- enum {
- EMPTY = 0, SAME, LESS, MORE
+ enum Type {
+ EMPTY = 0, SAME, LESS, MORE, INFINITE
};
- /**
- * 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);
- virtual void print();
-
- 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_Region();
+ Fl_Rect_Region(int x, int y, int w, int h);
+ Fl_Rect_Region(const Fl_Rect_Region&);
+ Fl_Rect_Region(enum Type what);
+ virtual ~Fl_Rect_Region() { }
+
+ int x() const { return pLeft; }
+ int y() const { return pTop; }
+ int w() const { return pRight - pLeft; }
+ int h() const { return pBottom - pTop; }
+
+ int left() const { return pLeft; }
+ int top() const { return pTop; }
+ int right() const { return pRight; }
+ int bottom() const { return pBottom; }
+ bool is_empty() const;
+ bool is_infinite() const;
+ void set_empty();
+ void set(int x, int y, int w, int h);
+ void set(const Fl_Rect_Region &r);
+ int intersect_with(const Fl_Rect_Region &r);
+
+ virtual void print(const char*) const;
+
+protected:
+ int pLeft, pTop, pRight, pBottom;
+
+private:
+ Fl_Rect_Region& operator = (const Fl_Rect_Region& other);
+};
+
+#if 0
/**
* The Fl_Complex_Region represents a clipping region of any shape.
*
@@ -85,9 +103,9 @@ public:
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 *rect);
- void subtract(Fl_Rect*);
- void intersect(Fl_Rect*);
+ 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; }
@@ -97,6 +115,7 @@ protected:
Fl_Complex_Region *pSubregion;
Fl_Complex_Region *pNext;
};
+#endif
/**
@@ -244,10 +263,8 @@ protected:
int32_t pStride;
uint16_t *pBits;
- // Fl_Rect_Region pScreenRegion;
- Fl_Rect_Region *pWindowRegion;
- Fl_Complex_Region *pDesktopRegion;
- Fl_Complex_Region *pClippingRegion;
+ Fl_Rect_Region pWindowRegion;
+ Fl_Rect_Region pClippingRegion;
};
diff --git a/src/drivers/Android/Fl_Android_Graphics_Driver.cxx b/src/drivers/Android/Fl_Android_Graphics_Driver.cxx
index dfd88e85a..817b5c0d1 100644
--- a/src/drivers/Android/Fl_Android_Graphics_Driver.cxx
+++ b/src/drivers/Android/Fl_Android_Graphics_Driver.cxx
@@ -37,10 +37,7 @@ Fl_Graphics_Driver *Fl_Graphics_Driver::newMainGraphicsDriver()
Fl_Android_Graphics_Driver::Fl_Android_Graphics_Driver() :
- pStride(0), pBits(0),
- pWindowRegion(new Fl_Rect_Region()),
- pDesktopRegion(new Fl_Complex_Region()),
- pClippingRegion(new Fl_Complex_Region())
+ pStride(0), pBits(0)
{
}
@@ -52,8 +49,6 @@ Fl_Android_Graphics_Driver::~Fl_Android_Graphics_Driver()
void Fl_Android_Graphics_Driver::make_current(Fl_Window *win)
{
- Fl_Android_Application::log_i("------------ make current \"%s\"", win->label());
-
// The Stride is the offset between lines in the graphics buffer
pStride = Fl_Android_Application::graphics_buffer().stride;
// Bits is the memory address of the top left corner of the window
@@ -62,13 +57,10 @@ void Fl_Android_Graphics_Driver::make_current(Fl_Window *win)
// TODO: set the clipping area
// set the clipping area to the physical screen size in window coordinates
- pWindowRegion->set(-win->x(), -win->y(), 600, 800);
- Fl_Rect_Region wr(0, 0, win->w(), win->h());
- pWindowRegion->intersect_with(&wr);
- pWindowRegion->print();
-
- pDesktopRegion->set(pWindowRegion);
+ pWindowRegion.set(-win->x(), -win->y(), 600, 800);
+ pWindowRegion.intersect_with(Fl_Rect_Region(0, 0, win->w(), win->h()));
+#if 0
// 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
Fl_Window *wTop = Fl::first_window();
@@ -78,11 +70,9 @@ void Fl_Android_Graphics_Driver::make_current(Fl_Window *win)
pDesktopRegion->subtract(&r);
wTop = Fl::next_window(wTop);
}
+#endif
- // TODO: we can optimize this by using some "copy on write" system
- pClippingRegion->clone(pDesktopRegion);
- pClippingRegion->print();
- Fl_Android_Application::log_i("------------ make current done");
+ pClippingRegion.set(pWindowRegion);
}
@@ -106,7 +96,7 @@ static uint16_t make565(Fl_Color crgba)
void Fl_Android_Graphics_Driver::rectf_unscaled(float x, float y, float w, float h)
{
Fl_Rect_Region r(x, y, w, h);
- if (r.intersect_with((Fl_Rect_Region*)pClippingRegion)) {
+ if (r.intersect_with(pClippingRegion)) {
rectf_unclipped(r.x(), r.y(), r.w(), r.h());
}
// TODO: create a complex region by intersecting r with the pClippingRegion
@@ -135,8 +125,8 @@ void Fl_Android_Graphics_Driver::rectf_unscaled(float x, float y, float w, float
*/
}
-void Fl_Android_Graphics_Driver::rectf_unclipped(float x, float y, float w, float h) {
- Fl_Android_Application::log_w("rectf unclipped %g %g %g %g", x, y, w, h);
+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
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$".
//