Line data Source code
1 : /*
2 : * Copyright 2006 The Android Open Source Project
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 "SkPathEffect.h"
9 : #include "SkPath.h"
10 : #include "SkReadBuffer.h"
11 : #include "SkWriteBuffer.h"
12 :
13 : ///////////////////////////////////////////////////////////////////////////////
14 :
15 0 : void SkPathEffect::computeFastBounds(SkRect* dst, const SkRect& src) const {
16 0 : *dst = src;
17 0 : }
18 :
19 0 : bool SkPathEffect::asPoints(PointData* results, const SkPath& src,
20 : const SkStrokeRec&, const SkMatrix&, const SkRect*) const {
21 0 : return false;
22 : }
23 :
24 0 : SkPathEffect::DashType SkPathEffect::asADash(DashInfo* info) const {
25 0 : return kNone_DashType;
26 : }
27 :
28 : ///////////////////////////////////////////////////////////////////////////////
29 :
30 : /** \class SkPairPathEffect
31 :
32 : Common baseclass for Compose and Sum. This subclass manages two pathEffects,
33 : including flattening them. It does nothing in filterPath, and is only useful
34 : for managing the lifetimes of its two arguments.
35 : */
36 0 : class SK_API SkPairPathEffect : public SkPathEffect {
37 : protected:
38 0 : SkPairPathEffect(sk_sp<SkPathEffect> pe0, sk_sp<SkPathEffect> pe1)
39 0 : : fPE0(std::move(pe0)), fPE1(std::move(pe1))
40 : {
41 0 : SkASSERT(fPE0.get());
42 0 : SkASSERT(fPE1.get());
43 0 : }
44 :
45 0 : void flatten(SkWriteBuffer& buffer) const override {
46 0 : buffer.writeFlattenable(fPE0.get());
47 0 : buffer.writeFlattenable(fPE1.get());
48 0 : }
49 :
50 : // these are visible to our subclasses
51 : sk_sp<SkPathEffect> fPE0;
52 : sk_sp<SkPathEffect> fPE1;
53 :
54 : SK_TO_STRING_OVERRIDE()
55 :
56 : private:
57 : typedef SkPathEffect INHERITED;
58 : };
59 :
60 : #ifndef SK_IGNORE_TO_STRING
61 0 : void SkPairPathEffect::toString(SkString* str) const {
62 0 : str->appendf("first: ");
63 0 : if (fPE0) {
64 0 : fPE0->toString(str);
65 : }
66 0 : str->appendf(" second: ");
67 0 : if (fPE1) {
68 0 : fPE1->toString(str);
69 : }
70 0 : }
71 : #endif
72 :
73 : ///////////////////////////////////////////////////////////////////////////////////////////////////
74 :
75 : /** \class SkComposePathEffect
76 :
77 : This subclass of SkPathEffect composes its two arguments, to create
78 : a compound pathEffect.
79 : */
80 0 : class SK_API SkComposePathEffect : public SkPairPathEffect {
81 : public:
82 : /** Construct a pathEffect whose effect is to apply first the inner pathEffect
83 : and the the outer pathEffect (e.g. outer(inner(path)))
84 : The reference counts for outer and inner are both incremented in the constructor,
85 : and decremented in the destructor.
86 : */
87 0 : static sk_sp<SkPathEffect> Make(sk_sp<SkPathEffect> outer, sk_sp<SkPathEffect> inner) {
88 0 : if (!outer) {
89 0 : return inner;
90 : }
91 0 : if (!inner) {
92 0 : return outer;
93 : }
94 0 : return sk_sp<SkPathEffect>(new SkComposePathEffect(outer, inner));
95 : }
96 :
97 0 : bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
98 : const SkRect* cullRect) const override {
99 0 : SkPath tmp;
100 0 : const SkPath* ptr = &src;
101 :
102 0 : if (fPE1->filterPath(&tmp, src, rec, cullRect)) {
103 0 : ptr = &tmp;
104 : }
105 0 : return fPE0->filterPath(dst, *ptr, rec, cullRect);
106 : }
107 :
108 :
109 : SK_TO_STRING_OVERRIDE()
110 0 : SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposePathEffect)
111 :
112 : #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
113 : bool exposedInAndroidJavaAPI() const override { return true; }
114 : #endif
115 :
116 : protected:
117 0 : SkComposePathEffect(sk_sp<SkPathEffect> outer, sk_sp<SkPathEffect> inner)
118 0 : : INHERITED(outer, inner) {}
119 :
120 : private:
121 : // illegal
122 : SkComposePathEffect(const SkComposePathEffect&);
123 : SkComposePathEffect& operator=(const SkComposePathEffect&);
124 : friend class SkPathEffect;
125 :
126 : typedef SkPairPathEffect INHERITED;
127 : };
128 :
129 0 : sk_sp<SkFlattenable> SkComposePathEffect::CreateProc(SkReadBuffer& buffer) {
130 0 : sk_sp<SkPathEffect> pe0(buffer.readPathEffect());
131 0 : sk_sp<SkPathEffect> pe1(buffer.readPathEffect());
132 0 : return SkComposePathEffect::Make(std::move(pe0), std::move(pe1));
133 : }
134 :
135 : #ifndef SK_IGNORE_TO_STRING
136 0 : void SkComposePathEffect::toString(SkString* str) const {
137 0 : str->appendf("SkComposePathEffect: (");
138 0 : this->INHERITED::toString(str);
139 0 : str->appendf(")");
140 0 : }
141 : #endif
142 :
143 : ///////////////////////////////////////////////////////////////////////////////
144 :
145 : /** \class SkSumPathEffect
146 :
147 : This subclass of SkPathEffect applies two pathEffects, one after the other.
148 : Its filterPath() returns true if either of the effects succeeded.
149 : */
150 0 : class SK_API SkSumPathEffect : public SkPairPathEffect {
151 : public:
152 : /** Construct a pathEffect whose effect is to apply two effects, in sequence.
153 : (e.g. first(path) + second(path))
154 : The reference counts for first and second are both incremented in the constructor,
155 : and decremented in the destructor.
156 : */
157 0 : static sk_sp<SkPathEffect> Make(sk_sp<SkPathEffect> first, sk_sp<SkPathEffect> second) {
158 0 : if (!first) {
159 0 : return second;
160 : }
161 0 : if (!second) {
162 0 : return first;
163 : }
164 0 : return sk_sp<SkPathEffect>(new SkSumPathEffect(first, second));
165 : }
166 :
167 0 : bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
168 : const SkRect* cullRect) const override {
169 : // use bit-or so that we always call both, even if the first one succeeds
170 0 : return fPE0->filterPath(dst, src, rec, cullRect) |
171 0 : fPE1->filterPath(dst, src, rec, cullRect);
172 : }
173 :
174 :
175 : SK_TO_STRING_OVERRIDE()
176 0 : SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSumPathEffect)
177 :
178 : #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
179 : bool exposedInAndroidJavaAPI() const override { return true; }
180 : #endif
181 :
182 : protected:
183 0 : SkSumPathEffect(sk_sp<SkPathEffect> first, sk_sp<SkPathEffect> second)
184 0 : : INHERITED(first, second) {}
185 :
186 : private:
187 : // illegal
188 : SkSumPathEffect(const SkSumPathEffect&);
189 : SkSumPathEffect& operator=(const SkSumPathEffect&);
190 : friend class SkPathEffect;
191 :
192 : typedef SkPairPathEffect INHERITED;
193 : };
194 :
195 0 : sk_sp<SkFlattenable> SkSumPathEffect::CreateProc(SkReadBuffer& buffer) {
196 0 : sk_sp<SkPathEffect> pe0(buffer.readPathEffect());
197 0 : sk_sp<SkPathEffect> pe1(buffer.readPathEffect());
198 0 : return SkSumPathEffect::Make(pe0, pe1);
199 : }
200 :
201 : #ifndef SK_IGNORE_TO_STRING
202 0 : void SkSumPathEffect::toString(SkString* str) const {
203 0 : str->appendf("SkSumPathEffect: (");
204 0 : this->INHERITED::toString(str);
205 0 : str->appendf(")");
206 0 : }
207 : #endif
208 :
209 : ///////////////////////////////////////////////////////////////////////////////////////////////////
210 :
211 0 : sk_sp<SkPathEffect> SkPathEffect::MakeSum(sk_sp<SkPathEffect> first, sk_sp<SkPathEffect> second) {
212 0 : return SkSumPathEffect::Make(std::move(first), std::move(second));
213 : }
214 :
215 0 : sk_sp<SkPathEffect> SkPathEffect::MakeCompose(sk_sp<SkPathEffect> outer,
216 : sk_sp<SkPathEffect> inner) {
217 0 : return SkComposePathEffect::Make(std::move(outer), std::move(inner));
218 : }
219 :
220 0 : SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkPathEffect)
221 0 : SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposePathEffect)
222 0 : SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSumPathEffect)
223 0 : SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
|