blob: 337bb28650de4a80fb1aa9024b0484e65aa24de9 [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 */
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 demonstrate tonal color shadows
18
19class ShadowColorView : public SampleView {
20 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
45 // overrides from SkEventSink
46 bool onQuery(SkEvent* evt) override {
47 if (SampleCode::TitleQ(*evt)) {
48 SampleCode::TitleR(evt, "ShadowColor");
49 return true;
50 }
51
52 SkUnichar uni;
53 if (SampleCode::CharQ(*evt, &uni)) {
54 bool handled = false;
55 switch (uni) {
56 case 'W':
57 fShowAmbient = !fShowAmbient;
58 handled = true;
59 break;
60 case 'S':
61 fShowSpot = !fShowSpot;
62 handled = true;
63 break;
64 case 'T':
65 fUseAlt = !fUseAlt;
66 handled = true;
67 break;
68 case 'O':
69 fShowObject = !fShowObject;
70 handled = true;
71 break;
72 case 'X':
73 fTwoPassColor = !fTwoPassColor;
74 handled = true;
75 break;
76 case 'Z':
77 fDarkBackground = !fDarkBackground;
78 handled = true;
79 break;
80 case '>':
81 fZIndex = SkTMin(9, fZIndex+1);
82 handled = true;
83 break;
84 case '<':
85 fZIndex = SkTMax(0, fZIndex-1);
86 handled = true;
87 break;
88 default:
89 break;
90 }
91 if (handled) {
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040092 return true;
93 }
94 }
95 return this->INHERITED::onQuery(evt);
96 }
97
98 void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
99 const SkPoint3& zPlaneParams,
100 const SkPaint& paint, SkScalar ambientAlpha,
101 const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) {
102 if (!fShowAmbient) {
103 ambientAlpha = 0;
104 }
105 if (!fShowSpot) {
106 spotAlpha = 0;
107 }
108 uint32_t flags = 0;
109 if (fUseAlt) {
110 flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
111 }
112
113 if (fTwoPassColor) {
Jim Van Vertha5566842018-02-22 10:58:34 -0500114 SkColor ambientColor = SkColorSetARGB(ambientAlpha*255, 0, 0, 0);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400115 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
116 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -0500117 ambientColor, SK_ColorTRANSPARENT, flags);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400118
119 if (paint.getColor() != SK_ColorBLACK) {
120 SkColor color = paint.getColor();
121
122 uint8_t max = SkTMax(SkTMax(SkColorGetR(color), SkColorGetG(color)),
123 SkColorGetB(color));
124 uint8_t min = SkTMin(SkTMin(SkColorGetR(color), SkColorGetG(color)),
125 SkColorGetB(color));
126 SkScalar luminance = 0.5f*(max + min) / 255.f;
127 SkScalar alpha = (.6 - .4*luminance)*luminance*luminance + 0.3f;
128 spotAlpha -= (alpha - 0.3f)*.5f;
Jim Van Vertha5566842018-02-22 10:58:34 -0500129 SkColor spotColor = SkColorSetARGB(alpha*SkColorGetA(color), SkColorGetR(color),
130 SkColorGetG(color), SkColorGetB(color));
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400131
132 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
133 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -0500134 SK_ColorTRANSPARENT, spotColor, flags);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400135 }
136
Jim Van Vertha5566842018-02-22 10:58:34 -0500137 SkColor spotGreyscale = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400138 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
139 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -0500140 SK_ColorTRANSPARENT, spotGreyscale, flags);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400141 } else {
Jim Van Vertha5566842018-02-22 10:58:34 -0500142 SkColor color = paint.getColor();
143 SkColor baseAmbient = SkColorSetARGB(ambientAlpha*SkColorGetA(color),
144 SkColorGetR(color), SkColorGetG(color),
145 SkColorGetB(color));
146 SkColor baseSpot = SkColorSetARGB(spotAlpha*SkColorGetA(color),
147 SkColorGetR(color), SkColorGetG(color),
148 SkColorGetB(color));
149 SkColor tonalAmbient, tonalSpot;
150 SkShadowUtils::ComputeTonalColors(baseAmbient, baseSpot, &tonalAmbient, &tonalSpot);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400151 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
152 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -0500153 tonalAmbient, tonalSpot, flags);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400154 }
155 if (fShowObject) {
156 canvas->drawPath(path, paint);
157 } else {
158 SkPaint strokePaint;
159
160 strokePaint.setColor(paint.getColor());
161 strokePaint.setStyle(SkPaint::kStroke_Style);
162
163 canvas->drawPath(path, strokePaint);
164 }
165 }
166
167 void onDrawContent(SkCanvas* canvas) override {
168 const SkScalar kLightWidth = 600;
169 const SkScalar kAmbientAlpha = 0.03f;
170 const SkScalar kSpotAlpha = 0.25f;
171
172 const SkScalar kZValues[10] = { 1, 2, 3, 4, 6, 8, 9, 12, 16, 24 };
173
174 const SkColor kColors[30] = {
175 // purples
176 0xFF3A0072, 0xFF5D0099, 0xFF7F12B2, 0xFFA02AD1, 0xFFC245E5,
177 0xFFE95AF9, 0xFFFC79F0, 0xFFFDA6F0, 0xFFFFCCF8, 0xFFFFE1F9,
178 // oranges
179 0xFFEA3200, 0xFFFF4E00, 0xFFFF7300, 0xFFFF9100, 0xFFFFB000,
180 0xFFFFCE00, 0xFFFFE000, 0xFFFFF64D, 0xFFFFF98F, 0xFFFFFBCC,
181 // teals
182 0xFF004D51, 0xFF066266, 0xFF057F7F, 0xFF009999, 0xFF00B2B2,
183 0xFF15CCBE, 0xFF25E5CE, 0xFF2CFFE0, 0xFF80FFEA, 0xFFB3FFF0
184 };
185
186 SkPaint paint;
187 paint.setAntiAlias(true);
188 if (fDarkBackground) {
189 canvas->drawColor(0xFF111111);
190 paint.setColor(SK_ColorWHITE);
191 } else {
192 canvas->drawColor(0xFFEAEAEA);
193 paint.setColor(SK_ColorBLACK);
194 }
195
196 if (fTwoPassColor) {
197 canvas->drawText("Two pass", 8, 10, 15, paint);
198 } else {
199 canvas->drawText("One pass", 8, 10, 15, paint);
200 }
201
202 SkPoint3 lightPos = { 75, -400, 600 };
203 SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, kZValues[fZIndex]);
204 SkScalar yPos = 75;
205
206 for (int row = 0; row < 3; ++row) {
207 lightPos.fX = 75;
208 SkScalar xPos = 75;
209 for (int col = 0; col < 10; ++col) {
210 paint.setColor(kColors[10*row + col]);
211
212 canvas->save();
213 canvas->translate(xPos, yPos);
214 this->drawShadowedPath(canvas, fRectPath, zPlaneParams, paint, kAmbientAlpha,
215 lightPos, kLightWidth, kSpotAlpha);
216 canvas->restore();
217
218 lightPos.fX += 120;
219 xPos += 120;
220 }
221
222 lightPos.fY += 200;
223 yPos += 200;
224 }
225 }
226
227private:
228 typedef SampleView INHERITED;
229};
230
231//////////////////////////////////////////////////////////////////////////////
232
233static SkView* MyFactory() { return new ShadowColorView; }
234static SkViewRegister reg(MyFactory);