• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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(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 
nextScalarRange(SkRandom & rand,SkScalar min,SkScalar max)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:
CullView()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 
~CullView()130     virtual ~CullView() {
131         delete[] fPoints;
132     }
133 
134 protected:
135     // overrides from SkEventSink
onQuery(SkEvent * evt)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 
onDrawContent(SkCanvas * canvas)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(NULL);
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(NULL);
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 
MyFactory()196 static SkView* MyFactory() { return new CullView; }
197 static SkViewRegister reg(MyFactory);
198