• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
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 "include/core/SkCanvas.h"
9 #include "include/core/SkFont.h"
10 #include "include/core/SkImage.h"
11 #include "include/core/SkPath.h"
12 #include "include/core/SkPoint3.h"
13 #include "include/utils/SkShadowUtils.h"
14 #include "tools/Resources.h"
15 #include "tools/viewer/Slide.h"
16 
17 ////////////////////////////////////////////////////////////////////////////
18 // Sample to demonstrate tonal color shadows
19 
20 class ShadowColorSlide : public Slide {
21     SkPath    fRectPath;
22     int       fZIndex;
23 
24     bool      fShowAmbient;
25     bool      fShowSpot;
26     bool      fUseAlt;
27     bool      fShowObject;
28     bool      fTwoPassColor;
29     bool      fDarkBackground;
30 
31 public:
ShadowColorSlide()32     ShadowColorSlide()
33         : fZIndex(8)
34         , fShowAmbient(true)
35         , fShowSpot(true)
36         , fUseAlt(false)
37         , fShowObject(true)
38         , fTwoPassColor(false)
39         , fDarkBackground(false) {
40         fName = "ShadowColor";
41     }
42 
load(SkScalar w,SkScalar h)43     void load(SkScalar w, SkScalar h) override {
44         fRectPath.addRect(SkRect::MakeXYWH(-50, -50, 100, 100));
45     }
46 
onChar(SkUnichar uni)47     bool onChar(SkUnichar uni) override {
48             bool handled = false;
49             switch (uni) {
50                 case 'W':
51                     fShowAmbient = !fShowAmbient;
52                     handled = true;
53                     break;
54                 case 'S':
55                     fShowSpot = !fShowSpot;
56                     handled = true;
57                     break;
58                 case 'T':
59                     fUseAlt = !fUseAlt;
60                     handled = true;
61                     break;
62                 case 'O':
63                     fShowObject = !fShowObject;
64                     handled = true;
65                     break;
66                 case 'X':
67                     fTwoPassColor = !fTwoPassColor;
68                     handled = true;
69                     break;
70                 case 'Z':
71                     fDarkBackground = !fDarkBackground;
72                     handled = true;
73                     break;
74                 case '>':
75                     fZIndex = std::min(9, fZIndex+1);
76                     handled = true;
77                     break;
78                 case '<':
79                     fZIndex = std::max(0, fZIndex-1);
80                     handled = true;
81                     break;
82                 default:
83                     break;
84             }
85             if (handled) {
86                 return true;
87             }
88             return false;
89     }
90 
draw(SkCanvas * canvas)91     void draw(SkCanvas* canvas) override {
92         const SkScalar kLightWidth = 600;
93         const SkScalar kAmbientAlpha = 0.03f;
94         const SkScalar kSpotAlpha = 0.25f;
95 
96         const SkScalar kZValues[10] = { 1, 2, 3, 4, 6, 8, 9, 12, 16, 24 };
97 
98         const SkColor kColors[30] = {
99             // purples
100             0xFF3A0072, 0xFF5D0099, 0xFF7F12B2, 0xFFA02AD1, 0xFFC245E5,
101             0xFFE95AF9, 0xFFFC79F0, 0xFFFDA6F0, 0xFFFFCCF8, 0xFFFFE1F9,
102             // oranges
103             0xFFEA3200, 0xFFFF4E00, 0xFFFF7300, 0xFFFF9100, 0xFFFFB000,
104             0xFFFFCE00, 0xFFFFE000, 0xFFFFF64D, 0xFFFFF98F, 0xFFFFFBCC,
105             // teals
106             0xFF004D51, 0xFF066266, 0xFF057F7F, 0xFF009999, 0xFF00B2B2,
107             0xFF15CCBE, 0xFF25E5CE, 0xFF2CFFE0, 0xFF80FFEA, 0xFFB3FFF0
108         };
109 
110         SkFont font;
111         SkPaint paint;
112         paint.setAntiAlias(true);
113         if (fDarkBackground) {
114             canvas->drawColor(0xFF111111);
115             paint.setColor(SK_ColorWHITE);
116         } else {
117             canvas->drawColor(0xFFEAEAEA);
118             paint.setColor(SK_ColorBLACK);
119         }
120         if (fTwoPassColor) {
121             canvas->drawString("Two pass", 10, 15, font, paint);
122         } else {
123             canvas->drawString("One pass", 10, 15, font, paint);
124         }
125 
126         SkPoint3 lightPos = { 75, -400, 600 };
127         SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, kZValues[fZIndex]);
128         SkScalar yPos = 75;
129 
130         for (int row = 0; row < 3; ++row) {
131             lightPos.fX = 75;
132             SkScalar xPos = 75;
133             for (int col = 0; col < 10; ++col) {
134                 paint.setColor(kColors[10*row + col]);
135 
136                 canvas->save();
137                 canvas->translate(xPos, yPos);
138                 this->drawShadowedPath(canvas, fRectPath, zPlaneParams, paint, kAmbientAlpha,
139                                        lightPos, kLightWidth, kSpotAlpha);
140                 canvas->restore();
141 
142                 lightPos.fX += 120;
143                 xPos += 120;
144             }
145 
146             lightPos.fY += 200;
147             yPos += 200;
148         }
149     }
150 
151 private:
drawShadowedPath(SkCanvas * canvas,const SkPath & path,const SkPoint3 & zPlaneParams,const SkPaint & paint,SkScalar ambientAlpha,const SkPoint3 & lightPos,SkScalar lightWidth,SkScalar spotAlpha)152     void drawShadowedPath(SkCanvas* canvas, const SkPath& path,
153                           const SkPoint3& zPlaneParams,
154                           const SkPaint& paint, SkScalar ambientAlpha,
155                           const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) {
156         if (!fShowAmbient) {
157             ambientAlpha = 0;
158         }
159         if (!fShowSpot) {
160             spotAlpha = 0;
161         }
162         uint32_t flags = 0;
163         if (fUseAlt) {
164             flags |= SkShadowFlags::kGeometricOnly_ShadowFlag;
165         }
166 
167         if (fTwoPassColor) {
168             SkColor ambientColor = SkColorSetARGB(ambientAlpha*255, 0, 0, 0);
169             SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
170                                       lightPos, lightWidth,
171                                       ambientColor, SK_ColorTRANSPARENT, flags);
172 
173             if (paint.getColor() != SK_ColorBLACK) {
174                 SkColor color = paint.getColor();
175 
176                 uint8_t max = std::max(std::max(SkColorGetR(color), SkColorGetG(color)),
177                                        SkColorGetB(color));
178                 uint8_t min = std::min(std::min(SkColorGetR(color), SkColorGetG(color)),
179                                        SkColorGetB(color));
180                 SkScalar luminance = 0.5f*(max + min) / 255.f;
181                 SkScalar alpha = (.6 - .4*luminance)*luminance*luminance + 0.3f;
182                 spotAlpha -= (alpha - 0.3f)*.5f;
183                 SkColor spotColor = SkColorSetARGB(alpha*SkColorGetA(color), SkColorGetR(color),
184                                                    SkColorGetG(color), SkColorGetB(color));
185 
186                 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
187                                           lightPos, lightWidth,
188                                           SK_ColorTRANSPARENT, spotColor, flags);
189             }
190 
191             SkColor spotGreyscale = SkColorSetARGB(spotAlpha * 255, 0, 0, 0);
192             SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
193                                       lightPos, lightWidth,
194                                       SK_ColorTRANSPARENT, spotGreyscale, flags);
195         } else {
196             SkColor color = paint.getColor();
197             SkColor baseAmbient = SkColorSetARGB(ambientAlpha*SkColorGetA(color),
198                                                  SkColorGetR(color), SkColorGetG(color),
199                                                  SkColorGetB(color));
200             SkColor baseSpot = SkColorSetARGB(spotAlpha*SkColorGetA(color),
201                                               SkColorGetR(color), SkColorGetG(color),
202                                               SkColorGetB(color));
203             SkColor tonalAmbient, tonalSpot;
204             SkShadowUtils::ComputeTonalColors(baseAmbient, baseSpot, &tonalAmbient, &tonalSpot);
205             SkShadowUtils::DrawShadow(canvas, path, zPlaneParams,
206                                       lightPos, lightWidth,
207                                       tonalAmbient, tonalSpot, flags);
208         }
209         if (fShowObject) {
210             canvas->drawPath(path, paint);
211         } else {
212             SkPaint strokePaint;
213 
214             strokePaint.setColor(paint.getColor());
215             strokePaint.setStyle(SkPaint::kStroke_Style);
216 
217             canvas->drawPath(path, strokePaint);
218         }
219     }
220 };
221 
222 //////////////////////////////////////////////////////////////////////////////
223 
224 DEF_SLIDE( return new ShadowColorSlide(); )
225