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 void SkPathEffect::computeFastBounds(SkRect* dst, const SkRect& src) const { 16 *dst = src; 17 } 18 19 bool SkPathEffect::asPoints(PointData* results, const SkPath& src, 20 const SkStrokeRec&, const SkMatrix&, const SkRect*) const { 21 return false; 22 } 23 24 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: 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 45 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 61 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 */ 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 97 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() 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: 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 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 136 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 */ 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 167 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() 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: 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 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 202 void SkSumPathEffect::toString(SkString* str) const { 203 str->appendf("SkSumPathEffect: ("); 204 this->INHERITED::toString(str); 205 str->appendf(")"); 206 } 207 #endif 208 209 /////////////////////////////////////////////////////////////////////////////////////////////////// 210 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 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