SkRasterClip.h revision 045e62d715f5ee9b03deb5af3c750f8318096179
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    bool isRect() const;
28    bool isComplex() const;
29    const SkIRect& getBounds() const;
30
31    bool setEmpty();
32    bool setRect(const SkIRect&);
33
34    bool setPath(const SkPath& path, const SkRegion& clip, bool doAA);
35    bool setPath(const SkPath& path, const SkIRect& clip, bool doAA);
36    bool setPath(const SkPath& path, const SkRasterClip&, bool doAA);
37
38    bool op(const SkIRect&, SkRegion::Op);
39    bool op(const SkRegion&, SkRegion::Op);
40    bool op(const SkRasterClip&, SkRegion::Op);
41    bool op(const SkRect&, SkRegion::Op, bool doAA);
42
43    void translate(int dx, int dy, SkRasterClip* dst) const;
44    void translate(int dx, int dy) {
45        this->translate(dx, dy, this);
46    }
47
48    bool quickContains(const SkIRect& rect) const;
49    bool quickContains(int left, int top, int right, int bottom) const {
50        return quickContains(SkIRect::MakeLTRB(left, top, right, bottom));
51    }
52
53    /**
54     *  Return true if this region is empty, or if the specified rectangle does
55     *  not intersect the region. Returning false is not a guarantee that they
56     *  intersect, but returning true is a guarantee that they do not.
57     */
58    bool quickReject(const SkIRect& rect) const {
59        return this->isEmpty() || rect.isEmpty() ||
60               !SkIRect::Intersects(this->getBounds(), rect);
61    }
62
63    // hack for SkCanvas::getTotalClip
64    const SkRegion& forceGetBW();
65
66#ifdef SK_DEBUG
67    void validate() const;
68#else
69    void validate() const {}
70#endif
71
72private:
73    SkRegion    fBW;
74    SkAAClip    fAA;
75    bool        fIsBW;
76
77    void convertToAA();
78};
79
80class SkAutoRasterClipValidate : SkNoncopyable {
81public:
82    SkAutoRasterClipValidate(const SkRasterClip& rc) : fRC(rc) {
83        fRC.validate();
84    }
85    ~SkAutoRasterClipValidate() {
86        fRC.validate();
87    }
88private:
89    const SkRasterClip& fRC;
90};
91
92#ifdef SK_DEBUG
93    #define AUTO_RASTERCLIP_VALIDATE(rc)    SkAutoRasterClipValidate arcv(rc)
94#else
95    #define AUTO_RASTERCLIP_VALIDATE(rc)
96#endif
97
98///////////////////////////////////////////////////////////////////////////////
99
100/**
101 *  Encapsulates the logic of deciding if we need to change/wrap the blitter
102 *  for aaclipping. If so, getRgn and getBlitter return modified values. If
103 *  not, they return the raw blitter and (bw) clip region.
104 *
105 *  We need to keep the constructor/destructor cost as small as possible, so we
106 *  can freely put this guy on the stack, and not pay too much for the case when
107 *  we're really BW anyways.
108 */
109class SkAAClipBlitterWrapper {
110public:
111    SkAAClipBlitterWrapper();
112    SkAAClipBlitterWrapper(const SkRasterClip&, SkBlitter*);
113    SkAAClipBlitterWrapper(const SkAAClip*, SkBlitter*);
114
115    void init(const SkRasterClip&, SkBlitter*);
116
117    const SkIRect& getBounds() const {
118        SkASSERT(fClipRgn);
119        return fClipRgn->getBounds();
120    }
121    const SkRegion& getRgn() const {
122        SkASSERT(fClipRgn);
123        return *fClipRgn;
124    }
125    SkBlitter* getBlitter() {
126        SkASSERT(fBlitter);
127        return fBlitter;
128    }
129
130private:
131    const SkAAClip* fAAClip;
132    SkRegion        fBWRgn;
133    SkAAClipBlitter fAABlitter;
134    // what we return
135    const SkRegion* fClipRgn;
136    SkBlitter* fBlitter;
137};
138
139#endif
140