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