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