• 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/utils/SkShadowUtils.h"
13 #include "samplecode/Sample.h"
14 #include "tools/Resources.h"
15 
16 ////////////////////////////////////////////////////////////////////////////
17 // Sample to compare the Material Design shadow reference to our results
18 
19 class ShadowRefView : public Sample {
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 
name()41     SkString name() override { return SkString("ShadowReference"); }
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 
drawBG(SkCanvas * canvas)71     void drawBG(SkCanvas* canvas) {
72         canvas->drawColor(0xFFFFFFFF);
73         canvas->drawImage(fReferenceImage, 10, 30);
74     }
75 
drawShadowedPath(SkCanvas * canvas,const SkPath & path,const SkPoint3 & zPlaneParams,const SkPaint & paint,SkScalar ambientAlpha,const SkPoint3 & lightPos,SkScalar lightWidth,SkScalar spotAlpha)76     void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
77                           const SkPoint3& zPlaneParams,
78                           const SkPaint& paint, SkScalar ambientAlpha,
79                           const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) {
80         if (!fShowAmbient) {
81             ambientAlpha = 0;
82         }
83         if (!fShowSpot) {
84             spotAlpha = 0;
85         }
86         uint32_t flags = 0;
87         if (fUseAlt) {
88             flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
89         }
90 
91         SkColor ambientColor = SkColorSetARGB(ambientAlpha * 255, 0, 0, 0);
92         SkColor spotColor = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
93         SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
94                                   lightPos, lightWidth,
95                                   ambientColor, spotColor, flags);
96 
97         if (fShowObject) {
98             canvas->drawPath(path, paint);
99         } else {
100             SkPaint strokePaint;
101 
102             strokePaint.setColor(paint.getColor());
103             strokePaint.setStyle(SkPaint::kStroke_Style);
104 
105             canvas->drawPath(path, strokePaint);
106         }
107     }
108 
onDrawContent(SkCanvas * canvas)109     void onDrawContent(SkCanvas* canvas) override {
110         this->drawBG(canvas);
111         const SkScalar kDP = 4;  // the reference image is 4x bigger than it is displayed on
112                                  // on the web page, so we need to reflect that here and
113                                  // multiply the heights and light params accordingly
114         const SkScalar kLightWidth = kDP*400;
115         const SkScalar kAmbientAlpha = 0.03f;
116         const SkScalar kSpotAlpha = 0.35f;
117 
118         SkPaint paint;
119         paint.setAntiAlias(true);
120         paint.setColor(SK_ColorWHITE);
121 
122         SkPoint3 lightPos = { 175, -800, kDP * 600 };
123         SkScalar xPos = 230;
124         SkScalar yPos = 254.25f;
125         SkRect clipRect = SkRect::MakeXYWH(45, 75, 122, 250);
126         SkPoint clipDelta = SkPoint::Make(320, 0);
127         SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, kDP * 2);
128 
129         canvas->save();
130         canvas->clipRect(clipRect);
131         canvas->translate(xPos, yPos);
132         this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
133                                lightPos, kLightWidth, kSpotAlpha);
134         canvas->restore();
135 
136         lightPos.fX += 320;
137         xPos += 320;
138         clipRect.offset(clipDelta);
139         zPlaneParams.fZ = kDP * 3;
140         canvas->save();
141         canvas->clipRect(clipRect);
142         canvas->translate(xPos, yPos);
143         this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
144                                lightPos, kLightWidth, kSpotAlpha);
145         canvas->restore();
146 
147         lightPos.fX += 320;
148         xPos += 320;
149         clipRect.offset(clipDelta);
150         zPlaneParams.fZ = kDP * 4;
151         canvas->save();
152         canvas->clipRect(clipRect);
153         canvas->translate(xPos, yPos);
154         this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
155                                lightPos, kLightWidth, kSpotAlpha);
156         canvas->restore();
157 
158         lightPos.fX += 320;
159         xPos += 320;
160         clipRect.offset(clipDelta);
161         zPlaneParams.fZ = kDP * 6;
162         canvas->save();
163         canvas->clipRect(clipRect);
164         canvas->translate(xPos, yPos);
165         this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
166                                lightPos, kLightWidth, kSpotAlpha);
167         canvas->restore();
168 
169         lightPos.fX += 320;
170         xPos += 320;
171         clipRect.offset(clipDelta);
172         zPlaneParams.fZ = kDP * 8;
173         canvas->save();
174         canvas->clipRect(clipRect);
175         canvas->translate(xPos, yPos);
176         this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
177                                lightPos, kLightWidth, kSpotAlpha);
178         canvas->restore();
179 
180         lightPos.fX += 320;
181         xPos += 320;
182         clipRect.offset(clipDelta);
183         zPlaneParams.fZ = kDP * 16;
184         canvas->save();
185         canvas->clipRect(clipRect);
186         canvas->translate(xPos, yPos);
187         this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
188                                lightPos, kLightWidth, kSpotAlpha);
189         canvas->restore();
190 
191     }
192 
193 private:
194     using INHERITED = Sample;
195 };
196 
197 //////////////////////////////////////////////////////////////////////////////
198 
199 DEF_SAMPLE( return new ShadowRefView(); )
200