blob: 011b22f9e79b07add8dd6798dc3f8ca284c940bb [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;
rmistry@google.comae933ce2012-08-23 18:19:56 +000022
reed@android.com8a1c16f2008-12-17 15:59:43 +000023 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;
rmistry@google.comae933ce2012-08-23 18:19:56 +000034
reed@android.com8a1c16f2008-12-17 15:59:43 +000035 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:
reed@google.come1ca7052013-12-17 19:22:07 +000082 array[n++].set(SkScalarRoundToInt(pts[0].fX),
83 SkScalarRoundToInt(pts[0].fY));
reed@android.com8a1c16f2008-12-17 15:59:43 +000084 break;
85 case SkPath::kLine_Verb:
reed@google.come1ca7052013-12-17 19:22:07 +000086 array[n++].set(SkScalarRoundToInt(pts[1].fX),
87 SkScalarRoundToInt(pts[1].fY));
reed@android.com8a1c16f2008-12-17 15:59:43 +000088 break;
89 case SkPath::kDone_Verb:
90 goto FINISHED2;
91 default:
92 break;
93 }
94 }
rmistry@google.comae933ce2012-08-23 18:19:56 +000095
reed@android.com8a1c16f2008-12-17 15:59:43 +000096FINISHED2:
97 *count = n;
98 return array;
99}
100
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000101static SkScalar nextScalarRange(SkRandom& rand, SkScalar min, SkScalar max) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000102 return min + SkScalarMul(rand.nextUScalar1(), max - min);
103}
104
reed@google.com961ddb02011-05-05 14:03:48 +0000105class CullView : public SampleView {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000106public:
rmistry@google.comae933ce2012-08-23 18:19:56 +0000107 CullView() {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000108 fClip.set(0, 0, SkIntToScalar(160), SkIntToScalar(160));
rmistry@google.comae933ce2012-08-23 18:19:56 +0000109
commit-bot@chromium.orge0e7cfe2013-09-09 20:09:12 +0000110 SkRandom rand;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000111
reed@android.com8a1c16f2008-12-17 15:59:43 +0000112 for (int i = 0; i < 50; i++) {
reed@google.com261b8e22011-04-14 17:53:24 +0000113 SkScalar x = nextScalarRange(rand, -fClip.width()*1, fClip.width()*2);
114 SkScalar y = nextScalarRange(rand, -fClip.height()*1, fClip.height()*2);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000115 if (i == 0)
116 fPath.moveTo(x, y);
117 else
118 fPath.lineTo(x, y);
119 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000120
reed@android.com8a1c16f2008-12-17 15:59:43 +0000121 SkScalar bump = fClip.width()/8;
122 subdivide(&fPath, bump);
123 subdivide(&fPath, bump);
124 subdivide(&fPath, bump);
125 fPoints = getpts(fPath, &fPtCount);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000126
reed@google.com961ddb02011-05-05 14:03:48 +0000127 this->setBGColor(0xFFDDDDDD);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000128 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000129
reed@google.com961ddb02011-05-05 14:03:48 +0000130 virtual ~CullView() {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000131 delete[] fPoints;
132 }
133
134protected:
135 // overrides from SkEventSink
reed@google.com961ddb02011-05-05 14:03:48 +0000136 virtual bool onQuery(SkEvent* evt) {
137 if (SampleCode::TitleQ(*evt)) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000138 SampleCode::TitleR(evt, "Culling");
139 return true;
140 }
141 return this->INHERITED::onQuery(evt);
142 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000143
reed@google.com961ddb02011-05-05 14:03:48 +0000144 virtual void onDrawContent(SkCanvas* canvas) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000145 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;
rmistry@google.comae933ce2012-08-23 18:19:56 +0000153
reed@android.com8a1c16f2008-12-17 15:59:43 +0000154 // 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);
halcanary96fcdcc2015-08-27 07:41:13 -0700164// paint.setPathEffect(nullptr);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000165#endif
166
167 SkPath tmp;
168 SkIRect iclip;
169 fClip.round(&iclip);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000170
reed@android.com8a1c16f2008-12-17 15:59:43 +0000171 SkCullPointsPath cpp(iclip, &tmp);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000172
reed@android.com8a1c16f2008-12-17 15:59:43 +0000173 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);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000176
reed@android.com8a1c16f2008-12-17 15:59:43 +0000177 paint.setColor(SK_ColorRED);
178 paint.setStrokeWidth(SkIntToScalar(3));
179 paint.setStrokeJoin(SkPaint::kRound_Join);
180 canvas->drawPath(tmp, paint);
rmistry@google.comae933ce2012-08-23 18:19:56 +0000181
halcanary96fcdcc2015-08-27 07:41:13 -0700182 this->inval(nullptr);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000183 }
rmistry@google.comae933ce2012-08-23 18:19:56 +0000184
reed@android.com8a1c16f2008-12-17 15:59:43 +0000185private:
186 SkRect fClip;
187 SkIPoint* fPoints;
188 SkPath fPath;
189 int fPtCount;
190
reed@google.com961ddb02011-05-05 14:03:48 +0000191 typedef SampleView INHERITED;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000192};
193
194//////////////////////////////////////////////////////////////////////////////
195
196static SkView* MyFactory() { return new CullView; }
197static SkViewRegister reg(MyFactory);