• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
computeFastBounds(SkRect * dst,const SkRect & src) const15 void SkPathEffect::computeFastBounds(SkRect* dst, const SkRect& src) const {
16     *dst = src;
17 }
18 
asPoints(PointData * results,const SkPath & src,const SkStrokeRec &,const SkMatrix &,const SkRect *) const19 bool SkPathEffect::asPoints(PointData* results, const SkPath& src,
20                     const SkStrokeRec&, const SkMatrix&, const SkRect*) const {
21     return false;
22 }
23 
asADash(DashInfo * info) const24 SkPathEffect::DashType SkPathEffect::asADash(DashInfo* info) const {
25     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 class SkPairPathEffect : public SkPathEffect {
37 protected:
SkPairPathEffect(sk_sp<SkPathEffect> pe0,sk_sp<SkPathEffect> pe1)38     SkPairPathEffect(sk_sp<SkPathEffect> pe0, sk_sp<SkPathEffect> pe1)
39         : fPE0(std::move(pe0)), fPE1(std::move(pe1))
40     {
41         SkASSERT(fPE0.get());
42         SkASSERT(fPE1.get());
43     }
44 
flatten(SkWriteBuffer & buffer) const45     void flatten(SkWriteBuffer& buffer) const override {
46         buffer.writeFlattenable(fPE0.get());
47         buffer.writeFlattenable(fPE1.get());
48     }
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
toString(SkString * str) const61 void SkPairPathEffect::toString(SkString* str) const {
62     str->appendf("first: ");
63     if (fPE0) {
64         fPE0->toString(str);
65     }
66     str->appendf(" second: ");
67     if (fPE1) {
68         fPE1->toString(str);
69     }
70 }
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 class 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      */
Make(sk_sp<SkPathEffect> outer,sk_sp<SkPathEffect> inner)87     static sk_sp<SkPathEffect> Make(sk_sp<SkPathEffect> outer, sk_sp<SkPathEffect> inner) {
88         if (!outer) {
89             return inner;
90         }
91         if (!inner) {
92             return outer;
93         }
94         return sk_sp<SkPathEffect>(new SkComposePathEffect(outer, inner));
95     }
96 
filterPath(SkPath * dst,const SkPath & src,SkStrokeRec * rec,const SkRect * cullRect) const97     bool filterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
98                     const SkRect* cullRect) const override {
99         SkPath          tmp;
100         const SkPath*   ptr = &src;
101 
102         if (fPE1->filterPath(&tmp, src, rec, cullRect)) {
103             ptr = &tmp;
104         }
105         return fPE0->filterPath(dst, *ptr, rec, cullRect);
106     }
107 
108 
109     SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkComposePathEffect)110     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:
SkComposePathEffect(sk_sp<SkPathEffect> outer,sk_sp<SkPathEffect> inner)117     SkComposePathEffect(sk_sp<SkPathEffect> outer, sk_sp<SkPathEffect> inner)
118         : 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 
CreateProc(SkReadBuffer & buffer)129 sk_sp<SkFlattenable> SkComposePathEffect::CreateProc(SkReadBuffer& buffer) {
130     sk_sp<SkPathEffect> pe0(buffer.readPathEffect());
131     sk_sp<SkPathEffect> pe1(buffer.readPathEffect());
132     return SkComposePathEffect::Make(std::move(pe0), std::move(pe1));
133 }
134 
135 #ifndef SK_IGNORE_TO_STRING
toString(SkString * str) const136 void SkComposePathEffect::toString(SkString* str) const {
137     str->appendf("SkComposePathEffect: (");
138     this->INHERITED::toString(str);
139     str->appendf(")");
140 }
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 class 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      */
Make(sk_sp<SkPathEffect> first,sk_sp<SkPathEffect> second)157     static sk_sp<SkPathEffect> Make(sk_sp<SkPathEffect> first, sk_sp<SkPathEffect> second) {
158         if (!first) {
159             return second;
160         }
161         if (!second) {
162             return first;
163         }
164         return sk_sp<SkPathEffect>(new SkSumPathEffect(first, second));
165     }
166 
filterPath(SkPath * dst,const SkPath & src,SkStrokeRec * rec,const SkRect * cullRect) const167     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         return fPE0->filterPath(dst, src, rec, cullRect) |
171                fPE1->filterPath(dst, src, rec, cullRect);
172     }
173 
174 
175     SK_TO_STRING_OVERRIDE()
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkSumPathEffect)176     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:
SkSumPathEffect(sk_sp<SkPathEffect> first,sk_sp<SkPathEffect> second)183     SkSumPathEffect(sk_sp<SkPathEffect> first, sk_sp<SkPathEffect> second)
184     : 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 
CreateProc(SkReadBuffer & buffer)195 sk_sp<SkFlattenable> SkSumPathEffect::CreateProc(SkReadBuffer& buffer) {
196     sk_sp<SkPathEffect> pe0(buffer.readPathEffect());
197     sk_sp<SkPathEffect> pe1(buffer.readPathEffect());
198     return SkSumPathEffect::Make(pe0, pe1);
199 }
200 
201 #ifndef SK_IGNORE_TO_STRING
toString(SkString * str) const202 void SkSumPathEffect::toString(SkString* str) const {
203     str->appendf("SkSumPathEffect: (");
204     this->INHERITED::toString(str);
205     str->appendf(")");
206 }
207 #endif
208 
209 ///////////////////////////////////////////////////////////////////////////////////////////////////
210 
MakeSum(sk_sp<SkPathEffect> first,sk_sp<SkPathEffect> second)211 sk_sp<SkPathEffect> SkPathEffect::MakeSum(sk_sp<SkPathEffect> first, sk_sp<SkPathEffect> second) {
212     return SkSumPathEffect::Make(std::move(first), std::move(second));
213 }
214 
MakeCompose(sk_sp<SkPathEffect> outer,sk_sp<SkPathEffect> inner)215 sk_sp<SkPathEffect> SkPathEffect::MakeCompose(sk_sp<SkPathEffect> outer,
216                                               sk_sp<SkPathEffect> inner) {
217     return SkComposePathEffect::Make(std::move(outer), std::move(inner));
218 }
219 
220 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkPathEffect)
221     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposePathEffect)
222     SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSumPathEffect)
223 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
224