1 #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
addbump(SkPath * path,const SkPoint pts[2],SkScalar bump)13 static void addbump(SkPath* path, const SkPoint pts[2], SkScalar bump) {
14 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
subdivide(SkPath * path,SkScalar bump)23 static void subdivide(SkPath* path, SkScalar bump) {
24 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
43 FINISH:
44 path->swap(tmp);
45 }
46
getpts(const SkPath & path,int * count)47 static SkIPoint* getpts(const SkPath& path, int* count) {
48 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
66 FINISHED:
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
87 FINISHED2:
88 *count = n;
89 return array;
90 }
91
nextScalarRange(SkRandom & rand,SkScalar min,SkScalar max)92 static SkScalar nextScalarRange(SkRandom& rand, SkScalar min, SkScalar max) {
93 return min + SkScalarMul(rand.nextUScalar1(), max - min);
94 }
95
96 class CullView : public SampleView {
97 public:
CullView()98 CullView() {
99 fClip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
100
101 SkRandom rand;
102
103 for (int i = 0; i < 50; i++) {
104 SkScalar x = nextScalarRange(rand, -fClip.width()*1, fClip.width()*2);
105 SkScalar y = nextScalarRange(rand, -fClip.height()*1, fClip.height()*2);
106 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);
117
118 this->setBGColor(0xFFDDDDDD);
119 }
120
~CullView()121 virtual ~CullView() {
122 delete[] fPoints;
123 }
124
125 protected:
126 // overrides from SkEventSink
onQuery(SkEvent * evt)127 virtual bool onQuery(SkEvent* evt) {
128 if (SampleCode::TitleQ(*evt)) {
129 SampleCode::TitleR(evt, "Culling");
130 return true;
131 }
132 return this->INHERITED::onQuery(evt);
133 }
134
onDrawContent(SkCanvas * canvas)135 virtual void onDrawContent(SkCanvas* canvas) {
136 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
176 private:
177 SkRect fClip;
178 SkIPoint* fPoints;
179 SkPath fPath;
180 int fPtCount;
181
182 typedef SampleView INHERITED;
183 };
184
185 //////////////////////////////////////////////////////////////////////////////
186
MyFactory()187 static SkView* MyFactory() { return new CullView; }
188 static SkViewRegister reg(MyFactory);
189
190