blob: f4b31ed35639cd29819a631d7d7c08e09ee04016 [file] [log] [blame]
Jim Van Verth34d6e4b2017-06-09 11:09:03 -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 */
Ben Wagnerb2c4ea62018-08-08 11:36:17 -04008#include "Sample.h"
Jim Van Verth34d6e4b2017-06-09 11:09:03 -04009#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 demonstrate tonal color shadows
18
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040019class ShadowColorView : public Sample {
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040020 SkPath fRectPath;
21 int fZIndex;
22
23 bool fShowAmbient;
24 bool fShowSpot;
25 bool fUseAlt;
26 bool fShowObject;
27 bool fTwoPassColor;
28 bool fDarkBackground;
29
30public:
31 ShadowColorView()
32 : fZIndex(8)
33 , fShowAmbient(true)
34 , fShowSpot(true)
35 , fUseAlt(false)
36 , fShowObject(true)
37 , fTwoPassColor(false)
38 , fDarkBackground(false) {}
39
40protected:
41 void onOnceBeforeDraw() override {
42 fRectPath.addRect(SkRect::MakeXYWH(-50, -50, 100, 100));
43 }
44
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040045 bool onQuery(Sample::Event* evt) override {
46 if (Sample::TitleQ(*evt)) {
47 Sample::TitleR(evt, "ShadowColor");
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040048 return true;
49 }
50
51 SkUnichar uni;
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040052 if (Sample::CharQ(*evt, &uni)) {
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040053 bool handled = false;
54 switch (uni) {
55 case 'W':
56 fShowAmbient = !fShowAmbient;
57 handled = true;
58 break;
59 case 'S':
60 fShowSpot = !fShowSpot;
61 handled = true;
62 break;
63 case 'T':
64 fUseAlt = !fUseAlt;
65 handled = true;
66 break;
67 case 'O':
68 fShowObject = !fShowObject;
69 handled = true;
70 break;
71 case 'X':
72 fTwoPassColor = !fTwoPassColor;
73 handled = true;
74 break;
75 case 'Z':
76 fDarkBackground = !fDarkBackground;
77 handled = true;
78 break;
79 case '>':
80 fZIndex = SkTMin(9, fZIndex+1);
81 handled = true;
82 break;
83 case '<':
84 fZIndex = SkTMax(0, fZIndex-1);
85 handled = true;
86 break;
87 default:
88 break;
89 }
90 if (handled) {
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040091 return true;
92 }
93 }
94 return this->INHERITED::onQuery(evt);
95 }
96
97 void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
98 const SkPoint3& zPlaneParams,
99 const SkPaint& paint, SkScalar ambientAlpha,
100 const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) {
101 if (!fShowAmbient) {
102 ambientAlpha = 0;
103 }
104 if (!fShowSpot) {
105 spotAlpha = 0;
106 }
107 uint32_t flags = 0;
108 if (fUseAlt) {
109 flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
110 }
111
112 if (fTwoPassColor) {
Jim Van Vertha5566842018-02-22 10:58:34 -0500113 SkColor ambientColor = SkColorSetARGB(ambientAlpha*255, 0, 0, 0);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400114 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
115 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -0500116 ambientColor, SK_ColorTRANSPARENT, flags);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400117
118 if (paint.getColor() != SK_ColorBLACK) {
119 SkColor color = paint.getColor();
120
121 uint8_t max = SkTMax(SkTMax(SkColorGetR(color), SkColorGetG(color)),
122 SkColorGetB(color));
123 uint8_t min = SkTMin(SkTMin(SkColorGetR(color), SkColorGetG(color)),
124 SkColorGetB(color));
125 SkScalar luminance = 0.5f*(max + min) / 255.f;
126 SkScalar alpha = (.6 - .4*luminance)*luminance*luminance + 0.3f;
127 spotAlpha -= (alpha - 0.3f)*.5f;
Jim Van Vertha5566842018-02-22 10:58:34 -0500128 SkColor spotColor = SkColorSetARGB(alpha*SkColorGetA(color), SkColorGetR(color),
129 SkColorGetG(color), SkColorGetB(color));
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400130
131 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
132 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -0500133 SK_ColorTRANSPARENT, spotColor, flags);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400134 }
135
Jim Van Vertha5566842018-02-22 10:58:34 -0500136 SkColor spotGreyscale = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400137 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
138 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -0500139 SK_ColorTRANSPARENT, spotGreyscale, flags);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400140 } else {
Jim Van Vertha5566842018-02-22 10:58:34 -0500141 SkColor color = paint.getColor();
142 SkColor baseAmbient = SkColorSetARGB(ambientAlpha*SkColorGetA(color),
143 SkColorGetR(color), SkColorGetG(color),
144 SkColorGetB(color));
145 SkColor baseSpot = SkColorSetARGB(spotAlpha*SkColorGetA(color),
146 SkColorGetR(color), SkColorGetG(color),
147 SkColorGetB(color));
148 SkColor tonalAmbient, tonalSpot;
149 SkShadowUtils::ComputeTonalColors(baseAmbient, baseSpot, &tonalAmbient, &tonalSpot);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400150 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
151 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -0500152 tonalAmbient, tonalSpot, flags);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400153 }
154 if (fShowObject) {
155 canvas->drawPath(path, paint);
156 } else {
157 SkPaint strokePaint;
158
159 strokePaint.setColor(paint.getColor());
160 strokePaint.setStyle(SkPaint::kStroke_Style);
161
162 canvas->drawPath(path, strokePaint);
163 }
164 }
165
166 void onDrawContent(SkCanvas* canvas) override {
167 const SkScalar kLightWidth = 600;
168 const SkScalar kAmbientAlpha = 0.03f;
169 const SkScalar kSpotAlpha = 0.25f;
170
171 const SkScalar kZValues[10] = { 1, 2, 3, 4, 6, 8, 9, 12, 16, 24 };
172
173 const SkColor kColors[30] = {
174 // purples
175 0xFF3A0072, 0xFF5D0099, 0xFF7F12B2, 0xFFA02AD1, 0xFFC245E5,
176 0xFFE95AF9, 0xFFFC79F0, 0xFFFDA6F0, 0xFFFFCCF8, 0xFFFFE1F9,
177 // oranges
178 0xFFEA3200, 0xFFFF4E00, 0xFFFF7300, 0xFFFF9100, 0xFFFFB000,
179 0xFFFFCE00, 0xFFFFE000, 0xFFFFF64D, 0xFFFFF98F, 0xFFFFFBCC,
180 // teals
181 0xFF004D51, 0xFF066266, 0xFF057F7F, 0xFF009999, 0xFF00B2B2,
182 0xFF15CCBE, 0xFF25E5CE, 0xFF2CFFE0, 0xFF80FFEA, 0xFFB3FFF0
183 };
184
185 SkPaint paint;
186 paint.setAntiAlias(true);
187 if (fDarkBackground) {
188 canvas->drawColor(0xFF111111);
189 paint.setColor(SK_ColorWHITE);
190 } else {
191 canvas->drawColor(0xFFEAEAEA);
192 paint.setColor(SK_ColorBLACK);
193 }
194
195 if (fTwoPassColor) {
196 canvas->drawText("Two pass", 8, 10, 15, paint);
197 } else {
198 canvas->drawText("One pass", 8, 10, 15, paint);
199 }
200
201 SkPoint3 lightPos = { 75, -400, 600 };
202 SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, kZValues[fZIndex]);
203 SkScalar yPos = 75;
204
205 for (int row = 0; row < 3; ++row) {
206 lightPos.fX = 75;
207 SkScalar xPos = 75;
208 for (int col = 0; col < 10; ++col) {
209 paint.setColor(kColors[10*row + col]);
210
211 canvas->save();
212 canvas->translate(xPos, yPos);
213 this->drawShadowedPath(canvas, fRectPath, zPlaneParams, paint, kAmbientAlpha,
214 lightPos, kLightWidth, kSpotAlpha);
215 canvas->restore();
216
217 lightPos.fX += 120;
218 xPos += 120;
219 }
220
221 lightPos.fY += 200;
222 yPos += 200;
223 }
224 }
225
226private:
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400227 typedef Sample INHERITED;
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400228};
229
230//////////////////////////////////////////////////////////////////////////////
231
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400232DEF_SAMPLE( return new ShadowColorView(); )