1 /* 2 * Copyright 2015 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 10 #include "SkDashPathEffect.h" 11 #include "SkPaint.h" 12 #include "SkPath.h" 13 #include "SkRRect.h" 14 15 namespace skiagm { 16 17 class ContourStartGM : public GM { 18 public: 19 ContourStartGM() { 20 const SkScalar kMaxDashLen = 100; 21 const SkScalar kDashGrowth = 1.2f; 22 23 SkSTArray<100, SkScalar> intervals; 24 for (SkScalar len = 1; len < kMaxDashLen; len *= kDashGrowth) { 25 intervals.push_back(len); 26 intervals.push_back(len); 27 } 28 29 fDashPaint.setAntiAlias(true); 30 fDashPaint.setStyle(SkPaint::kStroke_Style); 31 fDashPaint.setStrokeWidth(6); 32 fDashPaint.setColor(0xff008000); 33 fDashPaint.setPathEffect(SkDashPathEffect::Make(intervals.begin(), intervals.count(), 0)); 34 35 fPointsPaint.setColor(0xff800000); 36 fPointsPaint.setStrokeWidth(3); 37 38 fRect = SkRect::MakeLTRB(10, 10, 100, 70); 39 } 40 41 protected: 42 SkString onShortName() override { 43 return SkString("contour_start"); 44 } 45 46 SkISize onISize() override { return SkISize::Make(kImageWidth, kImageHeight); } 47 48 void onDraw(SkCanvas* canvas) override { 49 50 drawDirs(canvas, [](const SkRect& rect, SkPath::Direction dir, unsigned startIndex) { 51 SkPath path; 52 path.addRect(rect, dir, startIndex); 53 return path; 54 }); 55 56 drawDirs(canvas, [](const SkRect& rect, SkPath::Direction dir, unsigned startIndex) { 57 SkPath path; 58 path.addOval(rect, dir, startIndex); 59 return path; 60 }); 61 62 drawDirs(canvas, [](const SkRect& rect, SkPath::Direction dir, unsigned startIndex) { 63 SkRRect rrect; 64 const SkVector radii[4] = { {15, 15}, {15, 15}, {15, 15}, {15, 15}}; 65 rrect.setRectRadii(rect, radii); 66 67 SkPath path; 68 path.addRRect(rrect, dir, startIndex); 69 return path; 70 }); 71 72 drawDirs(canvas, [](const SkRect& rect, SkPath::Direction dir, unsigned startIndex) { 73 SkRRect rrect; 74 rrect.setRect(rect); 75 76 SkPath path; 77 path.addRRect(rrect, dir, startIndex); 78 return path; 79 }); 80 81 drawDirs(canvas, [](const SkRect& rect, SkPath::Direction dir, unsigned startIndex) { 82 SkRRect rrect; 83 rrect.setOval(rect); 84 85 SkPath path; 86 path.addRRect(rrect, dir, startIndex); 87 return path; 88 }); 89 90 } 91 92 private: 93 static constexpr int kImageWidth = 1200; 94 static constexpr int kImageHeight = 600; 95 96 SkPaint fDashPaint, fPointsPaint; 97 SkRect fRect; 98 99 void drawDirs(SkCanvas* canvas, 100 SkPath (*makePath)(const SkRect&, SkPath::Direction, unsigned)) const { 101 drawOneColumn(canvas, SkPath::kCW_Direction, makePath); 102 canvas->translate(kImageWidth / 10, 0); 103 drawOneColumn(canvas, SkPath::kCCW_Direction, makePath); 104 canvas->translate(kImageWidth / 10, 0); 105 } 106 107 void drawOneColumn(SkCanvas* canvas, SkPath::Direction dir, 108 SkPath (*makePath)(const SkRect&, SkPath::Direction, unsigned)) const { 109 SkAutoCanvasRestore acr(canvas, true); 110 111 for (unsigned i = 0; i < 8; ++i) { 112 const SkPath path = makePath(fRect, dir, i); 113 canvas->drawPath(path, fDashPaint); 114 115 const int n = path.countPoints(); 116 SkAutoTArray<SkPoint> points(n); 117 path.getPoints(points.get(), n); 118 canvas->drawPoints(SkCanvas::kPoints_PointMode, n, points.get(), fPointsPaint); 119 120 canvas->translate(0, kImageHeight / 8); 121 } 122 } 123 124 typedef GM INHERITED; 125 }; 126 127 DEF_GM( return new ContourStartGM(); ) 128 129 } // namespace skiagm 130