blob: 94374b53d3efeba5b803ab611e961e299a3ee904 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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 */
reed@android.com70149062009-11-16 20:39:43 +00008#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"
reed@android.com77f0ef72009-11-17 18:47:52 +000023
reed@android.com70149062009-11-16 20:39:43 +000024#include "SkLineClipper.h"
reed@android.com909994f2009-11-18 16:09:51 +000025#include "SkEdgeClipper.h"
reed@android.com77f0ef72009-11-17 18:47:52 +000026
reed@android.come28ff552009-11-19 20:46:39 +000027#define AUTO_ANIMATE true
28
29static int test0(SkPoint pts[], SkRect* clip) {
30 pts[0].set(200000, 140);
31 pts[1].set(-740000, 483);
robertphillips@google.comc6ce7502012-05-08 13:15:37 +000032 pts[2].set(SkFloatToScalar(1.00000102e-06f),
33 SkFloatToScalar(9.10000017e-05f));
reed@android.come28ff552009-11-19 20:46:39 +000034 clip->set(0, 0, 640, 480);
35 return 2;
36}
37
38///////////////////////////////////////////////////////////////////////////////
39
reed@android.com77f0ef72009-11-17 18:47:52 +000040static void drawQuad(SkCanvas* canvas, const SkPoint pts[3], const SkPaint& p) {
41 SkPath path;
42 path.moveTo(pts[0]);
43 path.quadTo(pts[1], pts[2]);
44 canvas->drawPath(path, p);
45}
46
reed@android.combb135862009-11-18 13:47:40 +000047static void drawCubic(SkCanvas* canvas, const SkPoint pts[4], const SkPaint& p) {
48 SkPath path;
49 path.moveTo(pts[0]);
50 path.cubicTo(pts[1], pts[2], pts[3]);
51 canvas->drawPath(path, p);
52}
53
reed@android.com77f0ef72009-11-17 18:47:52 +000054typedef void (*clipper_proc)(const SkPoint src[], const SkRect& clip,
55 SkCanvas*, const SkPaint&, const SkPaint&);
56
57static void check_clipper(int count, const SkPoint pts[], const SkRect& clip) {
58 for (int i = 0; i < count; i++) {
59 SkASSERT(pts[i].fX >= clip.fLeft);
60 SkASSERT(pts[i].fX <= clip.fRight);
61 SkASSERT(pts[i].fY >= clip.fTop);
62 SkASSERT(pts[i].fY <= clip.fBottom);
63 }
reed@android.com3a0cd7f2009-11-17 19:39:51 +000064
65 if (count > 1) {
reed@android.combb135862009-11-18 13:47:40 +000066 sk_assert_monotonic_y(pts, count);
reed@android.com3a0cd7f2009-11-17 19:39:51 +000067 }
reed@android.com77f0ef72009-11-17 18:47:52 +000068}
69
reed@android.come28ff552009-11-19 20:46:39 +000070static void line_intersector(const SkPoint src[], const SkRect& clip,
71 SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
reed@android.com77f0ef72009-11-17 18:47:52 +000072 canvas->drawPoints(SkCanvas::kLines_PointMode, 2, src, p1);
reed@android.come28ff552009-11-19 20:46:39 +000073
74 SkPoint dst[2];
75 if (SkLineClipper::IntersectLine(src, clip, dst)) {
76 check_clipper(2, dst, clip);
77 canvas->drawPoints(SkCanvas::kLines_PointMode, 2, dst, p0);
78 }
79}
reed@android.com77f0ef72009-11-17 18:47:52 +000080
reed@android.come28ff552009-11-19 20:46:39 +000081static void line_clipper(const SkPoint src[], const SkRect& clip,
82 SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
83 canvas->drawPoints(SkCanvas::kLines_PointMode, 2, src, p1);
84
reed@android.com77f0ef72009-11-17 18:47:52 +000085 SkPoint dst[SkLineClipper::kMaxPoints];
86 int count = SkLineClipper::ClipLine(src, clip, dst);
87 for (int i = 0; i < count; i++) {
88 check_clipper(2, &dst[i], clip);
89 canvas->drawPoints(SkCanvas::kLines_PointMode, 2, &dst[i], p0);
90 }
91}
92
93static void quad_clipper(const SkPoint src[], const SkRect& clip,
reed@android.combb135862009-11-18 13:47:40 +000094 SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
reed@android.com77f0ef72009-11-17 18:47:52 +000095 drawQuad(canvas, src, p1);
reed@android.combb135862009-11-18 13:47:40 +000096
reed@android.com909994f2009-11-18 16:09:51 +000097 SkEdgeClipper clipper;
reed@android.com77f0ef72009-11-17 18:47:52 +000098 if (clipper.clipQuad(src, clip)) {
reed@google.com4b0f0b22011-03-18 14:47:36 +000099 SkPoint pts[4];
reed@android.com77f0ef72009-11-17 18:47:52 +0000100 SkPath::Verb verb;
101 while ((verb = clipper.next(pts)) != SkPath::kDone_Verb) {
102 switch (verb) {
103 case SkPath::kLine_Verb:
reed@android.com3a0cd7f2009-11-17 19:39:51 +0000104 check_clipper(2, pts, clip);
reed@android.com77f0ef72009-11-17 18:47:52 +0000105 canvas->drawPoints(SkCanvas::kLines_PointMode, 2, pts, p0);
106 break;
107 case SkPath::kQuad_Verb:
reed@android.com3a0cd7f2009-11-17 19:39:51 +0000108 check_clipper(3, pts, clip);
reed@android.com77f0ef72009-11-17 18:47:52 +0000109 drawQuad(canvas, pts, p0);
110 break;
111 default:
112 SkASSERT(!"unexpected verb");
113 }
114 }
115 }
116}
117
reed@android.combb135862009-11-18 13:47:40 +0000118static void cubic_clipper(const SkPoint src[], const SkRect& clip,
119 SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
120 drawCubic(canvas, src, p1);
121
reed@android.com909994f2009-11-18 16:09:51 +0000122 SkEdgeClipper clipper;
reed@android.combb135862009-11-18 13:47:40 +0000123 if (clipper.clipCubic(src, clip)) {
124 SkPoint pts[4];
125 SkPath::Verb verb;
126 while ((verb = clipper.next(pts)) != SkPath::kDone_Verb) {
127 switch (verb) {
128 case SkPath::kLine_Verb:
129 check_clipper(2, pts, clip);
130 canvas->drawPoints(SkCanvas::kLines_PointMode, 2, pts, p0);
131 break;
132 case SkPath::kCubic_Verb:
133 // check_clipper(4, pts, clip);
134 drawCubic(canvas, pts, p0);
135 break;
136 default:
137 SkASSERT(!"unexpected verb");
138 }
139 }
140 }
141}
142
reed@android.com77f0ef72009-11-17 18:47:52 +0000143static const clipper_proc gProcs[] = {
reed@android.come28ff552009-11-19 20:46:39 +0000144 line_intersector,
reed@android.com77f0ef72009-11-17 18:47:52 +0000145 line_clipper,
reed@android.combb135862009-11-18 13:47:40 +0000146 quad_clipper,
147 cubic_clipper
reed@android.com77f0ef72009-11-17 18:47:52 +0000148};
149
150///////////////////////////////////////////////////////////////////////////////
reed@android.com70149062009-11-16 20:39:43 +0000151
152enum {
reed@android.com77f0ef72009-11-17 18:47:52 +0000153 W = 640/3,
154 H = 480/3
reed@android.com70149062009-11-16 20:39:43 +0000155};
156
mike@reedtribe.org90bb4972011-06-18 01:35:18 +0000157class LineClipperView : public SampleView {
reed@android.com44177402009-11-23 21:07:51 +0000158 SkMSec fNow;
reed@android.com3a0cd7f2009-11-17 19:39:51 +0000159 int fCounter;
reed@android.com77f0ef72009-11-17 18:47:52 +0000160 int fProcIndex;
reed@android.com70149062009-11-16 20:39:43 +0000161 SkRect fClip;
162 SkRandom fRand;
reed@android.com77f0ef72009-11-17 18:47:52 +0000163 SkPoint fPts[4];
reed@android.com70149062009-11-16 20:39:43 +0000164
165 void randPts() {
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000166 for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); i++) {
reed@android.com77f0ef72009-11-17 18:47:52 +0000167 fPts[i].set(fRand.nextUScalar1() * 640,
168 fRand.nextUScalar1() * 480);
169 }
reed@android.com3a0cd7f2009-11-17 19:39:51 +0000170 fCounter += 1;
reed@android.com70149062009-11-16 20:39:43 +0000171 }
172
173public:
174 LineClipperView() {
reed@android.come28ff552009-11-19 20:46:39 +0000175 fProcIndex = 0;
reed@android.com3a0cd7f2009-11-17 19:39:51 +0000176 fCounter = 0;
senorblanco@chromium.org50108cd2011-05-24 20:25:32 +0000177 fNow = 0;
reed@android.com3a0cd7f2009-11-17 19:39:51 +0000178
reed@android.com70149062009-11-16 20:39:43 +0000179 int x = (640 - W)/2;
180 int y = (480 - H)/2;
reed@google.com4b0f0b22011-03-18 14:47:36 +0000181 fClip.set(SkIntToScalar(x), SkIntToScalar(y),
182 SkIntToScalar(x + W), SkIntToScalar(y + H));
reed@android.com70149062009-11-16 20:39:43 +0000183 this->randPts();
184 }
185
186protected:
187 // overrides from SkEventSink
188 virtual bool onQuery(SkEvent* evt) {
189 if (SampleCode::TitleQ(*evt)) {
190 SampleCode::TitleR(evt, "LineClipper");
191 return true;
192 }
193 return this->INHERITED::onQuery(evt);
194 }
195
reed@android.com70149062009-11-16 20:39:43 +0000196 static void drawVLine(SkCanvas* canvas, SkScalar x, const SkPaint& paint) {
197 canvas->drawLine(x, -999, x, 999, paint);
198 }
199
200 static void drawHLine(SkCanvas* canvas, SkScalar y, const SkPaint& paint) {
201 canvas->drawLine(-999, y, 999, y, paint);
202 }
203
mike@reedtribe.org90bb4972011-06-18 01:35:18 +0000204 virtual void onDrawContent(SkCanvas* canvas) {
reed@android.com44177402009-11-23 21:07:51 +0000205 SkMSec now = SampleCode::GetAnimTime();
206 if (fNow != now) {
207 fNow = now;
208 this->randPts();
209 this->inval(NULL);
210 }
211
reed@android.come28ff552009-11-19 20:46:39 +0000212 // fProcIndex = test0(fPts, &fClip);
reed@android.com70149062009-11-16 20:39:43 +0000213
reed@android.com77f0ef72009-11-17 18:47:52 +0000214 SkPaint paint, paint1;
reed@android.com70149062009-11-16 20:39:43 +0000215
216 drawVLine(canvas, fClip.fLeft + SK_ScalarHalf, paint);
217 drawVLine(canvas, fClip.fRight - SK_ScalarHalf, paint);
218 drawHLine(canvas, fClip.fTop + SK_ScalarHalf, paint);
219 drawHLine(canvas, fClip.fBottom - SK_ScalarHalf, paint);
220
221 paint.setColor(SK_ColorLTGRAY);
222 canvas->drawRect(fClip, paint);
223
224 paint.setAntiAlias(true);
225 paint.setColor(SK_ColorBLUE);
reed@android.com77f0ef72009-11-17 18:47:52 +0000226 paint.setStyle(SkPaint::kStroke_Style);
227 // paint.setStrokeWidth(SkIntToScalar(3));
reed@android.com70149062009-11-16 20:39:43 +0000228 paint.setStrokeCap(SkPaint::kRound_Cap);
reed@android.com77f0ef72009-11-17 18:47:52 +0000229
230 paint1.setAntiAlias(true);
231 paint1.setColor(SK_ColorRED);
232 paint1.setStyle(SkPaint::kStroke_Style);
233 gProcs[fProcIndex](fPts, fClip, canvas, paint, paint1);
mike@reedtribe.org90bb4972011-06-18 01:35:18 +0000234 this->inval(NULL);
reed@android.com70149062009-11-16 20:39:43 +0000235 }
236
237 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
reed@android.com77f0ef72009-11-17 18:47:52 +0000238 // fProcIndex = (fProcIndex + 1) % SK_ARRAY_COUNT(gProcs);
239 if (x < 50 && y < 50) {
240 this->randPts();
241 }
reed@android.com70149062009-11-16 20:39:43 +0000242 this->inval(NULL);
243 return NULL;
244 }
245
246 virtual bool onClick(Click* click) {
247 return false;
248 }
249
250private:
mike@reedtribe.org90bb4972011-06-18 01:35:18 +0000251 typedef SampleView INHERITED;
reed@android.com70149062009-11-16 20:39:43 +0000252};
253
254//////////////////////////////////////////////////////////////////////////////
255
256static SkView* MyFactory() { return new LineClipperView; }
257static SkViewRegister reg(MyFactory);
258