blob: 778d0fc6c9bf8af60514f49b7f58032863a4ebab [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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 */
reed@android.com8a1c16f2008-12-17 15:59:43 +00008#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
reed@google.com961ddb02011-05-05 14:03:48 +000020static void addbump(SkPath* path, const SkPoint pts[2], SkScalar bump) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000021 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
reed@google.com961ddb02011-05-05 14:03:48 +000030static void subdivide(SkPath* path, SkScalar bump) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000031 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
50FINISH:
51 path->swap(tmp);
52}
53
reed@google.com961ddb02011-05-05 14:03:48 +000054static SkIPoint* getpts(const SkPath& path, int* count) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000055 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
73FINISHED:
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
94FINISHED2:
95 *count = n;
96 return array;
97}
98
reed@google.com961ddb02011-05-05 14:03:48 +000099static SkScalar nextScalarRange(SkRandom& rand, SkScalar min, SkScalar max) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000100 return min + SkScalarMul(rand.nextUScalar1(), max - min);
101}
102
reed@google.com961ddb02011-05-05 14:03:48 +0000103class CullView : public SampleView {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000104public:
reed@google.com961ddb02011-05-05 14:03:48 +0000105 CullView() {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000106 fClip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
107
108 SkRandom rand;
109
110 for (int i = 0; i < 50; i++) {
reed@google.com261b8e22011-04-14 17:53:24 +0000111 SkScalar x = nextScalarRange(rand, -fClip.width()*1, fClip.width()*2);
112 SkScalar y = nextScalarRange(rand, -fClip.height()*1, fClip.height()*2);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000113 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);
reed@google.com961ddb02011-05-05 14:03:48 +0000124
125 this->setBGColor(0xFFDDDDDD);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000126 }
127
reed@google.com961ddb02011-05-05 14:03:48 +0000128 virtual ~CullView() {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000129 delete[] fPoints;
130 }
131
132protected:
133 // overrides from SkEventSink
reed@google.com961ddb02011-05-05 14:03:48 +0000134 virtual bool onQuery(SkEvent* evt) {
135 if (SampleCode::TitleQ(*evt)) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000136 SampleCode::TitleR(evt, "Culling");
137 return true;
138 }
139 return this->INHERITED::onQuery(evt);
140 }
141
reed@google.com961ddb02011-05-05 14:03:48 +0000142 virtual void onDrawContent(SkCanvas* canvas) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000143 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
reed@android.com8a1c16f2008-12-17 15:59:43 +0000183private:
184 SkRect fClip;
185 SkIPoint* fPoints;
186 SkPath fPath;
187 int fPtCount;
188
reed@google.com961ddb02011-05-05 14:03:48 +0000189 typedef SampleView INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000190};
191
192//////////////////////////////////////////////////////////////////////////////
193
194static SkView* MyFactory() { return new CullView; }
195static SkViewRegister reg(MyFactory);
196