1 /* 2 * Copyright 2010 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkRasterClip_DEFINED 9 #define SkRasterClip_DEFINED 10 11 #include "SkRegion.h" 12 #include "SkAAClip.h" 13 14 class SkRasterClip { 15 public: 16 SkRasterClip(); 17 SkRasterClip(const SkIRect&); 18 SkRasterClip(const SkRasterClip&); 19 ~SkRasterClip(); 20 isBW()21 bool isBW() const { return fIsBW; } isAA()22 bool isAA() const { return !fIsBW; } bwRgn()23 const SkRegion& bwRgn() const { SkASSERT(fIsBW); return fBW; } aaRgn()24 const SkAAClip& aaRgn() const { SkASSERT(!fIsBW); return fAA; } 25 isEmpty()26 bool isEmpty() const { 27 SkASSERT(this->computeIsEmpty() == fIsEmpty); 28 return fIsEmpty; 29 } 30 isRect()31 bool isRect() const { 32 SkASSERT(this->computeIsRect() == fIsRect); 33 return fIsRect; 34 } 35 36 bool isComplex() const; 37 const SkIRect& getBounds() const; 38 39 bool setEmpty(); 40 bool setRect(const SkIRect&); 41 42 bool setPath(const SkPath& path, const SkRegion& clip, bool doAA); 43 bool setPath(const SkPath& path, const SkIRect& clip, bool doAA); 44 45 bool op(const SkIRect&, SkRegion::Op); 46 bool op(const SkRegion&, SkRegion::Op); 47 bool op(const SkRasterClip&, SkRegion::Op); 48 bool op(const SkRect&, SkRegion::Op, bool doAA); 49 50 void translate(int dx, int dy, SkRasterClip* dst) const; translate(int dx,int dy)51 void translate(int dx, int dy) { 52 this->translate(dx, dy, this); 53 } 54 55 bool quickContains(const SkIRect& rect) const; quickContains(int left,int top,int right,int bottom)56 bool quickContains(int left, int top, int right, int bottom) const { 57 return quickContains(SkIRect::MakeLTRB(left, top, right, bottom)); 58 } 59 60 /** 61 * Return true if this region is empty, or if the specified rectangle does 62 * not intersect the region. Returning false is not a guarantee that they 63 * intersect, but returning true is a guarantee that they do not. 64 */ quickReject(const SkIRect & rect)65 bool quickReject(const SkIRect& rect) const { 66 return this->isEmpty() || rect.isEmpty() || 67 !SkIRect::Intersects(this->getBounds(), rect); 68 } 69 70 // hack for SkCanvas::getTotalClip 71 const SkRegion& forceGetBW(); 72 73 #ifdef SK_DEBUG 74 void validate() const; 75 #else validate()76 void validate() const {} 77 #endif 78 79 private: 80 SkRegion fBW; 81 SkAAClip fAA; 82 bool fIsBW; 83 // these 2 are caches based on querying the right obj based on fIsBW 84 bool fIsEmpty; 85 bool fIsRect; 86 computeIsEmpty()87 bool computeIsEmpty() const { 88 return fIsBW ? fBW.isEmpty() : fAA.isEmpty(); 89 } 90 computeIsRect()91 bool computeIsRect() const { 92 return fIsBW ? fBW.isRect() : false; 93 } 94 updateCacheAndReturnNonEmpty()95 bool updateCacheAndReturnNonEmpty() { 96 fIsEmpty = this->computeIsEmpty(); 97 fIsRect = this->computeIsRect(); 98 return !fIsEmpty; 99 } 100 101 void convertToAA(); 102 }; 103 104 class SkAutoRasterClipValidate : SkNoncopyable { 105 public: SkAutoRasterClipValidate(const SkRasterClip & rc)106 SkAutoRasterClipValidate(const SkRasterClip& rc) : fRC(rc) { 107 fRC.validate(); 108 } ~SkAutoRasterClipValidate()109 ~SkAutoRasterClipValidate() { 110 fRC.validate(); 111 } 112 private: 113 const SkRasterClip& fRC; 114 }; 115 #define SkAutoRasterClipValidate(...) SK_REQUIRE_LOCAL_VAR(SkAutoRasterClipValidate) 116 117 #ifdef SK_DEBUG 118 #define AUTO_RASTERCLIP_VALIDATE(rc) SkAutoRasterClipValidate arcv(rc) 119 #else 120 #define AUTO_RASTERCLIP_VALIDATE(rc) 121 #endif 122 123 /////////////////////////////////////////////////////////////////////////////// 124 125 /** 126 * Encapsulates the logic of deciding if we need to change/wrap the blitter 127 * for aaclipping. If so, getRgn and getBlitter return modified values. If 128 * not, they return the raw blitter and (bw) clip region. 129 * 130 * We need to keep the constructor/destructor cost as small as possible, so we 131 * can freely put this guy on the stack, and not pay too much for the case when 132 * we're really BW anyways. 133 */ 134 class SkAAClipBlitterWrapper { 135 public: 136 SkAAClipBlitterWrapper(); 137 SkAAClipBlitterWrapper(const SkRasterClip&, SkBlitter*); 138 SkAAClipBlitterWrapper(const SkAAClip*, SkBlitter*); 139 140 void init(const SkRasterClip&, SkBlitter*); 141 getBounds()142 const SkIRect& getBounds() const { 143 SkASSERT(fClipRgn); 144 return fClipRgn->getBounds(); 145 } getRgn()146 const SkRegion& getRgn() const { 147 SkASSERT(fClipRgn); 148 return *fClipRgn; 149 } getBlitter()150 SkBlitter* getBlitter() { 151 SkASSERT(fBlitter); 152 return fBlitter; 153 } 154 155 private: 156 SkRegion fBWRgn; 157 SkAAClipBlitter fAABlitter; 158 // what we return 159 const SkRegion* fClipRgn; 160 SkBlitter* fBlitter; 161 }; 162 163 #endif 164