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 "SampleCode.h" 9#include "SkAnimTimer.h" 10#include "SkView.h" 11#include "SkCanvas.h" 12#include "SkGradientShader.h" 13#include "SkPath.h" 14#include "SkRegion.h" 15#include "SkShader.h" 16#include "SkUtils.h" 17#include "Sk1DPathEffect.h" 18#include "SkCornerPathEffect.h" 19#include "SkPathMeasure.h" 20#include "SkRandom.h" 21#include "SkColorPriv.h" 22#include "SkPixelXorXfermode.h" 23 24#define CORNER_RADIUS 12 25 26static const int gXY[] = { 27 4, 0, 0, -4, 8, -4, 12, 0, 8, 4, 0, 4 28}; 29 30static SkPathEffect* make_pe(int flags, SkScalar phase) { 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, 12, phase, 42 SkPath1DPathEffect::kRotate_Style); 43 44 if (flags == 2) 45 return outer; 46 47 SkPathEffect* inner = SkCornerPathEffect::Create(SkIntToScalar(CORNER_RADIUS)); 48 49 SkPathEffect* pe = SkComposePathEffect::Create(outer, inner); 50 outer->unref(); 51 inner->unref(); 52 return pe; 53} 54 55static SkPathEffect* make_warp_pe(SkScalar phase) { 56 SkPath path; 57 path.moveTo(SkIntToScalar(gXY[0]), SkIntToScalar(gXY[1])); 58 for (unsigned i = 2; i < SK_ARRAY_COUNT(gXY); i += 2) 59 path.lineTo(SkIntToScalar(gXY[i]), SkIntToScalar(gXY[i+1])); 60 path.close(); 61 path.offset(SkIntToScalar(-6), 0); 62 63 SkPathEffect* outer = SkPath1DPathEffect::Create( 64 path, 12, phase, SkPath1DPathEffect::kMorph_Style); 65 SkPathEffect* inner = SkCornerPathEffect::Create(SkIntToScalar(CORNER_RADIUS)); 66 67 SkPathEffect* pe = SkComposePathEffect::Create(outer, inner); 68 outer->unref(); 69 inner->unref(); 70 return pe; 71} 72 73/////////////////////////////////////////////////////////// 74 75#include "SkColorFilter.h" 76#include "SkLayerRasterizer.h" 77 78class TestRastBuilder : public SkLayerRasterizer::Builder { 79public: 80 TestRastBuilder() { 81 SkPaint paint; 82 paint.setAntiAlias(true); 83 84 paint.setAlpha(0x66); 85 this->addLayer(paint, SkIntToScalar(4), SkIntToScalar(4)); 86 87 paint.setAlpha(0xFF); 88 this->addLayer(paint); 89 } 90}; 91 92class PathEffectView : public SampleView { 93 SkPath fPath; 94 SkPoint fClickPt; 95 SkScalar fPhase; 96 97public: 98 PathEffectView() : fPhase(0) { 99 } 100 101protected: 102 void onOnceBeforeDraw() override { 103 SkRandom rand; 104 int steps = 20; 105 SkScalar dist = SkIntToScalar(400); 106 SkScalar x = SkIntToScalar(20); 107 SkScalar y = SkIntToScalar(50); 108 109 fPath.moveTo(x, y); 110 for (int i = 0; i < steps; i++) { 111 x += dist/steps; 112 SkScalar tmpY = y + SkIntToScalar(rand.nextS() % 25); 113 if (i == steps/2) { 114 fPath.moveTo(x, tmpY); 115 } else { 116 fPath.lineTo(x, tmpY); 117 } 118 } 119 120 { 121 SkRect oval; 122 oval.set(SkIntToScalar(20), SkIntToScalar(30), 123 SkIntToScalar(100), SkIntToScalar(60)); 124 oval.offset(x, 0); 125 fPath.addRoundRect(oval, SkIntToScalar(8), SkIntToScalar(8)); 126 } 127 128 fClickPt.set(SkIntToScalar(200), SkIntToScalar(200)); 129 130 this->setBGColor(0xFFDDDDDD); 131 } 132 133 bool onQuery(SkEvent* evt) override { 134 if (SampleCode::TitleQ(*evt)) { 135 SampleCode::TitleR(evt, "PathEffects"); 136 return true; 137 } 138 return this->INHERITED::onQuery(evt); 139 } 140 141 void onDrawContent(SkCanvas* canvas) override { 142 SkPaint paint; 143 144 canvas->translate(0, 50); 145 146 paint.setColor(SK_ColorBLUE); 147 paint.setPathEffect(make_pe(2, fPhase))->unref(); 148 canvas->drawPath(fPath, paint); 149 150 canvas->translate(0, 50); 151 152 paint.setARGB(0xFF, 0, 0xBB, 0); 153 paint.setPathEffect(make_pe(3, fPhase))->unref(); 154 canvas->drawPath(fPath, paint); 155 156 canvas->translate(0, 50); 157 158 paint.setARGB(0xFF, 0, 0, 0); 159 paint.setPathEffect(make_warp_pe(fPhase))->unref(); 160 TestRastBuilder testRastBuilder; 161 paint.setRasterizer(testRastBuilder.detachRasterizer())->unref(); 162 canvas->drawPath(fPath, paint); 163 } 164 165 bool onAnimate(const SkAnimTimer& timer) override { 166 fPhase = timer.scaled(40); 167 return true; 168 } 169 170private: 171 typedef SampleView INHERITED; 172}; 173 174////////////////////////////////////////////////////////////////////////////// 175 176static SkView* MyFactory() { return new PathEffectView; } 177static SkViewRegister reg(MyFactory); 178