• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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