Flutter Engine
The Flutter Engine
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
strokedlines.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"
16#include "include/core/SkPath.h"
20#include "include/core/SkRect.h"
23#include "include/core/SkSize.h"
31#include "tools/ToolUtils.h"
32
33#include <initializer_list>
34
35using namespace skia_private;
36
37constexpr int kNumColumns = 6;
38constexpr int kNumRows = 8;
39constexpr int kRadius = 40; // radius of the snowflake
40constexpr int kPad = 5; // padding on both sides of the snowflake
41constexpr int kNumSpokes = 6;
42constexpr SkScalar kStrokeWidth = 5.0f;
43
44static void draw_line(SkCanvas* canvas, const SkPoint& p0, const SkPoint& p1,
45 const SkPaint& paint, bool useDrawPath) {
46 if (useDrawPath) {
47 canvas->drawPath(SkPath::Line(p0, p1), paint);
48 } else {
49 canvas->drawLine(p0, p1, paint);
50 }
51}
52
53static void draw_fins(SkCanvas* canvas, const SkPoint& offset, float angle, const SkPaint& paint,
54 bool useDrawPath) {
55 SkScalar cos, sin;
56
57 // first fin
58 sin = SkScalarSin(angle + (SK_ScalarPI/4));
59 cos = SkScalarCos(angle + (SK_ScalarPI/4));
60 sin *= kRadius / 2.0f;
61 cos *= kRadius / 2.0f;
62
63 draw_line(canvas, offset, offset + SkPoint{cos, sin}, paint, useDrawPath);
64
65 // second fin
66 sin = SkScalarSin(angle - (SK_ScalarPI/4));
67 cos = SkScalarCos(angle - (SK_ScalarPI/4));
68 sin *= kRadius / 2.0f;
69 cos *= kRadius / 2.0f;
70
71 draw_line(canvas, offset, offset + SkPoint{cos, sin}, paint, useDrawPath);
72}
73
74// draw a snowflake centered at the origin
75static void draw_snowflake(SkCanvas* canvas, const SkPaint& paint, bool useDrawPath) {
76
78
79 SkScalar sin, cos, angle = 0.0f;
80 for (int i = 0; i < kNumSpokes/2; ++i, angle += SK_ScalarPI/(kNumSpokes/2)) {
81 sin = SkScalarSin(angle);
82 cos = SkScalarCos(angle);
83 sin *= kRadius;
84 cos *= kRadius;
85
86 // main spoke
87 draw_line(canvas, {-cos, -sin}, {cos, sin}, paint, useDrawPath);
88
89 // fins on positive side
90 const SkPoint posOffset = SkPoint::Make(0.5f * cos, 0.5f * sin);
91 draw_fins(canvas, posOffset, angle, paint, useDrawPath);
92
93 // fins on negative side
94 const SkPoint negOffset = SkPoint::Make(-0.5f * cos, -0.5f * sin);
95 draw_fins(canvas, negOffset, angle+SK_ScalarPI, paint, useDrawPath);
96 }
97}
98
99static void draw_row(SkCanvas* canvas, const SkPaint& paint, const SkMatrix& localMatrix,
100 bool useDrawPath) {
101 canvas->translate(kRadius+kPad, 0.0f);
102
104 for (auto isAA : { true, false }) {
105 SkPaint tmp(paint);
108 tmp.setStrokeCap(cap);
109 tmp.setAntiAlias(isAA);
110
111 int saveCount = canvas->save();
112 canvas->concat(localMatrix);
113 draw_snowflake(canvas, tmp, useDrawPath);
114 canvas->restoreToCount(saveCount);
115
116 canvas->translate(2*(kRadius+kPad), 0.0f);
117 }
118 }
119}
120
121namespace skiagm {
122
123// This GM exercises the special case of a stroked lines.
124// Various shaders are applied to ensure the coordinate spaces work out right.
125class StrokedLinesGM : public GM {
126public:
127 StrokedLinesGM(bool useDrawPath) : fUseDrawPath(useDrawPath) {
128 this->setBGColor(ToolUtils::color_to_565(0xFF1A65D7));
129 }
130
131protected:
132 SkString getName() const override {
133 // To preserve history, useDrawPath==true has no suffix.
134 SkString name{"strokedlines"};
135 if (!fUseDrawPath) {
136 name.append("_drawPoints");
137 }
138 return name;
139 }
140
141 SkISize getISize() override {
142 return SkISize::Make(kNumColumns * (2*kRadius+2*kPad), kNumRows * (2*kRadius+2*kPad));
143 }
144
145 void onOnceBeforeDraw() override {
146 // paints
147 {
148 // basic white
149 SkPaint p;
150 p.setColor(SK_ColorWHITE);
151 fPaints.push_back(p);
152 }
153 {
154 // gradient
156 SkPoint pts[] = { {-kRadius-kPad, -kRadius-kPad }, { kRadius+kPad, kRadius+kPad } };
157
158 SkPaint p;
159 p.setShader(SkGradientShader::MakeLinear(pts, colors, nullptr, 2, SkTileMode::kClamp));
160
161 fPaints.push_back(p);
162 }
163 {
164 // dashing
165 SkScalar intervals[] = { kStrokeWidth, kStrokeWidth };
166 int intervalCount = (int) std::size(intervals);
167 SkPaint p;
168 p.setColor(SK_ColorWHITE);
169 p.setPathEffect(SkDashPathEffect::Make(intervals, intervalCount, kStrokeWidth));
170
171 fPaints.push_back(p);
172 }
173 {
174 // Bitmap shader
175 SkBitmap bm;
176 bm.allocN32Pixels(2, 2);
177 *bm.getAddr32(0, 0) = *bm.getAddr32(1, 1) = 0xFFFFFFFF;
178 *bm.getAddr32(1, 0) = *bm.getAddr32(0, 1) = 0x0;
179
180 SkMatrix m;
181 m.setRotate(12.0f);
182 m.preScale(3.0f, 3.0f);
183
184 SkPaint p;
186 SkSamplingOptions(), m));
187 fPaints.push_back(p);
188 }
189 {
190 // blur
191 SkPaint p;
192 p.setColor(SK_ColorWHITE);
193 p.setMaskFilter(SkMaskFilter::MakeBlur(kOuter_SkBlurStyle, 3.0f));
194 fPaints.push_back(p);
195 }
196
197 // matrices
198 {
199 // rotation
200 SkMatrix m;
201 m.setRotate(12.0f);
202
203 fMatrices.push_back(m);
204 }
205 {
206 // skew
207 SkMatrix m;
208 m.setSkew(0.3f, 0.5f);
209
210 fMatrices.push_back(m);
211 }
212 {
213 // perspective
214 SkMatrix m;
215 m.reset();
216 m.setPerspX(-SK_Scalar1 / 300);
217 m.setPerspY(SK_Scalar1 / 300);
218
219 fMatrices.push_back(m);
220 }
221
222 SkASSERT(kNumRows == fPaints.size() + fMatrices.size());
223 }
224
225 void onDraw(SkCanvas* canvas) override {
226 canvas->translate(0, kRadius+kPad);
227
228 for (int i = 0; i < fPaints.size(); ++i) {
229 int saveCount = canvas->save();
230 draw_row(canvas, fPaints[i], SkMatrix::I(), fUseDrawPath);
231 canvas->restoreToCount(saveCount);
232
233 canvas->translate(0, 2*(kRadius+kPad));
234 }
235
236 for (int i = 0; i < fMatrices.size(); ++i) {
237 int saveCount = canvas->save();
238 draw_row(canvas, fPaints[0], fMatrices[i], fUseDrawPath);
239 canvas->restoreToCount(saveCount);
240
241 canvas->translate(0, 2*(kRadius+kPad));
242 }
243 }
244
245private:
246 TArray<SkPaint> fPaints;
247 TArray<SkMatrix> fMatrices;
248
249 const bool fUseDrawPath;
250
251 using INHERITED = GM;
252};
253
254//////////////////////////////////////////////////////////////////////////////
255
256DEF_GM(return new StrokedLinesGM(true);)
257DEF_GM(return new StrokedLinesGM(false);)
258
259//////////////////////////////////////////////////////////////////////////////
260
261static constexpr float kStrokeWidth = 20.f;
262
263static void draw_path(SkCanvas* canvas, const SkPoint& p0, const SkPoint& p1, SkPaint::Cap cap) {
264 // Add a gradient *not* aligned with the line's points to show local coords are tracked properly
265 constexpr SkRect kRect {-kStrokeWidth, -kStrokeWidth, 2*kStrokeWidth, 4*kStrokeWidth};
266 constexpr SkPoint kPts[] {{kRect.fLeft, kRect.fTop}, {kRect.fRight, kRect.fBottom}};
268 constexpr SkScalar kStops[] {0.f, 0.75f, 1.f};
271
273 paint.setAntiAlias(true);
275
276 paint.setShader(std::move(shader));
277 paint.setStrokeWidth(kStrokeWidth);
278 paint.setStrokeCap(cap);
279 canvas->drawLine(p0, p1, paint);
280
281 // Show outline and control points
282 SkPath fillPath;
283 SkPath path = SkPath::Line(p0, p1);
285
287 paint.setStrokeWidth(0);
288 paint.setShader(nullptr);
289 paint.setColor(SK_ColorRED);
290 canvas->drawPath(fillPath, paint);
291
292 paint.setStrokeWidth(3);
293 paint.setStrokeCap(SkPaint::kSquare_Cap);
294 int n = fillPath.countPoints();
296 fillPath.getPoints(points.get(), n);
298}
299
300DEF_SIMPLE_GM(strokedline_caps, canvas, 1400, 740) {
301 canvas->translate(kStrokeWidth*3/2, kStrokeWidth*3/2);
302
303 constexpr SkPaint::Cap kCaps[] = {
305 };
306
307 constexpr float kLengths[] = {
309 };
310
311 for (size_t i = 0; i < std::size(kCaps); ++i) {
312 SkAutoCanvasRestore acr(canvas, true);
313
314 auto drawLine = [&](float x0, float y0, float x1, float y1) {
315 draw_path(canvas, {x0, y0}, {x1, y1}, kCaps[i]);
316 canvas->translate(std::max(x0, x1) + 2 * kStrokeWidth, 0);
317 };
318
319 for (size_t j = 0; j < std::size(kLengths); ++j) {
320 float l = kLengths[j];
321
322 drawLine(0.f, 0.f, l, l);
323 drawLine(l, l, 0.f, 0.f);
324 drawLine(l/2, 0, l/2, l);
325 drawLine(0, l/2, l, l/2);
326 }
327
329
330 acr.restore();
331 canvas->translate(0, kLengths[0] + 2 * kStrokeWidth);
332 }
333}
334
335} // namespace skiagm
static const int points[]
#define SkASSERT(cond)
Definition: SkAssert.h:116
@ kOuter_SkBlurStyle
nothing inside, fuzzy outside
Definition: SkBlurTypes.h:14
uint32_t SkColor
Definition: SkColor.h:37
constexpr SkColor SK_ColorBLUE
Definition: SkColor.h:135
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
constexpr SkColor SK_ColorGREEN
Definition: SkColor.h:131
constexpr SkColor SK_ColorWHITE
Definition: SkColor.h:122
#define SkScalarSin(radians)
Definition: SkScalar.h:45
#define SK_Scalar1
Definition: SkScalar.h:18
#define SkScalarCos(radians)
Definition: SkScalar.h:46
#define SK_ScalarPI
Definition: SkScalar.h:21
sk_sp< SkShader > makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix=nullptr) const
Definition: SkBitmap.cpp:669
void allocN32Pixels(int width, int height, bool isOpaque=false)
Definition: SkBitmap.cpp:232
uint32_t * getAddr32(int x, int y) const
Definition: SkBitmap.h:1260
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
Definition: SkCanvas.cpp:1361
void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint &paint)
Definition: SkCanvas.cpp:1710
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void drawLine(SkScalar x0, SkScalar y0, SkScalar x1, SkScalar y1, const SkPaint &paint)
Definition: SkCanvas.cpp:2700
void restoreToCount(int saveCount)
Definition: SkCanvas.cpp:478
int save()
Definition: SkCanvas.cpp:447
void drawPath(const SkPath &path, const SkPaint &paint)
Definition: SkCanvas.cpp:1747
void concat(const SkMatrix &matrix)
Definition: SkCanvas.cpp:1318
@ kPoints_PointMode
draw each point separately
Definition: SkCanvas.h:1241
static sk_sp< SkPathEffect > Make(const SkScalar intervals[], int count, SkScalar phase)
static sk_sp< SkShader > MakeLinear(const SkPoint pts[2], const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
static sk_sp< SkMaskFilter > MakeBlur(SkBlurStyle style, SkScalar sigma, bool respectCTM=true)
static const SkMatrix & I()
Definition: SkMatrix.cpp:1544
@ kRound_Cap
adds circle
Definition: SkPaint.h:335
@ kButt_Cap
no stroke extension
Definition: SkPaint.h:334
@ kSquare_Cap
adds square
Definition: SkPaint.h:336
void setStyle(Style style)
Definition: SkPaint.cpp:105
void setAntiAlias(bool aa)
Definition: SkPaint.h:170
void setStrokeCap(Cap cap)
Definition: SkPaint.cpp:179
@ kStroke_Style
set to stroke geometry
Definition: SkPaint.h:194
void setStrokeWidth(SkScalar width)
Definition: SkPaint.cpp:159
Definition: SkPath.h:59
int countPoints() const
Definition: SkPath.cpp:535
int getPoints(SkPoint points[], int max) const
Definition: SkPath.cpp:539
static SkPath Line(const SkPoint a, const SkPoint b)
Definition: SkPath.h:106
int size() const
Definition: SkTArray.h:421
Definition: gm.h:110
GM(SkColor backgroundColor=SK_ColorWHITE)
Definition: gm.cpp:81
void setBGColor(SkColor)
Definition: gm.cpp:159
StrokedLinesGM(bool useDrawPath)
void onDraw(SkCanvas *canvas) override
SkString getName() const override
SkISize getISize() override
void onOnceBeforeDraw() override
const Paint & paint
Definition: color_source.cc:38
float SkScalar
Definition: extension.cpp:12
static float max(float r, float g, float b)
Definition: hsl.cpp:49
PODArray< SkColor > colors
Definition: SkRecords.h:276
SkColor color_to_565(SkColor color)
Definition: ToolUtils.cpp:139
constexpr float kStops[]
const DlColor kColors[]
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
static constexpr SkPoint kPts[kPtsCount]
Definition: emptypath.cpp:123
DEF_GM(return F(C(clipbox), 0.0f, 0.0f, {})) DEF_GM(return F(C(clipbox)
DEF_SIMPLE_GM(hugebitmapshader, canvas, 100, 100)
static constexpr float kStrokeWidth
static void draw_path(SkCanvas *canvas, const SkRect &r, const SkPaint &p)
SK_API bool FillPathWithPaint(const SkPath &src, const SkPaint &paint, SkPath *dst, const SkRect *cullRect, SkScalar resScale=1)
Definition: SkPathUtils.cpp:23
static const SkPaint::Cap kCaps[]
SeparatedVector2 offset
constexpr int kPad
static void draw_row(SkCanvas *canvas, const SkPaint &paint, const SkMatrix &localMatrix, bool useDrawPath)
static void draw_fins(SkCanvas *canvas, const SkPoint &offset, float angle, const SkPaint &paint, bool useDrawPath)
static void draw_line(SkCanvas *canvas, const SkPoint &p0, const SkPoint &p1, const SkPaint &paint, bool useDrawPath)
constexpr int kNumColumns
constexpr SkScalar kStrokeWidth
constexpr int kNumRows
constexpr int kNumSpokes
static void draw_snowflake(SkCanvas *canvas, const SkPaint &paint, bool useDrawPath)
constexpr int kRadius
Definition: SkSize.h:16
static constexpr SkISize Make(int32_t w, int32_t h)
Definition: SkSize.h:20
static constexpr SkPoint Make(float x, float y)
Definition: SkPoint_impl.h:173
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition: SkRect.h:646