blob: 8d8a0aeaf6367c4028afd1635ce00234c7e122e9 [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"
15#include "SkGaussianEdgeShader.h"
16#include "SkPath.h"
17#include "SkPathOps.h"
18#include "SkPoint3.h"
19#include "SkShadowUtils.h"
20#include "SkUtils.h"
21#include "SkView.h"
22#include "sk_tool_utils.h"
23
24////////////////////////////////////////////////////////////////////////////
25
26class ShadowUtilsView : public SampleView {
27 SkTArray<SkPath> fPaths;
28 SkScalar fZDelta;
29
30 bool fShowAmbient;
31 bool fShowSpot;
32 bool fUseAlt;
33 bool fShowObject;
34 bool fIgnoreShadowAlpha;
35
36public:
37 ShadowUtilsView()
38 : fZDelta(0)
39 , fShowAmbient(true)
40 , fShowSpot(true)
41 , fUseAlt(false)
42 , fShowObject(false)
43 , fIgnoreShadowAlpha(false) {}
44
45protected:
46 void onOnceBeforeDraw() override {
47 fPaths.push_back().addRoundRect(SkRect::MakeWH(50, 50), 10, 10);
48 SkRRect oddRRect;
49 oddRRect.setNinePatch(SkRect::MakeWH(50, 50), 9, 13, 6, 16);
50 fPaths.push_back().addRRect(oddRRect);
51 fPaths.push_back().addRect(SkRect::MakeWH(50, 50));
52 fPaths.push_back().addCircle(25, 25, 25);
53 fPaths.push_back().cubicTo(100, 50, 20, 100, 0, 0);
54 fPaths.push_back().addOval(SkRect::MakeWH(20, 60));
55 }
56
57 // overrides from SkEventSink
58 bool onQuery(SkEvent* evt) override {
59 if (SampleCode::TitleQ(*evt)) {
60 SampleCode::TitleR(evt, "ShadowUtils");
61 return true;
62 }
63
64 SkUnichar uni;
65 if (SampleCode::CharQ(*evt, &uni)) {
66 bool handled = false;
67 switch (uni) {
68 case 'W':
69 fShowAmbient = !fShowAmbient;
70 handled = true;
71 break;
72 case 'S':
73 fShowSpot = !fShowSpot;
74 handled = true;
75 break;
76 case 'T':
77 fUseAlt = !fUseAlt;
78 handled = true;
79 break;
80 case 'O':
81 fShowObject = !fShowObject;
82 handled = true;
83 break;
84 case '>':
85 fZDelta += 0.5f;
86 handled = true;
87 break;
88 case '<':
89 fZDelta -= 0.5f;
90 handled = true;
91 break;
92 case '?':
93 fIgnoreShadowAlpha = !fIgnoreShadowAlpha;
94 handled = true;
95 break;
96 default:
97 break;
98 }
99 if (handled) {
100 this->inval(nullptr);
101 return true;
102 }
103 }
104 return this->INHERITED::onQuery(evt);
105 }
106
107 void drawBG(SkCanvas* canvas) {
Jim Van Verth8d1e0ac2017-05-05 15:53:23 -0400108 canvas->drawColor(0xFFFFFFFF);
Jim Van Verthe7705782017-05-04 14:00:59 -0400109 }
110
111 void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
Jim Van Verthe308a122017-05-08 14:19:30 -0400112 const SkPoint3& zPlaneParams,
Jim Van Verthe7705782017-05-04 14:00:59 -0400113 const SkPaint& paint, SkScalar ambientAlpha,
114 const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha,
115 uint32_t flags) {
116 if (fIgnoreShadowAlpha) {
117 ambientAlpha = 255;
118 spotAlpha = 255;
119 }
120 if (!fShowAmbient) {
121 ambientAlpha = 0;
122 }
123 if (!fShowSpot) {
124 spotAlpha = 0;
125 }
126 if (fUseAlt) {
127 flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
128 }
Jim Van Verth37c5a962017-05-10 14:13:24 -0400129 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
130 lightPos, lightWidth,
131 ambientAlpha, 0, SK_ColorRED, flags);
132 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
133 lightPos, lightWidth,
134 0, spotAlpha, SK_ColorBLUE, flags);
Jim Van Verthe7705782017-05-04 14:00:59 -0400135
136 if (fShowObject) {
137 canvas->drawPath(path, paint);
138 } else {
139 SkPaint strokePaint;
140
141 strokePaint.setColor(paint.getColor());
142 strokePaint.setStyle(SkPaint::kStroke_Style);
143
144 canvas->drawPath(path, strokePaint);
145 }
146 }
147
148 void onDrawContent(SkCanvas* canvas) override {
149 this->drawBG(canvas);
150
151 static constexpr int kW = 800;
152 static constexpr SkScalar kPad = 15.f;
Jim Van Verthe7705782017-05-04 14:00:59 -0400153 static constexpr SkScalar kLightR = 100.f;
154 static constexpr SkScalar kHeight = 50.f;
155 static constexpr SkScalar kAmbientAlpha = 0.5f;
156 static constexpr SkScalar kSpotAlpha = 0.5f;
Jim Van Verth8793e382017-05-22 15:52:21 -0400157 static constexpr SkPoint3 lightPos = { 250, 400, 500 };
Jim Van Verth9392f569c2017-05-16 15:01:43 -0400158
Jim Van Verthe7705782017-05-04 14:00:59 -0400159 canvas->translate(3 * kPad, 3 * kPad);
160 canvas->save();
161 SkScalar x = 0;
162 SkScalar dy = 0;
163 SkTDArray<SkMatrix> matrices;
164 matrices.push()->reset();
165 SkMatrix* m = matrices.push();
166 m->setRotate(33.f, 25.f, 25.f);
167 m->postScale(1.2f, 0.8f, 25.f, 25.f);
168 SkPaint paint;
169 paint.setColor(SK_ColorGREEN);
170 paint.setAntiAlias(true);
Jim Van Verthe308a122017-05-08 14:19:30 -0400171 SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, SkTMax(1.0f, kHeight + fZDelta));
Jim Van Verthe7705782017-05-04 14:00:59 -0400172 for (auto& m : matrices) {
173 for (auto flags : { kNone_ShadowFlag, kTransparentOccluder_ShadowFlag }) {
174 for (const auto& path : fPaths) {
175 SkRect postMBounds = path.getBounds();
176 m.mapRect(&postMBounds);
177 SkScalar w = postMBounds.width() + kHeight;
178 SkScalar dx = w + kPad;
179 if (x + dx > kW - 3 * kPad) {
180 canvas->restore();
181 canvas->translate(0, dy);
182 canvas->save();
183 x = 0;
184 dy = 0;
185 }
186
187 canvas->save();
188 canvas->concat(m);
Jim Van Verth9392f569c2017-05-16 15:01:43 -0400189 drawShadowedPath(canvas, path, zPlaneParams, paint, kAmbientAlpha, lightPos,
Jim Van Verthe308a122017-05-08 14:19:30 -0400190 kLightR, kSpotAlpha, flags);
Jim Van Verthe7705782017-05-04 14:00:59 -0400191 canvas->restore();
192
193 canvas->translate(dx, 0);
194 x += dx;
195 dy = SkTMax(dy, postMBounds.height() + kPad + kHeight);
196 }
197 }
198 }
199 // Show where the light is in x,y as a circle (specified in device space).
200 SkMatrix invCanvasM = canvas->getTotalMatrix();
201 if (invCanvasM.invert(&invCanvasM)) {
202 canvas->save();
203 canvas->concat(invCanvasM);
204 SkPaint paint;
205 paint.setColor(SK_ColorBLACK);
206 paint.setAntiAlias(true);
Jim Van Verth9392f569c2017-05-16 15:01:43 -0400207 canvas->drawCircle(lightPos.fX, lightPos.fY, kLightR / 10.f, paint);
Jim Van Verthe7705782017-05-04 14:00:59 -0400208 canvas->restore();
209 }
210 }
211
212private:
213 typedef SampleView INHERITED;
214};
215
216//////////////////////////////////////////////////////////////////////////////
217
218static SkView* MyFactory() { return new ShadowUtilsView; }
219static SkViewRegister reg(MyFactory);