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