#ifndef __lib_gdi_region_h #define __lib_gdi_region_h #include #include #include class gRegion { private: inline void FindBand( std::vector::const_iterator r, std::vector::const_iterator &rBandEnd, std::vector::const_iterator rEnd, int &ry1) { ry1 = r->y1; rBandEnd = r+1; while ((rBandEnd != rEnd) && (rBandEnd->y1 == ry1)) rBandEnd++; } inline void AppendRegions( std::vector::const_iterator r, std::vector::const_iterator rEnd) { rects.insert(rects.end(), r, rEnd); } int do_coalesce(int prevStart, unsigned int curStart); inline void coalesce(int &prevBand, unsigned int curBand) { if (curBand - prevBand == rects.size() - curBand) { prevBand = do_coalesce(prevBand, curBand); } else { prevBand = curBand; } }; void appendNonO(std::vector::const_iterator r, std::vector::const_iterator rEnd, int y1, int y2); void intersectO( std::vector::const_iterator r1, std::vector::const_iterator r1End, std::vector::const_iterator r2, std::vector::const_iterator r2End, int y1, int y2, int &overlap); void subtractO( std::vector::const_iterator r1, std::vector::const_iterator r1End, std::vector::const_iterator r2, std::vector::const_iterator r2End, int y1, int y2, int &overlap); void mergeO( std::vector::const_iterator r1, std::vector::const_iterator r1End, std::vector::const_iterator r2, std::vector::const_iterator r2End, int y1, int y2, int &overlap); void regionOp(const gRegion ®1, const gRegion ®2, int opcode, int &overlap); public: std::vector rects; eRect extends; enum { // note: bit 0 and bit 1 have special meanings OP_INTERSECT = 0, OP_SUBTRACT = 1, OP_UNION = 3 }; gRegion(const eRect &rect); gRegion(); virtual ~gRegion(); gRegion operator&(const gRegion &r2) const; gRegion operator-(const gRegion &r2) const; gRegion operator|(const gRegion &r2) const; gRegion &operator&=(const gRegion &r2); gRegion &operator-=(const gRegion &r2); gRegion &operator|=(const gRegion &r2); void intersect(const gRegion &r1, const gRegion &r2); void subtract(const gRegion &r1, const gRegion &r2); void merge(const gRegion &r1, const gRegion &r2); void moveBy(ePoint offset); bool empty() const { return extends.empty(); } bool valid() const { return extends.valid(); } static gRegion invalidRegion() { return gRegion(eRect::invalidRect()); } void scale(int x_n, int x_d, int y_n, int y_d); }; #endif