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