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