SkRasterClip.cpp revision 56074222ee31f617ff176865f4b7aa38ede3bb0a
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#include "SkRasterClip.h"
9
10
11SkRasterClip::SkRasterClip() {
12    fIsBW = true;
13}
14
15SkRasterClip::SkRasterClip(const SkIRect& bounds) : fBW(bounds) {
16    fIsBW = true;
17}
18
19SkRasterClip::~SkRasterClip() {}
20
21bool SkRasterClip::isEmpty() const {
22    return fIsBW ? fBW.isEmpty() : fAA.isEmpty();
23}
24
25bool SkRasterClip::isRect() const {
26    return fIsBW ? fBW.isRect() : false;
27}
28
29bool SkRasterClip::isComplex() const {
30    return fIsBW ? fBW.isComplex() : !fAA.isEmpty();
31}
32
33const SkIRect& SkRasterClip::getBounds() const {
34    return fIsBW ? fBW.getBounds() : fAA.getBounds();
35}
36
37bool SkRasterClip::setEmpty() {
38    fIsBW = true;
39    fBW.setEmpty();
40    fAA.setEmpty();
41    return false;
42}
43
44bool SkRasterClip::setRect(const SkIRect& rect) {
45    fIsBW = true;
46    fAA.setEmpty();
47    return fBW.setRect(rect);
48}
49
50bool SkRasterClip::setPath(const SkPath& path, const SkRegion& clip, bool doAA) {
51    if (this->isBW() && !doAA) {
52        return fBW.setPath(path, clip);
53    } else {
54        if (this->isBW()) {
55            this->convertToAA();
56        }
57        return fAA.setPath(path, &clip, doAA);
58    }
59}
60
61bool SkRasterClip::setPath(const SkPath& path, const SkIRect& clip, bool doAA) {
62    SkRegion tmp;
63    tmp.setRect(clip);
64    return this->setPath(path, tmp, doAA);
65}
66
67bool SkRasterClip::setPath(const SkPath& path, const SkRasterClip& clip,
68                           bool doAA) {
69    if (clip.isBW()) {
70        return this->setPath(path, clip.bwRgn(), doAA);
71    } else {
72        SkRegion tmp;
73        tmp.setRect(clip.getBounds());
74        if (!this->setPath(path, clip, doAA)) {
75            return false;
76        }
77        return this->op(clip, SkRegion::kIntersect_Op);
78    }
79}
80
81bool SkRasterClip::op(const SkIRect& rect, SkRegion::Op op) {
82    return fIsBW ? fBW.op(rect, op) : fAA.op(rect, op);
83}
84
85bool SkRasterClip::op(const SkRegion& rgn, SkRegion::Op op) {
86    if (fIsBW) {
87        return fBW.op(rgn, op);
88    } else {
89        SkAAClip tmp;
90        tmp.setRegion(rgn);
91        return fAA.op(tmp, op);
92    }
93}
94
95bool SkRasterClip::op(const SkRasterClip& clip, SkRegion::Op op) {
96    if (this->isBW() && clip.isBW()) {
97        return fBW.op(clip.fBW, op);
98    } else {
99        SkAAClip tmp;
100        const SkAAClip* other;
101
102        if (this->isBW()) {
103            this->convertToAA();
104        }
105        if (clip.isBW()) {
106            tmp.setRegion(clip.bwRgn());
107            other = &tmp;
108        } else {
109            other = &clip.aaRgn();
110        }
111        return fAA.op(*other, op);
112    }
113}
114
115// return true if x is nearly integral (within 1/256) since that is the highest
116// precision our aa code can have.
117static bool is_integral(SkScalar x) {
118    int ix = SkScalarRoundToInt(x);
119    SkScalar sx = SkIntToScalar(ix);
120    return SkScalarAbs(sx - x) < (SK_Scalar1 / 256);
121}
122
123bool SkRasterClip::op(const SkRect& r, SkRegion::Op op, bool doAA) {
124    if (doAA) {
125        // check that the rect really needs aa
126        if (is_integral(r.fLeft) && is_integral(r.fTop) &&
127            is_integral(r.fRight) && is_integral(r.fBottom)) {
128            doAA = false;
129        }
130    }
131
132    if (fIsBW && !doAA) {
133        SkIRect ir;
134        r.round(&ir);
135        return fBW.op(ir, op);
136    } else {
137        if (fIsBW) {
138            this->convertToAA();
139        }
140        return fAA.op(r, op, doAA);
141    }
142}
143
144const SkRegion& SkRasterClip::forceGetBW() {
145    if (!fIsBW) {
146        fBW.setRect(fAA.getBounds());
147    }
148    return fBW;
149}
150
151void SkRasterClip::convertToAA() {
152    SkASSERT(fIsBW);
153    fAA.setRegion(fBW);
154    fIsBW = false;
155}
156
157