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