Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
dashcircle.cpp
Go to the documentation of this file.
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/gm.h"
15#include "include/core/SkRect.h"
18#include "include/core/SkSize.h"
23
24int dash1[] = { 1, 1 };
25int dash2[] = { 1, 3 };
26int dash3[] = { 1, 1, 3, 3 };
27int dash4[] = { 1, 3, 2, 4 };
28
30 int* pattern;
31 int length;
32} dashExamples[] = {
33 { dash1, std::size(dash1) },
34 { dash2, std::size(dash2) },
35 { dash3, std::size(dash3) },
36 { dash4, std::size(dash4) }
37};
38
39
40class DashCircleGM : public skiagm::GM {
41public:
42 DashCircleGM() : fRotation(0) { }
43
44protected:
45 SkString getName() const override { return SkString("dashcircle"); }
46
47 SkISize getISize() override { return SkISize::Make(900, 1200); }
48
49 void onDraw(SkCanvas* canvas) override {
50 SkPaint refPaint;
51 refPaint.setAntiAlias(true);
52 refPaint.setColor(0xFFbf3f7f);
53 refPaint.setStroke(true);
54 refPaint.setStrokeWidth(1);
55 const SkScalar radius = 125;
56 SkRect oval = SkRect::MakeLTRB(-radius - 20, -radius - 20, radius + 20, radius + 20);
57 SkPath circle = SkPath::Circle(0, 0, radius);
58 SkScalar circumference = radius * SK_ScalarPI * 2;
59 int wedges[] = { 6, 12, 36 };
60 canvas->translate(radius+20, radius+20);
61 for (int wedge : wedges) {
62 SkScalar arcLength = 360.f / wedge;
63 canvas->save();
64 for (const DashExample& dashExample : dashExamples) {
65 SkPathBuilder refPath;
66 int dashUnits = 0;
67 for (int index = 0; index < dashExample.length; ++index) {
68 dashUnits += dashExample.pattern[index];
69 }
70 SkScalar unitLength = arcLength / dashUnits;
71 SkScalar angle = 0;
72 for (int index = 0; index < wedge; ++index) {
73 for (int i2 = 0; i2 < dashExample.length; i2 += 2) {
74 SkScalar span = dashExample.pattern[i2] * unitLength;
75 refPath.moveTo(0, 0);
76 refPath.arcTo(oval, angle, span, false);
77 refPath.close();
78 angle += span + (dashExample.pattern[i2 + 1]) * unitLength;
79 }
80 }
81 canvas->save();
82 canvas->rotate(fRotation);
83 canvas->drawPath(refPath.detach(), refPaint);
84 canvas->restore();
85 SkPaint p;
86 p.setAntiAlias(true);
87 p.setStroke(true);
88 p.setStrokeWidth(10);
89 SkScalar intervals[4];
90 int intervalCount = dashExample.length;
91 SkScalar dashLength = circumference / wedge / dashUnits;
92 for (int index = 0; index < dashExample.length; ++index) {
93 intervals[index] = dashExample.pattern[index] * dashLength;
94 }
95 p.setPathEffect(SkDashPathEffect::Make(intervals, intervalCount, 0));
96 canvas->save();
97 canvas->rotate(fRotation);
98 canvas->drawPath(circle, p);
99 canvas->restore();
100 canvas->translate(0, radius * 2 + 50);
101 }
102 canvas->restore();
103 canvas->translate(radius * 2 + 50, 0);
104 }
105 }
106
107 bool onAnimate(double nanos) override {
108 constexpr SkScalar kDesiredDurationSecs = 100.0f;
109
110 fRotation = TimeUtils::Scaled(1e-9 * nanos, 360.0f/kDesiredDurationSecs, 360.0f);
111 return true;
112 }
113
114private:
115 SkScalar fRotation;
116
117 using INHERITED = GM;
118};
119
120DEF_GM(return new DashCircleGM; )
121
122class DashCircle2GM : public skiagm::GM {
123public:
125
126protected:
127 SkString getName() const override { return SkString("dashcircle2"); }
128
129 SkISize getISize() override { return SkISize::Make(635, 900); }
130
131 void onDraw(SkCanvas* canvas) override {
132 // These intervals are defined relative to tau.
133 static constexpr SkScalar kIntervals[][2]{
134 {0.333f, 0.333f},
135 {0.015f, 0.015f},
136 {0.01f , 0.09f },
137 {0.097f, 0.003f},
138 {0.02f , 0.04f },
139 {0.1f , 0.2f },
140 {0.25f , 0.25f },
141 {0.6f , 0.7f }, // adds to > 1
142 {1.2f , 0.8f }, // on is > 1
143 {0.1f , 1.1f }, // off is > 1*/
144 };
145
146 static constexpr int kN = std::size(kIntervals);
147 static constexpr SkScalar kRadius = 20.f;
148 static constexpr SkScalar kStrokeWidth = 15.f;
149 static constexpr SkScalar kPad = 5.f;
150 static constexpr SkRect kCircle = {-kRadius, -kRadius, kRadius, kRadius};
151
152 static constexpr SkScalar kThinRadius = kRadius * 1.5;
153 static constexpr SkRect kThinCircle = {-kThinRadius, -kThinRadius,
154 kThinRadius, kThinRadius};
155 static constexpr SkScalar kThinStrokeWidth = 0.4f;
156
157 sk_sp<SkPathEffect> deffects[std::size(kIntervals)];
158 sk_sp<SkPathEffect> thinDEffects[std::size(kIntervals)];
159 for (int i = 0; i < kN; ++i) {
160 static constexpr SkScalar kTau = 2 * SK_ScalarPI;
161 static constexpr SkScalar kCircumference = kRadius * kTau;
162 SkScalar scaledIntervals[2] = {kCircumference * kIntervals[i][0],
163 kCircumference * kIntervals[i][1]};
164 deffects[i] = SkDashPathEffect::Make(
165 scaledIntervals, 2, kCircumference * fPhaseDegrees * kTau / 360.f);
166 static constexpr SkScalar kThinCircumference = kThinRadius * kTau;
167 scaledIntervals[0] = kThinCircumference * kIntervals[i][0];
168 scaledIntervals[1] = kThinCircumference * kIntervals[i][1];
169 thinDEffects[i] = SkDashPathEffect::Make(
170 scaledIntervals, 2, kThinCircumference * fPhaseDegrees * kTau / 360.f);
171 }
172
174 rotate.setRotate(25.f);
175 const SkMatrix kMatrices[]{
176 SkMatrix::I(),
177 SkMatrix::Scale(1.2f, 1.2f),
178 SkMatrix::MakeAll(1, 0, 0, 0, -1, 0, 0, 0, 1), // y flipper
179 SkMatrix::MakeAll(-1, 0, 0, 0, 1, 0, 0, 0, 1), // x flipper
180 SkMatrix::Scale(0.7f, 0.7f),
181 rotate,
183 SkMatrix::Concat(SkMatrix::MakeAll(-1, 0, 0, 0, 1, 0, 0, 0, 1), rotate),
184 rotate)
185 };
186
188 paint.setAntiAlias(true);
189 paint.setStrokeWidth(kStrokeWidth);
190 paint.setStroke(true);
191
192 // Compute the union of bounds of all of our test cases.
193 SkRect bounds = SkRect::MakeEmpty();
194 const SkRect kBounds = kThinCircle.makeOutset(kThinStrokeWidth / 2.f,
195 kThinStrokeWidth / 2.f);
196 for (const auto& m : kMatrices) {
197 SkRect devBounds;
198 m.mapRect(&devBounds, kBounds);
199 bounds.join(devBounds);
200 }
201
202 canvas->save();
203 canvas->translate(-bounds.fLeft + kPad, -bounds.fTop + kPad);
204 for (size_t i = 0; i < std::size(deffects); ++i) {
205 canvas->save();
206 for (const auto& m : kMatrices) {
207 canvas->save();
208 canvas->concat(m);
209
210 paint.setPathEffect(deffects[i]);
211 paint.setStrokeWidth(kStrokeWidth);
212 canvas->drawOval(kCircle, paint);
213
214 paint.setPathEffect(thinDEffects[i]);
215 paint.setStrokeWidth(kThinStrokeWidth);
216 canvas->drawOval(kThinCircle, paint);
217
218 canvas->restore();
219 canvas->translate(bounds.width() + kPad, 0);
220 }
221 canvas->restore();
222 canvas->translate(0, bounds.height() + kPad);
223 }
224 canvas->restore();
225 }
226
227protected:
228 bool onAnimate(double nanos) override {
229 fPhaseDegrees = 1e-9 * nanos;
230 return true;
231 }
232
233 // Init with a non-zero phase for when run as a non-animating GM.
234 SkScalar fPhaseDegrees = 12.f;
235};
236
237DEF_GM(return new DashCircle2GM;)
238
239DEF_SIMPLE_GM(maddash, canvas, 1600, 1600) {
240 canvas->drawRect({0, 0, 1600, 1600}, SkPaint());
241 SkPaint p;
242 p.setColor(SK_ColorRED);
243 p.setAntiAlias(true);
244 p.setStroke(true);
245 p.setStrokeWidth(380);
246
247 SkScalar intvls[] = { 2.5, 10 /* 1200 */ };
248 p.setPathEffect(SkDashPathEffect::Make(intvls, 2, 0));
249
250 canvas->drawCircle(400, 400, 200, p);
251
252 SkPathBuilder path;
253 path.moveTo(800, 400);
254 path.quadTo(1000, 400, 1000, 600);
255 path.quadTo(1000, 800, 800, 800);
256 path.quadTo(600, 800, 600, 600);
257 path.quadTo(600, 400, 800, 400);
258 path.close();
259 canvas->translate(350, 150);
260 p.setStrokeWidth(320);
261 canvas->drawPath(path.detach(), p);
262
263 path.moveTo(800, 400);
264 path.cubicTo(900, 400, 1000, 500, 1000, 600);
265 path.cubicTo(1000, 700, 900, 800, 800, 800);
266 path.cubicTo(700, 800, 600, 700, 600, 600);
267 path.cubicTo(600, 500, 700, 400, 800, 400);
268 path.close();
269 canvas->translate(-550, 500);
270 p.setStrokeWidth(300);
271 canvas->drawPath(path.detach(), p);
272}
constexpr SkColor SK_ColorRED
Definition SkColor.h:126
static bool rotate(const SkDCubic &cubic, int zero, int index, SkDCubic &rotPath)
#define SK_ScalarPI
Definition SkScalar.h:21
constexpr int kPad
SkString getName() const override
SkISize getISize() override
void onDraw(SkCanvas *canvas) override
bool onAnimate(double nanos) override
void onDraw(SkCanvas *canvas) override
bool onAnimate(double nanos) override
SkString getName() const override
SkISize getISize() override
void drawOval(const SkRect &oval, const SkPaint &paint)
void restore()
Definition SkCanvas.cpp:465
void translate(SkScalar dx, SkScalar dy)
void rotate(SkScalar degrees)
int save()
Definition SkCanvas.cpp:451
void drawPath(const SkPath &path, const SkPaint &paint)
void concat(const SkMatrix &matrix)
static sk_sp< SkPathEffect > Make(const SkScalar intervals[], int count, SkScalar phase)
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition SkMatrix.h:75
static SkMatrix MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar pers0, SkScalar pers1, SkScalar pers2)
Definition SkMatrix.h:179
static SkMatrix Concat(const SkMatrix &a, const SkMatrix &b)
Definition SkMatrix.h:1775
SkMatrix & setRotate(SkScalar degrees, SkScalar px, SkScalar py)
Definition SkMatrix.cpp:452
static const SkMatrix & I()
void setColor(SkColor color)
Definition SkPaint.cpp:119
void setAntiAlias(bool aa)
Definition SkPaint.h:170
void setStroke(bool)
Definition SkPaint.cpp:115
void setStrokeWidth(SkScalar width)
Definition SkPaint.cpp:159
SkPathBuilder & close()
SkPathBuilder & arcTo(const SkRect &oval, SkScalar startAngleDeg, SkScalar sweepAngleDeg, bool forceMoveTo)
SkPathBuilder & moveTo(SkPoint pt)
static SkPath Circle(SkScalar center_x, SkScalar center_y, SkScalar radius, SkPathDirection dir=SkPathDirection::kCW)
Definition SkPath.cpp:3530
GM(SkColor backgroundColor=SK_ColorWHITE)
Definition gm.cpp:81
const Paint & paint
int dash2[]
int dash3[]
int dash1[]
struct DashExample dashExamples[]
int dash4[]
float SkScalar
Definition extension.cpp:12
#define DEF_GM(CODE)
Definition gm.h:40
#define DEF_SIMPLE_GM(NAME, CANVAS, W, H)
Definition gm.h:50
static float Scaled(float time, float speed, float period=0)
Definition TimeUtils.h:27
constexpr SkScalar kStrokeWidth
constexpr int kRadius
static constexpr SkISize Make(int32_t w, int32_t h)
Definition SkSize.h:20
static constexpr SkRect MakeEmpty()
Definition SkRect.h:595
SkRect makeOutset(float dx, float dy) const
Definition SkRect.h:1002
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition SkRect.h:646