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