blob: 22b17a1e246d6de09fd43a8b41a52bd2eec313e4 [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 */
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#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"
Jim Van Verth623fadf2017-05-23 13:50:58 -040015
16////////////////////////////////////////////////////////////////////////////
17// Sample to compare the Material Design shadow reference to our results
18
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040019class ShadowRefView : public Sample {
Jim Van Verth623fadf2017-05-23 13:50:58 -040020 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
Hal Canary8a027312019-07-03 10:55:44 -040041 SkString name() override { return SkString("ShadowReference"); }
Jim Van Verth623fadf2017-05-23 13:50:58 -040042
Hal Canary8a027312019-07-03 10:55:44 -040043 bool onQuery(Sample::Event* evt) override {
Jim Van Verth623fadf2017-05-23 13:50:58 -040044 SkUnichar uni;
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040045 if (Sample::CharQ(*evt, &uni)) {
Jim Van Verth623fadf2017-05-23 13:50:58 -040046 bool handled = false;
47 switch (uni) {
48 case 'W':
49 fShowAmbient = !fShowAmbient;
50 handled = true;
51 break;
52 case 'S':
53 fShowSpot = !fShowSpot;
54 handled = true;
55 break;
56 case 'T':
57 fUseAlt = !fUseAlt;
58 handled = true;
59 break;
60 case 'O':
61 fShowObject = !fShowObject;
62 handled = true;
63 break;
64 default:
65 break;
66 }
67 if (handled) {
Jim Van Verth623fadf2017-05-23 13:50:58 -040068 return true;
69 }
70 }
71 return this->INHERITED::onQuery(evt);
72 }
73
74 void drawBG(SkCanvas* canvas) {
75 canvas->drawColor(0xFFFFFFFF);
76 canvas->drawImage(fReferenceImage, 10, 30);
77 }
78
79 void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
80 const SkPoint3& zPlaneParams,
81 const SkPaint& paint, SkScalar ambientAlpha,
82 const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) {
83 if (!fShowAmbient) {
84 ambientAlpha = 0;
85 }
86 if (!fShowSpot) {
87 spotAlpha = 0;
88 }
89 uint32_t flags = 0;
90 if (fUseAlt) {
91 flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
92 }
Jim Van Vertha5566842018-02-22 10:58:34 -050093
94 SkColor ambientColor = SkColorSetARGB(ambientAlpha * 255, 0, 0, 0);
95 SkColor spotColor = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
Jim Van Verth623fadf2017-05-23 13:50:58 -040096 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
97 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -050098 ambientColor, spotColor, flags);
Jim Van Verth623fadf2017-05-23 13:50:58 -040099
100 if (fShowObject) {
101 canvas->drawPath(path, paint);
102 } else {
103 SkPaint strokePaint;
104
105 strokePaint.setColor(paint.getColor());
106 strokePaint.setStyle(SkPaint::kStroke_Style);
107
108 canvas->drawPath(path, strokePaint);
109 }
110 }
111
112 void onDrawContent(SkCanvas* canvas) override {
113 this->drawBG(canvas);
114 const SkScalar kDP = 4; // the reference image is 4x bigger than it is displayed on
115 // on the web page, so we need to reflect that here and
116 // multiply the heights and light params accordingly
117 const SkScalar kLightWidth = kDP*400;
118 const SkScalar kAmbientAlpha = 0.03f;
119 const SkScalar kSpotAlpha = 0.35f;
120
121 SkPaint paint;
122 paint.setAntiAlias(true);
123 paint.setColor(SK_ColorWHITE);
124
125 SkPoint3 lightPos = { 175, -800, kDP * 600 };
126 SkScalar xPos = 230;
127 SkScalar yPos = 254.25f;
128 SkRect clipRect = SkRect::MakeXYWH(45, 75, 122, 250);
129 SkPoint clipDelta = SkPoint::Make(320, 0);
130 SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, kDP * 2);
131
132 canvas->save();
133 canvas->clipRect(clipRect);
134 canvas->translate(xPos, yPos);
135 this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
136 lightPos, kLightWidth, kSpotAlpha);
137 canvas->restore();
138
139 lightPos.fX += 320;
140 xPos += 320;
141 clipRect.offset(clipDelta);
142 zPlaneParams.fZ = kDP * 3;
143 canvas->save();
144 canvas->clipRect(clipRect);
145 canvas->translate(xPos, yPos);
146 this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
147 lightPos, kLightWidth, kSpotAlpha);
148 canvas->restore();
149
150 lightPos.fX += 320;
151 xPos += 320;
152 clipRect.offset(clipDelta);
153 zPlaneParams.fZ = kDP * 4;
154 canvas->save();
155 canvas->clipRect(clipRect);
156 canvas->translate(xPos, yPos);
157 this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
158 lightPos, kLightWidth, kSpotAlpha);
159 canvas->restore();
160
161 lightPos.fX += 320;
162 xPos += 320;
163 clipRect.offset(clipDelta);
164 zPlaneParams.fZ = kDP * 6;
165 canvas->save();
166 canvas->clipRect(clipRect);
167 canvas->translate(xPos, yPos);
168 this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
169 lightPos, kLightWidth, kSpotAlpha);
170 canvas->restore();
171
172 lightPos.fX += 320;
173 xPos += 320;
174 clipRect.offset(clipDelta);
175 zPlaneParams.fZ = kDP * 8;
176 canvas->save();
177 canvas->clipRect(clipRect);
178 canvas->translate(xPos, yPos);
179 this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
180 lightPos, kLightWidth, kSpotAlpha);
181 canvas->restore();
182
183 lightPos.fX += 320;
184 xPos += 320;
185 clipRect.offset(clipDelta);
186 zPlaneParams.fZ = kDP * 16;
187 canvas->save();
188 canvas->clipRect(clipRect);
189 canvas->translate(xPos, yPos);
190 this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha,
191 lightPos, kLightWidth, kSpotAlpha);
192 canvas->restore();
193
194 }
195
196private:
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400197 typedef Sample INHERITED;
Jim Van Verth623fadf2017-05-23 13:50:58 -0400198};
199
200//////////////////////////////////////////////////////////////////////////////
201
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400202DEF_SAMPLE( return new ShadowRefView(); )