blob: ec5ac3b9451716aec2e5abac8fff9452e0bb6b8d [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001/*
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
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#include "SkPathEffect.h"
9#include "SkPath.h"
commit-bot@chromium.org8b0e8ac2014-01-30 18:58:24 +000010#include "SkReadBuffer.h"
11#include "SkWriteBuffer.h"
reed@google.comfd4be262012-05-25 01:04:12 +000012
13///////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +000014
reed@google.com548a1f32012-12-18 16:12:09 +000015void SkPathEffect::computeFastBounds(SkRect* dst, const SkRect& src) const {
reed@google.come4f10a72012-05-15 20:47:50 +000016 *dst = src;
17}
18
skia.committer@gmail.com687c57c2012-11-29 02:01:19 +000019bool SkPathEffect::asPoints(PointData* results, const SkPath& src,
reed@google.com4bbdeac2013-01-24 21:03:11 +000020 const SkStrokeRec&, const SkMatrix&, const SkRect*) const {
robertphillips@google.com629ab542012-11-28 17:18:11 +000021 return false;
22}
23
commit-bot@chromium.orgaec14382014-04-22 15:21:18 +000024SkPathEffect::DashType SkPathEffect::asADash(DashInfo* info) const {
25 return kNone_DashType;
26}
27
reed@google.comfeb8cc82011-04-19 20:11:25 +000028///////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +000029
Mike Reeda07741a2017-02-25 22:34:32 -050030/** \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 */
36class SK_API SkPairPathEffect : public SkPathEffect {
37protected:
Mike Reed4a21c942017-03-09 07:51:09 -050038 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 }
Mike Reeda07741a2017-02-25 22:34:32 -050044
Mike Reed4a21c942017-03-09 07:51:09 -050045 void flatten(SkWriteBuffer& buffer) const override {
46 buffer.writeFlattenable(fPE0.get());
47 buffer.writeFlattenable(fPE1.get());
48 }
Mike Reeda07741a2017-02-25 22:34:32 -050049
50 // these are visible to our subclasses
51 sk_sp<SkPathEffect> fPE0;
52 sk_sp<SkPathEffect> fPE1;
53
54 SK_TO_STRING_OVERRIDE()
55
56private:
57 typedef SkPathEffect INHERITED;
58};
59
Mike Reed4a21c942017-03-09 07:51:09 -050060#ifndef SK_IGNORE_TO_STRING
61void 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
Mike Reeda07741a2017-02-25 22:34:32 -050075/** \class SkComposePathEffect
76
77 This subclass of SkPathEffect composes its two arguments, to create
78 a compound pathEffect.
79 */
80class SK_API SkComposePathEffect : public SkPairPathEffect {
81public:
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 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
Mike Reed4a21c942017-03-09 07:51:09 -050097 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
Mike Reeda07741a2017-02-25 22:34:32 -0500108
109 SK_TO_STRING_OVERRIDE()
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
116protected:
117 SkComposePathEffect(sk_sp<SkPathEffect> outer, sk_sp<SkPathEffect> inner)
Mike Reed4a21c942017-03-09 07:51:09 -0500118 : INHERITED(outer, inner) {}
Mike Reeda07741a2017-02-25 22:34:32 -0500119
120private:
121 // illegal
122 SkComposePathEffect(const SkComposePathEffect&);
123 SkComposePathEffect& operator=(const SkComposePathEffect&);
124 friend class SkPathEffect;
125
126 typedef SkPairPathEffect INHERITED;
127};
128
Mike Reed4a21c942017-03-09 07:51:09 -0500129sk_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
136void SkComposePathEffect::toString(SkString* str) const {
137 str->appendf("SkComposePathEffect: (");
138 this->INHERITED::toString(str);
139 str->appendf(")");
140}
141#endif
142
143///////////////////////////////////////////////////////////////////////////////
144
Mike Reeda07741a2017-02-25 22:34:32 -0500145/** \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 */
150class SK_API SkSumPathEffect : public SkPairPathEffect {
151public:
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 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
Mike Reed4a21c942017-03-09 07:51:09 -0500167 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
Mike Reeda07741a2017-02-25 22:34:32 -0500174
175 SK_TO_STRING_OVERRIDE()
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
182protected:
183 SkSumPathEffect(sk_sp<SkPathEffect> first, sk_sp<SkPathEffect> second)
184 : INHERITED(first, second) {}
185
186private:
187 // illegal
188 SkSumPathEffect(const SkSumPathEffect&);
189 SkSumPathEffect& operator=(const SkSumPathEffect&);
190 friend class SkPathEffect;
191
192 typedef SkPairPathEffect INHERITED;
193};
reed@android.com8a1c16f2008-12-17 15:59:43 +0000194
reed60c9b582016-04-03 09:11:13 -0700195sk_sp<SkFlattenable> SkSumPathEffect::CreateProc(SkReadBuffer& buffer) {
reeda4393342016-03-18 11:22:57 -0700196 sk_sp<SkPathEffect> pe0(buffer.readPathEffect());
197 sk_sp<SkPathEffect> pe1(buffer.readPathEffect());
reed60c9b582016-04-03 09:11:13 -0700198 return SkSumPathEffect::Make(pe0, pe1);
reed9fa60da2014-08-21 07:59:51 -0700199}
200
robertphillips42dbfa82015-01-26 06:08:52 -0800201#ifndef SK_IGNORE_TO_STRING
202void SkSumPathEffect::toString(SkString* str) const {
203 str->appendf("SkSumPathEffect: (");
204 this->INHERITED::toString(str);
205 str->appendf(")");
206}
207#endif
Mike Reeda07741a2017-02-25 22:34:32 -0500208
209///////////////////////////////////////////////////////////////////////////////////////////////////
210
211sk_sp<SkPathEffect> SkPathEffect::MakeSum(sk_sp<SkPathEffect> first, sk_sp<SkPathEffect> second) {
212 return SkSumPathEffect::Make(std::move(first), std::move(second));
213}
214
215sk_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
220SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkPathEffect)
221 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposePathEffect)
222 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSumPathEffect)
223SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END