Home | History | Annotate | Download | only in gm
      1 /*
      2  * Copyright 2016 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 "gm.h"
      9 #include "SkAnimTimer.h"
     10 #include "SkPath.h"
     11 #include "SkDashPathEffect.h"
     12 
     13 int dash1[] = { 1, 1 };
     14 int dash2[] = { 1, 3 };
     15 int dash3[] = { 1, 1, 3, 3 };
     16 int dash4[] = { 1, 3, 2, 4 };
     17 
     18 struct DashExample {
     19     int* pattern;
     20     int length;
     21 } dashExamples[] = {
     22     { dash1, SK_ARRAY_COUNT(dash1) },
     23     { dash2, SK_ARRAY_COUNT(dash2) },
     24     { dash3, SK_ARRAY_COUNT(dash3) },
     25     { dash4, SK_ARRAY_COUNT(dash4) }
     26 };
     27 
     28 
     29 class DashCircleGM : public skiagm::GM {
     30 public:
     31     DashCircleGM() : fRotation(0) { }
     32 
     33 protected:
     34     SkString onShortName() override { return SkString("dashcircle"); }
     35 
     36     SkISize onISize() override { return SkISize::Make(900, 1200); }
     37 
     38     void onDraw(SkCanvas* canvas) override {
     39         SkPaint refPaint;
     40         refPaint.setAntiAlias(true);
     41         refPaint.setColor(0xFFbf3f7f);
     42         refPaint.setStyle(SkPaint::kStroke_Style);
     43         refPaint.setStrokeWidth(1);
     44         const SkScalar radius = 125;
     45         SkRect oval = SkRect::MakeLTRB(-radius - 20, -radius - 20, radius + 20, radius + 20);
     46         SkPath circle;
     47         circle.addCircle(0, 0, radius);
     48         SkScalar circumference = radius * SK_ScalarPI * 2;
     49         int wedges[] = { 6, 12, 36 };
     50         canvas->translate(radius+20, radius+20);
     51         for (int wedge : wedges) {
     52             SkScalar arcLength = 360.f / wedge;
     53             canvas->save();
     54             for (const DashExample& dashExample : dashExamples) {
     55                 SkPath refPath;
     56                 int dashUnits = 0;
     57                 for (int index = 0; index < dashExample.length; ++index) {
     58                     dashUnits += dashExample.pattern[index];
     59                 }
     60                 SkScalar unitLength = arcLength / dashUnits;
     61                 SkScalar angle = 0;
     62                 for (int index = 0; index < wedge; ++index) {
     63                     for (int i2 = 0; i2 < dashExample.length; i2 += 2) {
     64                         SkScalar span = dashExample.pattern[i2] * unitLength;
     65                         refPath.moveTo(0, 0);
     66                         refPath.arcTo(oval, angle, span, false);
     67                         refPath.close();
     68                         angle += span + (dashExample.pattern[i2 + 1]) * unitLength;
     69                     }
     70                 }
     71                 canvas->save();
     72                 canvas->rotate(fRotation);
     73                 canvas->drawPath(refPath, refPaint);
     74                 canvas->restore();
     75                 SkPaint p;
     76                 p.setAntiAlias(true);
     77                 p.setStyle(SkPaint::kStroke_Style);
     78                 p.setStrokeWidth(10);
     79                 SkScalar intervals[4];
     80                 int intervalCount = dashExample.length;
     81                 SkScalar dashLength = circumference / wedge / dashUnits;
     82                 for (int index = 0; index < dashExample.length; ++index) {
     83                     intervals[index] = dashExample.pattern[index] * dashLength;
     84                 }
     85                 p.setPathEffect(SkDashPathEffect::Make(intervals, intervalCount, 0));
     86                 canvas->save();
     87                 canvas->rotate(fRotation);
     88                 canvas->drawPath(circle, p);
     89                 canvas->restore();
     90                 canvas->translate(0, radius * 2 + 50);
     91             }
     92             canvas->restore();
     93             canvas->translate(radius * 2 + 50, 0);
     94         }
     95     }
     96 
     97     bool onAnimate(const SkAnimTimer& timer) override {
     98         constexpr SkScalar kDesiredDurationSecs = 100.0f;
     99 
    100         fRotation = timer.scaled(360.0f/kDesiredDurationSecs, 360.0f);
    101         return true;
    102     }
    103 
    104 private:
    105     SkScalar fRotation;
    106 
    107     typedef GM INHERITED;
    108 };
    109 
    110 DEF_GM(return new DashCircleGM; )
    111