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