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 #include "SkLayerRasterizer.h"
     71 
     72 class TestRastBuilder : public SkLayerRasterizer::Builder {
     73 public:
     74     TestRastBuilder() {
     75         SkPaint paint;
     76         paint.setAntiAlias(true);
     77 
     78         paint.setAlpha(0x66);
     79         this->addLayer(paint, SkIntToScalar(4), SkIntToScalar(4));
     80 
     81         paint.setAlpha(0xFF);
     82         this->addLayer(paint);
     83     }
     84 };
     85 
     86 class PathEffectView : public SampleView {
     87     SkPath  fPath;
     88     SkPoint fClickPt;
     89     SkScalar fPhase;
     90 
     91 public:
     92     PathEffectView() : fPhase(0) {
     93         }
     94 
     95 protected:
     96     void onOnceBeforeDraw() override {
     97         SkRandom    rand;
     98         int         steps = 20;
     99         SkScalar    dist = SkIntToScalar(400);
    100         SkScalar    x = SkIntToScalar(20);
    101         SkScalar    y = SkIntToScalar(50);
    102 
    103         fPath.moveTo(x, y);
    104         for (int i = 0; i < steps; i++) {
    105             x += dist/steps;
    106             SkScalar tmpY = y + SkIntToScalar(rand.nextS() % 25);
    107             if (i == steps/2) {
    108                 fPath.moveTo(x, tmpY);
    109             } else {
    110                 fPath.lineTo(x, tmpY);
    111             }
    112         }
    113 
    114         {
    115             SkRect  oval;
    116             oval.set(SkIntToScalar(20), SkIntToScalar(30),
    117                      SkIntToScalar(100), SkIntToScalar(60));
    118             oval.offset(x, 0);
    119             fPath.addRoundRect(oval, SkIntToScalar(8), SkIntToScalar(8));
    120         }
    121 
    122         fClickPt.set(SkIntToScalar(200), SkIntToScalar(200));
    123 
    124         this->setBGColor(0xFFDDDDDD);
    125     }
    126 
    127     bool onQuery(SkEvent* evt) override {
    128         if (SampleCode::TitleQ(*evt)) {
    129             SampleCode::TitleR(evt, "PathEffects");
    130             return true;
    131         }
    132         return this->INHERITED::onQuery(evt);
    133     }
    134 
    135     void onDrawContent(SkCanvas* canvas) override {
    136         SkPaint paint;
    137 
    138         canvas->translate(0, 50);
    139 
    140         paint.setColor(SK_ColorBLUE);
    141         paint.setPathEffect(make_pe(2, fPhase));
    142         canvas->drawPath(fPath, paint);
    143 
    144         canvas->translate(0, 50);
    145 
    146         paint.setARGB(0xFF, 0, 0xBB, 0);
    147         paint.setPathEffect(make_pe(3, fPhase));
    148         canvas->drawPath(fPath, paint);
    149 
    150         canvas->translate(0, 50);
    151 
    152         paint.setARGB(0xFF, 0, 0, 0);
    153         paint.setPathEffect(make_warp_pe(fPhase));
    154         TestRastBuilder testRastBuilder;
    155         paint.setRasterizer(testRastBuilder.detach());
    156         canvas->drawPath(fPath, paint);
    157     }
    158 
    159     bool onAnimate(const SkAnimTimer& timer) override {
    160         fPhase = timer.scaled(40);
    161         return true;
    162     }
    163 
    164 private:
    165     typedef SampleView INHERITED;
    166 };
    167 
    168 //////////////////////////////////////////////////////////////////////////////
    169 
    170 static SkView* MyFactory() { return new PathEffectView; }
    171 static SkViewRegister reg(MyFactory);
    172