• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_SHADOW_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_SHADOW_H
18 
19 #include <functional>
20 #include "base/geometry/offset.h"
21 #include "core/components/common/properties/color.h"
22 #include "core/common/resource/resource_object.h"
23 
24 namespace OHOS::Ace {
25 
26 constexpr float LIGHT_HEIGHT = 600.0f; // System recommended value.
27 constexpr float LIGHT_RADIUS = 800.0f; // System recommended value.
28 constexpr float LIGHT_POSITION_X = 540.0f; // System recommended value.
29 constexpr float LIGHT_POSITION_Y = 0.0f; // System recommended value.
30 
31 enum class ShadowStyle {
32     OuterDefaultXS,
33     OuterDefaultSM,
34     OuterDefaultMD,
35     OuterDefaultLG,
36     OuterFloatingSM,
37     OuterFloatingMD,
38     None,
39 };
40 
41 enum class ShadowType {
42     COLOR,
43     BLUR,
44 };
45 
46 enum class ShadowColorStrategy : char {
47     NONE,
48     AVERAGE,
49     PRIMARY,
50 };
51 // A style class indicates the way to render shadow effect
52 class ACE_FORCE_EXPORT Shadow final {
53 public:
54     static Shadow Blend(const Shadow& to, const Shadow& from, float progress);
55 
56     Shadow() = default;
57     ~Shadow() = default;
58 
59     // create shadow for hardware rending.
Shadow(float elevation,Offset offset,Color spotColor,ShadowStyle style)60     Shadow(float elevation, Offset offset, Color spotColor, ShadowStyle style)
61         : offset_(offset), color_(spotColor), style_(style)
62     {
63         SetElevation(elevation);
64     };
65 
66      // create shadow for hardware rending.
Shadow(double radius,Offset offset,Color spotColor,ShadowStyle style)67     Shadow(double radius, Offset offset, Color spotColor, ShadowStyle style)
68         : offset_(offset), color_(spotColor), style_(style)
69     {
70         SetBlurRadius(radius);
71     };
72 
73     // create shadow for software rending.
Shadow(double blurRadius,double spreadRadius,Offset offset,Color spotColor)74     Shadow(double blurRadius, double spreadRadius, Offset offset, Color spotColor)
75         : spreadRadius_(spreadRadius), offset_(offset), color_(spotColor)
76     {
77         SetBlurRadius(blurRadius);
78     };
79 
80     static Shadow CreateShadow(ShadowStyle style);
81 
82     static void RegisterShadowResourceObj(Shadow& shadow,
83         RefPtr<ResourceObject>& radiusObj, RefPtr<ResourceObject>& colorObj,
84         RefPtr<ResourceObject>& offsetXObj, RefPtr<ResourceObject>& offsetYObj);
85 
86     bool operator==(const Shadow& rhs) const
87     {
88         return color_ == rhs.color_ && NearEqual(blurRadius_, rhs.blurRadius_) && offset_ == rhs.offset_ &&
89                NearEqual(spreadRadius_, rhs.spreadRadius_) && NearEqual(elevation_, rhs.elevation_) &&
90                isFilled_ == rhs.isFilled_ && colorStrategy_ == rhs.colorStrategy_ && type_ == rhs.type_;
91     }
92 
93     bool operator!=(const Shadow& rhs) const
94     {
95         return !(rhs == *this);
96     }
97 
SetColor(const Color & newColor)98     void SetColor(const Color& newColor)
99     {
100         color_ = newColor;
101     }
102 
GetColor()103     const Color& GetColor() const
104     {
105         return color_;
106     }
107 
SetBlurRadius(double blurRadius)108     void SetBlurRadius(double blurRadius)
109     {
110         if (blurRadius >= 0.0) {
111             blurRadius_ = blurRadius;
112             isHardwareAcceleration_ = false;
113             return;
114         }
115         blurRadius_ = 0.0;
116     }
117 
GetBlurRadius()118     double GetBlurRadius() const
119     {
120         return blurRadius_;
121     }
122 
SetOffset(const Offset & offset)123     void SetOffset(const Offset& offset)
124     {
125         offset_ = offset;
126     }
127 
GetOffset()128     const Offset& GetOffset() const
129     {
130         return offset_;
131     }
132 
SetOffsetX(double x)133     void SetOffsetX(double x)
134     {
135         offset_.SetX(x);
136     }
137 
SetOffsetY(double y)138     void SetOffsetY(double y)
139     {
140         offset_.SetY(y);
141     }
142 
SetSpreadRadius(double spreadRadius)143     void SetSpreadRadius(double spreadRadius)
144     {
145         spreadRadius_ = spreadRadius;
146         isHardwareAcceleration_ = false;
147     }
148 
GetSpreadRadius()149     double GetSpreadRadius() const
150     {
151         return spreadRadius_;
152     }
153 
SetElevation(float elevation)154     void SetElevation(float elevation)
155     {
156         if (elevation >= 0.0f && elevation < LIGHT_HEIGHT) {
157             elevation_ = elevation;
158             isHardwareAcceleration_ = true;
159             return;
160         }
161         elevation_ = 0.0f;
162     }
163 
GetElevation()164     float GetElevation() const
165     {
166         return elevation_;
167     }
168 
SetHardwareAcceleration(bool acceleration)169     void SetHardwareAcceleration(bool acceleration)
170     {
171         isHardwareAcceleration_ = acceleration;
172     }
173 
SetIsFilled(bool isFilled)174     void SetIsFilled(bool isFilled)
175     {
176         isFilled_ = isFilled;
177     }
178 
GetHardwareAcceleration()179     bool GetHardwareAcceleration() const
180     {
181         return isHardwareAcceleration_;
182     }
183 
SetLightHeight(float lightHeight)184     void SetLightHeight(float lightHeight)
185     {
186         if (lightHeight > 0.0f) {
187             lightHeight_ = lightHeight;
188         }
189     }
190 
GetLightHeight()191     float GetLightHeight() const
192     {
193         return lightHeight_;
194     }
195 
SetLightRadius(float lightRadius)196     void SetLightRadius(float lightRadius)
197     {
198         if (lightRadius > 0.0f) {
199             lightRadius_ = lightRadius;
200         }
201     }
202 
GetLightRadius()203     float GetLightRadius() const
204     {
205         return lightRadius_;
206     }
207 
GetStyle()208     ShadowStyle GetStyle() const
209     {
210         return style_;
211     }
212 
SetShadowType(ShadowType type)213     void SetShadowType(ShadowType type)
214     {
215         type_ = type;
216     }
217 
GetShadowType()218     ShadowType GetShadowType() const
219     {
220         return type_;
221     }
222 
SetShadowColorStrategy(ShadowColorStrategy colorStrategy)223     void SetShadowColorStrategy(ShadowColorStrategy colorStrategy)
224     {
225         colorStrategy_ = colorStrategy;
226     }
227 
GetShadowColorStrategy()228     ShadowColorStrategy GetShadowColorStrategy() const
229     {
230         return colorStrategy_;
231     }
232 
GetIsFilled()233     bool GetIsFilled() const
234     {
235         return isFilled_;
236     }
237 
IsValid()238     bool IsValid() const
239     {
240         if (isHardwareAcceleration_) {
241             return elevation_ > 0.0f && elevation_ < LIGHT_HEIGHT;
242         }
243         return blurRadius_ > 0.0 || spreadRadius_ > 0.0 || offset_ != Offset::Zero();
244     }
245 
UpdateColorByResourceId()246     void UpdateColorByResourceId()
247     {
248         color_.UpdateColorByResourceId();
249     }
250 
AddResource(const std::string & key,const RefPtr<ResourceObject> & resObj,std::function<void (const RefPtr<ResourceObject> &,Shadow &)> && updateFunc)251     void AddResource(
252         const std::string& key,
253         const RefPtr<ResourceObject>& resObj,
254         std::function<void(const RefPtr<ResourceObject>&, Shadow&)>&& updateFunc)
255     {
256         if (resObj == nullptr || !updateFunc) {
257             return;
258         }
259         resMap_[key] = {resObj, std::move(updateFunc)};
260     }
261 
ReloadResources()262     void ReloadResources()
263     {
264         for (const auto& [key, resourceUpdater] : resMap_) {
265             resourceUpdater.updateFunc(resourceUpdater.resObj, *this);
266         }
267     }
268 
269 private:
270     float lightHeight_ = LIGHT_HEIGHT;
271     float lightRadius_ = LIGHT_RADIUS;
272     float elevation_ = 0.0f; // Rosen always needs a non-zero elevation.
273     double blurRadius_ = 0.0;
274     double spreadRadius_ = 0.0;
275     Offset offset_;
276     Color color_ = Color::BLACK;
277     bool isHardwareAcceleration_ = false;
278     bool isFilled_ = false;
279     struct resourceUpdater {
280         RefPtr<ResourceObject> resObj;
281         std::function<void(const RefPtr<ResourceObject>&, Shadow&)> updateFunc;
282     };
283 
284     std::unordered_map<std::string, resourceUpdater> resMap_;
285     ShadowStyle style_ = ShadowStyle::None;
286     ShadowType type_ = ShadowType::COLOR;
287     ShadowColorStrategy colorStrategy_ = ShadowColorStrategy::NONE;
288 };
289 
290 } // namespace OHOS::Ace
291 
292 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BASE_PROPERTIES_SHADOW_H
293