blob: 85654706c80280be06acbe957aae9f3757ba3cec [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);
32 pts[2].set(1.00000102e-06f, 9.10000017e-05f);
33 clip->set(0, 0, 640, 480);
34 return 2;
35}
36
37///////////////////////////////////////////////////////////////////////////////
38
reed@android.com77f0ef72009-11-17 18:47:52 +000039static 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
reed@android.combb135862009-11-18 13:47:40 +000046static 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
reed@android.com77f0ef72009-11-17 18:47:52 +000053typedef void (*clipper_proc)(const SkPoint src[], const SkRect& clip,
54 SkCanvas*, const SkPaint&, const SkPaint&);
55
56static 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 }
reed@android.com3a0cd7f2009-11-17 19:39:51 +000063
64 if (count > 1) {
reed@android.combb135862009-11-18 13:47:40 +000065 sk_assert_monotonic_y(pts, count);
reed@android.com3a0cd7f2009-11-17 19:39:51 +000066 }
reed@android.com77f0ef72009-11-17 18:47:52 +000067}
68
reed@android.come28ff552009-11-19 20:46:39 +000069static void line_intersector(const SkPoint src[], const SkRect& clip,
70 SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
reed@android.com77f0ef72009-11-17 18:47:52 +000071 canvas->drawPoints(SkCanvas::kLines_PointMode, 2, src, p1);
reed@android.come28ff552009-11-19 20:46:39 +000072
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}
reed@android.com77f0ef72009-11-17 18:47:52 +000079
reed@android.come28ff552009-11-19 20:46:39 +000080static 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
reed@android.com77f0ef72009-11-17 18:47:52 +000084 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
92static void quad_clipper(const SkPoint src[], const SkRect& clip,
reed@android.combb135862009-11-18 13:47:40 +000093 SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
reed@android.com77f0ef72009-11-17 18:47:52 +000094 drawQuad(canvas, src, p1);
reed@android.combb135862009-11-18 13:47:40 +000095
reed@android.com909994f2009-11-18 16:09:51 +000096 SkEdgeClipper clipper;
reed@android.com77f0ef72009-11-17 18:47:52 +000097 if (clipper.clipQuad(src, clip)) {
reed@google.com4b0f0b22011-03-18 14:47:36 +000098 SkPoint pts[4];
reed@android.com77f0ef72009-11-17 18:47:52 +000099 SkPath::Verb verb;
100 while ((verb = clipper.next(pts)) != SkPath::kDone_Verb) {
101 switch (verb) {
102 case SkPath::kLine_Verb:
reed@android.com3a0cd7f2009-11-17 19:39:51 +0000103 check_clipper(2, pts, clip);
reed@android.com77f0ef72009-11-17 18:47:52 +0000104 canvas->drawPoints(SkCanvas::kLines_PointMode, 2, pts, p0);
105 break;
106 case SkPath::kQuad_Verb:
reed@android.com3a0cd7f2009-11-17 19:39:51 +0000107 check_clipper(3, pts, clip);
reed@android.com77f0ef72009-11-17 18:47:52 +0000108 drawQuad(canvas, pts, p0);
109 break;
110 default:
111 SkASSERT(!"unexpected verb");
112 }
113 }
114 }
115}
116
reed@android.combb135862009-11-18 13:47:40 +0000117static void cubic_clipper(const SkPoint src[], const SkRect& clip,
118 SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
119 drawCubic(canvas, src, p1);
120
reed@android.com909994f2009-11-18 16:09:51 +0000121 SkEdgeClipper clipper;
reed@android.combb135862009-11-18 13:47:40 +0000122 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
reed@android.com77f0ef72009-11-17 18:47:52 +0000142static const clipper_proc gProcs[] = {
reed@android.come28ff552009-11-19 20:46:39 +0000143 line_intersector,
reed@android.com77f0ef72009-11-17 18:47:52 +0000144 line_clipper,
reed@android.combb135862009-11-18 13:47:40 +0000145 quad_clipper,
146 cubic_clipper
reed@android.com77f0ef72009-11-17 18:47:52 +0000147};
148
149///////////////////////////////////////////////////////////////////////////////
reed@android.com70149062009-11-16 20:39:43 +0000150
151enum {
reed@android.com77f0ef72009-11-17 18:47:52 +0000152 W = 640/3,
153 H = 480/3
reed@android.com70149062009-11-16 20:39:43 +0000154};
155
mike@reedtribe.org90bb4972011-06-18 01:35:18 +0000156class LineClipperView : public SampleView {
reed@android.com44177402009-11-23 21:07:51 +0000157 SkMSec fNow;
reed@android.com3a0cd7f2009-11-17 19:39:51 +0000158 int fCounter;
reed@android.com77f0ef72009-11-17 18:47:52 +0000159 int fProcIndex;
reed@android.com70149062009-11-16 20:39:43 +0000160 SkRect fClip;
161 SkRandom fRand;
reed@android.com77f0ef72009-11-17 18:47:52 +0000162 SkPoint fPts[4];
reed@android.com70149062009-11-16 20:39:43 +0000163
164 void randPts() {
senorblanco@chromium.org64cc5792011-05-19 19:58:58 +0000165 for (size_t i = 0; i < SK_ARRAY_COUNT(fPts); i++) {
reed@android.com77f0ef72009-11-17 18:47:52 +0000166 fPts[i].set(fRand.nextUScalar1() * 640,
167 fRand.nextUScalar1() * 480);
168 }
reed@android.com3a0cd7f2009-11-17 19:39:51 +0000169 fCounter += 1;
reed@android.com70149062009-11-16 20:39:43 +0000170 }
171
172public:
173 LineClipperView() {
reed@android.come28ff552009-11-19 20:46:39 +0000174 fProcIndex = 0;
reed@android.com3a0cd7f2009-11-17 19:39:51 +0000175 fCounter = 0;
senorblanco@chromium.org50108cd2011-05-24 20:25:32 +0000176 fNow = 0;
reed@android.com3a0cd7f2009-11-17 19:39:51 +0000177
reed@android.com70149062009-11-16 20:39:43 +0000178 int x = (640 - W)/2;
179 int y = (480 - H)/2;
reed@google.com4b0f0b22011-03-18 14:47:36 +0000180 fClip.set(SkIntToScalar(x), SkIntToScalar(y),
181 SkIntToScalar(x + W), SkIntToScalar(y + H));
reed@android.com70149062009-11-16 20:39:43 +0000182 this->randPts();
183 }
184
185protected:
186 // overrides from SkEventSink
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
reed@android.com70149062009-11-16 20:39:43 +0000195 static void drawVLine(SkCanvas* canvas, SkScalar x, const SkPaint& paint) {
196 canvas->drawLine(x, -999, x, 999, paint);
197 }
198
199 static void drawHLine(SkCanvas* canvas, SkScalar y, const SkPaint& paint) {
200 canvas->drawLine(-999, y, 999, y, paint);
201 }
202
mike@reedtribe.org90bb4972011-06-18 01:35:18 +0000203 virtual void onDrawContent(SkCanvas* canvas) {
reed@android.com44177402009-11-23 21:07:51 +0000204 SkMSec now = SampleCode::GetAnimTime();
205 if (fNow != now) {
206 fNow = now;
207 this->randPts();
208 this->inval(NULL);
209 }
210
reed@android.come28ff552009-11-19 20:46:39 +0000211 // fProcIndex = test0(fPts, &fClip);
reed@android.com70149062009-11-16 20:39:43 +0000212
reed@android.com77f0ef72009-11-17 18:47:52 +0000213 SkPaint paint, paint1;
reed@android.com70149062009-11-16 20:39:43 +0000214
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);
reed@android.com77f0ef72009-11-17 18:47:52 +0000225 paint.setStyle(SkPaint::kStroke_Style);
226 // paint.setStrokeWidth(SkIntToScalar(3));
reed@android.com70149062009-11-16 20:39:43 +0000227 paint.setStrokeCap(SkPaint::kRound_Cap);
reed@android.com77f0ef72009-11-17 18:47:52 +0000228
229 paint1.setAntiAlias(true);
230 paint1.setColor(SK_ColorRED);
231 paint1.setStyle(SkPaint::kStroke_Style);
232 gProcs[fProcIndex](fPts, fClip, canvas, paint, paint1);
mike@reedtribe.org90bb4972011-06-18 01:35:18 +0000233 this->inval(NULL);
reed@android.com70149062009-11-16 20:39:43 +0000234 }
235
236 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
reed@android.com77f0ef72009-11-17 18:47:52 +0000237 // fProcIndex = (fProcIndex + 1) % SK_ARRAY_COUNT(gProcs);
238 if (x < 50 && y < 50) {
239 this->randPts();
240 }
reed@android.com70149062009-11-16 20:39:43 +0000241 this->inval(NULL);
242 return NULL;
243 }
244
245 virtual bool onClick(Click* click) {
246 return false;
247 }
248
249private:
mike@reedtribe.org90bb4972011-06-18 01:35:18 +0000250 typedef SampleView INHERITED;
reed@android.com70149062009-11-16 20:39:43 +0000251};
252
253//////////////////////////////////////////////////////////////////////////////
254
255static SkView* MyFactory() { return new LineClipperView; }
256static SkViewRegister reg(MyFactory);
257