OLD | NEW |
| (Empty) |
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 | |
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 | |
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 | |
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(SkScalarRoundToInt(pts[0].fX), | |
83 SkScalarRoundToInt(pts[0].fY)); | |
84 break; | |
85 case SkPath::kLine_Verb: | |
86 array[n++].set(SkScalarRoundToInt(pts[1].fX), | |
87 SkScalarRoundToInt(pts[1].fY)); | |
88 break; | |
89 case SkPath::kDone_Verb: | |
90 goto FINISHED2; | |
91 default: | |
92 break; | |
93 } | |
94 } | |
95 | |
96 FINISHED2: | |
97 *count = n; | |
98 return array; | |
99 } | |
100 | |
101 static SkScalar nextScalarRange(SkRandom& rand, SkScalar min, SkScalar max) { | |
102 return min + SkScalarMul(rand.nextUScalar1(), max - min); | |
103 } | |
104 | |
105 class CullView : public SampleView { | |
106 public: | |
107 CullView() { | |
108 fClip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160)); | |
109 | |
110 SkRandom rand; | |
111 | |
112 for (int i = 0; i < 50; i++) { | |
113 SkScalar x = nextScalarRange(rand, -fClip.width()*1, fClip.width()*2
); | |
114 SkScalar y = nextScalarRange(rand, -fClip.height()*1, fClip.height()
*2); | |
115 if (i == 0) | |
116 fPath.moveTo(x, y); | |
117 else | |
118 fPath.lineTo(x, y); | |
119 } | |
120 | |
121 SkScalar bump = fClip.width()/8; | |
122 subdivide(&fPath, bump); | |
123 subdivide(&fPath, bump); | |
124 subdivide(&fPath, bump); | |
125 fPoints = getpts(fPath, &fPtCount); | |
126 | |
127 this->setBGColor(0xFFDDDDDD); | |
128 } | |
129 | |
130 virtual ~CullView() { | |
131 delete[] fPoints; | |
132 } | |
133 | |
134 protected: | |
135 // overrides from SkEventSink | |
136 virtual bool onQuery(SkEvent* evt) { | |
137 if (SampleCode::TitleQ(*evt)) { | |
138 SampleCode::TitleR(evt, "Culling"); | |
139 return true; | |
140 } | |
141 return this->INHERITED::onQuery(evt); | |
142 } | |
143 | |
144 virtual void onDrawContent(SkCanvas* canvas) { | |
145 SkAutoCanvasRestore ar(canvas, true); | |
146 | |
147 canvas->translate( SkScalarHalf(this->width() - fClip.width()), | |
148 SkScalarHalf(this->height() - fClip.height())); | |
149 | |
150 // canvas->scale(SK_Scalar1*3, SK_Scalar1*3, 0, 0); | |
151 | |
152 SkPaint paint; | |
153 | |
154 // paint.setAntiAliasOn(true); | |
155 paint.setStyle(SkPaint::kStroke_Style); | |
156 | |
157 canvas->drawRect(fClip, paint); | |
158 | |
159 #if 1 | |
160 paint.setColor(0xFF555555); | |
161 paint.setStrokeWidth(SkIntToScalar(2)); | |
162 // paint.setPathEffect(new SkCornerPathEffect(SkIntToScalar(30)))->unref(
); | |
163 canvas->drawPath(fPath, paint); | |
164 // paint.setPathEffect(nullptr); | |
165 #endif | |
166 | |
167 SkPath tmp; | |
168 SkIRect iclip; | |
169 fClip.round(&iclip); | |
170 | |
171 SkCullPointsPath cpp(iclip, &tmp); | |
172 | |
173 cpp.moveTo(fPoints[0].fX, fPoints[0].fY); | |
174 for (int i = 0; i < fPtCount; i++) | |
175 cpp.lineTo(fPoints[i].fX, fPoints[i].fY); | |
176 | |
177 paint.setColor(SK_ColorRED); | |
178 paint.setStrokeWidth(SkIntToScalar(3)); | |
179 paint.setStrokeJoin(SkPaint::kRound_Join); | |
180 canvas->drawPath(tmp, paint); | |
181 | |
182 this->inval(nullptr); | |
183 } | |
184 | |
185 private: | |
186 SkRect fClip; | |
187 SkIPoint* fPoints; | |
188 SkPath fPath; | |
189 int fPtCount; | |
190 | |
191 typedef SampleView INHERITED; | |
192 }; | |
193 | |
194 ////////////////////////////////////////////////////////////////////////////// | |
195 | |
196 static SkView* MyFactory() { return new CullView; } | |
197 static SkViewRegister reg(MyFactory); | |
OLD | NEW |