• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 /*
3  * Copyright 2011 Google Inc.
4  *
5  * Use of this source code is governed by a BSD-style license that can be
6  * found in the LICENSE file.
7  */
8 #include "SampleCode.h"
9 #include "SkView.h"
10 #include "SkCanvas.h"
11 #include "SkGradientShader.h"
12 #include "SkGraphics.h"
13 #include "SkImageDecoder.h"
14 #include "SkPath.h"
15 #include "SkRegion.h"
16 #include "SkShader.h"
17 #include "SkUtils.h"
18 #include "SkXfermode.h"
19 #include "SkColorPriv.h"
20 #include "SkColorFilter.h"
21 #include "SkTime.h"
22 #include "SkRandom.h"
23 
24 #include "SkLineClipper.h"
25 #include "SkEdgeClipper.h"
26 
27 #define AUTO_ANIMATE    true
28 
test0(SkPoint pts[],SkRect * clip)29 static int test0(SkPoint pts[], SkRect* clip) {
30     pts[0].set(200000, 140);
31     pts[1].set(-740000, 483);
32     pts[2].set(1.00000102e-06f, 9.10000017e-05f);
33     clip->set(0, 0, 640, 480);
34     return 2;
35 }
36 
37 ///////////////////////////////////////////////////////////////////////////////
38 
drawQuad(SkCanvas * canvas,const SkPoint pts[3],const SkPaint & p)39 static void drawQuad(SkCanvas* canvas, const SkPoint pts[3], const SkPaint& p) {
40     SkPath path;
41     path.moveTo(pts[0]);
42     path.quadTo(pts[1], pts[2]);
43     canvas->drawPath(path, p);
44 }
45 
drawCubic(SkCanvas * canvas,const SkPoint pts[4],const SkPaint & p)46 static void drawCubic(SkCanvas* canvas, const SkPoint pts[4], const SkPaint& p) {
47     SkPath path;
48     path.moveTo(pts[0]);
49     path.cubicTo(pts[1], pts[2], pts[3]);
50     canvas->drawPath(path, p);
51 }
52 
53 typedef void (*clipper_proc)(const SkPoint src[], const SkRect& clip,
54                             SkCanvas*, const SkPaint&, const SkPaint&);
55 
check_clipper(int count,const SkPoint pts[],const SkRect & clip)56 static void check_clipper(int count, const SkPoint pts[], const SkRect& clip) {
57     for (int i = 0; i < count; i++) {
58         SkASSERT(pts[i].fX >= clip.fLeft);
59         SkASSERT(pts[i].fX <= clip.fRight);
60         SkASSERT(pts[i].fY >= clip.fTop);
61         SkASSERT(pts[i].fY <= clip.fBottom);
62     }
63 
64     if (count > 1) {
65         sk_assert_monotonic_y(pts, count);
66     }
67 }
68 
line_intersector(const SkPoint src[],const SkRect & clip,SkCanvas * canvas,const SkPaint & p0,const SkPaint & p1)69 static void line_intersector(const SkPoint src[], const SkRect& clip,
70                          SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
71     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, src, p1);
72 
73     SkPoint dst[2];
74     if (SkLineClipper::IntersectLine(src, clip, dst)) {
75         check_clipper(2, dst, clip);
76         canvas->drawPoints(SkCanvas::kLines_PointMode, 2, dst, p0);
77     }
78 }
79 
line_clipper(const SkPoint src[],const SkRect & clip,SkCanvas * canvas,const SkPaint & p0,const SkPaint & p1)80 static void line_clipper(const SkPoint src[], const SkRect& clip,
81                          SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
82     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, src, p1);
83 
84     SkPoint dst[SkLineClipper::kMaxPoints];
85     int count = SkLineClipper::ClipLine(src, clip, dst);
86     for (int i = 0; i < count; i++) {
87         check_clipper(2, &dst[i], clip);
88         canvas->drawPoints(SkCanvas::kLines_PointMode, 2, &dst[i], p0);
89     }
90 }
91 
quad_clipper(const SkPoint src[],const SkRect & clip,SkCanvas * canvas,const SkPaint & p0,const SkPaint & p1)92 static void quad_clipper(const SkPoint src[], const SkRect& clip,
93                          SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
94     drawQuad(canvas, src, p1);
95 
96     SkEdgeClipper clipper;
97     if (clipper.clipQuad(src, clip)) {
98         SkPoint pts[4];
99         SkPath::Verb verb;
100         while ((verb = clipper.next(pts)) != SkPath::kDone_Verb) {
101             switch (verb) {
102                 case SkPath::kLine_Verb:
103                     check_clipper(2, pts, clip);
104                     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, pts, p0);
105                     break;
106                 case SkPath::kQuad_Verb:
107                     check_clipper(3, pts, clip);
108                     drawQuad(canvas, pts, p0);
109                     break;
110                 default:
111                     SkASSERT(!"unexpected verb");
112             }
113         }
114     }
115 }
116 
cubic_clipper(const SkPoint src[],const SkRect & clip,SkCanvas * canvas,const SkPaint & p0,const SkPaint & p1)117 static void cubic_clipper(const SkPoint src[], const SkRect& clip,
118                        SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
119     drawCubic(canvas, src, p1);
120 
121     SkEdgeClipper clipper;
122     if (clipper.clipCubic(src, clip)) {
123         SkPoint pts[4];
124         SkPath::Verb verb;
125         while ((verb = clipper.next(pts)) != SkPath::kDone_Verb) {
126             switch (verb) {
127                 case SkPath::kLine_Verb:
128                     check_clipper(2, pts, clip);
129                     canvas->drawPoints(SkCanvas::kLines_PointMode, 2, pts, p0);
130                     break;
131                 case SkPath::kCubic_Verb:
132                  //   check_clipper(4, pts, clip);
133                     drawCubic(canvas, pts, p0);
134                     break;
135                 default:
136                     SkASSERT(!"unexpected verb");
137             }
138         }
139     }
140 }
141 
142 static const clipper_proc gProcs[] = {
143     line_intersector,
144     line_clipper,
145     quad_clipper,
146     cubic_clipper
147 };
148 
149 ///////////////////////////////////////////////////////////////////////////////
150 
151 enum {
152     W = 640/3,
153     H = 480/3
154 };
155 
156 class LineClipperView : public SampleView {
157     SkMSec      fNow;
158     int         fCounter;
159     int         fProcIndex;
160     SkRect      fClip;
161     SkRandom    fRand;
162     SkPoint     fPts[4];
163 
randPts()164     void randPts() {
165         for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); i++) {
166             fPts[i].set(fRand.nextUScalar1() * 640,
167                         fRand.nextUScalar1() * 480);
168         }
169         fCounter += 1;
170     }
171 
172 public:
LineClipperView()173 	LineClipperView() {
174         fProcIndex = 0;
175         fCounter = 0;
176         fNow = 0;
177 
178         int x = (640 - W)/2;
179         int y = (480 - H)/2;
180         fClip.set(SkIntToScalar(x), SkIntToScalar(y),
181                   SkIntToScalar(x + W), SkIntToScalar(y + H));
182         this->randPts();
183     }
184 
185 protected:
186     // overrides from SkEventSink
onQuery(SkEvent * evt)187     virtual bool onQuery(SkEvent* evt) {
188         if (SampleCode::TitleQ(*evt)) {
189             SampleCode::TitleR(evt, "LineClipper");
190             return true;
191         }
192         return this->INHERITED::onQuery(evt);
193     }
194 
drawVLine(SkCanvas * canvas,SkScalar x,const SkPaint & paint)195     static void drawVLine(SkCanvas* canvas, SkScalar x, const SkPaint& paint) {
196         canvas->drawLine(x, -999, x, 999, paint);
197     }
198 
drawHLine(SkCanvas * canvas,SkScalar y,const SkPaint & paint)199     static void drawHLine(SkCanvas* canvas, SkScalar y, const SkPaint& paint) {
200         canvas->drawLine(-999, y, 999, y, paint);
201     }
202 
onDrawContent(SkCanvas * canvas)203     virtual void onDrawContent(SkCanvas* canvas) {
204         SkMSec now = SampleCode::GetAnimTime();
205         if (fNow != now) {
206             fNow = now;
207             this->randPts();
208             this->inval(NULL);
209         }
210 
211      //   fProcIndex = test0(fPts, &fClip);
212 
213         SkPaint paint, paint1;
214 
215         drawVLine(canvas, fClip.fLeft + SK_ScalarHalf, paint);
216         drawVLine(canvas, fClip.fRight - SK_ScalarHalf, paint);
217         drawHLine(canvas, fClip.fTop + SK_ScalarHalf, paint);
218         drawHLine(canvas, fClip.fBottom - SK_ScalarHalf, paint);
219 
220         paint.setColor(SK_ColorLTGRAY);
221         canvas->drawRect(fClip, paint);
222 
223         paint.setAntiAlias(true);
224         paint.setColor(SK_ColorBLUE);
225         paint.setStyle(SkPaint::kStroke_Style);
226       //  paint.setStrokeWidth(SkIntToScalar(3));
227         paint.setStrokeCap(SkPaint::kRound_Cap);
228 
229         paint1.setAntiAlias(true);
230         paint1.setColor(SK_ColorRED);
231         paint1.setStyle(SkPaint::kStroke_Style);
232         gProcs[fProcIndex](fPts, fClip, canvas, paint, paint1);
233         this->inval(NULL);
234     }
235 
onFindClickHandler(SkScalar x,SkScalar y)236     virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
237      //   fProcIndex = (fProcIndex + 1) % SK_ARRAY_COUNT(gProcs);
238         if (x < 50 && y < 50) {
239             this->randPts();
240         }
241         this->inval(NULL);
242         return NULL;
243     }
244 
onClick(Click * click)245     virtual bool onClick(Click* click) {
246         return false;
247     }
248 
249 private:
250     typedef SampleView INHERITED;
251 };
252 
253 //////////////////////////////////////////////////////////////////////////////
254 
MyFactory()255 static SkView* MyFactory() { return new LineClipperView; }
256 static SkViewRegister reg(MyFactory);
257 
258