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