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