blob: 7b4eab605d53999c49a70c7933a69a1cd0132625 [file] [log] [blame]
reed@android.com8a1c16f2008-12-17 15:59:43 +00001#include "SampleCode.h"
2#include "SkView.h"
3#include "SkCanvas.h"
4#include "SkCornerPathEffect.h"
5#include "SkCullPoints.h"
6#include "SkGradientShader.h"
7#include "SkPath.h"
8#include "SkRegion.h"
9#include "SkShader.h"
10#include "SkUtils.h"
11#include "SkRandom.h"
12
reed@google.com961ddb02011-05-05 14:03:48 +000013static void addbump(SkPath* path, const SkPoint pts[2], SkScalar bump) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000014 SkVector tang;
15
16 tang.setLength(pts[1].fX - pts[0].fX, pts[1].fY - pts[0].fY, bump);
17
18 path->lineTo(SkScalarHalf(pts[0].fX + pts[1].fX) - tang.fY,
19 SkScalarHalf(pts[0].fY + pts[1].fY) + tang.fX);
20 path->lineTo(pts[1]);
21}
22
reed@google.com961ddb02011-05-05 14:03:48 +000023static void subdivide(SkPath* path, SkScalar bump) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000024 SkPath::Iter iter(*path, false);
25 SkPoint pts[4];
26 SkPath tmp;
27
28 for (;;)
29 switch (iter.next(pts)) {
30 case SkPath::kMove_Verb:
31 tmp.moveTo(pts[0]);
32 break;
33 case SkPath::kLine_Verb:
34 addbump(&tmp, pts, bump);
35 bump = -bump;
36 break;
37 case SkPath::kDone_Verb:
38 goto FINISH;
39 default:
40 break;
41 }
42
43FINISH:
44 path->swap(tmp);
45}
46
reed@google.com961ddb02011-05-05 14:03:48 +000047static SkIPoint* getpts(const SkPath& path, int* count) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000048 SkPoint pts[4];
49 int n = 1;
50 SkIPoint* array;
51
52 {
53 SkPath::Iter iter(path, false);
54 for (;;)
55 switch (iter.next(pts)) {
56 case SkPath::kLine_Verb:
57 n += 1;
58 break;
59 case SkPath::kDone_Verb:
60 goto FINISHED;
61 default:
62 break;
63 }
64 }
65
66FINISHED:
67 array = new SkIPoint[n];
68 n = 0;
69
70 {
71 SkPath::Iter iter(path, false);
72 for (;;)
73 switch (iter.next(pts)) {
74 case SkPath::kMove_Verb:
75 array[n++].set(SkScalarRound(pts[0].fX), SkScalarRound(pts[0].fY));
76 break;
77 case SkPath::kLine_Verb:
78 array[n++].set(SkScalarRound(pts[1].fX), SkScalarRound(pts[1].fY));
79 break;
80 case SkPath::kDone_Verb:
81 goto FINISHED2;
82 default:
83 break;
84 }
85 }
86
87FINISHED2:
88 *count = n;
89 return array;
90}
91
reed@google.com961ddb02011-05-05 14:03:48 +000092static SkScalar nextScalarRange(SkRandom& rand, SkScalar min, SkScalar max) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000093 return min + SkScalarMul(rand.nextUScalar1(), max - min);
94}
95
reed@google.com961ddb02011-05-05 14:03:48 +000096class CullView : public SampleView {
reed@android.com8a1c16f2008-12-17 15:59:43 +000097public:
reed@google.com961ddb02011-05-05 14:03:48 +000098 CullView() {
reed@android.com8a1c16f2008-12-17 15:59:43 +000099 fClip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
100
101 SkRandom rand;
102
103 for (int i = 0; i < 50; i++) {
reed@google.com261b8e22011-04-14 17:53:24 +0000104 SkScalar x = nextScalarRange(rand, -fClip.width()*1, fClip.width()*2);
105 SkScalar y = nextScalarRange(rand, -fClip.height()*1, fClip.height()*2);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000106 if (i == 0)
107 fPath.moveTo(x, y);
108 else
109 fPath.lineTo(x, y);
110 }
111
112 SkScalar bump = fClip.width()/8;
113 subdivide(&fPath, bump);
114 subdivide(&fPath, bump);
115 subdivide(&fPath, bump);
116 fPoints = getpts(fPath, &fPtCount);
reed@google.com961ddb02011-05-05 14:03:48 +0000117
118 this->setBGColor(0xFFDDDDDD);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000119 }
120
reed@google.com961ddb02011-05-05 14:03:48 +0000121 virtual ~CullView() {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000122 delete[] fPoints;
123 }
124
125protected:
126 // overrides from SkEventSink
reed@google.com961ddb02011-05-05 14:03:48 +0000127 virtual bool onQuery(SkEvent* evt) {
128 if (SampleCode::TitleQ(*evt)) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000129 SampleCode::TitleR(evt, "Culling");
130 return true;
131 }
132 return this->INHERITED::onQuery(evt);
133 }
134
reed@google.com961ddb02011-05-05 14:03:48 +0000135 virtual void onDrawContent(SkCanvas* canvas) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000136 SkAutoCanvasRestore ar(canvas, true);
137
138 canvas->translate( SkScalarHalf(this->width() - fClip.width()),
139 SkScalarHalf(this->height() - fClip.height()));
140
141 // canvas->scale(SK_Scalar1*3, SK_Scalar1*3, 0, 0);
142
143 SkPaint paint;
144
145 // paint.setAntiAliasOn(true);
146 paint.setStyle(SkPaint::kStroke_Style);
147
148 canvas->drawRect(fClip, paint);
149
150#if 1
151 paint.setColor(0xFF555555);
152 paint.setStrokeWidth(SkIntToScalar(2));
153// paint.setPathEffect(new SkCornerPathEffect(SkIntToScalar(30)))->unref();
154 canvas->drawPath(fPath, paint);
155// paint.setPathEffect(NULL);
156#endif
157
158 SkPath tmp;
159 SkIRect iclip;
160 fClip.round(&iclip);
161
162 SkCullPointsPath cpp(iclip, &tmp);
163
164 cpp.moveTo(fPoints[0].fX, fPoints[0].fY);
165 for (int i = 0; i < fPtCount; i++)
166 cpp.lineTo(fPoints[i].fX, fPoints[i].fY);
167
168 paint.setColor(SK_ColorRED);
169 paint.setStrokeWidth(SkIntToScalar(3));
170 paint.setStrokeJoin(SkPaint::kRound_Join);
171 canvas->drawPath(tmp, paint);
172
173 this->inval(NULL);
174 }
175
reed@android.com8a1c16f2008-12-17 15:59:43 +0000176private:
177 SkRect fClip;
178 SkIPoint* fPoints;
179 SkPath fPath;
180 int fPtCount;
181
reed@google.com961ddb02011-05-05 14:03:48 +0000182 typedef SampleView INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000183};
184
185//////////////////////////////////////////////////////////////////////////////
186
187static SkView* MyFactory() { return new CullView; }
188static SkViewRegister reg(MyFactory);
189