1 2 /* 3 * Copyright 2011 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 #include "SampleCode.h" 9 #include "SkView.h" 10 #include "SkCanvas.h" 11 #include "SkGradientShader.h" 12 #include "SkPath.h" 13 #include "SkRegion.h" 14 #include "SkShader.h" 15 #include "SkUtils.h" 16 #include "Sk1DPathEffect.h" 17 #include "SkCornerPathEffect.h" 18 #include "SkPathMeasure.h" 19 #include "SkRandom.h" 20 #include "SkColorPriv.h" 21 #include "SkPixelXorXfermode.h" 22 23 #define CORNER_RADIUS 12 24 static SkScalar gPhase; 25 26 static const int gXY[] = { 27 4, 0, 0, -4, 8, -4, 12, 0, 8, 4, 0, 4 28 }; 29 30 static SkPathEffect* make_pe(int flags) { 31 if (flags == 1) 32 return SkCornerPathEffect::Create(SkIntToScalar(CORNER_RADIUS)); 33 34 SkPath path; 35 path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1])); 36 for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2) 37 path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1])); 38 path.close(); 39 path.offset(SkIntToScalar(-6), 0); 40 41 SkPathEffect* outer = SkPath1DPathEffect::Create(path, SkIntToScalar(12), gPhase, SkPath1DPathEffect::kRotate_Style); 42 43 if (flags == 2) 44 return outer; 45 46 SkPathEffect* inner = SkCornerPathEffect::Create(SkIntToScalar(CORNER_RADIUS)); 47 48 SkPathEffect* pe = SkComposePathEffect::Create(outer, inner); 49 outer->unref(); 50 inner->unref(); 51 return pe; 52 } 53 54 static SkPathEffect* make_warp_pe() { 55 SkPath path; 56 path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1])); 57 for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2) 58 path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1])); 59 path.close(); 60 path.offset(SkIntToScalar(-6), 0); 61 62 SkPathEffect* outer = SkPath1DPathEffect::Create( 63 path, SkIntToScalar(12), gPhase, SkPath1DPathEffect::kMorph_Style); 64 SkPathEffect* inner = SkCornerPathEffect::Create(SkIntToScalar(CORNER_RADIUS)); 65 66 SkPathEffect* pe = SkComposePathEffect::Create(outer, inner); 67 outer->unref(); 68 inner->unref(); 69 return pe; 70 } 71 72 /////////////////////////////////////////////////////////// 73 74 #include "SkColorFilter.h" 75 #include "SkLayerRasterizer.h" 76 77 class TestRastBuilder : public SkLayerRasterizer::Builder { 78 public: 79 TestRastBuilder() { 80 SkPaint paint; 81 paint.setAntiAlias(true); 82 83 #if 0 84 paint.setStyle(SkPaint::kStroke_Style); 85 paint.setStrokeWidth(SK_Scalar1*4); 86 this->addLayer(paint); 87 88 paint.setStrokeWidth(SK_Scalar1*1); 89 paint.setXfermode(SkXfermode::kClear_Mode); 90 this->addLayer(paint); 91 #else 92 paint.setAlpha(0x66); 93 this->addLayer(paint, SkIntToScalar(4), SkIntToScalar(4)); 94 95 paint.setAlpha(0xFF); 96 this->addLayer(paint); 97 #endif 98 } 99 }; 100 101 class PathEffectView : public SampleView { 102 SkPath fPath; 103 SkPoint fClickPt; 104 public: 105 PathEffectView() { 106 SkRandom rand; 107 int steps = 20; 108 SkScalar dist = SkIntToScalar(400); 109 SkScalar x = SkIntToScalar(20); 110 SkScalar y = SkIntToScalar(50); 111 112 fPath.moveTo(x, y); 113 for (int i = 0; i < steps; i++) { 114 x += dist/steps; 115 SkScalar tmpY = y + SkIntToScalar(rand.nextS() % 25); 116 if (i == steps/2) { 117 fPath.moveTo(x, tmpY); 118 } else { 119 fPath.lineTo(x, tmpY); 120 } 121 } 122 123 { 124 SkRect oval; 125 oval.set(SkIntToScalar(20), SkIntToScalar(30), 126 SkIntToScalar(100), SkIntToScalar(60)); 127 oval.offset(x, 0); 128 fPath.addRoundRect(oval, SkIntToScalar(8), SkIntToScalar(8)); 129 } 130 131 fClickPt.set(SkIntToScalar(200), SkIntToScalar(200)); 132 133 this->setBGColor(0xFFDDDDDD); 134 } 135 136 protected: 137 // overrides from SkEventSink 138 virtual bool onQuery(SkEvent* evt) { 139 if (SampleCode::TitleQ(*evt)) { 140 SampleCode::TitleR(evt, "PathEffects"); 141 return true; 142 } 143 return this->INHERITED::onQuery(evt); 144 } 145 146 virtual void onDrawContent(SkCanvas* canvas) { 147 gPhase -= SampleCode::GetAnimSecondsDelta() * 40; 148 this->inval(NULL); 149 150 SkPaint paint; 151 152 #if 0 153 paint.setAntiAlias(true); 154 paint.setStyle(SkPaint::kStroke_Style); 155 paint.setStrokeWidth(SkIntToScalar(5)); 156 canvas->drawPath(fPath, paint); 157 paint.setStrokeWidth(0); 158 159 paint.setColor(SK_ColorWHITE); 160 paint.setPathEffect(make_pe(1))->unref(); 161 canvas->drawPath(fPath, paint); 162 #endif 163 164 canvas->translate(0, SkIntToScalar(50)); 165 166 paint.setColor(SK_ColorBLUE); 167 paint.setPathEffect(make_pe(2))->unref(); 168 canvas->drawPath(fPath, paint); 169 170 canvas->translate(0, SkIntToScalar(50)); 171 172 paint.setARGB(0xFF, 0, 0xBB, 0); 173 paint.setPathEffect(make_pe(3))->unref(); 174 canvas->drawPath(fPath, paint); 175 176 canvas->translate(0, SkIntToScalar(50)); 177 178 paint.setARGB(0xFF, 0, 0, 0); 179 paint.setPathEffect(make_warp_pe())->unref(); 180 TestRastBuilder testRastBuilder; 181 paint.setRasterizer(testRastBuilder.detachRasterizer())->unref(); 182 canvas->drawPath(fPath, paint); 183 } 184 185 private: 186 typedef SampleView INHERITED; 187 }; 188 189 ////////////////////////////////////////////////////////////////////////////// 190 191 static SkView* MyFactory() { return new PathEffectView; } 192 static SkViewRegister reg(MyFactory); 193