Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
PatchSlide.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
14#include "include/core/SkPath.h"
23#include "src/base/SkRandom.h"
24#include "src/base/SkTime.h"
25#include "src/base/SkUTF.h"
26#include "src/core/SkGeometry.h"
27#include "src/core/SkOSFile.h"
28#include "tools/DecodeUtils.h"
29#include "tools/Resources.h"
32#include "tools/viewer/Slide.h"
33
34namespace {
36 SkBitmap bm;
38 *size = SkIPoint{bm.width(), bm.height()};
40}
41
42static sk_sp<SkShader> make_shader1(const SkIPoint& size) {
43 SkPoint pts[] = { { 0, 0, },
44 { SkIntToScalar(size.fX), SkIntToScalar(size.fY) } };
46 return SkGradientShader::MakeLinear(pts, colors, nullptr,
47 std::size(colors), SkTileMode::kMirror);
48}
49
50class Patch {
51public:
52 Patch() { sk_bzero(fPts, sizeof(fPts)); }
53 ~Patch() {}
54
55 void setPatch(const SkPoint pts[12]) {
56 memcpy(fPts, pts, 12 * sizeof(SkPoint));
57 fPts[12] = pts[0]; // the last shall be first
58 }
59 void setBounds(int w, int h) { fW = w; fH = h; }
60
61 void draw(SkCanvas*, const SkPaint&, int segsU, int segsV,
62 bool doTextures, bool doColors);
63
64private:
65 SkPoint fPts[13];
66 int fW, fH;
67};
68
69static void eval_patch_edge(const SkPoint cubic[], SkPoint samples[], int segs) {
70 SkScalar t = 0;
71 SkScalar dt = SK_Scalar1 / segs;
72
73 samples[0] = cubic[0];
74 for (int i = 1; i < segs; i++) {
75 t += dt;
76 SkEvalCubicAt(cubic, t, &samples[i], nullptr, nullptr);
77 }
78}
79
80static void eval_sheet(const SkPoint edge[], int nu, int nv, int iu, int iv,
81 SkPoint* pt) {
82 const int TL = 0;
83 const int TR = nu;
84 const int BR = TR + nv;
85 const int BL = BR + nu;
86
87 SkScalar u = SkIntToScalar(iu) / nu;
88 SkScalar v = SkIntToScalar(iv) / nv;
89
90 SkScalar uv = u * v;
91 SkScalar Uv = (1 - u) * v;
92 SkScalar uV = u * (1 - v);
93 SkScalar UV = (1 - u) * (1 - v);
94
95 SkScalar x0 = UV * edge[TL].fX + uV * edge[TR].fX + Uv * edge[BL].fX + uv * edge[BR].fX;
96 SkScalar y0 = UV * edge[TL].fY + uV * edge[TR].fY + Uv * edge[BL].fY + uv * edge[BR].fY;
97
98 SkScalar x = (1 - v) * edge[TL+iu].fX + u * edge[TR+iv].fX +
99 v * edge[BR+nu-iu].fX + (1 - u) * edge[BL+nv-iv].fX - x0;
100 SkScalar y = (1 - v) * edge[TL+iu].fY + u * edge[TR+iv].fY +
101 v * edge[BR+nu-iu].fY + (1 - u) * edge[BL+nv-iv].fY - y0;
102 pt->set(x, y);
103}
104
105static SkColor make_color(SkScalar s, SkScalar t) {
107}
108
109void Patch::draw(SkCanvas* canvas, const SkPaint& paint, int nu, int nv,
110 bool doTextures, bool doColors) {
111 if (nu < 1 || nv < 1) {
112 return;
113 }
114
115 int i, npts = (nu + nv) * 2;
116 std::unique_ptr<SkPoint[]> storage(new SkPoint[npts + 1]);
117 SkPoint* edge0 = storage.get();
118 SkPoint* edge1 = edge0 + nu;
119 SkPoint* edge2 = edge1 + nv;
120 SkPoint* edge3 = edge2 + nu;
121
122 // evaluate the edge points
123 eval_patch_edge(fPts + 0, edge0, nu);
124 eval_patch_edge(fPts + 3, edge1, nv);
125 eval_patch_edge(fPts + 6, edge2, nu);
126 eval_patch_edge(fPts + 9, edge3, nv);
127 edge3[nv] = edge0[0]; // the last shall be first
128
129 for (i = 0; i < npts; i++) {
130// canvas->drawLine(edge0[i].fX, edge0[i].fY, edge0[i+1].fX, edge0[i+1].fY, paint);
131 }
132
133 int row, vertCount = (nu + 1) * (nv + 1);
134 std::unique_ptr<SkPoint[]> vertStorage(new SkPoint[vertCount]);
135 SkPoint* verts = vertStorage.get();
136
137 // first row
138 memcpy(verts, edge0, (nu + 1) * sizeof(SkPoint));
139 // rows
140 SkPoint* r = verts;
141 for (row = 1; row < nv; row++) {
142 r += nu + 1;
143 r[0] = edge3[nv - row];
144 for (int col = 1; col < nu; col++) {
145 eval_sheet(edge0, nu, nv, col, row, &r[col]);
146 }
147 r[nu] = edge1[row];
148 }
149 // last row
150 SkPoint* last = verts + nv * (nu + 1);
151 for (i = 0; i <= nu; i++) {
152 last[i] = edge2[nu - i];
153 }
154
155// canvas->drawPoints(verts, vertCount, paint);
156
157 int stripCount = (nu + 1) * 2;
158 std::unique_ptr<SkPoint[]> stripStorage(new SkPoint[stripCount * 2]);
159 std::unique_ptr<SkColor[]> colorStorage(new SkColor[stripCount]);
160 SkPoint* strip = stripStorage.get();
161 SkPoint* tex = strip + stripCount;
162 SkColor* colors = colorStorage.get();
163 SkScalar t = 0;
164 const SkScalar ds = SK_Scalar1 * fW / nu;
165 const SkScalar dt = SK_Scalar1 * fH / nv;
166 r = verts;
167 for (row = 0; row < nv; row++) {
168 SkPoint* upper = r;
169 SkPoint* lower = r + nu + 1;
170 r = lower;
171 SkScalar s = 0;
172 for (i = 0; i <= nu; i++) {
173 strip[i*2 + 0] = *upper++;
174 strip[i*2 + 1] = *lower++;
175 tex[i*2 + 0].set(s, t);
176 tex[i*2 + 1].set(s, t + dt);
177 colors[i*2 + 0] = make_color(s/fW, t/fH);
178 colors[i*2 + 1] = make_color(s/fW, (t + dt)/fH);
179 s += ds;
180 }
181 t += dt;
183 strip, doTextures ? tex : nullptr,
184 doColors ? colors : nullptr),
186 }
187}
188
189static void drawpatches(SkCanvas* canvas, const SkPaint& paint, int nu, int nv,
190 Patch* patch) {
191 SkAutoCanvasRestore ar(canvas, true);
192
193 patch->draw(canvas, paint, nu, nv, false, false);
194 canvas->translate(SkIntToScalar(180), 0);
195 patch->draw(canvas, paint, nu, nv, true, false);
196 canvas->translate(SkIntToScalar(180), 0);
197 patch->draw(canvas, paint, nu, nv, false, true);
198 canvas->translate(SkIntToScalar(180), 0);
199 patch->draw(canvas, paint, nu, nv, true, true);
200}
201
202static constexpr SkScalar DX = 20;
203static constexpr SkScalar DY = 0;
204static constexpr SkScalar kS = 50;
205static constexpr SkScalar kT = 40;
206
207struct PatchSlide : public ClickHandlerSlide {
208 sk_sp<SkShader> fShader0;
209 sk_sp<SkShader> fShader1;
210 SkScalar fAngle = 0;
211 SkIPoint fSize0 = {0, 0},
212 fSize1 = {0, 0};
213 SkPoint fPts[12] = {
214 {kS * 0, kT * 1},
215 {kS * 1, kT * 1},
216 {kS * 2, kT * 1},
217 {kS * 3, kT * 1},
218 {kS * 3, kT * 2},
219 {kS * 3, kT * 3},
220 {kS * 3, kT * 4},
221 {kS * 2, kT * 4},
222 {kS * 1, kT * 4},
223 {kS * 0, kT * 4},
224 {kS * 0, kT * 3},
225 {kS * 0, kT * 2},
226 };
227
228public:
229 PatchSlide() { fName = "Patch"; }
230
231 void load(SkScalar w, SkScalar h) override {
232 fShader0 = make_shader0(&fSize0);
233 fSize1 = fSize0;
234 if (fSize0.fX == 0 || fSize0.fY == 0) {
235 fSize1.set(2, 2);
236 }
237 fShader1 = make_shader1(fSize1);
238 }
239
240
241 void draw(SkCanvas* canvas) override {
242 canvas->clear(SK_ColorGRAY);
243
244 const int nu = 10;
245 const int nv = 10;
246
248 paint.setDither(true);
249
250 canvas->translate(DX, DY);
251
252 Patch patch;
253
254 paint.setShader(fShader0);
255 if (fSize0.fX == 0) {
256 fSize0.fX = 1;
257 }
258 if (fSize0.fY == 0) {
259 fSize0.fY = 1;
260 }
261 patch.setBounds(fSize0.fX, fSize0.fY);
262
263 patch.setPatch(fPts);
264 drawpatches(canvas, paint, nu, nv, &patch);
265
266 paint.setShader(nullptr);
267 paint.setAntiAlias(true);
268 paint.setStrokeWidth(SkIntToScalar(5));
269 canvas->drawPoints(SkCanvas::kPoints_PointMode, std::size(fPts), fPts, paint);
270
271 canvas->translate(0, SkIntToScalar(300));
272
273 paint.setAntiAlias(false);
274 paint.setShader(fShader1);
275 {
276 SkMatrix m;
277 m.setSkew(1, 0);
278 paint.setShader(paint.getShader()->makeWithLocalMatrix(m));
279 }
280 {
281 SkMatrix m;
282 m.setRotate(fAngle);
283 paint.setShader(paint.getShader()->makeWithLocalMatrix(m));
284 }
285 patch.setBounds(fSize1.fX, fSize1.fY);
286 drawpatches(canvas, paint, nu, nv, &patch);
287 }
288
289 bool animate(double nanos) override {
290 fAngle = TimeUtils::Scaled(1e-9 * nanos, 60, 360);
291 return true;
292 }
293
294protected:
295 class PtClick : public Click {
296 public:
297 int fIndex;
298 PtClick(int index) : fIndex(index) {}
299 };
300
301 Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
302 x -= DX;
303 y -= DY;
304 for (size_t i = 0; i < std::size(fPts); i++) {
305 if (hittest(fPts[i], x, y)) {
306 return new PtClick((int)i);
307 }
308 }
309 return nullptr;
310 }
311
312 bool onClick(Click* click) override {
313 fPts[((PtClick*)click)->fIndex].set(click->fCurr.fX - DX, click->fCurr.fY - DY);
314 return true;
315 }
316
317private:
318 static bool hittest(const SkPoint& pt, SkScalar x, SkScalar y) {
319 return SkPoint::Length(pt.fX - x, pt.fY - y) < SkIntToScalar(5);
320 }
321};
322} // namespace
323DEF_SLIDE( return new PatchSlide(); )
324
325//////////////////////////////////////////////////////////////////////////////
326
327namespace {
328static sk_sp<SkVertices> make_verts(const SkPath& path, SkScalar width) {
329 auto meas = SkContourMeasureIter(path, false).next();
330 if (!meas) {
331 return nullptr;
332 }
333
334 const SkPoint src[2] = {
335 { 0, -width/2 }, { 0, width/2 },
336 };
338
339 const SkScalar step = 2;
340 for (SkScalar distance = 0; distance < meas->length(); distance += step) {
341 SkMatrix mx;
342 if (!meas->getMatrix(distance, &mx)) {
343 continue;
344 }
345 SkPoint* dst = pts.append(2);
346 mx.mapPoints(dst, src, 2);
347 }
348
349 int vertCount = pts.size();
350 int indexCount = 0; // no texture
353 vertCount, indexCount, flags);
354 memcpy(builder.positions(), pts.begin(), vertCount * sizeof(SkPoint));
355 SkRandom rand;
356 for (int i = 0; i < vertCount; ++i) {
357 builder.colors()[i] = rand.nextU() | 0xFF000000;
358 }
359 SkDebugf("vert count = %d\n", vertCount);
360
361 return builder.detach();
362}
363
364class PseudoInkSlide : public ClickHandlerSlide {
365 enum { N = 100 };
367 sk_sp<SkVertices> fVertices[N];
368 SkPaint fSkeletonP, fStrokeP, fVertsP;
369 bool fDirty = true;
370
371public:
372 PseudoInkSlide() {
374 fSkeletonP.setAntiAlias(true);
375
377 fStrokeP.setStrokeWidth(30);
378 fStrokeP.setColor(0x44888888);
379 fName = "PseudoInk";
380 }
381
382 bool animate(double nanos) override { return true; }
383
384 void draw(SkCanvas* canvas) override {
385 if (fDirty) {
386 for (int i = 0; i < N; ++i) {
387 fVertices[i] = make_verts(fPath, 30);
388 }
389 fDirty = false;
390 }
391 for (int i = 0; i < N; ++i) {
392 canvas->drawVertices(fVertices[i], SkBlendMode::kSrc, fVertsP);
393 canvas->translate(1, 1);
394 }
395// canvas->drawPath(fPath, fStrokeP);
396 // canvas->drawPath(fPath, fSkeletonP);
397 }
398
399protected:
400 Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
401 Click* click = new Click();
402 fPath.reset();
403 fPath.moveTo(x, y);
404 return click;
405 }
406
407 bool onClick(Click* click) override {
408 switch (click->fState) {
410 fPath.lineTo(click->fCurr);
411 fDirty = true;
412 break;
413 default:
414 break;
415 }
416 return true;
417 }
418};
419} // namespace
420DEF_SLIDE( return new PseudoInkSlide(); )
SkPoint fPts[2]
SkPath fPath
static int step(int x, SkScalar min, SkScalar max)
Definition BlurTest.cpp:215
const char * fName
static constexpr int kS
static bool hittest(const SkPoint &target, SkScalar x, SkScalar y)
#define SkASSERT_RELEASE(cond)
Definition SkAssert.h:100
SkBlendMode
Definition SkBlendMode.h:38
@ kModulate
r = s*d
static U8CPU SkUnitScalarClampToByte(SkScalar x)
Definition SkColorPriv.h:36
uint32_t SkColor
Definition SkColor.h:37
constexpr SkColor SK_ColorGRAY
Definition SkColor.h:113
constexpr SkColor SK_ColorBLUE
Definition SkColor.h:135
constexpr SkColor SK_ColorRED
Definition SkColor.h:126
static constexpr SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition SkColor.h:49
constexpr SkColor SK_ColorGREEN
Definition SkColor.h:131
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
void SkEvalCubicAt(const SkPoint src[4], SkScalar t, SkPoint *loc, SkVector *tangent, SkVector *curvature)
static void sk_bzero(void *buffer, size_t size)
Definition SkMalloc.h:105
#define SK_Scalar1
Definition SkScalar.h:18
#define SkIntToScalar(x)
Definition SkScalar.h:57
#define DEF_SLIDE(code)
Definition Slide.h:25
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
Definition aaclip.cpp:27
#define N
Definition beziers.cpp:19
virtual bool onClick(Click *)=0
virtual Click * onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi)=0
int width() const
Definition SkBitmap.h:149
sk_sp< SkShader > makeShader(SkTileMode tmx, SkTileMode tmy, const SkSamplingOptions &, const SkMatrix *localMatrix=nullptr) const
Definition SkBitmap.cpp:669
int height() const
Definition SkBitmap.h:158
void drawPoints(PointMode mode, size_t count, const SkPoint pts[], const SkPaint &paint)
void translate(SkScalar dx, SkScalar dy)
void clear(SkColor color)
Definition SkCanvas.h:1199
void drawVertices(const SkVertices *vertices, SkBlendMode mode, const SkPaint &paint)
@ kPoints_PointMode
draw each point separately
Definition SkCanvas.h:1241
sk_sp< SkContourMeasure > next()
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)
void mapPoints(SkPoint dst[], const SkPoint src[], int count) const
Definition SkMatrix.cpp:770
void setStyle(Style style)
Definition SkPaint.cpp:105
void setColor(SkColor color)
Definition SkPaint.cpp:119
void setAntiAlias(bool aa)
Definition SkPaint.h:170
@ kStroke_Style
set to stroke geometry
Definition SkPaint.h:194
void setStrokeWidth(SkScalar width)
Definition SkPaint.cpp:159
SkPath & moveTo(SkScalar x, SkScalar y)
Definition SkPath.cpp:678
SkPath & lineTo(SkScalar x, SkScalar y)
Definition SkPath.cpp:718
SkPath & reset()
Definition SkPath.cpp:360
uint32_t nextU()
Definition SkRandom.h:42
int size() const
Definition SkTDArray.h:138
T * begin()
Definition SkTDArray.h:150
T * append()
Definition SkTDArray.h:191
@ kHasColors_BuilderFlag
Definition SkVertices.h:64
static sk_sp< SkVertices > MakeCopy(VertexMode mode, int vertexCount, const SkPoint positions[], const SkPoint texs[], const SkColor colors[], int indexCount, const uint16_t indices[])
@ kTriangleStrip_VertexMode
Definition SkVertices.h:32
virtual void load(SkScalar winWidth, SkScalar winHeight)
Definition Slide.h:40
virtual bool animate(double nanos)
Definition Slide.h:39
virtual void draw(SkCanvas *canvas)=0
const Paint & paint
float SkScalar
Definition extension.cpp:12
struct MyStruct s
FlutterSemanticsFlag flags
double y
double x
PODArray< SkColor > colors
Definition SkRecords.h:276
static float Scaled(float time, float speed, float period=0)
Definition TimeUtils.h:27
bool GetResourceAsBitmap(const char *resource, SkBitmap *dst)
Definition DecodeUtils.h:21
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
dst
Definition cp.py:12
AI float cubic(float precision, const SkPoint pts[], const VectorXform &vectorXform=VectorXform())
ModifierKey
Definition ModifierKey.h:9
SkScalar w
SkScalar h
int32_t width
int32_t fX
x-axis value
int32_t fY
y-axis value
void set(int32_t x, int32_t y)
float fX
x-axis value
void set(float x, float y)
static float Length(float x, float y)
Definition SkPoint.cpp:79
float fY
y-axis value
static sk_sp< SkShader > make_shader1(int w, int h)
static sk_sp< SkShader > make_shader0(int w, int h)