• 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(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