• 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 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