Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
ShadowUtilsSlide.cpp
Go to the documentation of this file.
1
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 */
10#include "include/core/SkPath.h"
16#include "src/base/SkUTF.h"
17#include "src/core/SkBlurMask.h"
18#include "tools/ToolUtils.h"
19#include "tools/viewer/Slide.h"
20
21using namespace skia_private;
22
23////////////////////////////////////////////////////////////////////////////
24
25class ShadowUtilsSlide : public Slide {
26 TArray<SkPath> fConvexPaths;
27 TArray<SkPath> fConcavePaths;
28 SkScalar fZDelta;
29
30 bool fShowAmbient;
31 bool fShowSpot;
32 bool fUseAlt;
33 bool fShowObject;
34 bool fIgnoreShadowAlpha;
35
36public:
38 : fZDelta(0)
39 , fShowAmbient(true)
40 , fShowSpot(true)
41 , fUseAlt(false)
42 , fShowObject(false)
43 , fIgnoreShadowAlpha(false) {
44 fName = "ShadowUtils";
45 }
46
47 void load(SkScalar w, SkScalar h) override {
48 fConvexPaths.push_back().addRoundRect(SkRect::MakeWH(50, 50), 10, 10);
49 SkRRect oddRRect;
50 oddRRect.setNinePatch(SkRect::MakeWH(50, 50), 9, 13, 6, 16);
51 fConvexPaths.push_back().addRRect(oddRRect);
52 fConvexPaths.push_back().addRect(SkRect::MakeWH(50, 50));
53 fConvexPaths.push_back().addCircle(25, 25, 25);
54 fConvexPaths.push_back().cubicTo(100, 50, 20, 100, 0, 0);
55 fConvexPaths.push_back().addOval(SkRect::MakeWH(20, 60));
56
57 // star
58 fConcavePaths.push_back().moveTo(0.0f, -33.3333f);
59 fConcavePaths.back().lineTo(9.62f, -16.6667f);
60 fConcavePaths.back().lineTo(28.867f, -16.6667f);
61 fConcavePaths.back().lineTo(19.24f, 0.0f);
62 fConcavePaths.back().lineTo(28.867f, 16.6667f);
63 fConcavePaths.back().lineTo(9.62f, 16.6667f);
64 fConcavePaths.back().lineTo(0.0f, 33.3333f);
65 fConcavePaths.back().lineTo(-9.62f, 16.6667f);
66 fConcavePaths.back().lineTo(-28.867f, 16.6667f);
67 fConcavePaths.back().lineTo(-19.24f, 0.0f);
68 fConcavePaths.back().lineTo(-28.867f, -16.6667f);
69 fConcavePaths.back().lineTo(-9.62f, -16.6667f);
70 fConcavePaths.back().close();
71
72 // dumbbell
73 fConcavePaths.push_back().moveTo(50, 0);
74 fConcavePaths.back().cubicTo(100, 25, 60, 50, 50, 0);
75 fConcavePaths.back().cubicTo(0, -25, 40, -50, 50, 0);
76 }
77
78 bool onChar(SkUnichar uni) override {
79 bool handled = false;
80 switch (uni) {
81 case 'W':
82 fShowAmbient = !fShowAmbient;
83 handled = true;
84 break;
85 case 'S':
86 fShowSpot = !fShowSpot;
87 handled = true;
88 break;
89 case 'T':
90 fUseAlt = !fUseAlt;
91 handled = true;
92 break;
93 case 'O':
94 fShowObject = !fShowObject;
95 handled = true;
96 break;
97 case '>':
98 fZDelta += 0.5f;
99 handled = true;
100 break;
101 case '<':
102 fZDelta -= 0.5f;
103 handled = true;
104 break;
105 case '?':
106 fIgnoreShadowAlpha = !fIgnoreShadowAlpha;
107 handled = true;
108 break;
109 default:
110 break;
111 }
112 if (handled) {
113 return true;
114 }
115 return false;
116 }
117
118 void draw(SkCanvas* canvas) override {
119 this->drawBG(canvas);
120
121 static constexpr int kW = 800;
122 static constexpr SkScalar kPad = 15.f;
123 static constexpr SkScalar kLightR = 100.f;
124 static constexpr SkScalar kHeight = 50.f;
125 static constexpr SkScalar kAmbientAlpha = 0.5f;
126 static constexpr SkScalar kSpotAlpha = 0.5f;
127 static constexpr SkPoint3 lightPos = { 250, 400, 500 };
128
129 canvas->translate(3 * kPad, 3 * kPad);
130 canvas->save();
131 SkScalar x = 0;
132 SkScalar dy = 0;
133 SkTDArray<SkMatrix> matrices;
134 matrices.append()->reset();
135 matrices.append()->setRotate(33.f, 25.f, 25.f).postScale(1.2f, 0.8f, 25.f, 25.f);
136 SkPaint greenPaint;
137 greenPaint.setColor(SK_ColorGREEN);
138 greenPaint.setAntiAlias(true);
139 SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, std::max(1.0f, kHeight + fZDelta));
140
141 // convex paths
142 for (auto& m : matrices) {
144 for (const auto& path : fConvexPaths) {
145 SkRect postMBounds = path.getBounds();
146 m.mapRect(&postMBounds);
147 SkScalar w = postMBounds.width() + kHeight;
148 SkScalar dx = w + kPad;
149 if (x + dx > kW - 3 * kPad) {
150 canvas->restore();
151 canvas->translate(0, dy);
152 canvas->save();
153 x = 0;
154 dy = 0;
155 }
156
157 canvas->save();
158 canvas->concat(m);
159 this->drawShadowedPath(canvas, path, zPlaneParams, greenPaint, kAmbientAlpha,
160 lightPos, kLightR, kSpotAlpha, flags);
161 canvas->restore();
162
163 canvas->translate(dx, 0);
164 x += dx;
165 dy = std::max(dy, postMBounds.height() + kPad + kHeight);
166 }
167 }
168 }
169
170 // concave paths
171 canvas->restore();
172 canvas->translate(kPad, dy);
173 canvas->save();
174 x = kPad;
175 dy = 0;
176 for (auto& m : matrices) {
177 for (const auto& path : fConcavePaths) {
178 SkRect postMBounds = path.getBounds();
179 m.mapRect(&postMBounds);
180 SkScalar w = postMBounds.width();
181 SkScalar dx = w + kPad;
182
183 canvas->save();
184 canvas->concat(m);
185 this->drawShadowedPath(canvas, path, zPlaneParams, greenPaint, kAmbientAlpha,
186 lightPos, kLightR, kSpotAlpha, kNone_ShadowFlag);
187 canvas->restore();
188
189 canvas->translate(dx, 0);
190 x += dx;
191 dy = std::max(dy, postMBounds.height() + kPad + kHeight);
192 }
193 }
194
195 // Show where the light is in x,y as a circle (specified in device space).
196 SkMatrix invCanvasM = canvas->getTotalMatrix();
197 if (invCanvasM.invert(&invCanvasM)) {
198 canvas->save();
199 canvas->concat(invCanvasM);
200 SkPaint blackPaint;
201 blackPaint.setColor(SK_ColorBLACK);
202 blackPaint.setAntiAlias(true);
203 canvas->drawCircle(lightPos.fX, lightPos.fY, kLightR / 10.f, blackPaint);
204 canvas->restore();
205 }
206 }
207
208private:
209 void drawBG(SkCanvas* canvas) {
210 canvas->drawColor(0xFFFFFFFF);
211 }
212
213 void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
214 const SkPoint3& zPlaneParams,
215 const SkPaint& paint, SkScalar ambientAlpha,
216 const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha,
217 uint32_t flags) {
218 if (fIgnoreShadowAlpha) {
219 ambientAlpha = 255;
220 spotAlpha = 255;
221 }
222 if (!fShowAmbient) {
223 ambientAlpha = 0;
224 }
225 if (!fShowSpot) {
226 spotAlpha = 0;
227 }
228 if (fUseAlt) {
230 }
231
232 SkColor ambientColor = SkColorSetARGB(ambientAlpha * 255, 255, 0, 0);
233 SkColor spotColor = SkColorSetARGB(spotAlpha * 255, 0, 0, 255);
234 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
235 lightPos, lightWidth,
236 ambientColor, spotColor, flags);
237
238 if (fShowObject) {
239 canvas->drawPath(path, paint);
240 } else {
241 SkPaint strokePaint;
242
243 strokePaint.setColor(paint.getColor());
244 strokePaint.setStyle(SkPaint::kStroke_Style);
245
246 canvas->drawPath(path, strokePaint);
247 }
248 }
249};
250
251//////////////////////////////////////////////////////////////////////////////
252
253DEF_SLIDE( return new ShadowUtilsSlide(); )
uint32_t SkColor
Definition SkColor.h:37
static constexpr SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition SkColor.h:49
constexpr SkColor SK_ColorBLACK
Definition SkColor.h:103
constexpr SkColor SK_ColorGREEN
Definition SkColor.h:131
@ kGeometricOnly_ShadowFlag
@ kTransparentOccluder_ShadowFlag
@ kNone_ShadowFlag
int32_t SkUnichar
Definition SkTypes.h:175
#define DEF_SLIDE(code)
Definition Slide.h:25
constexpr int kPad
constexpr int kW
void draw(SkCanvas *canvas) override
void load(SkScalar w, SkScalar h) override
bool onChar(SkUnichar uni) override
void restore()
Definition SkCanvas.cpp:465
void translate(SkScalar dx, SkScalar dy)
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
Definition SkCanvas.h:1182
SkMatrix getTotalMatrix() const
int save()
Definition SkCanvas.cpp:451
void drawPath(const SkPath &path, const SkPaint &paint)
void concat(const SkMatrix &matrix)
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint &paint)
bool invert(SkMatrix *inverse) const
Definition SkMatrix.h:1206
void setStyle(Style style)
Definition SkPaint.cpp:105
void setColor(SkColor color)
Definition SkPaint.cpp:119
void setAntiAlias(bool aa)
Definition SkPaint.h:170
@ kStroke_Style
set to stroke geometry
Definition SkPaint.h:194
void setNinePatch(const SkRect &rect, SkScalar leftRad, SkScalar topRad, SkScalar rightRad, SkScalar bottomRad)
Definition SkRRect.cpp:115
static void DrawShadow(SkCanvas *canvas, const SkPath &path, const SkPoint3 &zPlaneParams, const SkPoint3 &lightPos, SkScalar lightRadius, SkColor ambientColor, SkColor spotColor, uint32_t flags=SkShadowFlags::kNone_ShadowFlag)
T * append()
Definition SkTDArray.h:191
Definition Slide.h:29
SkString fName
Definition Slide.h:54
const Paint & paint
float SkScalar
Definition extension.cpp:12
FlutterSemanticsFlag flags
double x
SkScalar w
SkScalar h
SkScalar fX
Definition SkPoint3.h:16
static SkPoint3 Make(SkScalar x, SkScalar y, SkScalar z)
Definition SkPoint3.h:18
SkScalar fY
Definition SkPoint3.h:16
constexpr float height() const
Definition SkRect.h:769
constexpr float width() const
Definition SkRect.h:762
static constexpr SkRect MakeWH(float w, float h)
Definition SkRect.h:609
constexpr size_t kHeight