1 2 /* 3 * Copyright 2010 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 11 #ifndef GrClip_DEFINED 12 #define GrClip_DEFINED 13 14 #include "GrClipIterator.h" 15 #include "GrRect.h" 16 #include "GrPath.h" 17 #include "GrTemplates.h" 18 19 #include "SkTArray.h" 20 21 class GrClip { 22 public: 23 GrClip(); 24 GrClip(const GrClip& src); 25 /** 26 * If specified, the conservativeBounds parameter already takes (tx,ty) 27 * into account. 28 */ 29 GrClip(GrClipIterator* iter, GrScalar tx, GrScalar ty, 30 const GrRect* conservativeBounds = NULL); 31 GrClip(const GrIRect& rect); 32 GrClip(const GrRect& rect); 33 34 ~GrClip(); 35 36 GrClip& operator=(const GrClip& src); 37 hasConservativeBounds()38 bool hasConservativeBounds() const { return fConservativeBoundsValid; } 39 getConservativeBounds()40 const GrRect& getConservativeBounds() const { return fConservativeBounds; } 41 getElementCount()42 int getElementCount() const { return fList.count(); } 43 getElementType(int i)44 GrClipType getElementType(int i) const { return fList[i].fType; } 45 getPath(int i)46 const GrPath& getPath(int i) const { 47 GrAssert(kPath_ClipType == fList[i].fType); 48 return fList[i].fPath; 49 } 50 getPathFill(int i)51 GrPathFill getPathFill(int i) const { 52 GrAssert(kPath_ClipType == fList[i].fType); 53 return fList[i].fPathFill; 54 } 55 getRect(int i)56 const GrRect& getRect(int i) const { 57 GrAssert(kRect_ClipType == fList[i].fType); 58 return fList[i].fRect; 59 } 60 getOp(int i)61 GrSetOp getOp(int i) const { return fList[i].fOp; } 62 isRect()63 bool isRect() const { 64 if (1 == fList.count() && kRect_ClipType == fList[0].fType && 65 (kIntersect_SetOp == fList[0].fOp || 66 kReplace_SetOp == fList[0].fOp)) { 67 // if we determined that the clip is a single rect 68 // we ought to have also used that rect as the bounds. 69 GrAssert(fConservativeBoundsValid); 70 GrAssert(fConservativeBounds == fList[0].fRect); 71 return true; 72 } else { 73 return false; 74 } 75 } 76 isEmpty()77 bool isEmpty() const { return 0 == fList.count(); } 78 79 /** 80 * Resets this clip to be empty 81 */ 82 void setEmpty(); 83 84 /** 85 * If specified, the bounds parameter already takes (tx,ty) into account. 86 */ 87 void setFromIterator(GrClipIterator* iter, GrScalar tx, GrScalar ty, 88 const GrRect* conservativeBounds = NULL); 89 void setFromRect(const GrRect& rect); 90 void setFromIRect(const GrIRect& rect); 91 92 friend bool operator==(const GrClip& a, const GrClip& b) { 93 if (a.fList.count() != b.fList.count()) { 94 return false; 95 } 96 int count = a.fList.count(); 97 for (int i = 0; i < count; ++i) { 98 if (a.fList[i] != b.fList[i]) { 99 return false; 100 } 101 } 102 return true; 103 } 104 friend bool operator!=(const GrClip& a, const GrClip& b) { 105 return !(a == b); 106 } 107 108 private: 109 struct Element { 110 GrClipType fType; 111 GrRect fRect; 112 GrPath fPath; 113 GrPathFill fPathFill; 114 GrSetOp fOp; 115 bool operator ==(const Element& e) const { 116 if (e.fType != fType || e.fOp != fOp) { 117 return false; 118 } 119 switch (fType) { 120 case kRect_ClipType: 121 return fRect == e.fRect; 122 case kPath_ClipType: 123 return fPath == e.fPath; 124 default: 125 GrCrash("Unknown clip element type."); 126 return false; // suppress warning 127 } 128 } 129 bool operator !=(const Element& e) const { return !(*this == e); } 130 }; 131 132 GrRect fConservativeBounds; 133 bool fConservativeBoundsValid; 134 135 enum { 136 kPreAllocElements = 4, 137 }; 138 SkSTArray<kPreAllocElements, Element> fList; 139 }; 140 #endif 141 142