blob: 6cd63798b54fda959211ccc36b954655157118dd [file] [log] [blame]
Jim Van Verth623fadf2017-05-23 13:50:58 -04001
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
19class 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
28public:
29 ShadowRefView()
30 : fShowAmbient(true)
31 , fShowSpot(true)
32 , fUseAlt(false)
33 , fShowObject(true) {}
34
35protected:
36 void onOnceBeforeDraw() override {
37 fRRectPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-130, -128.5, 130, 128.5), 4, 4));
Hal Canaryc465d132017-12-08 10:21:31 -050038 fReferenceImage = GetResourceAsImage("images/shadowreference.png");
Jim Van Verth623fadf2017-05-23 13:50:58 -040039 }
40
41 // overrides from SkEventSink
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) {
Jim Van Verth623fadf2017-05-23 13:50:58 -040072 return true;
73 }
74 }
75 return this->INHERITED::onQuery(evt);
76 }
77
78 void drawBG(SkCanvas* canvas) {
79 canvas->drawColor(0xFFFFFFFF);
80 canvas->drawImage(fReferenceImage, 10, 30);
81 }
82
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 }
Jim Van Vertha5566842018-02-22 10:58:34 -050097
98 SkColor ambientColor = SkColorSetARGB(ambientAlpha * 255, 0, 0, 0);
99 SkColor spotColor = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
Jim Van Verth623fadf2017-05-23 13:50:58 -0400100 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
101 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -0500102 ambientColor, spotColor, flags);
Jim Van Verth623fadf2017-05-23 13:50:58 -0400103
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
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
200private:
201 typedef SampleView INHERITED;
202};
203
204//////////////////////////////////////////////////////////////////////////////
205
206static SkView* MyFactory() { return new ShadowRefView; }
207static SkViewRegister reg(MyFactory);