blob: 9573810da69e22c52ae0f8060b54c3ee44673692 [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
27typedef void (*clipper_proc)(const SkPoint src[], const SkRect& clip,
28 SkCanvas*, const SkPaint&, const SkPaint&);
29
30static void check_clipper(int count, const SkPoint pts[], const SkRect& clip) {
31 for (int i = 0; i < count; i++) {
32 SkASSERT(pts[i].fX >= clip.fLeft);
33 SkASSERT(pts[i].fX <= clip.fRight);
34 SkASSERT(pts[i].fY >= clip.fTop);
35 SkASSERT(pts[i].fY <= clip.fBottom);
36 }
reed@android.com3a0cd7f2009-11-17 19:39:51 +000037
38 if (count > 1) {
39 // now check that we're monotonic in Y
40 if (pts[0].fY > pts[count - 1].fY) {
41 for (int i = 1; i < count; i++) {
42 SkASSERT(pts[i - 1].fY >= pts[i].fY);
43 }
44 } else if (pts[0].fY < pts[count - 1].fY) {
45 for (int i = 1; i < count; i++) {
46 SkASSERT(pts[i - 1].fY <= pts[i].fY);
47 }
48 } else {
49 for (int i = 1; i < count; i++) {
50 SkASSERT(pts[i - 1].fY == pts[i].fY);
51 }
52 }
53 }
reed@android.com77f0ef72009-11-17 18:47:52 +000054}
55
56static void line_clipper(const SkPoint src[], const SkRect& clip,
57 SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
58 canvas->drawPoints(SkCanvas::kLines_PointMode, 2, src, p1);
59
60 SkPoint dst[SkLineClipper::kMaxPoints];
61 int count = SkLineClipper::ClipLine(src, clip, dst);
62 for (int i = 0; i < count; i++) {
63 check_clipper(2, &dst[i], clip);
64 canvas->drawPoints(SkCanvas::kLines_PointMode, 2, &dst[i], p0);
65 }
66}
67
68static void quad_clipper(const SkPoint src[], const SkRect& clip,
69 SkCanvas* canvas, const SkPaint& p0, const SkPaint& p1) {
70 drawQuad(canvas, src, p1);
71
72 SkQuadClipper2 clipper;
73 if (clipper.clipQuad(src, clip)) {
74 SkPoint pts[3];
75 SkPath::Verb verb;
76 while ((verb = clipper.next(pts)) != SkPath::kDone_Verb) {
77 switch (verb) {
78 case SkPath::kLine_Verb:
reed@android.com3a0cd7f2009-11-17 19:39:51 +000079 check_clipper(2, pts, clip);
reed@android.com77f0ef72009-11-17 18:47:52 +000080 canvas->drawPoints(SkCanvas::kLines_PointMode, 2, pts, p0);
81 break;
82 case SkPath::kQuad_Verb:
reed@android.com3a0cd7f2009-11-17 19:39:51 +000083 check_clipper(3, pts, clip);
reed@android.com77f0ef72009-11-17 18:47:52 +000084 drawQuad(canvas, pts, p0);
85 break;
86 default:
87 SkASSERT(!"unexpected verb");
88 }
89 }
90 }
91}
92
93static const clipper_proc gProcs[] = {
94 line_clipper,
95 quad_clipper
96};
97
98///////////////////////////////////////////////////////////////////////////////
reed@android.com70149062009-11-16 20:39:43 +000099
100enum {
reed@android.com77f0ef72009-11-17 18:47:52 +0000101 W = 640/3,
102 H = 480/3
reed@android.com70149062009-11-16 20:39:43 +0000103};
104
105class LineClipperView : public SkView {
reed@android.com3a0cd7f2009-11-17 19:39:51 +0000106 int fCounter;
reed@android.com77f0ef72009-11-17 18:47:52 +0000107 int fProcIndex;
reed@android.com70149062009-11-16 20:39:43 +0000108 SkRect fClip;
109 SkRandom fRand;
reed@android.com77f0ef72009-11-17 18:47:52 +0000110 SkPoint fPts[4];
reed@android.com70149062009-11-16 20:39:43 +0000111
112 void randPts() {
reed@android.com77f0ef72009-11-17 18:47:52 +0000113 for (int i = 0; i < SK_ARRAY_COUNT(fPts); i++) {
114 fPts[i].set(fRand.nextUScalar1() * 640,
115 fRand.nextUScalar1() * 480);
116 }
reed@android.com3a0cd7f2009-11-17 19:39:51 +0000117 fCounter += 1;
reed@android.com70149062009-11-16 20:39:43 +0000118 }
119
120public:
121 LineClipperView() {
reed@android.com3a0cd7f2009-11-17 19:39:51 +0000122 fProcIndex = 1;
123 fCounter = 0;
124
reed@android.com70149062009-11-16 20:39:43 +0000125 int x = (640 - W)/2;
126 int y = (480 - H)/2;
127 fClip.set(x, y, x + W, y + H);
128 this->randPts();
129 }
130
131protected:
132 // overrides from SkEventSink
133 virtual bool onQuery(SkEvent* evt) {
134 if (SampleCode::TitleQ(*evt)) {
135 SampleCode::TitleR(evt, "LineClipper");
136 return true;
137 }
138 return this->INHERITED::onQuery(evt);
139 }
140
141 void drawBG(SkCanvas* canvas) {
142 canvas->drawColor(SK_ColorWHITE);
143 }
144
145 static void drawVLine(SkCanvas* canvas, SkScalar x, const SkPaint& paint) {
146 canvas->drawLine(x, -999, x, 999, paint);
147 }
148
149 static void drawHLine(SkCanvas* canvas, SkScalar y, const SkPaint& paint) {
150 canvas->drawLine(-999, y, 999, y, paint);
151 }
152
reed@android.com70149062009-11-16 20:39:43 +0000153 virtual void onDraw(SkCanvas* canvas) {
154 this->drawBG(canvas);
155
reed@android.com77f0ef72009-11-17 18:47:52 +0000156 SkPaint paint, paint1;
reed@android.com70149062009-11-16 20:39:43 +0000157
158 drawVLine(canvas, fClip.fLeft + SK_ScalarHalf, paint);
159 drawVLine(canvas, fClip.fRight - SK_ScalarHalf, paint);
160 drawHLine(canvas, fClip.fTop + SK_ScalarHalf, paint);
161 drawHLine(canvas, fClip.fBottom - SK_ScalarHalf, paint);
162
163 paint.setColor(SK_ColorLTGRAY);
164 canvas->drawRect(fClip, paint);
165
166 paint.setAntiAlias(true);
167 paint.setColor(SK_ColorBLUE);
reed@android.com77f0ef72009-11-17 18:47:52 +0000168 paint.setStyle(SkPaint::kStroke_Style);
169 // paint.setStrokeWidth(SkIntToScalar(3));
reed@android.com70149062009-11-16 20:39:43 +0000170 paint.setStrokeCap(SkPaint::kRound_Cap);
reed@android.com77f0ef72009-11-17 18:47:52 +0000171
172 paint1.setAntiAlias(true);
173 paint1.setColor(SK_ColorRED);
174 paint1.setStyle(SkPaint::kStroke_Style);
175 gProcs[fProcIndex](fPts, fClip, canvas, paint, paint1);
reed@android.com70149062009-11-16 20:39:43 +0000176
177 if (true) {
178 this->randPts();
179 this->inval(NULL);
180 }
181 }
182
183 virtual SkView::Click* onFindClickHandler(SkScalar x, SkScalar y) {
reed@android.com77f0ef72009-11-17 18:47:52 +0000184 // fProcIndex = (fProcIndex + 1) % SK_ARRAY_COUNT(gProcs);
185 if (x < 50 && y < 50) {
186 this->randPts();
187 }
reed@android.com70149062009-11-16 20:39:43 +0000188 this->inval(NULL);
189 return NULL;
190 }
191
192 virtual bool onClick(Click* click) {
193 return false;
194 }
195
196private:
197 typedef SkView INHERITED;
198};
199
200//////////////////////////////////////////////////////////////////////////////
201
202static SkView* MyFactory() { return new LineClipperView; }
203static SkViewRegister reg(MyFactory);
204