Main Page | Namespace List | Class Hierarchy | Class List | File List | Namespace Members | Class Members | Related Pages

region.h

00001 // This interface is based on the one in the file region.h in gtk+.
00002 // That file didn't contain license info, so is presumably under the
00003 // same LGPL license as the rest of that library.
00004 
00005 // Stolen from Gtk+ and C++-ized by Ron Steinke, January 2003
00006 
00007 #ifndef _WFTK_REGION_H_
00008 #define _WFTK_REGION_H_
00009 
00010 #include <SDL/SDL.h>
00011 
00012 #include <wftk/point.h>
00013 #include <wftk/rect.h>
00014 #include <vector>
00015 #include <cassert>
00016 
00017 namespace wftk { 
00018 
00021 class Region
00022 {
00023  public:
00025   Region();
00027   Region(const Region&);
00029   enum FillRule
00030   {
00031     EVEN_ODD_RULE, 
00032     WINDING_RULE   
00033   };
00035   Region(const std::vector<Point>, FillRule);
00037   Region(const SDL_Rect&);
00039   Region(const Point&);
00040 
00041   ~Region() {delete [] rects;}
00042 
00044   Region& operator=(const Region&);
00045 
00047   Rect getClipbox() const
00048     {return Rect(extents.x1, extents.y1,
00049         extents.x2 - extents.x1, extents.y2 - extents.y1);}
00050 
00052   class RectList {
00053    public:
00055     RectList(unsigned n) : rects_(new SDL_Rect[n]), nrects_(n) {}
00057     RectList(const RectList& rl) : rects_(0), nrects_(0) {operator=(rl);}
00058     ~RectList() {delete [] rects_;}
00059 
00061     RectList& operator=(const RectList& rl);
00062 
00064     SDL_Rect* rects() const {return rects_;}
00066     unsigned nrects() const {return nrects_;}
00067 
00068     // The 0 index for overflow is safe, but kind of silly
00070     SDL_Rect& operator[](unsigned n) {return rects_[n < nrects_ ? n : 0];}
00071 
00072    private:
00073     SDL_Rect* rects_;
00074     unsigned nrects_;
00075   };
00076 
00077 #ifndef WFTK_DISABLE_DEPRECATED
00078 
00079   RectList getRectangles() const;
00080 #endif
00081 
00082   // a better solution than getRectangles(), with no memory allocation
00083   unsigned long nRects() const {return numRects;}
00084   Rect getRect(unsigned long i) const
00085     {assert(i < (unsigned long) numRects); return rects[i];}
00086 
00088   bool empty() const {return numRects == 0;}
00090   bool operator==(const Region&) const;
00092   bool operator!=(const Region& r) const {return !operator==(r);}
00094   bool operator<(const Region&) const;
00096   bool contains(const Point&) const;
00098   enum OverlapType
00099   {
00100     OVERLAP_IN,  
00101     OVERLAP_OUT, 
00102     OVERLAP_PART 
00103   };
00105   OverlapType overlap(const SDL_Rect&) const;
00106 
00108   void clear();
00109 
00111   friend Region operator|(const Region& r, const Region& r2)
00112     {Region out(r); out |= r2; return out;}
00114   friend Region operator&(const Region& r, const Region& r2)
00115     {Region out(r); out &= r2; return out;}
00117   friend Region operator-(const Region& r, const Region& r2)
00118     {Region out(r); out -= r2; return out;}
00120   friend Region operator^(const Region& r, const Region& r2)
00121     {Region out(r); out ^= r2; return out;}
00122 
00124   void offset(int dx, int dy);
00126   void offset(const Point& p) {offset(p.x, p.y);}
00133   void shrink(int dx, int dy);
00134 
00136   Region& operator|=(const Region&);
00138   Region& operator&=(const Region&);
00140   Region& operator-=(const Region&);
00142   Region& operator^=(const Region&);
00143 
00145 
00151   Region boundary(bool inside) const;
00152 
00153  private:
00154   long size, numRects;
00155   struct RegionBox
00156   {
00157     int x1, y1, x2, y2;
00158 
00159     // used in Region::getRectangles()
00160     operator Rect() const {return Rect(x1, y1, x2-x1, y2-y1);}
00161 
00162   } *rects, extents;
00163 
00164  public:
00165 
00166   // const_iterator has to be declared after RegionBox
00167 
00169   class const_iterator
00170   {
00171    public:
00172     const_iterator() : box_(0) {}
00173     const_iterator(const RegionBox* begin, const RegionBox* end);
00174 
00175     bool operator==(const const_iterator& I) const
00176     {return box_ == I.box_ && p_ == I.p_;} // need box_ equality for end() case
00177     bool operator!=(const const_iterator& I) const
00178     {return !operator==(I);}
00179 
00180     const_iterator& operator++();
00181     const_iterator operator++(int)
00182     {const_iterator tmp(*this); operator++(); return tmp;}
00183 
00184     const Point& operator*() const {return p_;}
00185     const Point* operator->() const {return &p_;}
00186 
00187    private:
00188     const RegionBox *box_, *final_;
00189     Point p_;
00190   };
00191 
00192   const_iterator begin() const {return const_iterator(rects, rects + numRects);}
00193   const_iterator end() const {return const_iterator(rects + numRects, rects + numRects);}
00194 
00195  private:
00196 
00197   typedef void (Region::*overlapFunc) (
00198                    RegionBox *r1,
00199                    RegionBox *r1End,
00200                    RegionBox *r2,
00201                    RegionBox *r2End,
00202                    int          y1,
00203                    int          y2);
00204   typedef void (Region::*nonOverlapFunc) (
00205                   RegionBox *r,
00206                   RegionBox *rEnd,
00207                   int          y1,
00208                   int          y2);
00209   /*
00210    * used to allocate buffers for points and link
00211    * the buffers together
00212    */
00213   struct POINTBLOCK {
00214     /*
00215      * number of points to buffer before sending them off
00216      * to scanlines() :  Must be an even number
00217      */
00218     static const int NUMPTSTOBUFFER = 200;
00219     wftk::Point pts[NUMPTSTOBUFFER];
00220     POINTBLOCK *next;
00221   };
00222 
00223   void miSetExtents();
00224   void Compress(
00225      Region *s,
00226      Region *t,
00227      unsigned int      dx,
00228      int        xdir,
00229      int        grow);
00230   void miIntersectO (
00231           RegionBox *r1,
00232           RegionBox *r1End,
00233           RegionBox *r2,
00234           RegionBox *r2End,
00235           int          y1,
00236           int          y2);
00237   int
00238   miCoalesce (
00239         int       prevStart,
00240         int       curStart);
00241   void
00242   miRegionOp(
00243        const Region *reg1,
00244        const Region *reg2,
00245        overlapFunc    overlapFn,
00246        nonOverlapFunc nonOverlap1Fn,
00247        nonOverlapFunc nonOverlap2Fn);
00248   void
00249   miUnionNonO (
00250          RegionBox *r,
00251          RegionBox *rEnd,
00252          int          y1,
00253          int          y2);
00254   void
00255   miUnionO (
00256       RegionBox *r1,
00257       RegionBox *r1End,
00258       RegionBox *r2,
00259       RegionBox *r2End,
00260       int          y1,
00261       int          y2);
00262   void
00263   miSubtractNonO1 (
00264          RegionBox *r,
00265          RegionBox *rEnd,
00266          int          y1,
00267          int          y2);
00268   void
00269   miSubtractO(
00270          RegionBox *r1,
00271          RegionBox *r1End,
00272          RegionBox *r2,
00273          RegionBox *r2End,
00274          int          y1,
00275          int          y2);
00276   int PtsToRegion(
00277     int  numFullPtBlocks, int iCurPtBlock,
00278     POINTBLOCK *FirstPtBlock);
00279 };
00280 
00281 } // namespace
00282 
00283 #endif // _WFTK_REGION_H_
00284 

Generated Tue Oct 26 19:02:12 2004.
Copyright © 1998-2003 by the respective authors.

This document is licensed under the terms of the GNU Free Documentation License and may be freely distributed under the conditions given by this license.