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