blob: 7e015aacec0e71f72f9d38cffc87578d498bffe8 [file] [log] [blame]
reed@google.comd1e3c5f2011-10-10 19:36:25 +00001/*
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();
reed@google.comba16da92011-10-11 13:15:03 +000017 SkRasterClip(const SkIRect&);
reed@google.comd1e3c5f2011-10-10 19:36:25 +000018 SkRasterClip(const SkRasterClip&);
19 ~SkRasterClip();
20
21 bool isBW() const { return fIsBW; }
22 bool isAA() const { return !fIsBW; }
reed@google.com34f7e472011-10-13 15:11:59 +000023 const SkRegion& bwRgn() const { SkASSERT(fIsBW); return fBW; }
24 const SkAAClip& aaRgn() const { SkASSERT(!fIsBW); return fAA; }
reed@google.comd1e3c5f2011-10-10 19:36:25 +000025
reed@google.coma1c6ff42012-05-11 14:36:57 +000026 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
reed@google.comd1e3c5f2011-10-10 19:36:25 +000036 bool isComplex() const;
37 const SkIRect& getBounds() const;
38
39 bool setEmpty();
reed@google.comba16da92011-10-11 13:15:03 +000040 bool setRect(const SkIRect&);
reed@google.comd1e3c5f2011-10-10 19:36:25 +000041
42 bool setPath(const SkPath& path, const SkRegion& clip, bool doAA);
43 bool setPath(const SkPath& path, const SkIRect& clip, bool doAA);
44 bool setPath(const SkPath& path, const SkRasterClip&, bool doAA);
45
46 bool op(const SkIRect&, SkRegion::Op);
reed@google.comba16da92011-10-11 13:15:03 +000047 bool op(const SkRegion&, SkRegion::Op);
reed@google.comd1e3c5f2011-10-10 19:36:25 +000048 bool op(const SkRasterClip&, SkRegion::Op);
reed@google.com00177082011-10-12 14:34:30 +000049 bool op(const SkRect&, SkRegion::Op, bool doAA);
reed@google.comd1e3c5f2011-10-10 19:36:25 +000050
reed@google.com34f7e472011-10-13 15:11:59 +000051 void translate(int dx, int dy, SkRasterClip* dst) const;
52 void translate(int dx, int dy) {
53 this->translate(dx, dy, this);
54 }
reed@google.comd1e3c5f2011-10-10 19:36:25 +000055
reed@google.com045e62d2011-10-24 12:19:46 +000056 bool quickContains(const SkIRect& rect) const;
57 bool quickContains(int left, int top, int right, int bottom) const {
58 return quickContains(SkIRect::MakeLTRB(left, top, right, bottom));
59 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +000060
reed@google.com34f7e472011-10-13 15:11:59 +000061 /**
62 * Return true if this region is empty, or if the specified rectangle does
63 * not intersect the region. Returning false is not a guarantee that they
64 * intersect, but returning true is a guarantee that they do not.
65 */
66 bool quickReject(const SkIRect& rect) const {
67 return this->isEmpty() || rect.isEmpty() ||
68 !SkIRect::Intersects(this->getBounds(), rect);
69 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +000070
reed@google.com34f7e472011-10-13 15:11:59 +000071 // hack for SkCanvas::getTotalClip
reed@google.comba16da92011-10-11 13:15:03 +000072 const SkRegion& forceGetBW();
73
reed@google.com045e62d2011-10-24 12:19:46 +000074#ifdef SK_DEBUG
75 void validate() const;
76#else
77 void validate() const {}
78#endif
79
reed@google.comd1e3c5f2011-10-10 19:36:25 +000080private:
81 SkRegion fBW;
82 SkAAClip fAA;
83 bool fIsBW;
reed@google.coma1c6ff42012-05-11 14:36:57 +000084 // these 2 are caches based on querying the right obj based on fIsBW
85 bool fIsEmpty;
86 bool fIsRect;
87
88 bool computeIsEmpty() const {
89 return fIsBW ? fBW.isEmpty() : fAA.isEmpty();
90 }
91
92 bool computeIsRect() const {
93 return fIsBW ? fBW.isRect() : false;
94 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +000095
reed@google.coma1c6ff42012-05-11 14:36:57 +000096 bool updateCacheAndReturnNonEmpty() {
97 fIsEmpty = this->computeIsEmpty();
98 fIsRect = this->computeIsRect();
99 return !fIsEmpty;
100 }
reed@google.comd1e3c5f2011-10-10 19:36:25 +0000101
102 void convertToAA();
103};
104
reed@google.com045e62d2011-10-24 12:19:46 +0000105class SkAutoRasterClipValidate : SkNoncopyable {
106public:
107 SkAutoRasterClipValidate(const SkRasterClip& rc) : fRC(rc) {
108 fRC.validate();
109 }
110 ~SkAutoRasterClipValidate() {
111 fRC.validate();
112 }
113private:
114 const SkRasterClip& fRC;
115};
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 */
134class SkAAClipBlitterWrapper {
135public:
136 SkAAClipBlitterWrapper();
137 SkAAClipBlitterWrapper(const SkRasterClip&, SkBlitter*);
138 SkAAClipBlitterWrapper(const SkAAClip*, SkBlitter*);
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000139
reed@google.com045e62d2011-10-24 12:19:46 +0000140 void init(const SkRasterClip&, SkBlitter*);
141
142 const SkIRect& getBounds() const {
143 SkASSERT(fClipRgn);
144 return fClipRgn->getBounds();
145 }
146 const SkRegion& getRgn() const {
147 SkASSERT(fClipRgn);
148 return *fClipRgn;
149 }
150 SkBlitter* getBlitter() {
151 SkASSERT(fBlitter);
152 return fBlitter;
153 }
rmistry@google.comfbfcd562012-08-23 18:09:54 +0000154
reed@google.com045e62d2011-10-24 12:19:46 +0000155private:
156 const SkAAClip* fAAClip;
157 SkRegion fBWRgn;
158 SkAAClipBlitter fAABlitter;
159 // what we return
160 const SkRegion* fClipRgn;
161 SkBlitter* fBlitter;
162};
163
reed@google.comd1e3c5f2011-10-10 19:36:25 +0000164#endif