#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))
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())
{
}
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);
}
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)
++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;
} 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;
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;
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; \
} \
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 ®1, const gRegion ®2, int opcode, int &overlap)
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;
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)
{
+ /* 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);
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);
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);
}
+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);
+}
+