blob: 19e5aae71cc13a3c2a77b7e394c940099f15bff5 [file] [log] [blame]
Jim Van Verthe7705782017-05-04 14:00:59 -04001
2/*
3 * Copyright 2017 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 "SkAnimTimer.h"
10#include "SkBlurMask.h"
11#include "SkBlurMaskFilter.h"
12#include "SkColorFilter.h"
13#include "SkCamera.h"
14#include "SkCanvas.h"
Jim Van Verthe7705782017-05-04 14:00:59 -040015#include "SkPath.h"
16#include "SkPathOps.h"
17#include "SkPoint3.h"
18#include "SkShadowUtils.h"
19#include "SkUtils.h"
20#include "SkView.h"
21#include "sk_tool_utils.h"
22
23////////////////////////////////////////////////////////////////////////////
24
25class ShadowUtilsView : public SampleView {
26 SkTArray<SkPath> fPaths;
27 SkScalar fZDelta;
28
29 bool fShowAmbient;
30 bool fShowSpot;
31 bool fUseAlt;
32 bool fShowObject;
33 bool fIgnoreShadowAlpha;
34
35public:
36 ShadowUtilsView()
37 : fZDelta(0)
38 , fShowAmbient(true)
39 , fShowSpot(true)
40 , fUseAlt(false)
41 , fShowObject(false)
42 , fIgnoreShadowAlpha(false) {}
43
44protected:
45 void onOnceBeforeDraw() override {
46 fPaths.push_back().addRoundRect(SkRect::MakeWH(50, 50), 10, 10);
47 SkRRect oddRRect;
48 oddRRect.setNinePatch(SkRect::MakeWH(50, 50), 9, 13, 6, 16);
49 fPaths.push_back().addRRect(oddRRect);
50 fPaths.push_back().addRect(SkRect::MakeWH(50, 50));
51 fPaths.push_back().addCircle(25, 25, 25);
52 fPaths.push_back().cubicTo(100, 50, 20, 100, 0, 0);
53 fPaths.push_back().addOval(SkRect::MakeWH(20, 60));
54 }
55
56 // overrides from SkEventSink
57 bool onQuery(SkEvent* evt) override {
58 if (SampleCode::TitleQ(*evt)) {
59 SampleCode::TitleR(evt, "ShadowUtils");
60 return true;
61 }
62
63 SkUnichar uni;
64 if (SampleCode::CharQ(*evt, &uni)) {
65 bool handled = false;
66 switch (uni) {
67 case 'W':
68 fShowAmbient = !fShowAmbient;
69 handled = true;
70 break;
71 case 'S':
72 fShowSpot = !fShowSpot;
73 handled = true;
74 break;
75 case 'T':
76 fUseAlt = !fUseAlt;
77 handled = true;
78 break;
79 case 'O':
80 fShowObject = !fShowObject;
81 handled = true;
82 break;
83 case '>':
84 fZDelta += 0.5f;
85 handled = true;
86 break;
87 case '<':
88 fZDelta -= 0.5f;
89 handled = true;
90 break;
91 case '?':
92 fIgnoreShadowAlpha = !fIgnoreShadowAlpha;
93 handled = true;
94 break;
95 default:
96 break;
97 }
98 if (handled) {
Jim Van Verthe7705782017-05-04 14:00:59 -040099 return true;
100 }
101 }
102 return this->INHERITED::onQuery(evt);
103 }
104
105 void drawBG(SkCanvas* canvas) {
Jim Van Verth8d1e0ac2017-05-05 15:53:23 -0400106 canvas->drawColor(0xFFFFFFFF);
Jim Van Verthe7705782017-05-04 14:00:59 -0400107 }
108
109 void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
Jim Van Verthe308a122017-05-08 14:19:30 -0400110 const SkPoint3& zPlaneParams,
Jim Van Verthe7705782017-05-04 14:00:59 -0400111 const SkPaint& paint, SkScalar ambientAlpha,
112 const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha,
113 uint32_t flags) {
114 if (fIgnoreShadowAlpha) {
115 ambientAlpha = 255;
116 spotAlpha = 255;
117 }
118 if (!fShowAmbient) {
119 ambientAlpha = 0;
120 }
121 if (!fShowSpot) {
122 spotAlpha = 0;
123 }
124 if (fUseAlt) {
125 flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
126 }
Jim Van Vertha5566842018-02-22 10:58:34 -0500127
128 SkColor ambientColor = SkColorSetARGB(ambientAlpha * 255, 255, 0, 0);
129 SkColor spotColor = SkColorSetARGB(spotAlpha * 255, 0, 0, 255);
Jim Van Verth37c5a962017-05-10 14:13:24 -0400130 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
131 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -0500132 ambientColor, spotColor, flags);
Jim Van Verthe7705782017-05-04 14:00:59 -0400133
134 if (fShowObject) {
135 canvas->drawPath(path, paint);
136 } else {
137 SkPaint strokePaint;
138
139 strokePaint.setColor(paint.getColor());
140 strokePaint.setStyle(SkPaint::kStroke_Style);
141
142 canvas->drawPath(path, strokePaint);
143 }
144 }
145
146 void onDrawContent(SkCanvas* canvas) override {
147 this->drawBG(canvas);
148
149 static constexpr int kW = 800;
150 static constexpr SkScalar kPad = 15.f;
Jim Van Verthe7705782017-05-04 14:00:59 -0400151 static constexpr SkScalar kLightR = 100.f;
152 static constexpr SkScalar kHeight = 50.f;
153 static constexpr SkScalar kAmbientAlpha = 0.5f;
154 static constexpr SkScalar kSpotAlpha = 0.5f;
Jim Van Verth8793e382017-05-22 15:52:21 -0400155 static constexpr SkPoint3 lightPos = { 250, 400, 500 };
Jim Van Verth9392f569c2017-05-16 15:01:43 -0400156
Jim Van Verthe7705782017-05-04 14:00:59 -0400157 canvas->translate(3 * kPad, 3 * kPad);
158 canvas->save();
159 SkScalar x = 0;
160 SkScalar dy = 0;
161 SkTDArray<SkMatrix> matrices;
162 matrices.push()->reset();
163 SkMatrix* m = matrices.push();
164 m->setRotate(33.f, 25.f, 25.f);
165 m->postScale(1.2f, 0.8f, 25.f, 25.f);
166 SkPaint paint;
167 paint.setColor(SK_ColorGREEN);
168 paint.setAntiAlias(true);
Jim Van Verthe308a122017-05-08 14:19:30 -0400169 SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, SkTMax(1.0f, kHeight + fZDelta));
Jim Van Verthe7705782017-05-04 14:00:59 -0400170 for (auto& m : matrices) {
171 for (auto flags : { kNone_ShadowFlag, kTransparentOccluder_ShadowFlag }) {
172 for (const auto& path : fPaths) {
173 SkRect postMBounds = path.getBounds();
174 m.mapRect(&postMBounds);
175 SkScalar w = postMBounds.width() + kHeight;
176 SkScalar dx = w + kPad;
177 if (x + dx > kW - 3 * kPad) {
178 canvas->restore();
179 canvas->translate(0, dy);
180 canvas->save();
181 x = 0;
182 dy = 0;
183 }
184
185 canvas->save();
186 canvas->concat(m);
Jim Van Verth9392f569c2017-05-16 15:01:43 -0400187 drawShadowedPath(canvas, path, zPlaneParams, paint, kAmbientAlpha, lightPos,
Jim Van Verthe308a122017-05-08 14:19:30 -0400188 kLightR, kSpotAlpha, flags);
Jim Van Verthe7705782017-05-04 14:00:59 -0400189 canvas->restore();
190
191 canvas->translate(dx, 0);
192 x += dx;
193 dy = SkTMax(dy, postMBounds.height() + kPad + kHeight);
194 }
195 }
196 }
197 // Show where the light is in x,y as a circle (specified in device space).
198 SkMatrix invCanvasM = canvas->getTotalMatrix();
199 if (invCanvasM.invert(&invCanvasM)) {
200 canvas->save();
201 canvas->concat(invCanvasM);
202 SkPaint paint;
203 paint.setColor(SK_ColorBLACK);
204 paint.setAntiAlias(true);
Jim Van Verth9392f569c2017-05-16 15:01:43 -0400205 canvas->drawCircle(lightPos.fX, lightPos.fY, kLightR / 10.f, paint);
Jim Van Verthe7705782017-05-04 14:00:59 -0400206 canvas->restore();
207 }
208 }
209
210private:
211 typedef SampleView INHERITED;
212};
213
214//////////////////////////////////////////////////////////////////////////////
215
216static SkView* MyFactory() { return new ShadowUtilsView; }
217static SkViewRegister reg(MyFactory);