/* Talin's Region Manager */ #ifndef __REGIONS #define __REGIONS /* ===================================================================== * Constants * ===================================================================== */ // Boolean operations which can be done on two regions. enum regOps { // 00 01 10 11 // ~~ ~~ ~~ ~~ regOpClear = 0, // 0 0 0 0 regOpAnd, // 0 0 0 1 regOpAndReverse, // 0 0 1 0 regOpCopy, // 0 0 1 1 regOpAndInverted, // 0 1 0 0 regOpNoOp, // 0 1 0 1 regOpXor, // 0 1 1 0 regOpOr, // 0 1 1 1 // These operations are not supported because they // would create an inverted region. (However, we could // eventually support these by having an "inverted" bit // in the region struct. Of course, this would mean that each // time we use an opcode, we'd have to figure out what the // "correct" opcode is, probably using De Morgan's theorem: // NOT(a) or NOT(b) = NOT( a and b ). For example, a NAND operation // on two non-inverted regions can be synthesized by doing an // AND and then setting the 'inverted' bit on the result. // Of course, "drawing" through an inverted region is going // to be difficult, since getting the clip-rects is harder.) /* regOpNor, // 1 0 0 0 regOpEquiv, // 1 0 0 1 regOpInvert, // 1 0 1 0 regOpOrReverse, // 1 0 1 1 regOpCopyInverted, // 1 1 0 0 regOpOrInverted, // 1 1 0 1 regOpNand, // 1 1 1 0 regOpSet, // 1 1 1 1 */ }; /* ===================================================================== * evalOp: inline function to evalulate any boolean operator * ===================================================================== */ inline bool evalOp( int16 op, int16 a, int16 b ) { int16 bit = a ? 4 : 8; // Test the truth table in the bits return op & (b ? bit >> 2 : bit); } /* ===================================================================== * RegionRect: contains the individual clip rectangles for the region * ===================================================================== */ class RegionRect { private: friend class Region; friend class RegionStrip; friend class StripWalker; friend class RegionWalker; friend class RegionIterator; // We store only an x-position and a width. int16 x, // left edge of rect width; // width of span RegionRect *next; // pointer to next rect RegionRect(); // constructor }; /* ===================================================================== * RegionStrip: A horizontal strip of region rectangles * ===================================================================== */ class RegionStrip { private: friend class Region; friend class RegionRect; friend class StripWalker; friend class RegionWalker; friend class RegionIterator; RegionStrip *next; // pointer to next strip RegionRect *rectList, // list of rectangles in strip. *lastRect; // last rectangle added. int16 yPos, // y position of strip height; // height of the strip RegionStrip(); // constructor ~RegionStrip(); // destructor bool stripsEqual( RegionStrip &strip ); // compare strips for equality void addRect( int16 xPos, int16 width ); // add rectangle to strip RegionStrip *combine( // combine two strips Rect16 stripExtent, // extent of strip RegionStrip &strip, // region strip to combine with int16 op ); // boolean operation // Returns the left and right edge of a strip void stripExtent( int16 &leftEdge, int16 &width ); // Makes a copy of a strip. RegionStrip *copy( int16 y, int16 h ); }; /* ===================================================================== * Region * ===================================================================== */ class Region { private: friend class RegionRect; friend class RegionStrip; friend class StripWalker; friend class RegionWalker; friend class RegionIterator; enum regionFlags { empty = (1<<0), // indicates "empty region" simpleRect = (1<<1), // region is simple rectangle inverted = (1<<2), // space outside region is inside }; int16 flags; Rect16 bounds; // bounding box of entire region RegionStrip *stripList; public: // Constructor and destructor Region(); ~Region(); void clearRegion(); // set region to empty void addRect( const Rect16 &r ); // add a rectangle void addRegion( const Region ® ); // add a region void subtractRect( const Rect16 &r ); // clear a rectangle from a region void subtractRegion( const Region ® ); // clear a region fro a region // These will do various boolean operations on a region void boolOpRect( const Rect16 &r, int16 op ); void boolOpRegion( const Region ®, int16 op ); // Return the bounding rectangle of a region Rect16 getBounds() { return bounds; } // void expand( int16 dx, int16 dy ); void extractRegion( Region & ); // copy region and then clear }; /* ===================================================================== * RegionIterator: iterates through all cliprects in region * ===================================================================== */ class RegionIterator { private: const Region *region; Rect16 searchRect; const RegionStrip *strip; RegionRect *rect; bool simpleFlag; int16 stripYPos, stripHeight; public: RegionIterator( const Region *reg, const Rect16 &search ); bool next( Rect16 &clipRect ); }; #endif