1 /* 2 * Copyright 2011 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 "Sample.h" 9 #include "SkAnimTimer.h" 10 #include "SkCanvas.h" 11 #include "SkGradientShader.h" 12 #include "SkPath.h" 13 #include "SkRegion.h" 14 #include "SkShader.h" 15 #include "SkUTF.h" 16 #include "Sk1DPathEffect.h" 17 #include "SkCornerPathEffect.h" 18 #include "SkPathMeasure.h" 19 #include "SkRandom.h" 20 #include "SkColorPriv.h" 21 22 #define CORNER_RADIUS 12 23 24 static const int gXY[] = { 25 4, 0, 0, -4, 8, -4, 12, 0, 8, 4, 0, 4 26 }; 27 28 static sk_sp<SkPathEffect> make_pe(int flags, SkScalar phase) { 29 if (flags == 1) { 30 return SkCornerPathEffect::Make(SkIntToScalar(CORNER_RADIUS)); 31 } 32 33 SkPath path; 34 path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1])); 35 for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2) 36 path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1])); 37 path.close(); 38 path.offset(SkIntToScalar(-6), 0); 39 40 auto outer = SkPath1DPathEffect::Make(path, 12, phase, SkPath1DPathEffect::kRotate_Style); 41 42 if (flags == 2) 43 return outer; 44 45 auto inner = SkCornerPathEffect::Make(SkIntToScalar(CORNER_RADIUS)); 46 47 return SkPathEffect::MakeCompose(outer, inner); 48 } 49 50 static sk_sp<SkPathEffect> make_warp_pe(SkScalar phase) { 51 SkPath path; 52 path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1])); 53 for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2) { 54 path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1])); 55 } 56 path.close(); 57 path.offset(SkIntToScalar(-6), 0); 58 59 auto outer = SkPath1DPathEffect::Make( 60 path, 12, phase, SkPath1DPathEffect::kMorph_Style); 61 auto inner = SkCornerPathEffect::Make(SkIntToScalar(CORNER_RADIUS)); 62 63 return SkPathEffect::MakeCompose(outer, inner); 64 } 65 66 /////////////////////////////////////////////////////////// 67 68 #include "SkColorFilter.h" 69 70 class PathEffectView : public Sample { 71 SkPath fPath; 72 SkPoint fClickPt; 73 SkScalar fPhase; 74 75 public: 76 PathEffectView() : fPhase(0) { 77 } 78 79 protected: 80 void onOnceBeforeDraw() override { 81 SkRandom rand; 82 int steps = 20; 83 SkScalar dist = SkIntToScalar(400); 84 SkScalar x = SkIntToScalar(20); 85 SkScalar y = SkIntToScalar(50); 86 87 fPath.moveTo(x, y); 88 for (int i = 0; i < steps; i++) { 89 x += dist/steps; 90 SkScalar tmpY = y + SkIntToScalar(rand.nextS() % 25); 91 if (i == steps/2) { 92 fPath.moveTo(x, tmpY); 93 } else { 94 fPath.lineTo(x, tmpY); 95 } 96 } 97 98 { 99 SkRect oval; 100 oval.set(SkIntToScalar(20), SkIntToScalar(30), 101 SkIntToScalar(100), SkIntToScalar(60)); 102 oval.offset(x, 0); 103 fPath.addRoundRect(oval, SkIntToScalar(8), SkIntToScalar(8)); 104 } 105 106 fClickPt.set(SkIntToScalar(200), SkIntToScalar(200)); 107 108 this->setBGColor(0xFFDDDDDD); 109 } 110 111 bool onQuery(Sample::Event* evt) override { 112 if (Sample::TitleQ(*evt)) { 113 Sample::TitleR(evt, "PathEffects"); 114 return true; 115 } 116 return this->INHERITED::onQuery(evt); 117 } 118 119 void onDrawContent(SkCanvas* canvas) override { 120 SkPaint paint; 121 122 canvas->translate(0, 50); 123 124 paint.setColor(SK_ColorBLUE); 125 paint.setPathEffect(make_pe(2, fPhase)); 126 canvas->drawPath(fPath, paint); 127 128 canvas->translate(0, 50); 129 130 paint.setARGB(0xFF, 0, 0xBB, 0); 131 paint.setPathEffect(make_pe(3, fPhase)); 132 canvas->drawPath(fPath, paint); 133 134 canvas->translate(0, 50); 135 136 paint.setARGB(0xFF, 0, 0, 0); 137 paint.setPathEffect(make_warp_pe(fPhase)); 138 canvas->drawPath(fPath, paint); 139 } 140 141 bool onAnimate(const SkAnimTimer& timer) override { 142 fPhase = timer.scaled(40); 143 return true; 144 } 145 146 private: 147 typedef Sample INHERITED; 148 }; 149 150 ////////////////////////////////////////////////////////////////////////////// 151 152 DEF_SAMPLE( return new PathEffectView(); ) 153