blob: 8ebe95105b428acc4f3cb8e326ecd7b05c75269a [file] [log] [blame]
reed@android.com70149062009-11-16 20:39:43 +00001#include "SampleCode.h"
2#include "SkView.h"
3#include "SkCanvas.h"
4#include "SkGradientShader.h"
5#include "SkGraphics.h"
6#include "SkImageDecoder.h"
7#include "SkPath.h"
8#include "SkRegion.h"
9#include "SkShader.h"
10#include "SkUtils.h"
11#include "SkXfermode.h"
12#include "SkColorPriv.h"
13#include "SkColorFilter.h"
14#include "SkTime.h"
15#include "SkRandom.h"
reed@android.com77f0ef72009-11-17 18:47:52 +000016
reed@android.com70149062009-11-16 20:39:43 +000017#include "SkLineClipper.h"
reed@android.com77f0ef72009-11-17 18:47:52 +000018#include "SkQuadClipper.h"
19
20static void drawQuad(SkCanvas* canvas, const SkPoint pts[3], const SkPaint& p) {
21 SkPath path;
22 path.moveTo(pts[0]);
23 path.quadTo(pts[1], pts[2]);
24 canvas->drawPath(path, p);
25}
26
reed@android.combb135862009-11-18 13:47:40 +000027static void drawCubic(SkCanvas* canvas, const SkPoint pts[4], const SkPaint& p) {
28 SkPath path;
29 path.moveTo(pts[0]);
30 path.cubicTo(pts[1], pts[2], pts[3]);
31 canvas->drawPath(path, p);
32}
33
reed@android.com77f0ef72009-11-17 18:47:52 +000034typedef void (*clipper_proc)(const SkPoint src[], const SkRect& clip,
35 SkCanvas*, const SkPaint&, const SkPaint&);
36
37static void check_clipper(int count, const SkPoint pts[], const SkRect& clip) {
38 for (int i = 0; i < count; i++) {
39 SkASSERT(pts[i].fX >= clip.fLeft);
40 SkASSERT(pts[i].fX <= clip.fRight);
41 SkASSERT(pts[i].fY >= clip.fTop);
42 SkASSERT(pts[i].fY <= clip.fBottom);
43 }
reed@android.com3a0cd7f2009-11-17 19:39:51 +000044
45 if (count > 1) {
reed@android.combb135862009-11-18 13:47:40 +000046 sk_assert_monotonic_y(pts, count);
reed@android.com3a0cd7f2009-11-17 19:39:51 +000047 }
reed@android.com77f0ef72009-11-17 18:47:52 +000048}
49
50static void line_clipper(const SkPoint src[], const SkRect& clip,
51 SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
52 canvas->drawPoints(SkCanvas::kLines_PointMode, 2, src, p1);
53
54 SkPoint dst[SkLineClipper::kMaxPoints];
55 int count = SkLineClipper::ClipLine(src, clip, dst);
56 for (int i = 0; i < count; i++) {
57 check_clipper(2, &dst[i], clip);
58 canvas->drawPoints(SkCanvas::kLines_PointMode, 2, &dst[i], p0);
59 }
60}
61
62static void quad_clipper(const SkPoint src[], const SkRect& clip,
reed@android.combb135862009-11-18 13:47:40 +000063 SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
reed@android.com77f0ef72009-11-17 18:47:52 +000064 drawQuad(canvas, src, p1);
reed@android.combb135862009-11-18 13:47:40 +000065
reed@android.com77f0ef72009-11-17 18:47:52 +000066 SkQuadClipper2 clipper;
67 if (clipper.clipQuad(src, clip)) {
68 SkPoint pts[3];
69 SkPath::Verb verb;
70 while ((verb = clipper.next(pts)) != SkPath::kDone_Verb) {
71 switch (verb) {
72 case SkPath::kLine_Verb:
reed@android.com3a0cd7f2009-11-17 19:39:51 +000073 check_clipper(2, pts, clip);
reed@android.com77f0ef72009-11-17 18:47:52 +000074 canvas->drawPoints(SkCanvas::kLines_PointMode, 2, pts, p0);
75 break;
76 case SkPath::kQuad_Verb:
reed@android.com3a0cd7f2009-11-17 19:39:51 +000077 check_clipper(3, pts, clip);
reed@android.com77f0ef72009-11-17 18:47:52 +000078 drawQuad(canvas, pts, p0);
79 break;
80 default:
81 SkASSERT(!"unexpected verb");
82 }
83 }
84 }
85}
86
reed@android.combb135862009-11-18 13:47:40 +000087static void cubic_clipper(const SkPoint src[], const SkRect& clip,
88 SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
89 drawCubic(canvas, src, p1);
90
91 SkQuadClipper2 clipper;
92 if (clipper.clipCubic(src, clip)) {
93 SkPoint pts[4];
94 SkPath::Verb verb;
95 while ((verb = clipper.next(pts)) != SkPath::kDone_Verb) {
96 switch (verb) {
97 case SkPath::kLine_Verb:
98 check_clipper(2, pts, clip);
99 canvas->drawPoints(SkCanvas::kLines_PointMode, 2, pts, p0);
100 break;
101 case SkPath::kCubic_Verb:
102 // check_clipper(4, pts, clip);
103 drawCubic(canvas, pts, p0);
104 break;
105 default:
106 SkASSERT(!"unexpected verb");
107 }
108 }
109 }
110}
111
reed@android.com77f0ef72009-11-17 18:47:52 +0000112static const clipper_proc gProcs[] = {
113 line_clipper,
reed@android.combb135862009-11-18 13:47:40 +0000114 quad_clipper,
115 cubic_clipper
reed@android.com77f0ef72009-11-17 18:47:52 +0000116};
117
118///////////////////////////////////////////////////////////////////////////////
reed@android.com70149062009-11-16 20:39:43 +0000119
120enum {
reed@android.com77f0ef72009-11-17 18:47:52 +0000121 W = 640/3,
122 H = 480/3
reed@android.com70149062009-11-16 20:39:43 +0000123};
124
125class LineClipperView : public SkView {
reed@android.com3a0cd7f2009-11-17 19:39:51 +0000126 int fCounter;
reed@android.com77f0ef72009-11-17 18:47:52 +0000127 int fProcIndex;
reed@android.com70149062009-11-16 20:39:43 +0000128 SkRect fClip;
129 SkRandom fRand;
reed@android.com77f0ef72009-11-17 18:47:52 +0000130 SkPoint fPts[4];
reed@android.com70149062009-11-16 20:39:43 +0000131
132 void randPts() {
reed@android.com77f0ef72009-11-17 18:47:52 +0000133 for (int i = 0; i < SK_ARRAY_COUNT(fPts); i++) {
134 fPts[i].set(fRand.nextUScalar1() * 640,
135 fRand.nextUScalar1() * 480);
136 }
reed@android.com3a0cd7f2009-11-17 19:39:51 +0000137 fCounter += 1;
reed@android.com70149062009-11-16 20:39:43 +0000138 }
139
140public:
141 LineClipperView() {
reed@android.combb135862009-11-18 13:47:40 +0000142 fProcIndex = 2;
reed@android.com3a0cd7f2009-11-17 19:39:51 +0000143 fCounter = 0;
144
reed@android.com70149062009-11-16 20:39:43 +0000145 int x = (640 - W)/2;
146 int y = (480 - H)/2;
147 fClip.set(x, y, x + W, y + H);
148 this->randPts();
149 }
150
151protected:
152 // overrides from SkEventSink
153 virtual bool onQuery(SkEvent* evt) {
154 if (SampleCode::TitleQ(*evt)) {
155 SampleCode::TitleR(evt, "LineClipper");
156 return true;
157 }
158 return this->INHERITED::onQuery(evt);
159 }
160
161 void drawBG(SkCanvas* canvas) {
162 canvas->drawColor(SK_ColorWHITE);
163 }
164
165 static void drawVLine(SkCanvas* canvas, SkScalar x, const SkPaint& paint) {
166 canvas->drawLine(x, -999, x, 999, paint);
167 }
168
169 static void drawHLine(SkCanvas* canvas, SkScalar y, const SkPaint& paint) {
170 canvas->drawLine(-999, y, 999, y, paint);
171 }
172
reed@android.com70149062009-11-16 20:39:43 +0000173 virtual void onDraw(SkCanvas* canvas) {
174 this->drawBG(canvas);
175
reed@android.com77f0ef72009-11-17 18:47:52 +0000176 SkPaint paint, paint1;
reed@android.com70149062009-11-16 20:39:43 +0000177
178 drawVLine(canvas, fClip.fLeft + SK_ScalarHalf, paint);
179 drawVLine(canvas, fClip.fRight - SK_ScalarHalf, paint);
180 drawHLine(canvas, fClip.fTop + SK_ScalarHalf, paint);
181 drawHLine(canvas, fClip.fBottom - SK_ScalarHalf, paint);
182
183 paint.setColor(SK_ColorLTGRAY);
184 canvas->drawRect(fClip, paint);
185
186 paint.setAntiAlias(true);
187 paint.setColor(SK_ColorBLUE);
reed@android.com77f0ef72009-11-17 18:47:52 +0000188 paint.setStyle(SkPaint::kStroke_Style);
189 // paint.setStrokeWidth(SkIntToScalar(3));
reed@android.com70149062009-11-16 20:39:43 +0000190 paint.setStrokeCap(SkPaint::kRound_Cap);
reed@android.com77f0ef72009-11-17 18:47:52 +0000191
192 paint1.setAntiAlias(true);
193 paint1.setColor(SK_ColorRED);
194 paint1.setStyle(SkPaint::kStroke_Style);
195 gProcs[fProcIndex](fPts, fClip, canvas, paint, paint1);
reed@android.com70149062009-11-16 20:39:43 +0000196
197 if (true) {
198 this->randPts();
199 this->inval(NULL);
200 }
201 }
202
203 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
reed@android.com77f0ef72009-11-17 18:47:52 +0000204 // fProcIndex = (fProcIndex + 1) % SK_ARRAY_COUNT(gProcs);
205 if (x < 50 && y < 50) {
206 this->randPts();
207 }
reed@android.com70149062009-11-16 20:39:43 +0000208 this->inval(NULL);
209 return NULL;
210 }
211
212 virtual bool onClick(Click* click) {
213 return false;
214 }
215
216private:
217 typedef SkView INHERITED;
218};
219
220//////////////////////////////////////////////////////////////////////////////
221
222static SkView* MyFactory() { return new LineClipperView; }
223static SkViewRegister reg(MyFactory);
224