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