xref: /aosp_15_r20/external/skia/tools/viewer/ShadowReferenceSlide.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
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  */
8 #include "include/core/SkCanvas.h"
9 #include "include/core/SkImage.h"
10 #include "include/core/SkPath.h"
11 #include "include/core/SkPoint3.h"
12 #include "include/core/SkRRect.h"
13 #include "include/utils/SkShadowUtils.h"
14 #include "tools/DecodeUtils.h"
15 #include "tools/Resources.h"
16 #include "tools/viewer/Slide.h"
17 
18 ////////////////////////////////////////////////////////////////////////////
19 // Sample to compare the Material Design shadow reference to our results
20 
21 class ShadowRefSlide : public Slide {
22     SkPath         fRRectPath;
23     sk_sp<SkImage> fReferenceImage;
24 
25     bool      fShowAmbient;
26     bool      fShowSpot;
27     bool      fUseAlt;
28     bool      fShowObject;
29 
30 public:
ShadowRefSlide()31     ShadowRefSlide()
32         : fShowAmbient(true)
33         , fShowSpot(true)
34         , fUseAlt(false)
35         , fShowObject(true) {
36         fName = "ShadowReference";
37     }
38 
load(SkScalar w,SkScalar h)39     void load(SkScalar w, SkScalar h) override {
40         fRRectPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-130, -128.5, 130, 128.5), 4, 4));
41         fReferenceImage = ToolUtils::GetResourceAsImage("images/shadowreference.png");
42     }
43 
onChar(SkUnichar uni)44     bool onChar(SkUnichar uni) override {
45             bool handled = false;
46             switch (uni) {
47                 case 'W':
48                     fShowAmbient = !fShowAmbient;
49                     handled = true;
50                     break;
51                 case 'S':
52                     fShowSpot = !fShowSpot;
53                     handled = true;
54                     break;
55                 case 'T':
56                     fUseAlt = !fUseAlt;
57                     handled = true;
58                     break;
59                 case 'O':
60                     fShowObject = !fShowObject;
61                     handled = true;
62                     break;
63                 default:
64                     break;
65             }
66             if (handled) {
67                 return true;
68             }
69             return false;
70     }
71 
draw(SkCanvas * canvas)72     void draw(SkCanvas* canvas) override {
73         this->drawBG(canvas);
74         const SkScalar kDP = 4;  // the reference image is 4x bigger than it is displayed on
75                                  // on the web page, so we need to reflect that here and
76                                  // multiply the heights and light params accordingly
77         const SkScalar kLightWidth = kDP*400;
78         const SkScalar kAmbientAlpha = 0.03f;
79         const SkScalar kSpotAlpha = 0.35f;
80 
81         SkPaint paint;
82         paint.setAntiAlias(true);
83         paint.setColor(SK_ColorWHITE);
84 
85         SkPoint3 lightPos = { 175, -800, kDP * 600 };
86         SkScalar xPos = 230;
87         SkScalar yPos = 254.25f;
88         SkRect clipRect = SkRect::MakeXYWH(45, 75, 122, 250);
89         SkPoint clipDelta = SkPoint::Make(320, 0);
90         SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, kDP * 2);
91 
92         canvas->save();
93         canvas->clipRect(clipRect);
94         canvas->translate(xPos, yPos);
95         this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
96                                lightPos, kLightWidth, kSpotAlpha);
97         canvas->restore();
98 
99         lightPos.fX += 320;
100         xPos += 320;
101         clipRect.offset(clipDelta);
102         zPlaneParams.fZ = kDP * 3;
103         canvas->save();
104         canvas->clipRect(clipRect);
105         canvas->translate(xPos, yPos);
106         this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
107                                lightPos, kLightWidth, kSpotAlpha);
108         canvas->restore();
109 
110         lightPos.fX += 320;
111         xPos += 320;
112         clipRect.offset(clipDelta);
113         zPlaneParams.fZ = kDP * 4;
114         canvas->save();
115         canvas->clipRect(clipRect);
116         canvas->translate(xPos, yPos);
117         this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
118                                lightPos, kLightWidth, kSpotAlpha);
119         canvas->restore();
120 
121         lightPos.fX += 320;
122         xPos += 320;
123         clipRect.offset(clipDelta);
124         zPlaneParams.fZ = kDP * 6;
125         canvas->save();
126         canvas->clipRect(clipRect);
127         canvas->translate(xPos, yPos);
128         this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
129                                lightPos, kLightWidth, kSpotAlpha);
130         canvas->restore();
131 
132         lightPos.fX += 320;
133         xPos += 320;
134         clipRect.offset(clipDelta);
135         zPlaneParams.fZ = kDP * 8;
136         canvas->save();
137         canvas->clipRect(clipRect);
138         canvas->translate(xPos, yPos);
139         this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
140                                lightPos, kLightWidth, kSpotAlpha);
141         canvas->restore();
142 
143         lightPos.fX += 320;
144         xPos += 320;
145         clipRect.offset(clipDelta);
146         zPlaneParams.fZ = kDP * 16;
147         canvas->save();
148         canvas->clipRect(clipRect);
149         canvas->translate(xPos, yPos);
150         this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
151                                lightPos, kLightWidth, kSpotAlpha);
152         canvas->restore();
153 
154     }
155 
156 private:
drawBG(SkCanvas * canvas)157     void drawBG(SkCanvas* canvas) {
158         canvas->drawColor(0xFFFFFFFF);
159         canvas->drawImage(fReferenceImage, 10, 30);
160     }
161 
drawShadowedPath(SkCanvas * canvas,const SkPath & path,const SkPoint3 & zPlaneParams,const SkPaint & paint,SkScalar ambientAlpha,const SkPoint3 & lightPos,SkScalar lightWidth,SkScalar spotAlpha)162     void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
163                           const SkPoint3& zPlaneParams,
164                           const SkPaint& paint, SkScalar ambientAlpha,
165                           const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) {
166         if (!fShowAmbient) {
167             ambientAlpha = 0;
168         }
169         if (!fShowSpot) {
170             spotAlpha = 0;
171         }
172         uint32_t flags = 0;
173         if (fUseAlt) {
174             flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
175         }
176 
177         SkColor ambientColor = SkColorSetARGB(ambientAlpha * 255, 0, 0, 0);
178         SkColor spotColor = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
179         SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
180                                   lightPos, lightWidth,
181                                   ambientColor, spotColor, flags);
182 
183         if (fShowObject) {
184             canvas->drawPath(path, paint);
185         } else {
186             SkPaint strokePaint;
187 
188             strokePaint.setColor(paint.getColor());
189             strokePaint.setStyle(SkPaint::kStroke_Style);
190 
191             canvas->drawPath(path, strokePaint);
192         }
193     }
194 };
195 
196 //////////////////////////////////////////////////////////////////////////////
197 
198 DEF_SLIDE( return new ShadowRefSlide(); )
199