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/SkImage.h" 10 #include "include/core/SkPath.h" 11 #include "include/core/SkPoint3.h" 12 #include "include/core/SkRRect.h" 13 #include "include/utils/SkShadowUtils.h" 14 #include "tools/DecodeUtils.h" 15 #include "tools/Resources.h" 16 #include "tools/viewer/Slide.h" 17 18 //////////////////////////////////////////////////////////////////////////// 19 // Sample to compare the Material Design shadow reference to our results 20 21 class ShadowRefSlide : public Slide { 22 SkPath fRRectPath; 23 sk_sp<SkImage> fReferenceImage; 24 25 bool fShowAmbient; 26 bool fShowSpot; 27 bool fUseAlt; 28 bool fShowObject; 29 30 public: ShadowRefSlide()31 ShadowRefSlide() 32 : fShowAmbient(true) 33 , fShowSpot(true) 34 , fUseAlt(false) 35 , fShowObject(true) { 36 fName = "ShadowReference"; 37 } 38 load(SkScalar w,SkScalar h)39 void load(SkScalar w, SkScalar h) override { 40 fRRectPath.addRRect(SkRRect::MakeRectXY(SkRect::MakeXYWH(-130, -128.5, 130, 128.5), 4, 4)); 41 fReferenceImage = ToolUtils::GetResourceAsImage("images/shadowreference.png"); 42 } 43 onChar(SkUnichar uni)44 bool onChar(SkUnichar uni) override { 45 bool handled = false; 46 switch (uni) { 47 case 'W': 48 fShowAmbient = !fShowAmbient; 49 handled = true; 50 break; 51 case 'S': 52 fShowSpot = !fShowSpot; 53 handled = true; 54 break; 55 case 'T': 56 fUseAlt = !fUseAlt; 57 handled = true; 58 break; 59 case 'O': 60 fShowObject = !fShowObject; 61 handled = true; 62 break; 63 default: 64 break; 65 } 66 if (handled) { 67 return true; 68 } 69 return false; 70 } 71 draw(SkCanvas * canvas)72 void draw(SkCanvas* canvas) override { 73 this->drawBG(canvas); 74 const SkScalar kDP = 4; // the reference image is 4x bigger than it is displayed on 75 // on the web page, so we need to reflect that here and 76 // multiply the heights and light params accordingly 77 const SkScalar kLightWidth = kDP*400; 78 const SkScalar kAmbientAlpha = 0.03f; 79 const SkScalar kSpotAlpha = 0.35f; 80 81 SkPaint paint; 82 paint.setAntiAlias(true); 83 paint.setColor(SK_ColorWHITE); 84 85 SkPoint3 lightPos = { 175, -800, kDP * 600 }; 86 SkScalar xPos = 230; 87 SkScalar yPos = 254.25f; 88 SkRect clipRect = SkRect::MakeXYWH(45, 75, 122, 250); 89 SkPoint clipDelta = SkPoint::Make(320, 0); 90 SkPoint3 zPlaneParams = SkPoint3::Make(0, 0, kDP * 2); 91 92 canvas->save(); 93 canvas->clipRect(clipRect); 94 canvas->translate(xPos, yPos); 95 this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha, 96 lightPos, kLightWidth, kSpotAlpha); 97 canvas->restore(); 98 99 lightPos.fX += 320; 100 xPos += 320; 101 clipRect.offset(clipDelta); 102 zPlaneParams.fZ = kDP * 3; 103 canvas->save(); 104 canvas->clipRect(clipRect); 105 canvas->translate(xPos, yPos); 106 this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha, 107 lightPos, kLightWidth, kSpotAlpha); 108 canvas->restore(); 109 110 lightPos.fX += 320; 111 xPos += 320; 112 clipRect.offset(clipDelta); 113 zPlaneParams.fZ = kDP * 4; 114 canvas->save(); 115 canvas->clipRect(clipRect); 116 canvas->translate(xPos, yPos); 117 this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha, 118 lightPos, kLightWidth, kSpotAlpha); 119 canvas->restore(); 120 121 lightPos.fX += 320; 122 xPos += 320; 123 clipRect.offset(clipDelta); 124 zPlaneParams.fZ = kDP * 6; 125 canvas->save(); 126 canvas->clipRect(clipRect); 127 canvas->translate(xPos, yPos); 128 this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha, 129 lightPos, kLightWidth, kSpotAlpha); 130 canvas->restore(); 131 132 lightPos.fX += 320; 133 xPos += 320; 134 clipRect.offset(clipDelta); 135 zPlaneParams.fZ = kDP * 8; 136 canvas->save(); 137 canvas->clipRect(clipRect); 138 canvas->translate(xPos, yPos); 139 this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha, 140 lightPos, kLightWidth, kSpotAlpha); 141 canvas->restore(); 142 143 lightPos.fX += 320; 144 xPos += 320; 145 clipRect.offset(clipDelta); 146 zPlaneParams.fZ = kDP * 16; 147 canvas->save(); 148 canvas->clipRect(clipRect); 149 canvas->translate(xPos, yPos); 150 this->drawShadowedPath(canvas, fRRectPath, zPlaneParams, paint, kAmbientAlpha, 151 lightPos, kLightWidth, kSpotAlpha); 152 canvas->restore(); 153 154 } 155 156 private: drawBG(SkCanvas * canvas)157 void drawBG(SkCanvas* canvas) { 158 canvas->drawColor(0xFFFFFFFF); 159 canvas->drawImage(fReferenceImage, 10, 30); 160 } 161 drawShadowedPath(SkCanvas * canvas,const SkPath & path,const SkPoint3 & zPlaneParams,const SkPaint & paint,SkScalar ambientAlpha,const SkPoint3 & lightPos,SkScalar lightWidth,SkScalar spotAlpha)162 void drawShadowedPath(SkCanvas* canvas, const SkPath& path, 163 const SkPoint3& zPlaneParams, 164 const SkPaint& paint, SkScalar ambientAlpha, 165 const SkPoint3& lightPos, SkScalar lightWidth, SkScalar spotAlpha) { 166 if (!fShowAmbient) { 167 ambientAlpha = 0; 168 } 169 if (!fShowSpot) { 170 spotAlpha = 0; 171 } 172 uint32_t flags = 0; 173 if (fUseAlt) { 174 flags |= SkShadowFlags::kGeometricOnly_ShadowFlag; 175 } 176 177 SkColor ambientColor = SkColorSetARGB(ambientAlpha * 255, 0, 0, 0); 178 SkColor spotColor = SkColorSetARGB(spotAlpha * 255, 0, 0, 0); 179 SkShadowUtils::DrawShadow(canvas, path, zPlaneParams, 180 lightPos, lightWidth, 181 ambientColor, spotColor, flags); 182 183 if (fShowObject) { 184 canvas->drawPath(path, paint); 185 } else { 186 SkPaint strokePaint; 187 188 strokePaint.setColor(paint.getColor()); 189 strokePaint.setStyle(SkPaint::kStroke_Style); 190 191 canvas->drawPath(path, strokePaint); 192 } 193 } 194 }; 195 196 ////////////////////////////////////////////////////////////////////////////// 197 198 DEF_SLIDE( return new ShadowRefSlide(); ) 199