Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
convexpaths.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2011 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"
17#include "include/core/SkSize.h"
21#include "src/base/SkRandom.h"
22
23using namespace skia_private;
24
25namespace {
26
27class SkDoOnce {
28public:
29 SkDoOnce() { fDidOnce = false; }
30 // Make noncopyable
31 SkDoOnce(SkDoOnce&) = delete;
32 SkDoOnce& operator=(SkDoOnce&) = delete;
33
34 bool needToDo() const { return !fDidOnce; }
35 bool alreadyDone() const { return fDidOnce; }
36 void accomplished() {
37 SkASSERT(!fDidOnce);
38 fDidOnce = true;
39 }
40
41private:
42 bool fDidOnce;
43};
44
45class ConvexPathsGM : public skiagm::GM {
46 SkDoOnce fOnce;
47
48 void onOnceBeforeDraw() override { this->setBGColor(0xFF000000); }
49
50 SkString getName() const override { return SkString("convexpaths"); }
51
52 SkISize getISize() override { return {1200, 1100}; }
53
54 void makePaths() {
55 if (fOnce.alreadyDone()) {
56 return;
57 }
58 fOnce.accomplished();
59
61 fPaths.push_back(b.moveTo(0, 0)
62 .quadTo(50, 100, 0, 100)
63 .lineTo(0, 0)
64 .detach());
65
66 fPaths.push_back(b.moveTo(0, 50)
67 .quadTo(50, 0, 100, 50)
68 .quadTo(50, 100, 0, 50)
69 .detach());
70
71 fPaths.push_back(SkPath::Rect({0, 0, 100, 100}, SkPathDirection::kCW));
72 fPaths.push_back(SkPath::Rect({0, 0, 100, 100}, SkPathDirection::kCCW));
73 fPaths.push_back(SkPath::Circle(50, 50, 50, SkPathDirection::kCW));
74 fPaths.push_back(SkPath::Oval(SkRect::MakeXYWH(0, 0, 50, 100), SkPathDirection::kCW));
75 fPaths.push_back(SkPath::Oval(SkRect::MakeXYWH(0, 0, 100, 5), SkPathDirection::kCCW));
76 fPaths.push_back(SkPath::Oval(SkRect::MakeXYWH(0, 0, 1, 100), SkPathDirection::kCCW));
77 fPaths.push_back(SkPath::RRect(SkRRect::MakeRectXY({0, 0, 100, 100}, 40, 20),
79
80 // large number of points
81 enum {
82 kLength = 100,
83 kPtsPerSide = (1 << 12),
84 };
85 b.moveTo(0, 0);
86 for (int i = 1; i < kPtsPerSide; ++i) { // skip the first point due to moveTo.
87 b.lineTo(kLength * SkIntToScalar(i) / kPtsPerSide, 0);
88 }
89 for (int i = 0; i < kPtsPerSide; ++i) {
90 b.lineTo(kLength, kLength * SkIntToScalar(i) / kPtsPerSide);
91 }
92 for (int i = kPtsPerSide; i > 0; --i) {
93 b.lineTo(kLength * SkIntToScalar(i) / kPtsPerSide, kLength);
94 }
95 for (int i = kPtsPerSide; i > 0; --i) {
96 b.lineTo(0, kLength * SkIntToScalar(i) / kPtsPerSide);
97 }
98 fPaths.push_back(b.detach());
99
100 // shallow diagonals
101 fPaths.push_back(SkPath::Polygon({{0,0}, {100,1}, {98,100}, {3,96}}, false));
102
103 fPaths.push_back(b.arcTo(SkRect::MakeXYWH(0, 0, 50, 100), 25, 130, false)
104 .detach());
105
106 // cubics
107 fPaths.push_back(b.cubicTo( 1, 1, 10, 90, 0, 100).detach());
108 fPaths.push_back(b.cubicTo(100, 50, 20, 100, 0, 0).detach());
109
110 // path that has a cubic with a repeated first control point and
111 // a repeated last control point.
112 fPaths.push_back(b.moveTo(10, 10)
113 .cubicTo(10, 10, 10, 0, 20, 0)
114 .lineTo(40, 0)
115 .cubicTo(40, 0, 50, 0, 50, 10)
116 .detach());
117
118 // path that has two cubics with repeated middle control points.
119 fPaths.push_back(b.moveTo(10, 10)
120 .cubicTo(10, 0, 10, 0, 20, 0)
121 .lineTo(40, 0)
122 .cubicTo(50, 0, 50, 0, 50, 10)
123 .detach());
124
125 // cubic where last three points are almost a line
126 fPaths.push_back(b.moveTo(0, 228.0f/8)
127 .cubicTo( 628.0f/ 8, 82.0f/8,
128 1255.0f/ 8, 141.0f/8,
129 1883.0f/ 8, 202.0f/8)
130 .detach());
131
132 // flat cubic where the at end point tangents both point outward.
133 fPaths.push_back(b.moveTo(10, 0)
134 .cubicTo(0, 1, 30, 1, 20, 0)
135 .detach());
136
137 // flat cubic where initial tangent is in, end tangent out
138 fPaths.push_back(b.moveTo(0, 0)
139 .cubicTo(10, 1, 30, 1, 20, 0)
140 .detach());
141
142 // flat cubic where initial tangent is out, end tangent in
143 fPaths.push_back(b.moveTo(10, 0)
144 .cubicTo(0, 1, 20, 1, 30, 0)
145 .detach());
146
147 // triangle where one edge is a degenerate quad
148 fPaths.push_back(b.moveTo(8.59375f, 45)
149 .quadTo(16.9921875f, 45,
150 31.25f, 45)
151 .lineTo(100, 100)
152 .lineTo(8.59375f, 45)
153 .detach());
154
155 // triangle where one edge is a quad with a repeated point
156 fPaths.push_back(b.moveTo(0, 25)
157 .lineTo(50, 0)
158 .quadTo(50, 50, 50, 50)
159 .detach());
160
161 // triangle where one edge is a cubic with a 2x repeated point
162 fPaths.push_back(b.moveTo(0, 25)
163 .lineTo(50, 0)
164 .cubicTo(50, 0, 50, 50, 50, 50)
165 .detach());
166
167 // triangle where one edge is a quad with a nearly repeated point
168 fPaths.push_back(b.moveTo(0, 25)
169 .lineTo(50, 0)
170 .quadTo(50, 49.95f, 50, 50)
171 .detach());
172
173 // triangle where one edge is a cubic with a 3x nearly repeated point
174 fPaths.push_back(b.moveTo(0, 25)
175 .lineTo(50, 0)
176 .cubicTo(50, 49.95f, 50, 49.97f, 50, 50)
177 .detach());
178
179 // triangle where there is a point degenerate cubic at one corner
180 fPaths.push_back(b.moveTo(0, 25)
181 .lineTo(50, 0)
182 .lineTo(50, 50)
183 .cubicTo(50, 50, 50, 50, 50, 50)
184 .detach());
185
186 // point line
187 fPaths.push_back(SkPath::Line({50, 50}, {50, 50}));
188
189 // point quad
190 fPaths.push_back(b.moveTo(50, 50)
191 .quadTo(50, 50, 50, 50)
192 .detach());
193
194 // point cubic
195 fPaths.push_back(b.moveTo(50, 50)
196 .cubicTo(50, 50, 50, 50, 50, 50)
197 .detach());
198
199 // moveTo only paths
200 fPaths.push_back(b.moveTo(0, 0)
201 .moveTo(0, 0)
202 .moveTo(1, 1)
203 .moveTo(1, 1)
204 .moveTo(10, 10)
205 .detach());
206
207 fPaths.push_back(b.moveTo(0, 0)
208 .moveTo(0, 0)
209 .detach());
210
211 // line degenerate
212 fPaths.push_back(b.lineTo(100, 100).detach());
213 fPaths.push_back(b.quadTo(100, 100, 0, 0).detach());
214 fPaths.push_back(b.quadTo(100, 100, 50, 50).detach());
215 fPaths.push_back(b.quadTo(50, 50, 100, 100).detach());
216 fPaths.push_back(b.cubicTo(0, 0, 0, 0, 100, 100).detach());
217
218 // skbug.com/8928
219 fPaths.push_back(b.moveTo(16.875f, 192.594f)
220 .cubicTo(45.625f, 192.594f, 74.375f, 192.594f, 103.125f, 192.594f)
221 .cubicTo(88.75f, 167.708f, 74.375f, 142.823f, 60, 117.938f)
222 .cubicTo(45.625f, 142.823f, 31.25f, 167.708f, 16.875f, 192.594f)
223 .close()
224 .detach());
225 SkMatrix m;
226 m.setAll(0.1f, 0, -1, 0, 0.115207f, -2.64977f, 0, 0, 1);
227 fPaths.back().transform(m);
228
229 // small circle. This is listed last so that it has device coords far
230 // from the origin (small area relative to x,y values).
231 fPaths.push_back(SkPath::Circle(0, 0, 1.2f));
232 }
233
234 void onDraw(SkCanvas* canvas) override {
235 this->makePaths();
236
238 paint.setAntiAlias(true);
239 SkRandom rand;
240 canvas->translate(20, 20);
241
242 // As we've added more paths this has gotten pretty big. Scale the whole thing down.
243 canvas->scale(2.0f/3, 2.0f/3);
244
245 for (int i = 0; i < fPaths.size(); ++i) {
246 canvas->save();
247 // position the path, and make it at off-integer coords.
248 canvas->translate(200.0f * (i % 5) + 1.0f/10,
249 200.0f * (i / 5) + 9.0f/10);
250 SkColor color = rand.nextU();
251 color |= 0xff000000;
252 paint.setColor(color);
253#if 0 // This hitting on 32bit Linux builds for some paths. Temporarily disabling while it is
254 // debugged.
255 SkASSERT(fPaths[i].isConvex());
256#endif
257 canvas->drawPath(fPaths[i], paint);
258 canvas->restore();
259 }
260 }
261
262 TArray<SkPath> fPaths;
263};
264} // namespace
265
266DEF_GM( return new ConvexPathsGM; )
SkColor4f color
#define SkASSERT(cond)
Definition SkAssert.h:116
uint32_t SkColor
Definition SkColor.h:37
#define SkIntToScalar(x)
Definition SkScalar.h:57
void restore()
Definition SkCanvas.cpp:465
void translate(SkScalar dx, SkScalar dy)
int save()
Definition SkCanvas.cpp:451
void drawPath(const SkPath &path, const SkPaint &paint)
void scale(SkScalar sx, SkScalar sy)
static SkPath RRect(const SkRRect &, SkPathDirection dir=SkPathDirection::kCW)
Definition SkPath.cpp:3534
static SkPath Rect(const SkRect &, SkPathDirection=SkPathDirection::kCW, unsigned startIndex=0)
Definition SkPath.cpp:3518
static SkPath Circle(SkScalar center_x, SkScalar center_y, SkScalar radius, SkPathDirection dir=SkPathDirection::kCW)
Definition SkPath.cpp:3530
static SkPath Oval(const SkRect &, SkPathDirection=SkPathDirection::kCW)
Definition SkPath.cpp:3522
static SkPath Polygon(const SkPoint pts[], int count, bool isClosed, SkPathFillType=SkPathFillType::kWinding, bool isVolatile=false)
Definition SkPath.cpp:3546
static SkPath Line(const SkPoint a, const SkPoint b)
Definition SkPath.h:106
static SkRRect MakeRectXY(const SkRect &rect, SkScalar xRad, SkScalar yRad)
Definition SkRRect.h:180
uint32_t nextU()
Definition SkRandom.h:42
virtual SkISize getISize()=0
virtual void onOnceBeforeDraw()
Definition gm.cpp:167
void setBGColor(SkColor)
Definition gm.cpp:159
virtual SkString getName() const =0
virtual DrawResult onDraw(SkCanvas *, SkString *errorMsg)
Definition gm.cpp:139
const Paint & paint
static bool b
#define DEF_GM(CODE)
Definition gm.h:40
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
Definition SkRect.h:659