xref: /aosp_15_r20/external/skia/tools/viewer/PathClipSlide.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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/SkCanvas.h"
9*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorFilter.h"
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkColorPriv.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkGraphics.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPath.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRegion.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkShader.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkTypeface.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "include/effects/SkGradientShader.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkTo.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkTime.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkUTF.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "tools/viewer/ClickHandlerSlide.h"
21*c8dee2aaSAndroid Build Coastguard Worker 
22*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
23*c8dee2aaSAndroid Build Coastguard Worker 
24*c8dee2aaSAndroid Build Coastguard Worker class PathClipSlide : public ClickHandlerSlide {
25*c8dee2aaSAndroid Build Coastguard Worker public:
26*c8dee2aaSAndroid Build Coastguard Worker     SkRect fOval;
27*c8dee2aaSAndroid Build Coastguard Worker     SkPoint fCenter;
28*c8dee2aaSAndroid Build Coastguard Worker 
PathClipSlide()29*c8dee2aaSAndroid Build Coastguard Worker     PathClipSlide() : fOval(SkRect::MakeWH(200, 50)), fCenter(SkPoint::Make(250, 250)) {
30*c8dee2aaSAndroid Build Coastguard Worker         fName = "PathClip";
31*c8dee2aaSAndroid Build Coastguard Worker     }
32*c8dee2aaSAndroid Build Coastguard Worker 
draw(SkCanvas * canvas)33*c8dee2aaSAndroid Build Coastguard Worker     void draw(SkCanvas* canvas) override {
34*c8dee2aaSAndroid Build Coastguard Worker         const SkRect oval = fOval.makeOffset(fCenter.fX - fOval.centerX(),
35*c8dee2aaSAndroid Build Coastguard Worker                                              fCenter.fY - fOval.centerY());
36*c8dee2aaSAndroid Build Coastguard Worker 
37*c8dee2aaSAndroid Build Coastguard Worker         SkPaint p;
38*c8dee2aaSAndroid Build Coastguard Worker         p.setAntiAlias(true);
39*c8dee2aaSAndroid Build Coastguard Worker 
40*c8dee2aaSAndroid Build Coastguard Worker         p.setStyle(SkPaint::kStroke_Style);
41*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawOval(oval, p);
42*c8dee2aaSAndroid Build Coastguard Worker 
43*c8dee2aaSAndroid Build Coastguard Worker         const SkRect r = SkRect::MakeLTRB(200, 200, 300, 300);
44*c8dee2aaSAndroid Build Coastguard Worker         canvas->clipRect(r);
45*c8dee2aaSAndroid Build Coastguard Worker 
46*c8dee2aaSAndroid Build Coastguard Worker         p.setStyle(SkPaint::kFill_Style);
47*c8dee2aaSAndroid Build Coastguard Worker         p.setColor(SK_ColorRED);
48*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawRect(r, p);
49*c8dee2aaSAndroid Build Coastguard Worker 
50*c8dee2aaSAndroid Build Coastguard Worker         p.setColor(0x800000FF);
51*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawOval(oval, p);
52*c8dee2aaSAndroid Build Coastguard Worker     }
53*c8dee2aaSAndroid Build Coastguard Worker 
54*c8dee2aaSAndroid Build Coastguard Worker protected:
onFindClickHandler(SkScalar x,SkScalar y,skui::ModifierKey)55*c8dee2aaSAndroid Build Coastguard Worker     Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) override {
56*c8dee2aaSAndroid Build Coastguard Worker         return new Click([&](Click* c) {
57*c8dee2aaSAndroid Build Coastguard Worker             fCenter = c->fCurr;
58*c8dee2aaSAndroid Build Coastguard Worker             return false;
59*c8dee2aaSAndroid Build Coastguard Worker         });
60*c8dee2aaSAndroid Build Coastguard Worker     }
61*c8dee2aaSAndroid Build Coastguard Worker 
onClick(ClickHandlerSlide::Click *)62*c8dee2aaSAndroid Build Coastguard Worker     bool onClick(ClickHandlerSlide::Click *) override { return false; }
63*c8dee2aaSAndroid Build Coastguard Worker };
DEF_SLIDE(return new PathClipSlide;)64*c8dee2aaSAndroid Build Coastguard Worker DEF_SLIDE( return new PathClipSlide; )
65*c8dee2aaSAndroid Build Coastguard Worker 
66*c8dee2aaSAndroid Build Coastguard Worker //////////////////////////////////////////////////////////////////////////////
67*c8dee2aaSAndroid Build Coastguard Worker 
68*c8dee2aaSAndroid Build Coastguard Worker static int clip_line(const SkRect& bounds, SkPoint p0, SkPoint p1, SkPoint edges[]) {
69*c8dee2aaSAndroid Build Coastguard Worker     SkPoint* edgesStart = edges;
70*c8dee2aaSAndroid Build Coastguard Worker 
71*c8dee2aaSAndroid Build Coastguard Worker     if (p0.fY == p1.fY) {
72*c8dee2aaSAndroid Build Coastguard Worker         return 0;
73*c8dee2aaSAndroid Build Coastguard Worker     }
74*c8dee2aaSAndroid Build Coastguard Worker 
75*c8dee2aaSAndroid Build Coastguard Worker     if (p0.fY > p1.fY) {
76*c8dee2aaSAndroid Build Coastguard Worker         using std::swap;
77*c8dee2aaSAndroid Build Coastguard Worker         swap(p0, p1);
78*c8dee2aaSAndroid Build Coastguard Worker     }
79*c8dee2aaSAndroid Build Coastguard Worker     // now we're monotonic in Y: p0 <= p1
80*c8dee2aaSAndroid Build Coastguard Worker     if (p1.fY <= bounds.top() || p0.fY >= bounds.bottom()) {
81*c8dee2aaSAndroid Build Coastguard Worker         return 0;
82*c8dee2aaSAndroid Build Coastguard Worker     }
83*c8dee2aaSAndroid Build Coastguard Worker 
84*c8dee2aaSAndroid Build Coastguard Worker     double dxdy = (double)(p1.fX - p0.fX) / (p1.fY - p0.fY);
85*c8dee2aaSAndroid Build Coastguard Worker     if (p0.fY < bounds.top()) {
86*c8dee2aaSAndroid Build Coastguard Worker         p0.fX = SkDoubleToScalar(p0.fX + dxdy * (bounds.top() - p0.fY));
87*c8dee2aaSAndroid Build Coastguard Worker         p0.fY = bounds.top();
88*c8dee2aaSAndroid Build Coastguard Worker     }
89*c8dee2aaSAndroid Build Coastguard Worker     if (p1.fY > bounds.bottom()) {
90*c8dee2aaSAndroid Build Coastguard Worker         p1.fX = SkDoubleToScalar(p1.fX + dxdy * (bounds.bottom() - p1.fY));
91*c8dee2aaSAndroid Build Coastguard Worker         p1.fY = bounds.bottom();
92*c8dee2aaSAndroid Build Coastguard Worker     }
93*c8dee2aaSAndroid Build Coastguard Worker 
94*c8dee2aaSAndroid Build Coastguard Worker     // Now p0...p1 is strictly inside bounds vertically, so we just need to clip horizontally
95*c8dee2aaSAndroid Build Coastguard Worker 
96*c8dee2aaSAndroid Build Coastguard Worker     if (p0.fX > p1.fX) {
97*c8dee2aaSAndroid Build Coastguard Worker         using std::swap;
98*c8dee2aaSAndroid Build Coastguard Worker         swap(p0, p1);
99*c8dee2aaSAndroid Build Coastguard Worker     }
100*c8dee2aaSAndroid Build Coastguard Worker     // now we're left-to-right: p0 .. p1
101*c8dee2aaSAndroid Build Coastguard Worker 
102*c8dee2aaSAndroid Build Coastguard Worker     if (p1.fX <= bounds.left()) {   // entirely to the left
103*c8dee2aaSAndroid Build Coastguard Worker         p0.fX = p1.fX = bounds.left();
104*c8dee2aaSAndroid Build Coastguard Worker         *edges++ = p0;
105*c8dee2aaSAndroid Build Coastguard Worker         *edges++ = p1;
106*c8dee2aaSAndroid Build Coastguard Worker         return 2;
107*c8dee2aaSAndroid Build Coastguard Worker     }
108*c8dee2aaSAndroid Build Coastguard Worker     if (p0.fX >= bounds.right()) {  // entirely to the right
109*c8dee2aaSAndroid Build Coastguard Worker         p0.fX = p1.fX = bounds.right();
110*c8dee2aaSAndroid Build Coastguard Worker         *edges++ = p0;
111*c8dee2aaSAndroid Build Coastguard Worker         *edges++ = p1;
112*c8dee2aaSAndroid Build Coastguard Worker         return 2;
113*c8dee2aaSAndroid Build Coastguard Worker     }
114*c8dee2aaSAndroid Build Coastguard Worker 
115*c8dee2aaSAndroid Build Coastguard Worker     if (p0.fX < bounds.left()) {
116*c8dee2aaSAndroid Build Coastguard Worker         float y = SkDoubleToScalar(p0.fY + (bounds.left() - p0.fX) / dxdy);
117*c8dee2aaSAndroid Build Coastguard Worker         *edges++ = SkPoint::Make(bounds.left(), p0.fY);
118*c8dee2aaSAndroid Build Coastguard Worker         *edges++ = SkPoint::Make(bounds.left(), y);
119*c8dee2aaSAndroid Build Coastguard Worker         p0.set(bounds.left(), y);
120*c8dee2aaSAndroid Build Coastguard Worker     }
121*c8dee2aaSAndroid Build Coastguard Worker     if (p1.fX > bounds.right()) {
122*c8dee2aaSAndroid Build Coastguard Worker         float y = SkDoubleToScalar(p0.fY + (bounds.right() - p0.fX) / dxdy);
123*c8dee2aaSAndroid Build Coastguard Worker         *edges++ = p0;
124*c8dee2aaSAndroid Build Coastguard Worker         *edges++ = SkPoint::Make(bounds.right(), y);
125*c8dee2aaSAndroid Build Coastguard Worker         *edges++ = SkPoint::Make(bounds.right(), p1.fY);
126*c8dee2aaSAndroid Build Coastguard Worker     } else {
127*c8dee2aaSAndroid Build Coastguard Worker         *edges++ = p0;
128*c8dee2aaSAndroid Build Coastguard Worker         *edges++ = p1;
129*c8dee2aaSAndroid Build Coastguard Worker     }
130*c8dee2aaSAndroid Build Coastguard Worker     return SkToInt(edges - edgesStart);
131*c8dee2aaSAndroid Build Coastguard Worker }
132*c8dee2aaSAndroid Build Coastguard Worker 
draw_clipped_line(SkCanvas * canvas,const SkRect & bounds,SkPoint p0,SkPoint p1,const SkPaint & paint)133*c8dee2aaSAndroid Build Coastguard Worker static void draw_clipped_line(SkCanvas* canvas, const SkRect& bounds,
134*c8dee2aaSAndroid Build Coastguard Worker                               SkPoint p0, SkPoint p1, const SkPaint& paint) {
135*c8dee2aaSAndroid Build Coastguard Worker     SkPoint verts[6];
136*c8dee2aaSAndroid Build Coastguard Worker     int count = clip_line(bounds, p0, p1, verts);
137*c8dee2aaSAndroid Build Coastguard Worker 
138*c8dee2aaSAndroid Build Coastguard Worker     SkPath path;
139*c8dee2aaSAndroid Build Coastguard Worker     path.addPoly(verts, count, false);
140*c8dee2aaSAndroid Build Coastguard Worker     canvas->drawPath(path, paint);
141*c8dee2aaSAndroid Build Coastguard Worker }
142*c8dee2aaSAndroid Build Coastguard Worker 
143*c8dee2aaSAndroid Build Coastguard Worker // Demonstrate edge-clipping that is used in the scan converter
144*c8dee2aaSAndroid Build Coastguard Worker //
145*c8dee2aaSAndroid Build Coastguard Worker class EdgeClipSlide : public ClickHandlerSlide {
146*c8dee2aaSAndroid Build Coastguard Worker     enum {
147*c8dee2aaSAndroid Build Coastguard Worker         N = 3
148*c8dee2aaSAndroid Build Coastguard Worker     };
149*c8dee2aaSAndroid Build Coastguard Worker     SkPoint fPoly[N];
150*c8dee2aaSAndroid Build Coastguard Worker     SkRect  fClip;
151*c8dee2aaSAndroid Build Coastguard Worker     SkColor fEdgeColor[N];
152*c8dee2aaSAndroid Build Coastguard Worker 
153*c8dee2aaSAndroid Build Coastguard Worker public:
EdgeClipSlide()154*c8dee2aaSAndroid Build Coastguard Worker     EdgeClipSlide() : fClip(SkRect::MakeLTRB(150, 150, 550, 450)) {
155*c8dee2aaSAndroid Build Coastguard Worker         fPoly[0].set(300, 40);
156*c8dee2aaSAndroid Build Coastguard Worker         fPoly[1].set(550, 250);
157*c8dee2aaSAndroid Build Coastguard Worker         fPoly[2].set(40, 450);
158*c8dee2aaSAndroid Build Coastguard Worker 
159*c8dee2aaSAndroid Build Coastguard Worker         fEdgeColor[0] = 0xFFFF0000;
160*c8dee2aaSAndroid Build Coastguard Worker         fEdgeColor[1] = 0xFF00FF00;
161*c8dee2aaSAndroid Build Coastguard Worker         fEdgeColor[2] = 0xFF0000FF;
162*c8dee2aaSAndroid Build Coastguard Worker         fName = "EdgeClip";
163*c8dee2aaSAndroid Build Coastguard Worker     }
164*c8dee2aaSAndroid Build Coastguard Worker 
snap(SkScalar x)165*c8dee2aaSAndroid Build Coastguard Worker     static SkScalar snap(SkScalar x) {
166*c8dee2aaSAndroid Build Coastguard Worker         return SkScalarRoundToScalar(x * 0.5f) * 2;
167*c8dee2aaSAndroid Build Coastguard Worker     }
snap(const SkPoint & pt)168*c8dee2aaSAndroid Build Coastguard Worker     static SkPoint snap(const SkPoint& pt) {
169*c8dee2aaSAndroid Build Coastguard Worker         return SkPoint::Make(snap(pt.x()), snap(pt.y()));
170*c8dee2aaSAndroid Build Coastguard Worker     }
snap(SkPoint dst[],const SkPoint src[],int count)171*c8dee2aaSAndroid Build Coastguard Worker     static void snap(SkPoint dst[], const SkPoint src[], int count) {
172*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < count; ++i) {
173*c8dee2aaSAndroid Build Coastguard Worker             dst[i] = snap(src[i]);
174*c8dee2aaSAndroid Build Coastguard Worker         }
175*c8dee2aaSAndroid Build Coastguard Worker     }
176*c8dee2aaSAndroid Build Coastguard Worker 
draw(SkCanvas * canvas)177*c8dee2aaSAndroid Build Coastguard Worker     void draw(SkCanvas* canvas) override {
178*c8dee2aaSAndroid Build Coastguard Worker         SkPath path;
179*c8dee2aaSAndroid Build Coastguard Worker         path.addPoly(fPoly, N, true);
180*c8dee2aaSAndroid Build Coastguard Worker 
181*c8dee2aaSAndroid Build Coastguard Worker         // Draw the full triangle, stroked and filled
182*c8dee2aaSAndroid Build Coastguard Worker         SkPaint p;
183*c8dee2aaSAndroid Build Coastguard Worker         p.setAntiAlias(true);
184*c8dee2aaSAndroid Build Coastguard Worker         p.setColor(0xFFE0E0E0);
185*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawPath(path, p);
186*c8dee2aaSAndroid Build Coastguard Worker         p.setStyle(SkPaint::kStroke_Style);
187*c8dee2aaSAndroid Build Coastguard Worker         p.setStrokeWidth(2);
188*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < N; ++i) {
189*c8dee2aaSAndroid Build Coastguard Worker             const int j = (i + 1) % N;
190*c8dee2aaSAndroid Build Coastguard Worker             p.setColor(fEdgeColor[i]);
191*c8dee2aaSAndroid Build Coastguard Worker             p.setAlpha(0x88);
192*c8dee2aaSAndroid Build Coastguard Worker             canvas->drawLine(fPoly[i], fPoly[j], p);
193*c8dee2aaSAndroid Build Coastguard Worker         }
194*c8dee2aaSAndroid Build Coastguard Worker         p.setStyle(SkPaint::kFill_Style);
195*c8dee2aaSAndroid Build Coastguard Worker 
196*c8dee2aaSAndroid Build Coastguard Worker         // Draw the clip itself
197*c8dee2aaSAndroid Build Coastguard Worker         p.setColor(0xFF8888CC);
198*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawRect(fClip, p);
199*c8dee2aaSAndroid Build Coastguard Worker 
200*c8dee2aaSAndroid Build Coastguard Worker         // Draw the filled triangle through the clip
201*c8dee2aaSAndroid Build Coastguard Worker         p.setColor(0xFF88CC88);
202*c8dee2aaSAndroid Build Coastguard Worker         canvas->save();
203*c8dee2aaSAndroid Build Coastguard Worker         canvas->clipRect(fClip);
204*c8dee2aaSAndroid Build Coastguard Worker         canvas->drawPath(path, p);
205*c8dee2aaSAndroid Build Coastguard Worker         canvas->restore();
206*c8dee2aaSAndroid Build Coastguard Worker 
207*c8dee2aaSAndroid Build Coastguard Worker         p.setStyle(SkPaint::kStroke_Style);
208*c8dee2aaSAndroid Build Coastguard Worker         p.setStrokeWidth(6);
209*c8dee2aaSAndroid Build Coastguard Worker 
210*c8dee2aaSAndroid Build Coastguard Worker         // Draw each of the "Edges" that survived the clipping
211*c8dee2aaSAndroid Build Coastguard Worker         // We use a layer, so we can PLUS the different edge-colors, showing where two edges
212*c8dee2aaSAndroid Build Coastguard Worker         // canceled each other out.
213*c8dee2aaSAndroid Build Coastguard Worker         canvas->saveLayer(nullptr, nullptr);
214*c8dee2aaSAndroid Build Coastguard Worker         p.setBlendMode(SkBlendMode::kPlus);
215*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < N; ++i) {
216*c8dee2aaSAndroid Build Coastguard Worker             const int j = (i + 1) % N;
217*c8dee2aaSAndroid Build Coastguard Worker             p.setColor(fEdgeColor[i]);
218*c8dee2aaSAndroid Build Coastguard Worker             draw_clipped_line(canvas, fClip, fPoly[i], fPoly[j], p);
219*c8dee2aaSAndroid Build Coastguard Worker         }
220*c8dee2aaSAndroid Build Coastguard Worker         canvas->restore();
221*c8dee2aaSAndroid Build Coastguard Worker     }
222*c8dee2aaSAndroid Build Coastguard Worker 
223*c8dee2aaSAndroid Build Coastguard Worker     class MyClick : public Click {
224*c8dee2aaSAndroid Build Coastguard Worker     public:
MyClick()225*c8dee2aaSAndroid Build Coastguard Worker         MyClick() {}
226*c8dee2aaSAndroid Build Coastguard Worker         virtual void handleMove() = 0;
227*c8dee2aaSAndroid Build Coastguard Worker     };
228*c8dee2aaSAndroid Build Coastguard Worker 
229*c8dee2aaSAndroid Build Coastguard Worker     class VertClick : public MyClick {
230*c8dee2aaSAndroid Build Coastguard Worker         SkPoint* fPt;
231*c8dee2aaSAndroid Build Coastguard Worker     public:
VertClick(SkPoint * pt)232*c8dee2aaSAndroid Build Coastguard Worker         VertClick(SkPoint* pt) : fPt(pt) {}
handleMove()233*c8dee2aaSAndroid Build Coastguard Worker         void handleMove() override { *fPt = snap(fCurr); }
234*c8dee2aaSAndroid Build Coastguard Worker     };
235*c8dee2aaSAndroid Build Coastguard Worker 
236*c8dee2aaSAndroid Build Coastguard Worker     class DragRectClick : public MyClick {
237*c8dee2aaSAndroid Build Coastguard Worker         SkRect* fRect;
238*c8dee2aaSAndroid Build Coastguard Worker     public:
DragRectClick(SkRect * rect)239*c8dee2aaSAndroid Build Coastguard Worker         DragRectClick(SkRect* rect) : fRect(rect) {}
handleMove()240*c8dee2aaSAndroid Build Coastguard Worker         void handleMove() override { fRect->offset(fCurr.x() - fPrev.x(), fCurr.y() - fPrev.y()); }
241*c8dee2aaSAndroid Build Coastguard Worker     };
242*c8dee2aaSAndroid Build Coastguard Worker 
243*c8dee2aaSAndroid Build Coastguard Worker     class DragPolyClick : public MyClick {
244*c8dee2aaSAndroid Build Coastguard Worker         SkPoint fSrc[100];
245*c8dee2aaSAndroid Build Coastguard Worker         SkPoint* fPoly;
246*c8dee2aaSAndroid Build Coastguard Worker         int fCount;
247*c8dee2aaSAndroid Build Coastguard Worker     public:
DragPolyClick(SkPoint poly[],int count)248*c8dee2aaSAndroid Build Coastguard Worker         DragPolyClick(SkPoint poly[], int count) : fPoly(poly), fCount(count)
249*c8dee2aaSAndroid Build Coastguard Worker         {
250*c8dee2aaSAndroid Build Coastguard Worker             SkASSERT((size_t)count <= std::size(fSrc));
251*c8dee2aaSAndroid Build Coastguard Worker             memcpy(fSrc, poly, count * sizeof(SkPoint));
252*c8dee2aaSAndroid Build Coastguard Worker         }
handleMove()253*c8dee2aaSAndroid Build Coastguard Worker         void handleMove() override {
254*c8dee2aaSAndroid Build Coastguard Worker             const SkScalar dx = fCurr.x() - fOrig.x();
255*c8dee2aaSAndroid Build Coastguard Worker             const SkScalar dy = fCurr.y() - fOrig.y();
256*c8dee2aaSAndroid Build Coastguard Worker             for (int i = 0; i < fCount; ++i) {
257*c8dee2aaSAndroid Build Coastguard Worker                 fPoly[i].set(snap(fSrc[i].x() + dx), snap(fSrc[i].y() + dy));
258*c8dee2aaSAndroid Build Coastguard Worker             }
259*c8dee2aaSAndroid Build Coastguard Worker         }
260*c8dee2aaSAndroid Build Coastguard Worker     };
261*c8dee2aaSAndroid Build Coastguard Worker 
262*c8dee2aaSAndroid Build Coastguard Worker     class DoNothingClick : public MyClick {
263*c8dee2aaSAndroid Build Coastguard Worker     public:
DoNothingClick()264*c8dee2aaSAndroid Build Coastguard Worker         DoNothingClick() {}
handleMove()265*c8dee2aaSAndroid Build Coastguard Worker         void handleMove() override {}
266*c8dee2aaSAndroid Build Coastguard Worker     };
267*c8dee2aaSAndroid Build Coastguard Worker 
hit_test(const SkPoint & pt,SkScalar x,SkScalar y)268*c8dee2aaSAndroid Build Coastguard Worker     static bool hit_test(const SkPoint& pt, SkScalar x, SkScalar y) {
269*c8dee2aaSAndroid Build Coastguard Worker         const SkScalar rad = 8;
270*c8dee2aaSAndroid Build Coastguard Worker         const SkScalar dx = pt.x() - x;
271*c8dee2aaSAndroid Build Coastguard Worker         const SkScalar dy = pt.y() - y;
272*c8dee2aaSAndroid Build Coastguard Worker         return dx*dx + dy*dy <= rad*rad;
273*c8dee2aaSAndroid Build Coastguard Worker     }
274*c8dee2aaSAndroid Build Coastguard Worker 
275*c8dee2aaSAndroid Build Coastguard Worker protected:
onFindClickHandler(SkScalar x,SkScalar y,skui::ModifierKey)276*c8dee2aaSAndroid Build Coastguard Worker     Click* onFindClickHandler(SkScalar x, SkScalar y, skui::ModifierKey) override {
277*c8dee2aaSAndroid Build Coastguard Worker         for (int i = 0; i < N; ++i) {
278*c8dee2aaSAndroid Build Coastguard Worker             if (hit_test(fPoly[i], x, y)) {
279*c8dee2aaSAndroid Build Coastguard Worker                 return new VertClick(&fPoly[i]);
280*c8dee2aaSAndroid Build Coastguard Worker             }
281*c8dee2aaSAndroid Build Coastguard Worker         }
282*c8dee2aaSAndroid Build Coastguard Worker 
283*c8dee2aaSAndroid Build Coastguard Worker         SkPath path;
284*c8dee2aaSAndroid Build Coastguard Worker         path.addPoly(fPoly, N, true);
285*c8dee2aaSAndroid Build Coastguard Worker         if (path.contains(x, y)) {
286*c8dee2aaSAndroid Build Coastguard Worker             return new DragPolyClick(fPoly, N);
287*c8dee2aaSAndroid Build Coastguard Worker         }
288*c8dee2aaSAndroid Build Coastguard Worker 
289*c8dee2aaSAndroid Build Coastguard Worker         if (fClip.intersects(SkRect::MakeLTRB(x - 1, y - 1, x + 1, y + 1))) {
290*c8dee2aaSAndroid Build Coastguard Worker             return new DragRectClick(&fClip);
291*c8dee2aaSAndroid Build Coastguard Worker         }
292*c8dee2aaSAndroid Build Coastguard Worker         return new DoNothingClick();
293*c8dee2aaSAndroid Build Coastguard Worker     }
294*c8dee2aaSAndroid Build Coastguard Worker 
onClick(Click * click)295*c8dee2aaSAndroid Build Coastguard Worker     bool onClick(Click* click) override {
296*c8dee2aaSAndroid Build Coastguard Worker         ((MyClick*)click)->handleMove();
297*c8dee2aaSAndroid Build Coastguard Worker         return true;
298*c8dee2aaSAndroid Build Coastguard Worker     }
299*c8dee2aaSAndroid Build Coastguard Worker };
300*c8dee2aaSAndroid Build Coastguard Worker 
301*c8dee2aaSAndroid Build Coastguard Worker DEF_SLIDE( return new EdgeClipSlide; )
302