add stop service
[enigma2.git] / lib / gdi / region.cpp
index f341e79a61de30aeb17bc6918c91be336acee6a7..d75221fe882f6e2794be6555e6c94a29c2eaad8f 100644 (file)
@@ -1,6 +1,7 @@
 #include <lib/gdi/erect.h>
 #include <lib/gdi/epoint.h>
 #include <lib/gdi/region.h>
 #include <lib/gdi/erect.h>
 #include <lib/gdi/epoint.h>
 #include <lib/gdi/region.h>
+#include <lib/base/eerror.h>
 
 #undef max
 #define max(a,b)  ((a) > (b) ? (a) : (b))
 
 #undef max
 #define max(a,b)  ((a) > (b) ? (a) : (b))
 
 gRegion::gRegion(const eRect &rect) : extends(rect)
 {
 
 gRegion::gRegion(const eRect &rect) : extends(rect)
 {
-       rects.push_back(rect);
+       if (rect.valid() && !rect.empty())
+               rects.push_back(rect);
 }
 
 }
 
-gRegion::gRegion()
+gRegion::gRegion() : extends(eRect::emptyRect())
 {
 }
 
 {
 }
 
@@ -87,7 +89,7 @@ void gRegion::appendNonO(std::vector<eRect>::const_iterator r,
        rects.reserve(rects.size() + newRects);
        do {
                assert(r->x1 < r->x2);
        rects.reserve(rects.size() + newRects);
        do {
                assert(r->x1 < r->x2);
-               rects.push_back(eRect(r->x1, y1, r->x2, y2));
+               rects.push_back(eRect(r->x1, y1, r->x2 - r->x1, y2 - y1));
                r++;
        } while (r != rEnd);
 }
                r++;
        } while (r != rEnd);
 }
@@ -110,7 +112,7 @@ void gRegion::intersectO(
                x2 = min(r1->x2, r2->x2);
                
                if (x1 < x2)
                x2 = min(r1->x2, r2->x2);
                
                if (x1 < x2)
-                       rects.push_back(eRect(x1, y1, x2, y2));
+                       rects.push_back(eRect(x1, y1, x2 - x1, y2 - y1));
                if (r1->x2 == x2)
                        r1++;
                if (r2->x2 == x2)
                if (r1->x2 == x2)
                        r1++;
                if (r2->x2 == x2)
@@ -145,7 +147,7 @@ void gRegion::subtractO(
                                ++r2;
                } else if (r2->x1 < r1->x2) {
                        assert(x1<r2->x1);
                                ++r2;
                } else if (r2->x1 < r1->x2) {
                        assert(x1<r2->x1);
-                       rects.push_back(eRect(x1, y1, r2->x1, y2));
+                       rects.push_back(eRect(x1, y1, r2->x1 - x1, y2 - y1));
                        x1 = r2->x2;
                        if (x1 >= r1->x2) {
                                ++r1;
                        x1 = r2->x2;
                        if (x1 >= r1->x2) {
                                ++r1;
@@ -156,7 +158,7 @@ void gRegion::subtractO(
                } else
                {
                        if (r1->x2 > x1)
                } else
                {
                        if (r1->x2 > x1)
-                               rects.push_back(eRect(x1, y1, r1->x2, y2));
+                               rects.push_back(eRect(x1, y1, r1->x2 - x1, y2 - y1));
                        ++r1;
                        if (r1 != r1End)
                                x1 = r1->x1;
                        ++r1;
                        if (r1 != r1End)
                                x1 = r1->x1;
@@ -165,7 +167,7 @@ void gRegion::subtractO(
        while (r1 != r1End)
        {
                assert(x1<r1->x2);
        while (r1 != r1End)
        {
                assert(x1<r1->x2);
-               rects.push_back(eRect(x1, y1, r1->x2, y2));
+               rects.push_back(eRect(x1, y1, r1->x2 - x1, y2 - y1));
                ++r1;
                if (r1 != r1End)
                        x1 = r1->x1;
                ++r1;
                if (r1 != r1End)
                        x1 = r1->x1;
@@ -180,7 +182,7 @@ void gRegion::subtractO(
                if (x2 < r->x2) x2 = r->x2;                             \
        } else {                                                  \
                /* Add current rectangle, start new one */              \
                if (x2 < r->x2) x2 = r->x2;                             \
        } else {                                                  \
                /* Add current rectangle, start new one */              \
-               rects.push_back(eRect(x1, y1, x2, y2));                 \
+               rects.push_back(eRect(x1, y1, x2 - x1, y2 - y1));       \
                x1 = r->x1;                                             \
                x2 = r->x2;                                             \
        }                                                         \
                x1 = r->x1;                                             \
                x2 = r->x2;                                             \
        }                                                         \
@@ -225,7 +227,7 @@ void gRegion::mergeO(
                        MERGERECT(r2);
                } while (r2 != r2End);
        }
                        MERGERECT(r2);
                } while (r2 != r2End);
        }
-       rects.push_back(eRect(x1, y1, x2, y2));
+       rects.push_back(eRect(x1, y1, x2 - x1, y2 - y1));
 }
 
 void gRegion::regionOp(const gRegion &reg1, const gRegion &reg2, int opcode, int &overlap)
 }
 
 void gRegion::regionOp(const gRegion &reg1, const gRegion &reg2, int opcode, int &overlap)
@@ -264,8 +266,8 @@ void gRegion::regionOp(const gRegion &reg1, const gRegion &reg2, int opcode, int
                                bot = min(r1->y2, r2y1);
                                if (top != bot) {
                                        curBand = rects.size();
                                bot = min(r1->y2, r2y1);
                                if (top != bot) {
                                        curBand = rects.size();
-                                               appendNonO(r1, r1BandEnd, top, bot);
-                                               coalesce(prevBand, curBand);
+                                       appendNonO(r1, r1BandEnd, top, bot);
+                                       coalesce(prevBand, curBand);
                                }
                        }
                        ytop = r2y1;
                                }
                        }
                        ytop = r2y1;
@@ -318,10 +320,28 @@ void gRegion::regionOp(const gRegion &reg1, const gRegion &reg2, int opcode, int
                coalesce(prevBand, curBand);
                AppendRegions(r2BandEnd, r2End);
        }
                coalesce(prevBand, curBand);
                AppendRegions(r2BandEnd, r2End);
        }
+       
+       extends = eRect();
+
+       for (unsigned int a = 0; a<rects.size(); ++a)
+               extends = extends | rects[a];
+       if (!extends.valid())
+               extends = eRect::emptyRect();
 }
        
 void gRegion::intersect(const gRegion &r1, const gRegion &r2)
 {
 }
        
 void gRegion::intersect(const gRegion &r1, const gRegion &r2)
 {
+               /* in case one region is empty, the resulting regions is empty, too. */
+       if (r1.rects.empty())
+       {
+               *this = r1;
+               return;
+       }
+       if (r2.rects.empty())
+       {
+               *this = r2;
+               return;
+       }
        int overlap;
        // TODO: handle trivial reject
        regionOp(r1, r2, OP_INTERSECT, overlap);
        int overlap;
        // TODO: handle trivial reject
        regionOp(r1, r2, OP_INTERSECT, overlap);
@@ -329,6 +349,11 @@ void gRegion::intersect(const gRegion &r1, const gRegion &r2)
 
 void gRegion::subtract(const gRegion &r1, const gRegion &r2)
 {
 
 void gRegion::subtract(const gRegion &r1, const gRegion &r2)
 {
+       if (r1.rects.empty() || r2.rects.empty())
+       {
+               *this = r1;
+               return;
+       }
        int overlap;
        // TODO: handle trivial reject
        regionOp(r1, r2, OP_SUBTRACT, overlap);
        int overlap;
        // TODO: handle trivial reject
        regionOp(r1, r2, OP_SUBTRACT, overlap);
@@ -336,8 +361,68 @@ void gRegion::subtract(const gRegion &r1, const gRegion &r2)
        
 void gRegion::merge(const gRegion &r1, const gRegion &r2)
 {
        
 void gRegion::merge(const gRegion &r1, const gRegion &r2)
 {
+       if (r1.rects.empty())
+       {
+               *this = r2;
+               return;
+       }
+       if (r2.rects.empty())
+       {
+               *this = r1;
+               return;
+       }
        int overlap;
        // TODO: handle trivial reject
        regionOp(r1, r2, OP_UNION, overlap);
 }
 
        int overlap;
        // TODO: handle trivial reject
        regionOp(r1, r2, OP_UNION, overlap);
 }
 
+gRegion gRegion::operator&(const gRegion &r2) const
+{
+       gRegion res;
+       res.intersect(*this, r2);
+       return res;
+}
+
+gRegion gRegion::operator-(const gRegion &r2) const 
+{
+       gRegion res;
+       res.subtract(*this, r2);
+       return res;
+}
+
+gRegion gRegion::operator|(const gRegion &r2) const
+{
+       gRegion res;
+       res.merge(*this, r2);
+       return res;
+}
+
+gRegion &gRegion::operator&=(const gRegion &r2)
+{
+       gRegion res;
+       res.intersect(*this, r2);
+       return *this = res;
+}
+
+gRegion &gRegion::operator-=(const gRegion &r2)
+{
+       gRegion res;
+       res.subtract(*this, r2);
+       return *this = res;
+}
+
+gRegion &gRegion::operator|=(const gRegion &r2)
+{
+       gRegion res;
+       res.merge(*this, r2);
+       return *this = res;
+}
+
+void gRegion::moveBy(ePoint offset)
+{
+       extends.moveBy(offset);
+       unsigned int i;
+       for (i=0; i<rects.size(); ++i)
+               rects[i].moveBy(offset);
+}
+