blob: 7313bda1c5abfcdd4437bd7707df30b68e3b356c [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 */
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "samplecode/Sample.h"
9#include "tools/Resources.h"
Hal Canarya70ae1a2019-01-08 15:04:23 -050010
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkCanvas.h"
12#include "include/core/SkFont.h"
13#include "include/core/SkImage.h"
14#include "include/core/SkPath.h"
15#include "include/core/SkPoint3.h"
16#include "include/utils/SkShadowUtils.h"
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040017
18////////////////////////////////////////////////////////////////////////////
19// Sample to demonstrate tonal color shadows
20
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040021class ShadowColorView : public Sample {
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040022 SkPath fRectPath;
23 int fZIndex;
24
25 bool fShowAmbient;
26 bool fShowSpot;
27 bool fUseAlt;
28 bool fShowObject;
29 bool fTwoPassColor;
30 bool fDarkBackground;
31
32public:
33 ShadowColorView()
34 : fZIndex(8)
35 , fShowAmbient(true)
36 , fShowSpot(true)
37 , fUseAlt(false)
38 , fShowObject(true)
39 , fTwoPassColor(false)
40 , fDarkBackground(false) {}
41
42protected:
43 void onOnceBeforeDraw() override {
44 fRectPath.addRect(SkRect::MakeXYWH(-50, -50, 100, 100));
45 }
46
Hal Canary8a027312019-07-03 10:55:44 -040047 SkString name() override { return SkString("ShadowColor"); }
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040048
Hal Canary6cc65e12019-07-03 15:53:04 -040049 bool onChar(SkUnichar uni) override {
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040050 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 case 'X':
69 fTwoPassColor = !fTwoPassColor;
70 handled = true;
71 break;
72 case 'Z':
73 fDarkBackground = !fDarkBackground;
74 handled = true;
75 break;
76 case '>':
Brian Osman788b9162020-02-07 10:36:46 -050077 fZIndex = std::min(9, fZIndex+1);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040078 handled = true;
79 break;
80 case '<':
Brian Osman788b9162020-02-07 10:36:46 -050081 fZIndex = std::max(0, fZIndex-1);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040082 handled = true;
83 break;
84 default:
85 break;
86 }
87 if (handled) {
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040088 return true;
89 }
Hal Canary6cc65e12019-07-03 15:53:04 -040090 return false;
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040091 }
92
Hal Canary6cc65e12019-07-03 15:53:04 -040093
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040094 void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
95 const SkPoint3& zPlaneParams,
96 const SkPaint& paint, SkScalar ambientAlpha,
97 const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) {
98 if (!fShowAmbient) {
99 ambientAlpha = 0;
100 }
101 if (!fShowSpot) {
102 spotAlpha = 0;
103 }
104 uint32_t flags = 0;
105 if (fUseAlt) {
106 flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
107 }
108
109 if (fTwoPassColor) {
Jim Van Vertha5566842018-02-22 10:58:34 -0500110 SkColor ambientColor = SkColorSetARGB(ambientAlpha*255, 0, 0, 0);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400111 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
112 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -0500113 ambientColor, SK_ColorTRANSPARENT, flags);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400114
115 if (paint.getColor() != SK_ColorBLACK) {
116 SkColor color = paint.getColor();
117
Brian Osman788b9162020-02-07 10:36:46 -0500118 uint8_t max = std::max(std::max(SkColorGetR(color), SkColorGetG(color)),
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400119 SkColorGetB(color));
Brian Osman788b9162020-02-07 10:36:46 -0500120 uint8_t min = std::min(std::min(SkColorGetR(color), SkColorGetG(color)),
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400121 SkColorGetB(color));
122 SkScalar luminance = 0.5f*(max + min) / 255.f;
123 SkScalar alpha = (.6 - .4*luminance)*luminance*luminance + 0.3f;
124 spotAlpha -= (alpha - 0.3f)*.5f;
Jim Van Vertha5566842018-02-22 10:58:34 -0500125 SkColor spotColor = SkColorSetARGB(alpha*SkColorGetA(color), SkColorGetR(color),
126 SkColorGetG(color), SkColorGetB(color));
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400127
128 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
129 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -0500130 SK_ColorTRANSPARENT, spotColor, flags);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400131 }
132
Jim Van Vertha5566842018-02-22 10:58:34 -0500133 SkColor spotGreyscale = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400134 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
135 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -0500136 SK_ColorTRANSPARENT, spotGreyscale, flags);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400137 } else {
Jim Van Vertha5566842018-02-22 10:58:34 -0500138 SkColor color = paint.getColor();
139 SkColor baseAmbient = SkColorSetARGB(ambientAlpha*SkColorGetA(color),
140 SkColorGetR(color), SkColorGetG(color),
141 SkColorGetB(color));
142 SkColor baseSpot = SkColorSetARGB(spotAlpha*SkColorGetA(color),
143 SkColorGetR(color), SkColorGetG(color),
144 SkColorGetB(color));
145 SkColor tonalAmbient, tonalSpot;
146 SkShadowUtils::ComputeTonalColors(baseAmbient, baseSpot, &tonalAmbient, &tonalSpot);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400147 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
148 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -0500149 tonalAmbient, tonalSpot, flags);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400150 }
151 if (fShowObject) {
152 canvas->drawPath(path, paint);
153 } else {
154 SkPaint strokePaint;
155
156 strokePaint.setColor(paint.getColor());
157 strokePaint.setStyle(SkPaint::kStroke_Style);
158
159 canvas->drawPath(path, strokePaint);
160 }
161 }
162
163 void onDrawContent(SkCanvas* canvas) override {
164 const SkScalar kLightWidth = 600;
165 const SkScalar kAmbientAlpha = 0.03f;
166 const SkScalar kSpotAlpha = 0.25f;
167
168 const SkScalar kZValues[10] = { 1, 2, 3, 4, 6, 8, 9, 12, 16, 24 };
169
170 const SkColor kColors[30] = {
171 // purples
172 0xFF3A0072, 0xFF5D0099, 0xFF7F12B2, 0xFFA02AD1, 0xFFC245E5,
173 0xFFE95AF9, 0xFFFC79F0, 0xFFFDA6F0, 0xFFFFCCF8, 0xFFFFE1F9,
174 // oranges
175 0xFFEA3200, 0xFFFF4E00, 0xFFFF7300, 0xFFFF9100, 0xFFFFB000,
176 0xFFFFCE00, 0xFFFFE000, 0xFFFFF64D, 0xFFFFF98F, 0xFFFFFBCC,
177 // teals
178 0xFF004D51, 0xFF066266, 0xFF057F7F, 0xFF009999, 0xFF00B2B2,
179 0xFF15CCBE, 0xFF25E5CE, 0xFF2CFFE0, 0xFF80FFEA, 0xFFB3FFF0
180 };
181
Hal Canarya70ae1a2019-01-08 15:04:23 -0500182 SkFont font;
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400183 SkPaint paint;
184 paint.setAntiAlias(true);
185 if (fDarkBackground) {
186 canvas->drawColor(0xFF111111);
187 paint.setColor(SK_ColorWHITE);
188 } else {
189 canvas->drawColor(0xFFEAEAEA);
190 paint.setColor(SK_ColorBLACK);
191 }
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400192 if (fTwoPassColor) {
Hal Canarya70ae1a2019-01-08 15:04:23 -0500193 canvas->drawString("Two pass", 10, 15, font, paint);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400194 } else {
Hal Canarya70ae1a2019-01-08 15:04:23 -0500195 canvas->drawString("One pass", 10, 15, font, paint);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400196 }
197
198 SkPoint3 lightPos = { 75, -400, 600 };
199 SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, kZValues[fZIndex]);
200 SkScalar yPos = 75;
201
202 for (int row = 0; row < 3; ++row) {
203 lightPos.fX = 75;
204 SkScalar xPos = 75;
205 for (int col = 0; col < 10; ++col) {
206 paint.setColor(kColors[10*row + col]);
207
208 canvas->save();
209 canvas->translate(xPos, yPos);
210 this->drawShadowedPath(canvas, fRectPath, zPlaneParams, paint, kAmbientAlpha,
211 lightPos, kLightWidth, kSpotAlpha);
212 canvas->restore();
213
214 lightPos.fX += 120;
215 xPos += 120;
216 }
217
218 lightPos.fY += 200;
219 yPos += 200;
220 }
221 }
222
223private:
John Stiles7571f9e2020-09-02 22:42:33 -0400224 using INHERITED = Sample;
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400225};
226
227//////////////////////////////////////////////////////////////////////////////
228
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400229DEF_SAMPLE( return new ShadowColorView(); )