blob: 0536060d0c8f30025a4a5b56631fefcdd2a8e704 [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"
Hal Canarya70ae1a2019-01-08 15:04:23 -050010
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040011#include "SkCanvas.h"
Hal Canarya70ae1a2019-01-08 15:04:23 -050012#include "SkFont.h"
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040013#include "SkImage.h"
14#include "SkPath.h"
15#include "SkPoint3.h"
16#include "SkShadowUtils.h"
17
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
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040047 bool onQuery(Sample::Event* evt) override {
48 if (Sample::TitleQ(*evt)) {
49 Sample::TitleR(evt, "ShadowColor");
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040050 return true;
51 }
52
53 SkUnichar uni;
Ben Wagnerb2c4ea62018-08-08 11:36:17 -040054 if (Sample::CharQ(*evt, &uni)) {
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040055 bool handled = false;
56 switch (uni) {
57 case 'W':
58 fShowAmbient = !fShowAmbient;
59 handled = true;
60 break;
61 case 'S':
62 fShowSpot = !fShowSpot;
63 handled = true;
64 break;
65 case 'T':
66 fUseAlt = !fUseAlt;
67 handled = true;
68 break;
69 case 'O':
70 fShowObject = !fShowObject;
71 handled = true;
72 break;
73 case 'X':
74 fTwoPassColor = !fTwoPassColor;
75 handled = true;
76 break;
77 case 'Z':
78 fDarkBackground = !fDarkBackground;
79 handled = true;
80 break;
81 case '>':
82 fZIndex = SkTMin(9, fZIndex+1);
83 handled = true;
84 break;
85 case '<':
86 fZIndex = SkTMax(0, fZIndex-1);
87 handled = true;
88 break;
89 default:
90 break;
91 }
92 if (handled) {
Jim Van Verth34d6e4b2017-06-09 11:09:03 -040093 return true;
94 }
95 }
96 return this->INHERITED::onQuery(evt);
97 }
98
99 void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
100 const SkPoint3& zPlaneParams,
101 const SkPaint& paint, SkScalar ambientAlpha,
102 const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) {
103 if (!fShowAmbient) {
104 ambientAlpha = 0;
105 }
106 if (!fShowSpot) {
107 spotAlpha = 0;
108 }
109 uint32_t flags = 0;
110 if (fUseAlt) {
111 flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
112 }
113
114 if (fTwoPassColor) {
Jim Van Vertha5566842018-02-22 10:58:34 -0500115 SkColor ambientColor = SkColorSetARGB(ambientAlpha*255, 0, 0, 0);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400116 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
117 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -0500118 ambientColor, SK_ColorTRANSPARENT, flags);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400119
120 if (paint.getColor() != SK_ColorBLACK) {
121 SkColor color = paint.getColor();
122
123 uint8_t max = SkTMax(SkTMax(SkColorGetR(color), SkColorGetG(color)),
124 SkColorGetB(color));
125 uint8_t min = SkTMin(SkTMin(SkColorGetR(color), SkColorGetG(color)),
126 SkColorGetB(color));
127 SkScalar luminance = 0.5f*(max + min) / 255.f;
128 SkScalar alpha = (.6 - .4*luminance)*luminance*luminance + 0.3f;
129 spotAlpha -= (alpha - 0.3f)*.5f;
Jim Van Vertha5566842018-02-22 10:58:34 -0500130 SkColor spotColor = SkColorSetARGB(alpha*SkColorGetA(color), SkColorGetR(color),
131 SkColorGetG(color), SkColorGetB(color));
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400132
133 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
134 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -0500135 SK_ColorTRANSPARENT, spotColor, flags);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400136 }
137
Jim Van Vertha5566842018-02-22 10:58:34 -0500138 SkColor spotGreyscale = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400139 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
140 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -0500141 SK_ColorTRANSPARENT, spotGreyscale, flags);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400142 } else {
Jim Van Vertha5566842018-02-22 10:58:34 -0500143 SkColor color = paint.getColor();
144 SkColor baseAmbient = SkColorSetARGB(ambientAlpha*SkColorGetA(color),
145 SkColorGetR(color), SkColorGetG(color),
146 SkColorGetB(color));
147 SkColor baseSpot = SkColorSetARGB(spotAlpha*SkColorGetA(color),
148 SkColorGetR(color), SkColorGetG(color),
149 SkColorGetB(color));
150 SkColor tonalAmbient, tonalSpot;
151 SkShadowUtils::ComputeTonalColors(baseAmbient, baseSpot, &tonalAmbient, &tonalSpot);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400152 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
153 lightPos, lightWidth,
Jim Van Vertha5566842018-02-22 10:58:34 -0500154 tonalAmbient, tonalSpot, flags);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400155 }
156 if (fShowObject) {
157 canvas->drawPath(path, paint);
158 } else {
159 SkPaint strokePaint;
160
161 strokePaint.setColor(paint.getColor());
162 strokePaint.setStyle(SkPaint::kStroke_Style);
163
164 canvas->drawPath(path, strokePaint);
165 }
166 }
167
168 void onDrawContent(SkCanvas* canvas) override {
169 const SkScalar kLightWidth = 600;
170 const SkScalar kAmbientAlpha = 0.03f;
171 const SkScalar kSpotAlpha = 0.25f;
172
173 const SkScalar kZValues[10] = { 1, 2, 3, 4, 6, 8, 9, 12, 16, 24 };
174
175 const SkColor kColors[30] = {
176 // purples
177 0xFF3A0072, 0xFF5D0099, 0xFF7F12B2, 0xFFA02AD1, 0xFFC245E5,
178 0xFFE95AF9, 0xFFFC79F0, 0xFFFDA6F0, 0xFFFFCCF8, 0xFFFFE1F9,
179 // oranges
180 0xFFEA3200, 0xFFFF4E00, 0xFFFF7300, 0xFFFF9100, 0xFFFFB000,
181 0xFFFFCE00, 0xFFFFE000, 0xFFFFF64D, 0xFFFFF98F, 0xFFFFFBCC,
182 // teals
183 0xFF004D51, 0xFF066266, 0xFF057F7F, 0xFF009999, 0xFF00B2B2,
184 0xFF15CCBE, 0xFF25E5CE, 0xFF2CFFE0, 0xFF80FFEA, 0xFFB3FFF0
185 };
186
Hal Canarya70ae1a2019-01-08 15:04:23 -0500187 SkFont font;
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400188 SkPaint paint;
189 paint.setAntiAlias(true);
190 if (fDarkBackground) {
191 canvas->drawColor(0xFF111111);
192 paint.setColor(SK_ColorWHITE);
193 } else {
194 canvas->drawColor(0xFFEAEAEA);
195 paint.setColor(SK_ColorBLACK);
196 }
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400197 if (fTwoPassColor) {
Hal Canarya70ae1a2019-01-08 15:04:23 -0500198 canvas->drawString("Two pass", 10, 15, font, paint);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400199 } else {
Hal Canarya70ae1a2019-01-08 15:04:23 -0500200 canvas->drawString("One pass", 10, 15, font, paint);
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400201 }
202
203 SkPoint3 lightPos = { 75, -400, 600 };
204 SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, kZValues[fZIndex]);
205 SkScalar yPos = 75;
206
207 for (int row = 0; row < 3; ++row) {
208 lightPos.fX = 75;
209 SkScalar xPos = 75;
210 for (int col = 0; col < 10; ++col) {
211 paint.setColor(kColors[10*row + col]);
212
213 canvas->save();
214 canvas->translate(xPos, yPos);
215 this->drawShadowedPath(canvas, fRectPath, zPlaneParams, paint, kAmbientAlpha,
216 lightPos, kLightWidth, kSpotAlpha);
217 canvas->restore();
218
219 lightPos.fX += 120;
220 xPos += 120;
221 }
222
223 lightPos.fY += 200;
224 yPos += 200;
225 }
226 }
227
228private:
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400229 typedef Sample INHERITED;
Jim Van Verth34d6e4b2017-06-09 11:09:03 -0400230};
231
232//////////////////////////////////////////////////////////////////////////////
233
Ben Wagnerb2c4ea62018-08-08 11:36:17 -0400234DEF_SAMPLE( return new ShadowColorView(); )