1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2011 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker
8*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkBitmap.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkCanvas.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorFilter.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorPriv.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkContourMeasure.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkGraphics.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPath.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPathEffect.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRegion.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkShader.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkStream.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypeface.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkVertices.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkGradientShader.h"
22*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTDArray.h"
23*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkRandom.h"
24*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkTime.h"
25*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkUTF.h"
26*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkGeometry.h"
27*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkOSFile.h"
28*c8dee2aaSAndroid Build Coastguard Worker #include "tools/DecodeUtils.h"
29*c8dee2aaSAndroid Build Coastguard Worker #include "tools/Resources.h"
30*c8dee2aaSAndroid Build Coastguard Worker #include "tools/timer/TimeUtils.h"
31*c8dee2aaSAndroid Build Coastguard Worker #include "tools/viewer/ClickHandlerSlide.h"
32*c8dee2aaSAndroid Build Coastguard Worker #include "tools/viewer/Slide.h"
33*c8dee2aaSAndroid Build Coastguard Worker
34*c8dee2aaSAndroid Build Coastguard Worker namespace {
make_shader0(SkIPoint * size)35*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkShader> make_shader0(SkIPoint* size) {
36*c8dee2aaSAndroid Build Coastguard Worker SkBitmap bm;
37*c8dee2aaSAndroid Build Coastguard Worker SkASSERT_RELEASE(ToolUtils::GetResourceAsBitmap("images/dog.jpg", &bm));
38*c8dee2aaSAndroid Build Coastguard Worker *size = SkIPoint{bm.width(), bm.height()};
39*c8dee2aaSAndroid Build Coastguard Worker return bm.makeShader(SkSamplingOptions(SkFilterMode::kLinear));
40*c8dee2aaSAndroid Build Coastguard Worker }
41*c8dee2aaSAndroid Build Coastguard Worker
make_shader1(const SkIPoint & size)42*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkShader> make_shader1(const SkIPoint& size) {
43*c8dee2aaSAndroid Build Coastguard Worker SkPoint pts[] = { { 0, 0, },
44*c8dee2aaSAndroid Build Coastguard Worker { SkIntToScalar(size.fX), SkIntToScalar(size.fY) } };
45*c8dee2aaSAndroid Build Coastguard Worker SkColor colors[] = { SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorRED };
46*c8dee2aaSAndroid Build Coastguard Worker return SkGradientShader::MakeLinear(pts, colors, nullptr,
47*c8dee2aaSAndroid Build Coastguard Worker std::size(colors), SkTileMode::kMirror);
48*c8dee2aaSAndroid Build Coastguard Worker }
49*c8dee2aaSAndroid Build Coastguard Worker
50*c8dee2aaSAndroid Build Coastguard Worker class Patch {
51*c8dee2aaSAndroid Build Coastguard Worker public:
Patch()52*c8dee2aaSAndroid Build Coastguard Worker Patch() { sk_bzero(fPts, sizeof(fPts)); }
~Patch()53*c8dee2aaSAndroid Build Coastguard Worker ~Patch() {}
54*c8dee2aaSAndroid Build Coastguard Worker
setPatch(const SkPoint pts[12])55*c8dee2aaSAndroid Build Coastguard Worker void setPatch(const SkPoint pts[12]) {
56*c8dee2aaSAndroid Build Coastguard Worker memcpy(fPts, pts, 12 * sizeof(SkPoint));
57*c8dee2aaSAndroid Build Coastguard Worker fPts[12] = pts[0]; // the last shall be first
58*c8dee2aaSAndroid Build Coastguard Worker }
setBounds(int w,int h)59*c8dee2aaSAndroid Build Coastguard Worker void setBounds(int w, int h) { fW = w; fH = h; }
60*c8dee2aaSAndroid Build Coastguard Worker
61*c8dee2aaSAndroid Build Coastguard Worker void draw(SkCanvas*, const SkPaint&, int segsU, int segsV,
62*c8dee2aaSAndroid Build Coastguard Worker bool doTextures, bool doColors);
63*c8dee2aaSAndroid Build Coastguard Worker
64*c8dee2aaSAndroid Build Coastguard Worker private:
65*c8dee2aaSAndroid Build Coastguard Worker SkPoint fPts[13];
66*c8dee2aaSAndroid Build Coastguard Worker int fW, fH;
67*c8dee2aaSAndroid Build Coastguard Worker };
68*c8dee2aaSAndroid Build Coastguard Worker
eval_patch_edge(const SkPoint cubic[],SkPoint samples[],int segs)69*c8dee2aaSAndroid Build Coastguard Worker static void eval_patch_edge(const SkPoint cubic[], SkPoint samples[], int segs) {
70*c8dee2aaSAndroid Build Coastguard Worker SkScalar t = 0;
71*c8dee2aaSAndroid Build Coastguard Worker SkScalar dt = SK_Scalar1 / segs;
72*c8dee2aaSAndroid Build Coastguard Worker
73*c8dee2aaSAndroid Build Coastguard Worker samples[0] = cubic[0];
74*c8dee2aaSAndroid Build Coastguard Worker for (int i = 1; i < segs; i++) {
75*c8dee2aaSAndroid Build Coastguard Worker t += dt;
76*c8dee2aaSAndroid Build Coastguard Worker SkEvalCubicAt(cubic, t, &samples[i], nullptr, nullptr);
77*c8dee2aaSAndroid Build Coastguard Worker }
78*c8dee2aaSAndroid Build Coastguard Worker }
79*c8dee2aaSAndroid Build Coastguard Worker
eval_sheet(const SkPoint edge[],int nu,int nv,int iu,int iv,SkPoint * pt)80*c8dee2aaSAndroid Build Coastguard Worker static void eval_sheet(const SkPoint edge[], int nu, int nv, int iu, int iv,
81*c8dee2aaSAndroid Build Coastguard Worker SkPoint* pt) {
82*c8dee2aaSAndroid Build Coastguard Worker const int TL = 0;
83*c8dee2aaSAndroid Build Coastguard Worker const int TR = nu;
84*c8dee2aaSAndroid Build Coastguard Worker const int BR = TR + nv;
85*c8dee2aaSAndroid Build Coastguard Worker const int BL = BR + nu;
86*c8dee2aaSAndroid Build Coastguard Worker
87*c8dee2aaSAndroid Build Coastguard Worker SkScalar u = SkIntToScalar(iu) / nu;
88*c8dee2aaSAndroid Build Coastguard Worker SkScalar v = SkIntToScalar(iv) / nv;
89*c8dee2aaSAndroid Build Coastguard Worker
90*c8dee2aaSAndroid Build Coastguard Worker SkScalar uv = u * v;
91*c8dee2aaSAndroid Build Coastguard Worker SkScalar Uv = (1 - u) * v;
92*c8dee2aaSAndroid Build Coastguard Worker SkScalar uV = u * (1 - v);
93*c8dee2aaSAndroid Build Coastguard Worker SkScalar UV = (1 - u) * (1 - v);
94*c8dee2aaSAndroid Build Coastguard Worker
95*c8dee2aaSAndroid Build Coastguard Worker SkScalar x0 = UV * edge[TL].fX + uV * edge[TR].fX + Uv * edge[BL].fX + uv * edge[BR].fX;
96*c8dee2aaSAndroid Build Coastguard Worker SkScalar y0 = UV * edge[TL].fY + uV * edge[TR].fY + Uv * edge[BL].fY + uv * edge[BR].fY;
97*c8dee2aaSAndroid Build Coastguard Worker
98*c8dee2aaSAndroid Build Coastguard Worker SkScalar x = (1 - v) * edge[TL+iu].fX + u * edge[TR+iv].fX +
99*c8dee2aaSAndroid Build Coastguard Worker v * edge[BR+nu-iu].fX + (1 - u) * edge[BL+nv-iv].fX - x0;
100*c8dee2aaSAndroid Build Coastguard Worker SkScalar y = (1 - v) * edge[TL+iu].fY + u * edge[TR+iv].fY +
101*c8dee2aaSAndroid Build Coastguard Worker v * edge[BR+nu-iu].fY + (1 - u) * edge[BL+nv-iv].fY - y0;
102*c8dee2aaSAndroid Build Coastguard Worker pt->set(x, y);
103*c8dee2aaSAndroid Build Coastguard Worker }
104*c8dee2aaSAndroid Build Coastguard Worker
make_color(SkScalar s,SkScalar t)105*c8dee2aaSAndroid Build Coastguard Worker static SkColor make_color(SkScalar s, SkScalar t) {
106*c8dee2aaSAndroid Build Coastguard Worker return SkColorSetARGB(0xFF, SkUnitScalarClampToByte(s), SkUnitScalarClampToByte(t), 0);
107*c8dee2aaSAndroid Build Coastguard Worker }
108*c8dee2aaSAndroid Build Coastguard Worker
draw(SkCanvas * canvas,const SkPaint & paint,int nu,int nv,bool doTextures,bool doColors)109*c8dee2aaSAndroid Build Coastguard Worker void Patch::draw(SkCanvas* canvas, const SkPaint& paint, int nu, int nv,
110*c8dee2aaSAndroid Build Coastguard Worker bool doTextures, bool doColors) {
111*c8dee2aaSAndroid Build Coastguard Worker if (nu < 1 || nv < 1) {
112*c8dee2aaSAndroid Build Coastguard Worker return;
113*c8dee2aaSAndroid Build Coastguard Worker }
114*c8dee2aaSAndroid Build Coastguard Worker
115*c8dee2aaSAndroid Build Coastguard Worker int i, npts = (nu + nv) * 2;
116*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkPoint[]> storage(new SkPoint[npts + 1]);
117*c8dee2aaSAndroid Build Coastguard Worker SkPoint* edge0 = storage.get();
118*c8dee2aaSAndroid Build Coastguard Worker SkPoint* edge1 = edge0 + nu;
119*c8dee2aaSAndroid Build Coastguard Worker SkPoint* edge2 = edge1 + nv;
120*c8dee2aaSAndroid Build Coastguard Worker SkPoint* edge3 = edge2 + nu;
121*c8dee2aaSAndroid Build Coastguard Worker
122*c8dee2aaSAndroid Build Coastguard Worker // evaluate the edge points
123*c8dee2aaSAndroid Build Coastguard Worker eval_patch_edge(fPts + 0, edge0, nu);
124*c8dee2aaSAndroid Build Coastguard Worker eval_patch_edge(fPts + 3, edge1, nv);
125*c8dee2aaSAndroid Build Coastguard Worker eval_patch_edge(fPts + 6, edge2, nu);
126*c8dee2aaSAndroid Build Coastguard Worker eval_patch_edge(fPts + 9, edge3, nv);
127*c8dee2aaSAndroid Build Coastguard Worker edge3[nv] = edge0[0]; // the last shall be first
128*c8dee2aaSAndroid Build Coastguard Worker
129*c8dee2aaSAndroid Build Coastguard Worker for (i = 0; i < npts; i++) {
130*c8dee2aaSAndroid Build Coastguard Worker // canvas->drawLine(edge0[i].fX, edge0[i].fY, edge0[i+1].fX, edge0[i+1].fY, paint);
131*c8dee2aaSAndroid Build Coastguard Worker }
132*c8dee2aaSAndroid Build Coastguard Worker
133*c8dee2aaSAndroid Build Coastguard Worker int row, vertCount = (nu + 1) * (nv + 1);
134*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkPoint[]> vertStorage(new SkPoint[vertCount]);
135*c8dee2aaSAndroid Build Coastguard Worker SkPoint* verts = vertStorage.get();
136*c8dee2aaSAndroid Build Coastguard Worker
137*c8dee2aaSAndroid Build Coastguard Worker // first row
138*c8dee2aaSAndroid Build Coastguard Worker memcpy(verts, edge0, (nu + 1) * sizeof(SkPoint));
139*c8dee2aaSAndroid Build Coastguard Worker // rows
140*c8dee2aaSAndroid Build Coastguard Worker SkPoint* r = verts;
141*c8dee2aaSAndroid Build Coastguard Worker for (row = 1; row < nv; row++) {
142*c8dee2aaSAndroid Build Coastguard Worker r += nu + 1;
143*c8dee2aaSAndroid Build Coastguard Worker r[0] = edge3[nv - row];
144*c8dee2aaSAndroid Build Coastguard Worker for (int col = 1; col < nu; col++) {
145*c8dee2aaSAndroid Build Coastguard Worker eval_sheet(edge0, nu, nv, col, row, &r[col]);
146*c8dee2aaSAndroid Build Coastguard Worker }
147*c8dee2aaSAndroid Build Coastguard Worker r[nu] = edge1[row];
148*c8dee2aaSAndroid Build Coastguard Worker }
149*c8dee2aaSAndroid Build Coastguard Worker // last row
150*c8dee2aaSAndroid Build Coastguard Worker SkPoint* last = verts + nv * (nu + 1);
151*c8dee2aaSAndroid Build Coastguard Worker for (i = 0; i <= nu; i++) {
152*c8dee2aaSAndroid Build Coastguard Worker last[i] = edge2[nu - i];
153*c8dee2aaSAndroid Build Coastguard Worker }
154*c8dee2aaSAndroid Build Coastguard Worker
155*c8dee2aaSAndroid Build Coastguard Worker // canvas->drawPoints(verts, vertCount, paint);
156*c8dee2aaSAndroid Build Coastguard Worker
157*c8dee2aaSAndroid Build Coastguard Worker int stripCount = (nu + 1) * 2;
158*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkPoint[]> stripStorage(new SkPoint[stripCount * 2]);
159*c8dee2aaSAndroid Build Coastguard Worker std::unique_ptr<SkColor[]> colorStorage(new SkColor[stripCount]);
160*c8dee2aaSAndroid Build Coastguard Worker SkPoint* strip = stripStorage.get();
161*c8dee2aaSAndroid Build Coastguard Worker SkPoint* tex = strip + stripCount;
162*c8dee2aaSAndroid Build Coastguard Worker SkColor* colors = colorStorage.get();
163*c8dee2aaSAndroid Build Coastguard Worker SkScalar t = 0;
164*c8dee2aaSAndroid Build Coastguard Worker const SkScalar ds = SK_Scalar1 * fW / nu;
165*c8dee2aaSAndroid Build Coastguard Worker const SkScalar dt = SK_Scalar1 * fH / nv;
166*c8dee2aaSAndroid Build Coastguard Worker r = verts;
167*c8dee2aaSAndroid Build Coastguard Worker for (row = 0; row < nv; row++) {
168*c8dee2aaSAndroid Build Coastguard Worker SkPoint* upper = r;
169*c8dee2aaSAndroid Build Coastguard Worker SkPoint* lower = r + nu + 1;
170*c8dee2aaSAndroid Build Coastguard Worker r = lower;
171*c8dee2aaSAndroid Build Coastguard Worker SkScalar s = 0;
172*c8dee2aaSAndroid Build Coastguard Worker for (i = 0; i <= nu; i++) {
173*c8dee2aaSAndroid Build Coastguard Worker strip[i*2 + 0] = *upper++;
174*c8dee2aaSAndroid Build Coastguard Worker strip[i*2 + 1] = *lower++;
175*c8dee2aaSAndroid Build Coastguard Worker tex[i*2 + 0].set(s, t);
176*c8dee2aaSAndroid Build Coastguard Worker tex[i*2 + 1].set(s, t + dt);
177*c8dee2aaSAndroid Build Coastguard Worker colors[i*2 + 0] = make_color(s/fW, t/fH);
178*c8dee2aaSAndroid Build Coastguard Worker colors[i*2 + 1] = make_color(s/fW, (t + dt)/fH);
179*c8dee2aaSAndroid Build Coastguard Worker s += ds;
180*c8dee2aaSAndroid Build Coastguard Worker }
181*c8dee2aaSAndroid Build Coastguard Worker t += dt;
182*c8dee2aaSAndroid Build Coastguard Worker canvas->drawVertices(SkVertices::MakeCopy(SkVertices::kTriangleStrip_VertexMode, stripCount,
183*c8dee2aaSAndroid Build Coastguard Worker strip, doTextures ? tex : nullptr,
184*c8dee2aaSAndroid Build Coastguard Worker doColors ? colors : nullptr),
185*c8dee2aaSAndroid Build Coastguard Worker SkBlendMode::kModulate, paint);
186*c8dee2aaSAndroid Build Coastguard Worker }
187*c8dee2aaSAndroid Build Coastguard Worker }
188*c8dee2aaSAndroid Build Coastguard Worker
drawpatches(SkCanvas * canvas,const SkPaint & paint,int nu,int nv,Patch * patch)189*c8dee2aaSAndroid Build Coastguard Worker static void drawpatches(SkCanvas* canvas, const SkPaint& paint, int nu, int nv,
190*c8dee2aaSAndroid Build Coastguard Worker Patch* patch) {
191*c8dee2aaSAndroid Build Coastguard Worker SkAutoCanvasRestore ar(canvas, true);
192*c8dee2aaSAndroid Build Coastguard Worker
193*c8dee2aaSAndroid Build Coastguard Worker patch->draw(canvas, paint, nu, nv, false, false);
194*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(SkIntToScalar(180), 0);
195*c8dee2aaSAndroid Build Coastguard Worker patch->draw(canvas, paint, nu, nv, true, false);
196*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(SkIntToScalar(180), 0);
197*c8dee2aaSAndroid Build Coastguard Worker patch->draw(canvas, paint, nu, nv, false, true);
198*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(SkIntToScalar(180), 0);
199*c8dee2aaSAndroid Build Coastguard Worker patch->draw(canvas, paint, nu, nv, true, true);
200*c8dee2aaSAndroid Build Coastguard Worker }
201*c8dee2aaSAndroid Build Coastguard Worker
202*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkScalar DX = 20;
203*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkScalar DY = 0;
204*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkScalar kS = 50;
205*c8dee2aaSAndroid Build Coastguard Worker static constexpr SkScalar kT = 40;
206*c8dee2aaSAndroid Build Coastguard Worker
207*c8dee2aaSAndroid Build Coastguard Worker struct PatchSlide : public ClickHandlerSlide {
208*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkShader> fShader0;
209*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkShader> fShader1;
210*c8dee2aaSAndroid Build Coastguard Worker SkScalar fAngle = 0;
211*c8dee2aaSAndroid Build Coastguard Worker SkIPoint fSize0 = {0, 0},
212*c8dee2aaSAndroid Build Coastguard Worker fSize1 = {0, 0};
213*c8dee2aaSAndroid Build Coastguard Worker SkPoint fPts[12] = {
214*c8dee2aaSAndroid Build Coastguard Worker {kS * 0, kT * 1},
215*c8dee2aaSAndroid Build Coastguard Worker {kS * 1, kT * 1},
216*c8dee2aaSAndroid Build Coastguard Worker {kS * 2, kT * 1},
217*c8dee2aaSAndroid Build Coastguard Worker {kS * 3, kT * 1},
218*c8dee2aaSAndroid Build Coastguard Worker {kS * 3, kT * 2},
219*c8dee2aaSAndroid Build Coastguard Worker {kS * 3, kT * 3},
220*c8dee2aaSAndroid Build Coastguard Worker {kS * 3, kT * 4},
221*c8dee2aaSAndroid Build Coastguard Worker {kS * 2, kT * 4},
222*c8dee2aaSAndroid Build Coastguard Worker {kS * 1, kT * 4},
223*c8dee2aaSAndroid Build Coastguard Worker {kS * 0, kT * 4},
224*c8dee2aaSAndroid Build Coastguard Worker {kS * 0, kT * 3},
225*c8dee2aaSAndroid Build Coastguard Worker {kS * 0, kT * 2},
226*c8dee2aaSAndroid Build Coastguard Worker };
227*c8dee2aaSAndroid Build Coastguard Worker
228*c8dee2aaSAndroid Build Coastguard Worker public:
PatchSlide__anonb6045d310111::PatchSlide229*c8dee2aaSAndroid Build Coastguard Worker PatchSlide() { fName = "Patch"; }
230*c8dee2aaSAndroid Build Coastguard Worker
load__anonb6045d310111::PatchSlide231*c8dee2aaSAndroid Build Coastguard Worker void load(SkScalar w, SkScalar h) override {
232*c8dee2aaSAndroid Build Coastguard Worker fShader0 = make_shader0(&fSize0);
233*c8dee2aaSAndroid Build Coastguard Worker fSize1 = fSize0;
234*c8dee2aaSAndroid Build Coastguard Worker if (fSize0.fX == 0 || fSize0.fY == 0) {
235*c8dee2aaSAndroid Build Coastguard Worker fSize1.set(2, 2);
236*c8dee2aaSAndroid Build Coastguard Worker }
237*c8dee2aaSAndroid Build Coastguard Worker fShader1 = make_shader1(fSize1);
238*c8dee2aaSAndroid Build Coastguard Worker }
239*c8dee2aaSAndroid Build Coastguard Worker
240*c8dee2aaSAndroid Build Coastguard Worker
draw__anonb6045d310111::PatchSlide241*c8dee2aaSAndroid Build Coastguard Worker void draw(SkCanvas* canvas) override {
242*c8dee2aaSAndroid Build Coastguard Worker canvas->clear(SK_ColorGRAY);
243*c8dee2aaSAndroid Build Coastguard Worker
244*c8dee2aaSAndroid Build Coastguard Worker const int nu = 10;
245*c8dee2aaSAndroid Build Coastguard Worker const int nv = 10;
246*c8dee2aaSAndroid Build Coastguard Worker
247*c8dee2aaSAndroid Build Coastguard Worker SkPaint paint;
248*c8dee2aaSAndroid Build Coastguard Worker paint.setDither(true);
249*c8dee2aaSAndroid Build Coastguard Worker
250*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(DX, DY);
251*c8dee2aaSAndroid Build Coastguard Worker
252*c8dee2aaSAndroid Build Coastguard Worker Patch patch;
253*c8dee2aaSAndroid Build Coastguard Worker
254*c8dee2aaSAndroid Build Coastguard Worker paint.setShader(fShader0);
255*c8dee2aaSAndroid Build Coastguard Worker if (fSize0.fX == 0) {
256*c8dee2aaSAndroid Build Coastguard Worker fSize0.fX = 1;
257*c8dee2aaSAndroid Build Coastguard Worker }
258*c8dee2aaSAndroid Build Coastguard Worker if (fSize0.fY == 0) {
259*c8dee2aaSAndroid Build Coastguard Worker fSize0.fY = 1;
260*c8dee2aaSAndroid Build Coastguard Worker }
261*c8dee2aaSAndroid Build Coastguard Worker patch.setBounds(fSize0.fX, fSize0.fY);
262*c8dee2aaSAndroid Build Coastguard Worker
263*c8dee2aaSAndroid Build Coastguard Worker patch.setPatch(fPts);
264*c8dee2aaSAndroid Build Coastguard Worker drawpatches(canvas, paint, nu, nv, &patch);
265*c8dee2aaSAndroid Build Coastguard Worker
266*c8dee2aaSAndroid Build Coastguard Worker paint.setShader(nullptr);
267*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(true);
268*c8dee2aaSAndroid Build Coastguard Worker paint.setStrokeWidth(SkIntToScalar(5));
269*c8dee2aaSAndroid Build Coastguard Worker canvas->drawPoints(SkCanvas::kPoints_PointMode, std::size(fPts), fPts, paint);
270*c8dee2aaSAndroid Build Coastguard Worker
271*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(0, SkIntToScalar(300));
272*c8dee2aaSAndroid Build Coastguard Worker
273*c8dee2aaSAndroid Build Coastguard Worker paint.setAntiAlias(false);
274*c8dee2aaSAndroid Build Coastguard Worker paint.setShader(fShader1);
275*c8dee2aaSAndroid Build Coastguard Worker {
276*c8dee2aaSAndroid Build Coastguard Worker SkMatrix m;
277*c8dee2aaSAndroid Build Coastguard Worker m.setSkew(1, 0);
278*c8dee2aaSAndroid Build Coastguard Worker paint.setShader(paint.getShader()->makeWithLocalMatrix(m));
279*c8dee2aaSAndroid Build Coastguard Worker }
280*c8dee2aaSAndroid Build Coastguard Worker {
281*c8dee2aaSAndroid Build Coastguard Worker SkMatrix m;
282*c8dee2aaSAndroid Build Coastguard Worker m.setRotate(fAngle);
283*c8dee2aaSAndroid Build Coastguard Worker paint.setShader(paint.getShader()->makeWithLocalMatrix(m));
284*c8dee2aaSAndroid Build Coastguard Worker }
285*c8dee2aaSAndroid Build Coastguard Worker patch.setBounds(fSize1.fX, fSize1.fY);
286*c8dee2aaSAndroid Build Coastguard Worker drawpatches(canvas, paint, nu, nv, &patch);
287*c8dee2aaSAndroid Build Coastguard Worker }
288*c8dee2aaSAndroid Build Coastguard Worker
animate__anonb6045d310111::PatchSlide289*c8dee2aaSAndroid Build Coastguard Worker bool animate(double nanos) override {
290*c8dee2aaSAndroid Build Coastguard Worker fAngle = TimeUtils::Scaled(1e-9 * nanos, 60, 360);
291*c8dee2aaSAndroid Build Coastguard Worker return true;
292*c8dee2aaSAndroid Build Coastguard Worker }
293*c8dee2aaSAndroid Build Coastguard Worker
294*c8dee2aaSAndroid Build Coastguard Worker protected:
295*c8dee2aaSAndroid Build Coastguard Worker class PtClick : public Click {
296*c8dee2aaSAndroid Build Coastguard Worker public:
297*c8dee2aaSAndroid Build Coastguard Worker int fIndex;
PtClick(int index)298*c8dee2aaSAndroid Build Coastguard Worker PtClick(int index) : fIndex(index) {}
299*c8dee2aaSAndroid Build Coastguard Worker };
300*c8dee2aaSAndroid Build Coastguard Worker
onFindClickHandler__anonb6045d310111::PatchSlide301*c8dee2aaSAndroid Build Coastguard Worker Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
302*c8dee2aaSAndroid Build Coastguard Worker x -= DX;
303*c8dee2aaSAndroid Build Coastguard Worker y -= DY;
304*c8dee2aaSAndroid Build Coastguard Worker for (size_t i = 0; i < std::size(fPts); i++) {
305*c8dee2aaSAndroid Build Coastguard Worker if (hittest(fPts[i], x, y)) {
306*c8dee2aaSAndroid Build Coastguard Worker return new PtClick((int)i);
307*c8dee2aaSAndroid Build Coastguard Worker }
308*c8dee2aaSAndroid Build Coastguard Worker }
309*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
310*c8dee2aaSAndroid Build Coastguard Worker }
311*c8dee2aaSAndroid Build Coastguard Worker
onClick__anonb6045d310111::PatchSlide312*c8dee2aaSAndroid Build Coastguard Worker bool onClick(Click* click) override {
313*c8dee2aaSAndroid Build Coastguard Worker fPts[((PtClick*)click)->fIndex].set(click->fCurr.fX - DX, click->fCurr.fY - DY);
314*c8dee2aaSAndroid Build Coastguard Worker return true;
315*c8dee2aaSAndroid Build Coastguard Worker }
316*c8dee2aaSAndroid Build Coastguard Worker
317*c8dee2aaSAndroid Build Coastguard Worker private:
hittest__anonb6045d310111::PatchSlide318*c8dee2aaSAndroid Build Coastguard Worker static bool hittest(const SkPoint& pt, SkScalar x, SkScalar y) {
319*c8dee2aaSAndroid Build Coastguard Worker return SkPoint::Length(pt.fX - x, pt.fY - y) < SkIntToScalar(5);
320*c8dee2aaSAndroid Build Coastguard Worker }
321*c8dee2aaSAndroid Build Coastguard Worker };
322*c8dee2aaSAndroid Build Coastguard Worker } // namespace
323*c8dee2aaSAndroid Build Coastguard Worker DEF_SLIDE( return new PatchSlide(); )
324*c8dee2aaSAndroid Build Coastguard Worker
325*c8dee2aaSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
326*c8dee2aaSAndroid Build Coastguard Worker
327*c8dee2aaSAndroid Build Coastguard Worker namespace {
make_verts(const SkPath & path,SkScalar width)328*c8dee2aaSAndroid Build Coastguard Worker static sk_sp<SkVertices> make_verts(const SkPath& path, SkScalar width) {
329*c8dee2aaSAndroid Build Coastguard Worker auto meas = SkContourMeasureIter(path, false).next();
330*c8dee2aaSAndroid Build Coastguard Worker if (!meas) {
331*c8dee2aaSAndroid Build Coastguard Worker return nullptr;
332*c8dee2aaSAndroid Build Coastguard Worker }
333*c8dee2aaSAndroid Build Coastguard Worker
334*c8dee2aaSAndroid Build Coastguard Worker const SkPoint src[2] = {
335*c8dee2aaSAndroid Build Coastguard Worker { 0, -width/2 }, { 0, width/2 },
336*c8dee2aaSAndroid Build Coastguard Worker };
337*c8dee2aaSAndroid Build Coastguard Worker SkTDArray<SkPoint> pts;
338*c8dee2aaSAndroid Build Coastguard Worker
339*c8dee2aaSAndroid Build Coastguard Worker const SkScalar step = 2;
340*c8dee2aaSAndroid Build Coastguard Worker for (SkScalar distance = 0; distance < meas->length(); distance += step) {
341*c8dee2aaSAndroid Build Coastguard Worker SkMatrix mx;
342*c8dee2aaSAndroid Build Coastguard Worker if (!meas->getMatrix(distance, &mx)) {
343*c8dee2aaSAndroid Build Coastguard Worker continue;
344*c8dee2aaSAndroid Build Coastguard Worker }
345*c8dee2aaSAndroid Build Coastguard Worker SkPoint* dst = pts.append(2);
346*c8dee2aaSAndroid Build Coastguard Worker mx.mapPoints(dst, src, 2);
347*c8dee2aaSAndroid Build Coastguard Worker }
348*c8dee2aaSAndroid Build Coastguard Worker
349*c8dee2aaSAndroid Build Coastguard Worker int vertCount = pts.size();
350*c8dee2aaSAndroid Build Coastguard Worker int indexCount = 0; // no texture
351*c8dee2aaSAndroid Build Coastguard Worker unsigned flags = SkVertices::kHasColors_BuilderFlag;
352*c8dee2aaSAndroid Build Coastguard Worker SkVertices::Builder builder(SkVertices::kTriangleStrip_VertexMode,
353*c8dee2aaSAndroid Build Coastguard Worker vertCount, indexCount, flags);
354*c8dee2aaSAndroid Build Coastguard Worker memcpy(builder.positions(), pts.begin(), vertCount * sizeof(SkPoint));
355*c8dee2aaSAndroid Build Coastguard Worker SkRandom rand;
356*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < vertCount; ++i) {
357*c8dee2aaSAndroid Build Coastguard Worker builder.colors()[i] = rand.nextU() | 0xFF000000;
358*c8dee2aaSAndroid Build Coastguard Worker }
359*c8dee2aaSAndroid Build Coastguard Worker SkDebugf("vert count = %d\n", vertCount);
360*c8dee2aaSAndroid Build Coastguard Worker
361*c8dee2aaSAndroid Build Coastguard Worker return builder.detach();
362*c8dee2aaSAndroid Build Coastguard Worker }
363*c8dee2aaSAndroid Build Coastguard Worker
364*c8dee2aaSAndroid Build Coastguard Worker class PseudoInkSlide : public ClickHandlerSlide {
365*c8dee2aaSAndroid Build Coastguard Worker enum { N = 100 };
366*c8dee2aaSAndroid Build Coastguard Worker SkPath fPath;
367*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SkVertices> fVertices[N];
368*c8dee2aaSAndroid Build Coastguard Worker SkPaint fSkeletonP, fStrokeP, fVertsP;
369*c8dee2aaSAndroid Build Coastguard Worker bool fDirty = true;
370*c8dee2aaSAndroid Build Coastguard Worker
371*c8dee2aaSAndroid Build Coastguard Worker public:
PseudoInkSlide()372*c8dee2aaSAndroid Build Coastguard Worker PseudoInkSlide() {
373*c8dee2aaSAndroid Build Coastguard Worker fSkeletonP.setStyle(SkPaint::kStroke_Style);
374*c8dee2aaSAndroid Build Coastguard Worker fSkeletonP.setAntiAlias(true);
375*c8dee2aaSAndroid Build Coastguard Worker
376*c8dee2aaSAndroid Build Coastguard Worker fStrokeP.setStyle(SkPaint::kStroke_Style);
377*c8dee2aaSAndroid Build Coastguard Worker fStrokeP.setStrokeWidth(30);
378*c8dee2aaSAndroid Build Coastguard Worker fStrokeP.setColor(0x44888888);
379*c8dee2aaSAndroid Build Coastguard Worker fName = "PseudoInk";
380*c8dee2aaSAndroid Build Coastguard Worker }
381*c8dee2aaSAndroid Build Coastguard Worker
animate(double nanos)382*c8dee2aaSAndroid Build Coastguard Worker bool animate(double nanos) override { return true; }
383*c8dee2aaSAndroid Build Coastguard Worker
draw(SkCanvas * canvas)384*c8dee2aaSAndroid Build Coastguard Worker void draw(SkCanvas* canvas) override {
385*c8dee2aaSAndroid Build Coastguard Worker if (fDirty) {
386*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < N; ++i) {
387*c8dee2aaSAndroid Build Coastguard Worker fVertices[i] = make_verts(fPath, 30);
388*c8dee2aaSAndroid Build Coastguard Worker }
389*c8dee2aaSAndroid Build Coastguard Worker fDirty = false;
390*c8dee2aaSAndroid Build Coastguard Worker }
391*c8dee2aaSAndroid Build Coastguard Worker for (int i = 0; i < N; ++i) {
392*c8dee2aaSAndroid Build Coastguard Worker canvas->drawVertices(fVertices[i], SkBlendMode::kSrc, fVertsP);
393*c8dee2aaSAndroid Build Coastguard Worker canvas->translate(1, 1);
394*c8dee2aaSAndroid Build Coastguard Worker }
395*c8dee2aaSAndroid Build Coastguard Worker // canvas->drawPath(fPath, fStrokeP);
396*c8dee2aaSAndroid Build Coastguard Worker // canvas->drawPath(fPath, fSkeletonP);
397*c8dee2aaSAndroid Build Coastguard Worker }
398*c8dee2aaSAndroid Build Coastguard Worker
399*c8dee2aaSAndroid Build Coastguard Worker protected:
onFindClickHandler(SkScalar x,SkScalar y,skui::ModifierKey modi)400*c8dee2aaSAndroid Build Coastguard Worker Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey modi) override {
401*c8dee2aaSAndroid Build Coastguard Worker Click* click = new Click();
402*c8dee2aaSAndroid Build Coastguard Worker fPath.reset();
403*c8dee2aaSAndroid Build Coastguard Worker fPath.moveTo(x, y);
404*c8dee2aaSAndroid Build Coastguard Worker return click;
405*c8dee2aaSAndroid Build Coastguard Worker }
406*c8dee2aaSAndroid Build Coastguard Worker
onClick(Click * click)407*c8dee2aaSAndroid Build Coastguard Worker bool onClick(Click* click) override {
408*c8dee2aaSAndroid Build Coastguard Worker switch (click->fState) {
409*c8dee2aaSAndroid Build Coastguard Worker case skui::InputState::kMove:
410*c8dee2aaSAndroid Build Coastguard Worker fPath.lineTo(click->fCurr);
411*c8dee2aaSAndroid Build Coastguard Worker fDirty = true;
412*c8dee2aaSAndroid Build Coastguard Worker break;
413*c8dee2aaSAndroid Build Coastguard Worker default:
414*c8dee2aaSAndroid Build Coastguard Worker break;
415*c8dee2aaSAndroid Build Coastguard Worker }
416*c8dee2aaSAndroid Build Coastguard Worker return true;
417*c8dee2aaSAndroid Build Coastguard Worker }
418*c8dee2aaSAndroid Build Coastguard Worker };
419*c8dee2aaSAndroid Build Coastguard Worker } // namespace
420*c8dee2aaSAndroid Build Coastguard Worker DEF_SLIDE( return new PseudoInkSlide(); )
421