/src/skia/modules/skottie/src/effects/DropShadowEffect.cpp
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2019 Google Inc. |
3 | | * |
4 | | * Use of this source code is governed by a BSD-style license that can be |
5 | | * found in the LICENSE file. |
6 | | */ |
7 | | |
8 | | #include "include/core/SkColor.h" |
9 | | #include "include/core/SkPoint.h" |
10 | | #include "include/core/SkRefCnt.h" |
11 | | #include "include/core/SkScalar.h" |
12 | | #include "include/private/base/SkTPin.h" |
13 | | #include "include/private/base/SkTo.h" |
14 | | #include "modules/skottie/src/SkottiePriv.h" |
15 | | #include "modules/skottie/src/SkottieValue.h" |
16 | | #include "modules/skottie/src/animator/Animator.h" |
17 | | #include "modules/skottie/src/effects/Effects.h" |
18 | | #include "modules/sksg/include/SkSGRenderEffect.h" |
19 | | #include "modules/sksg/include/SkSGRenderNode.h" |
20 | | |
21 | | #include <cstddef> |
22 | | #include <utility> |
23 | | |
24 | | namespace skjson { |
25 | | class ArrayValue; |
26 | | } |
27 | | |
28 | | namespace skottie { |
29 | | namespace internal { |
30 | | |
31 | | namespace { |
32 | | |
33 | | class DropShadowAdapter final : public AnimatablePropertyContainer { |
34 | | public: |
35 | | static sk_sp<DropShadowAdapter> Make(const skjson::ArrayValue& jprops, |
36 | | sk_sp<sksg::RenderNode> layer, |
37 | 9.91k | const AnimationBuilder& abuilder) { |
38 | 9.91k | enum : size_t { |
39 | 9.91k | kShadowColor_Index = 0, |
40 | 9.91k | kOpacity_Index = 1, |
41 | 9.91k | kDirection_Index = 2, |
42 | 9.91k | kDistance_Index = 3, |
43 | 9.91k | kSoftness_Index = 4, |
44 | 9.91k | kShadowOnly_Index = 5, |
45 | 9.91k | }; |
46 | | |
47 | 9.91k | sk_sp<DropShadowAdapter> adapter(new DropShadowAdapter(std::move(layer))); |
48 | | |
49 | 9.91k | EffectBinder(jprops, abuilder, adapter.get()) |
50 | 9.91k | .bind(kShadowColor_Index, adapter->fColor ) |
51 | 9.91k | .bind( kOpacity_Index, adapter->fOpacity ) |
52 | 9.91k | .bind( kDirection_Index, adapter->fDirection) |
53 | 9.91k | .bind( kDistance_Index, adapter->fDistance ) |
54 | 9.91k | .bind( kSoftness_Index, adapter->fSoftness ) |
55 | 9.91k | .bind( kShadowOnly_Index, adapter->fShdwOnly ); |
56 | | |
57 | 9.91k | return adapter; |
58 | 9.91k | } |
59 | | |
60 | 9.91k | const sk_sp<sksg::RenderNode>& node() const { return fImageFilterEffect; } |
61 | | |
62 | | private: |
63 | | explicit DropShadowAdapter(sk_sp<sksg::RenderNode> layer) |
64 | | : fDropShadow(sksg::DropShadowImageFilter::Make()) |
65 | 9.91k | , fImageFilterEffect(sksg::ImageFilterEffect::Make(std::move(layer), fDropShadow)) {} |
66 | | |
67 | 9.91k | void onSync() override { |
68 | | // fColor -> RGB, fOpacity -> A |
69 | 9.91k | const SkColor color = fColor; |
70 | 9.91k | fDropShadow->setColor(SkColorSetA(color, SkTPin(SkScalarRoundToInt(fOpacity), 0, 255))); |
71 | | |
72 | | // The offset is specified in terms of a bearing + distance. |
73 | 9.91k | const auto rad = SkDegreesToRadians(90 - fDirection); |
74 | 9.91k | fDropShadow->setOffset(SkVector::Make( fDistance * SkScalarCos(rad), |
75 | 9.91k | -fDistance * SkScalarSin(rad))); |
76 | | |
77 | 9.91k | const auto sigma = fSoftness * kBlurSizeToSigma; |
78 | 9.91k | fDropShadow->setSigma(SkVector::Make(sigma, sigma)); |
79 | | |
80 | 9.91k | fDropShadow->setMode(SkToBool(fShdwOnly) |
81 | 9.91k | ? sksg::DropShadowImageFilter::Mode::kShadowOnly |
82 | 9.91k | : sksg::DropShadowImageFilter::Mode::kShadowAndForeground); |
83 | 9.91k | } |
84 | | |
85 | | const sk_sp<sksg::DropShadowImageFilter> fDropShadow; |
86 | | const sk_sp<sksg::RenderNode> fImageFilterEffect; |
87 | | |
88 | | ColorValue fColor = { 0, 0, 0, 1 }; |
89 | | ScalarValue fOpacity = 255, |
90 | | fDirection = 0, |
91 | | fDistance = 0, |
92 | | fSoftness = 0, |
93 | | fShdwOnly = 0; |
94 | | }; |
95 | | |
96 | | } // namespace |
97 | | |
98 | | sk_sp<sksg::RenderNode> EffectBuilder::attachDropShadowEffect(const skjson::ArrayValue& jprops, |
99 | 9.91k | sk_sp<sksg::RenderNode> layer) const { |
100 | 9.91k | return fBuilder->attachDiscardableAdapter<DropShadowAdapter>(jprops, |
101 | 9.91k | std::move(layer), |
102 | 9.91k | *fBuilder); |
103 | 9.91k | } |
104 | | |
105 | | } // namespace internal |
106 | | } // namespace skottie |