Flutter Engine
The Flutter Engine
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"
15#include "src/base/SkUTF.h"
16#include "src/core/SkBlurMask.h"
17#include "tools/ToolUtils.h"
18#include "tools/viewer/Slide.h"
19
20using namespace skia_private;
21
22////////////////////////////////////////////////////////////////////////////
23
24class ShadowUtilsSlide : public Slide {
25 TArray<SkPath> fConvexPaths;
26 TArray<SkPath> fConcavePaths;
27 SkScalar fZDelta;
28
29 bool fShowAmbient;
30 bool fShowSpot;
31 bool fUseAlt;
32 bool fShowObject;
33 bool fIgnoreShadowAlpha;
34
35public:
37 : fZDelta(0)
38 , fShowAmbient(true)
39 , fShowSpot(true)
40 , fUseAlt(false)
41 , fShowObject(false)
42 , fIgnoreShadowAlpha(false) {
43 fName = "ShadowUtils";
44 }
45
46 void load(SkScalar w, SkScalar h) override {
47 fConvexPaths.push_back().addRoundRect(SkRect::MakeWH(50, 50), 10, 10);
48 SkRRect oddRRect;
49 oddRRect.setNinePatch(SkRect::MakeWH(50, 50), 9, 13, 6, 16);
50 fConvexPaths.push_back().addRRect(oddRRect);
51 fConvexPaths.push_back().addRect(SkRect::MakeWH(50, 50));
52 fConvexPaths.push_back().addCircle(25, 25, 25);
53 fConvexPaths.push_back().cubicTo(100, 50, 20, 100, 0, 0);
54 fConvexPaths.push_back().addOval(SkRect::MakeWH(20, 60));
55
56 // star
57 fConcavePaths.push_back().moveTo(0.0f, -33.3333f);
58 fConcavePaths.back().lineTo(9.62f, -16.6667f);
59 fConcavePaths.back().lineTo(28.867f, -16.6667f);
60 fConcavePaths.back().lineTo(19.24f, 0.0f);
61 fConcavePaths.back().lineTo(28.867f, 16.6667f);
62 fConcavePaths.back().lineTo(9.62f, 16.6667f);
63 fConcavePaths.back().lineTo(0.0f, 33.3333f);
64 fConcavePaths.back().lineTo(-9.62f, 16.6667f);
65 fConcavePaths.back().lineTo(-28.867f, 16.6667f);
66 fConcavePaths.back().lineTo(-19.24f, 0.0f);
67 fConcavePaths.back().lineTo(-28.867f, -16.6667f);
68 fConcavePaths.back().lineTo(-9.62f, -16.6667f);
69 fConcavePaths.back().close();
70
71 // dumbbell
72 fConcavePaths.push_back().moveTo(50, 0);
73 fConcavePaths.back().cubicTo(100, 25, 60, 50, 50, 0);
74 fConcavePaths.back().cubicTo(0, -25, 40, -50, 50, 0);
75 }
76
77 bool onChar(SkUnichar uni) override {
78 bool handled = false;
79 switch (uni) {
80 case 'W':
81 fShowAmbient = !fShowAmbient;
82 handled = true;
83 break;
84 case 'S':
85 fShowSpot = !fShowSpot;
86 handled = true;
87 break;
88 case 'T':
89 fUseAlt = !fUseAlt;
90 handled = true;
91 break;
92 case 'O':
93 fShowObject = !fShowObject;
94 handled = true;
95 break;
96 case '>':
97 fZDelta += 0.5f;
98 handled = true;
99 break;
100 case '<':
101 fZDelta -= 0.5f;
102 handled = true;
103 break;
104 case '?':
105 fIgnoreShadowAlpha = !fIgnoreShadowAlpha;
106 handled = true;
107 break;
108 default:
109 break;
110 }
111 if (handled) {
112 return true;
113 }
114 return false;
115 }
116
117 void draw(SkCanvas* canvas) override {
118 this->drawBG(canvas);
119
120 static constexpr int kW = 800;
121 static constexpr SkScalar kPad = 15.f;
122 static constexpr SkScalar kLightR = 100.f;
123 static constexpr SkScalar kHeight = 50.f;
124 static constexpr SkScalar kAmbientAlpha = 0.5f;
125 static constexpr SkScalar kSpotAlpha = 0.5f;
126 static constexpr SkPoint3 lightPos = { 250, 400, 500 };
127
128 canvas->translate(3 * kPad, 3 * kPad);
129 canvas->save();
130 SkScalar x = 0;
131 SkScalar dy = 0;
132 SkTDArray<SkMatrix> matrices;
133 matrices.append()->reset();
134 matrices.append()->setRotate(33.f, 25.f, 25.f).postScale(1.2f, 0.8f, 25.f, 25.f);
135 SkPaint greenPaint;
136 greenPaint.setColor(SK_ColorGREEN);
137 greenPaint.setAntiAlias(true);
138 SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, std::max(1.0f, kHeight + fZDelta));
139
140 // convex paths
141 for (auto& m : matrices) {
143 for (const auto& path : fConvexPaths) {
144 SkRect postMBounds = path.getBounds();
145 m.mapRect(&postMBounds);
146 SkScalar w = postMBounds.width() + kHeight;
147 SkScalar dx = w + kPad;
148 if (x + dx > kW - 3 * kPad) {
149 canvas->restore();
150 canvas->translate(0, dy);
151 canvas->save();
152 x = 0;
153 dy = 0;
154 }
155
156 canvas->save();
157 canvas->concat(m);
158 this->drawShadowedPath(canvas, path, zPlaneParams, greenPaint, kAmbientAlpha,
159 lightPos, kLightR, kSpotAlpha, flags);
160 canvas->restore();
161
162 canvas->translate(dx, 0);
163 x += dx;
164 dy = std::max(dy, postMBounds.height() + kPad + kHeight);
165 }
166 }
167 }
168
169 // concave paths
170 canvas->restore();
171 canvas->translate(kPad, dy);
172 canvas->save();
173 x = kPad;
174 dy = 0;
175 for (auto& m : matrices) {
176 for (const auto& path : fConcavePaths) {
177 SkRect postMBounds = path.getBounds();
178 m.mapRect(&postMBounds);
179 SkScalar w = postMBounds.width();
180 SkScalar dx = w + kPad;
181
182 canvas->save();
183 canvas->concat(m);
184 this->drawShadowedPath(canvas, path, zPlaneParams, greenPaint, kAmbientAlpha,
185 lightPos, kLightR, kSpotAlpha, kNone_ShadowFlag);
186 canvas->restore();
187
188 canvas->translate(dx, 0);
189 x += dx;
190 dy = std::max(dy, postMBounds.height() + kPad + kHeight);
191 }
192 }
193
194 // Show where the light is in x,y as a circle (specified in device space).
195 SkMatrix invCanvasM = canvas->getTotalMatrix();
196 if (invCanvasM.invert(&invCanvasM)) {
197 canvas->save();
198 canvas->concat(invCanvasM);
199 SkPaint blackPaint;
200 blackPaint.setColor(SK_ColorBLACK);
201 blackPaint.setAntiAlias(true);
202 canvas->drawCircle(lightPos.fX, lightPos.fY, kLightR / 10.f, blackPaint);
203 canvas->restore();
204 }
205 }
206
207private:
208 void drawBG(SkCanvas* canvas) {
209 canvas->drawColor(0xFFFFFFFF);
210 }
211
212 void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
213 const SkPoint3& zPlaneParams,
214 const SkPaint& paint, SkScalar ambientAlpha,
215 const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha,
216 uint32_t flags) {
217 if (fIgnoreShadowAlpha) {
218 ambientAlpha = 255;
219 spotAlpha = 255;
220 }
221 if (!fShowAmbient) {
222 ambientAlpha = 0;
223 }
224 if (!fShowSpot) {
225 spotAlpha = 0;
226 }
227 if (fUseAlt) {
229 }
230
231 SkColor ambientColor = SkColorSetARGB(ambientAlpha * 255, 255, 0, 0);
232 SkColor spotColor = SkColorSetARGB(spotAlpha * 255, 0, 0, 255);
233 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
234 lightPos, lightWidth,
235 ambientColor, spotColor, flags);
236
237 if (fShowObject) {
238 canvas->drawPath(path, paint);
239 } else {
240 SkPaint strokePaint;
241
242 strokePaint.setColor(paint.getColor());
243 strokePaint.setStyle(SkPaint::kStroke_Style);
244
245 canvas->drawPath(path, strokePaint);
246 }
247 }
248};
249
250//////////////////////////////////////////////////////////////////////////////
251
252DEF_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
Definition: SkShadowUtils.h:29
@ kTransparentOccluder_ShadowFlag
Definition: SkShadowUtils.h:27
@ kNone_ShadowFlag
Definition: SkShadowUtils.h:24
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:461
void translate(SkScalar dx, SkScalar dy)
Definition: SkCanvas.cpp:1278
void drawColor(SkColor color, SkBlendMode mode=SkBlendMode::kSrcOver)
Definition: SkCanvas.h:1182
SkMatrix getTotalMatrix() const
Definition: SkCanvas.cpp:1629
int save()
Definition: SkCanvas.cpp:447
void drawPath(const SkPath &path, const SkPaint &paint)
Definition: SkCanvas.cpp:1747
void concat(const SkMatrix &matrix)
Definition: SkCanvas.cpp:1318
void drawCircle(SkScalar cx, SkScalar cy, SkScalar radius, const SkPaint &paint)
Definition: SkCanvas.cpp:2707
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
Definition: SkPath.h:59
SkPath & addCircle(SkScalar x, SkScalar y, SkScalar radius, SkPathDirection dir=SkPathDirection::kCW)
Definition: SkPath.cpp:1213
SkPath & moveTo(SkScalar x, SkScalar y)
Definition: SkPath.cpp:688
SkPath & lineTo(SkScalar x, SkScalar y)
Definition: SkPath.cpp:728
SkPath & addRRect(const SkRRect &rrect, SkPathDirection dir=SkPathDirection::kCW)
Definition: SkPath.cpp:1000
SkPath & addRoundRect(const SkRect &rect, SkScalar rx, SkScalar ry, SkPathDirection dir=SkPathDirection::kCW)
Definition: SkPath.cpp:1093
SkPath & addOval(const SkRect &oval, SkPathDirection dir=SkPathDirection::kCW)
Definition: SkPath.cpp:1106
SkPath & cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3)
Definition: SkPath.cpp:799
SkPath & close()
Definition: SkPath.cpp:823
SkPath & addRect(const SkRect &rect, SkPathDirection dir, unsigned start)
Definition: SkPath.cpp:864
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
Definition: color_source.cc:38
float SkScalar
Definition: extension.cpp:12
FlutterSemanticsFlag flags
static float max(float r, float g, float b)
Definition: hsl.cpp:49
double x
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
Definition: SkRecords.h:208
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
Definition: switches.h:57
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