1 /* 2 * Copyright (c) 2023-2024 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_INTERFACE_INNERAPI_DRAWABLE_DESCRIPTOR_H 17 #define FOUNDATION_ACE_INTERFACE_INNERAPI_DRAWABLE_DESCRIPTOR_H 18 19 #define ACE_FORCE_EXPORT __attribute__((visibility("default"))) 20 21 #ifndef ACE_EXPORT 22 #ifndef HIDDEN_SYMBOL 23 #define ACE_EXPORT ACE_FORCE_EXPORT 24 #else 25 #define ACE_EXPORT 26 #endif 27 #endif 28 29 #include <optional> 30 #include <string> 31 #include <tuple> 32 #include <utility> 33 34 #include "image_converter.h" 35 #ifndef USE_ROSEN_DRAWING 36 #include "include/core/SkBlendMode.h" 37 #include "include/core/SkCanvas.h" 38 #include "include/core/SkPaint.h" 39 #else 40 #include "draw/canvas.h" 41 #include "image/bitmap.h" 42 #include "image/image_info.h" 43 #endif 44 #include "resource_manager.h" 45 46 #include "drawable_descriptor_log.h" 47 48 namespace OHOS::Ace::Napi { 49 using OptionalPixelMap = std::optional<std::shared_ptr<Media::PixelMap>>; 50 struct DrawableItem { 51 using RState = Global::Resource::RState; 52 std::unique_ptr<uint8_t[]> data_; 53 size_t len_ = 0; 54 RState state_ = Global::Resource::ERROR; 55 }; 56 57 class ACE_EXPORT DrawableDescriptor { 58 public: 59 enum class DrawableType { 60 BASE, 61 LAYERED, 62 ANIMATED, 63 PIXELMAP, 64 }; 65 DrawableDescriptor() = default; DrawableDescriptor(std::shared_ptr<Media::PixelMap> pixelMap)66 explicit DrawableDescriptor(std::shared_ptr<Media::PixelMap> pixelMap) : pixelMap_(std::move(pixelMap)) {}; DrawableDescriptor(std::unique_ptr<uint8_t[]> mediaData,size_t len)67 DrawableDescriptor(std::unique_ptr<uint8_t[]> mediaData, size_t len) 68 : mediaData_(std::move(mediaData)), len_(len) {}; 69 virtual ~DrawableDescriptor() = default; 70 virtual std::shared_ptr<Media::PixelMap> GetPixelMap(); 71 virtual DrawableType GetDrawableType(); SetPixelMap(std::shared_ptr<Media::PixelMap> pixelMap)72 void SetPixelMap(std::shared_ptr<Media::PixelMap> pixelMap) 73 { 74 pixelMap_ = pixelMap; 75 } HasPixelMap()76 bool HasPixelMap() 77 { 78 return pixelMap_.has_value(); 79 } ResetPixelMap()80 void ResetPixelMap() 81 { 82 pixelMap_.reset(); 83 } 84 85 private: 86 bool GetPixelMapFromBuffer(); 87 88 std::unique_ptr<uint8_t[]> mediaData_; 89 size_t len_ = 0; 90 OptionalPixelMap pixelMap_; 91 }; 92 93 class ACE_EXPORT LayeredDrawableDescriptor : public DrawableDescriptor { 94 public: 95 LayeredDrawableDescriptor() = default; LayeredDrawableDescriptor(std::unique_ptr<uint8_t[]> jsonBuf,size_t len,const std::shared_ptr<Global::Resource::ResourceManager> & resourceMgr)96 LayeredDrawableDescriptor(std::unique_ptr<uint8_t[]> jsonBuf, size_t len, 97 const std::shared_ptr<Global::Resource::ResourceManager>& resourceMgr) 98 : jsonBuf_(std::move(jsonBuf)), len_(len) 99 { 100 InitialResource(resourceMgr); 101 jsonBuf_.reset(); 102 }; LayeredDrawableDescriptor(std::unique_ptr<uint8_t[]> jsonBuf,size_t len,const std::shared_ptr<Global::Resource::ResourceManager> & resourceMgr,std::string path,uint32_t iconType,uint32_t density)103 LayeredDrawableDescriptor(std::unique_ptr<uint8_t[]> jsonBuf, size_t len, 104 const std::shared_ptr<Global::Resource::ResourceManager>& resourceMgr, std::string path, uint32_t iconType, 105 uint32_t density) 106 : jsonBuf_(std::move(jsonBuf)), len_(len), maskPath_(std::move(path)), iconType_(iconType), density_(density) 107 { 108 InitialResource(resourceMgr); 109 jsonBuf_.reset(); 110 }; LayeredDrawableDescriptor(std::unique_ptr<uint8_t[]> jsonBuf,size_t len,const std::shared_ptr<Global::Resource::ResourceManager> & resourceMgr,std::string path,uint32_t iconType,std::pair<std::unique_ptr<uint8_t[]>,size_t> & foregroundInfo,std::pair<std::unique_ptr<uint8_t[]>,size_t> & backgroundInfo)111 LayeredDrawableDescriptor(std::unique_ptr<uint8_t[]> jsonBuf, size_t len, 112 const std::shared_ptr<Global::Resource::ResourceManager>& resourceMgr, std::string path, uint32_t iconType, 113 std::pair<std::unique_ptr<uint8_t[]>, size_t>& foregroundInfo, 114 std::pair<std::unique_ptr<uint8_t[]>, size_t>& backgroundInfo) 115 : jsonBuf_(std::move(jsonBuf)), len_(len), maskPath_(std::move(path)), iconType_(iconType) 116 { 117 InitLayeredParam(foregroundInfo, backgroundInfo); 118 InitialResource(resourceMgr); 119 jsonBuf_.reset(); 120 }; 121 122 ~LayeredDrawableDescriptor() override = default; 123 std::unique_ptr<DrawableDescriptor> GetForeground(); 124 std::unique_ptr<DrawableDescriptor> GetBackground(); 125 std::unique_ptr<DrawableDescriptor> GetMask(); 126 std::shared_ptr<Media::PixelMap> GetPixelMap() override; 127 DrawableType GetDrawableType() override; 128 static std::string GetStaticMaskClipPath(); 129 void InitLayeredParam(std::pair<std::unique_ptr<uint8_t[]>, size_t> &foregroundInfo, 130 std::pair<std::unique_ptr<uint8_t[]>, size_t> &backgroundInfo); SetForeground(std::shared_ptr<Media::PixelMap> foreground)131 void SetForeground(std::shared_ptr<Media::PixelMap> foreground) 132 { 133 foreground_ = foreground; 134 customized_ = true; 135 } 136 SetBackground(std::shared_ptr<Media::PixelMap> background)137 void SetBackground(std::shared_ptr<Media::PixelMap> background) 138 { 139 background_ = background; 140 customized_ = true; 141 } 142 SetMask(std::shared_ptr<Media::PixelMap> mask)143 void SetMask(std::shared_ptr<Media::PixelMap> mask) 144 { 145 mask_ = mask; 146 customized_ = true; 147 } 148 Customized()149 bool Customized() 150 { 151 return customized_; 152 } 153 154 void InitialMask(const std::shared_ptr<Global::Resource::ResourceManager>& resourceMgr); 155 bool GetDefaultMask(); 156 157 bool GetCompositePixelMapWithBadge( 158 const std::shared_ptr<Media::PixelMap> layeredPixelMap, 159 const std::shared_ptr<Media::PixelMap> badgedPixelMap, 160 std::shared_ptr<Media::PixelMap> &compositePixelMap); 161 162 private: 163 friend class ImageConverter; 164 void InitialResource(const std::shared_ptr<Global::Resource::ResourceManager>& resourceMgr); 165 bool PreGetPixelMapFromJsonBuf( 166 const std::shared_ptr<Global::Resource::ResourceManager>& resourceMgr, bool isBackground); 167 DrawableItem PreGetDrawableItem( 168 const std::shared_ptr<Global::Resource::ResourceManager>& resourceMgr, const char* item); 169 std::unique_ptr<Media::ImageSource> CreateImageSource(DrawableItem& drawableItem, uint32_t& errorCode); 170 bool GetPixelMapFromJsonBuf(bool isBackground); 171 bool GetMaskByName(std::shared_ptr<Global::Resource::ResourceManager>& resourceMgr, const std::string& name); 172 bool CreatePixelMap(); 173 bool GetMaskByPath(); 174 #ifndef USE_ROSEN_DRAWING 175 void DrawOntoCanvas( 176 const std::shared_ptr<SkBitmap>& bitMap, float width, float height, SkCanvas& canvas, const SkPaint& paint); 177 #else 178 bool GetLayeredIconParm(std::shared_ptr<Rosen::Drawing::Bitmap>& foreground, 179 std::shared_ptr<Rosen::Drawing::Bitmap>& background, std::shared_ptr<Rosen::Drawing::Bitmap>& mask); 180 Rosen::Drawing::ImageInfo ImageInfo(); 181 void CompositeIconNotAdaptive(std::shared_ptr<Rosen::Drawing::Bitmap>& foreground, 182 std::shared_ptr<Rosen::Drawing::Bitmap>& background, std::shared_ptr<Rosen::Drawing::Bitmap>& mask); 183 void CompositeIconAdaptive(std::shared_ptr<Rosen::Drawing::Bitmap>& foreground, 184 std::shared_ptr<Rosen::Drawing::Bitmap>& background, std::shared_ptr<Rosen::Drawing::Bitmap>& mask); 185 Rosen::Drawing::ImageInfo CreateRSImageInfo(OptionalPixelMap pixelmap, int32_t width, int32_t height); 186 void TransformToPixelMap(const Rosen::Drawing::Bitmap& bitmap, const Rosen::Drawing::ImageInfo& imageInfo); 187 void DrawOntoCanvas(const std::shared_ptr<Rosen::Drawing::Bitmap>& bitMap, float width, float height, 188 Rosen::Drawing::Canvas& canvas); 189 void BlendForeground(Rosen::Drawing::Canvas& bitmapCanvas, Rosen::Drawing::Brush& brush, 190 Rosen::Drawing::Image& image, const std::shared_ptr<Rosen::Drawing::Bitmap>& background, 191 const std::shared_ptr<Rosen::Drawing::Bitmap>& foreground); 192 #endif 193 194 std::unique_ptr<uint8_t[]> defaultMaskData_; 195 size_t defaultMaskDataLength_ = 0; 196 DrawableItem backgroundItem_; 197 DrawableItem foregroundItem_; 198 std::unique_ptr<uint8_t[]> jsonBuf_; 199 size_t len_ = 0; 200 std::string maskPath_; 201 uint32_t iconType_ = 0; 202 uint32_t density_ = 0; 203 OptionalPixelMap foreground_; 204 OptionalPixelMap background_; 205 OptionalPixelMap mask_; 206 OptionalPixelMap layeredPixelMap_; 207 bool customized_ = false; 208 }; 209 210 class ACE_EXPORT AnimatedDrawableDescriptor : public DrawableDescriptor { 211 public: AnimatedDrawableDescriptor(std::vector<std::shared_ptr<Media::PixelMap>> pixelMaps,int32_t duration,int32_t iterations)212 AnimatedDrawableDescriptor(std::vector<std::shared_ptr<Media::PixelMap>> pixelMaps, int32_t duration, 213 int32_t iterations): pixelMapList_(std::move(pixelMaps)), duration_(duration), iterations_(iterations) {}; 214 ~AnimatedDrawableDescriptor() override = default; 215 std::shared_ptr<Media::PixelMap> GetPixelMap() override; 216 DrawableType GetDrawableType() override; 217 std::vector<std::shared_ptr<Media::PixelMap>> GetPixelMapList(); 218 int32_t GetDuration(); 219 int32_t GetIterations(); 220 void SetDuration(int32_t duration); 221 void SetIterations(int32_t iterations); 222 private: 223 std::vector<std::shared_ptr<Media::PixelMap>> pixelMapList_; 224 int32_t duration_ = -1; 225 int32_t iterations_ = 1; 226 }; 227 228 class DrawableDescriptorFactory { 229 public: 230 using DrawableType = DrawableDescriptor::DrawableType; 231 using ResourceManager = Global::Resource::ResourceManager; 232 using RState = Global::Resource::RState; Create(int32_t id,const std::shared_ptr<ResourceManager> & resourceMgr,RState & state,DrawableType & drawableType,uint32_t density)233 static std::unique_ptr<DrawableDescriptor> Create(int32_t id, const std::shared_ptr<ResourceManager>& resourceMgr, 234 RState& state, DrawableType& drawableType, uint32_t density) 235 { 236 std::string type; 237 size_t len; 238 std::unique_ptr<uint8_t[]> jsonBuf; 239 state = resourceMgr->GetDrawableInfoById(id, type, len, jsonBuf, density); 240 if (state != Global::Resource::SUCCESS) { 241 HILOGE("Failed to get drawable info from resmgr"); 242 return nullptr; 243 } 244 transform(type.begin(), type.end(), type.begin(), ::tolower); 245 if (type == "json") { 246 HILOGD("Create LayeredDrawableDescriptor object"); 247 drawableType = DrawableDescriptor::DrawableType::LAYERED; 248 state = Global::Resource::SUCCESS; 249 return std::make_unique<LayeredDrawableDescriptor>(std::move(jsonBuf), len, resourceMgr); 250 } 251 if (type == "png" || type == "jpg" || type == "bmp" || type == "svg" || type == "gif" || type == "webp" || 252 type == "astc" || type == "sut") { 253 HILOGD("Create DrawableDescriptor object"); 254 drawableType = DrawableDescriptor::DrawableType::BASE; 255 state = Global::Resource::SUCCESS; 256 return std::make_unique<DrawableDescriptor>(std::move(jsonBuf), len); 257 } 258 HILOGE("unknow resource type: %{public}s", type.c_str()); 259 state = Global::Resource::INVALID_FORMAT; 260 return nullptr; 261 } 262 Create(const char * name,const std::shared_ptr<ResourceManager> & resourceMgr,RState & state,DrawableType & drawableType,uint32_t density)263 static std::unique_ptr<DrawableDescriptor> Create(const char* name, 264 const std::shared_ptr<ResourceManager>& resourceMgr, RState& state, DrawableType& drawableType, 265 uint32_t density) 266 { 267 std::string type; 268 size_t len; 269 std::unique_ptr<uint8_t[]> jsonBuf; 270 state = resourceMgr->GetDrawableInfoByName(name, type, len, jsonBuf, density); 271 if (state != Global::Resource::SUCCESS) { 272 HILOGE("Failed to get drawable info from resmgr"); 273 return nullptr; 274 } 275 transform(type.begin(), type.end(), type.begin(), ::tolower); 276 if (type == "json") { 277 HILOGD("Create LayeredDrawableDescriptor object"); 278 drawableType = DrawableDescriptor::DrawableType::LAYERED; 279 state = Global::Resource::SUCCESS; 280 return std::make_unique<LayeredDrawableDescriptor>(std::move(jsonBuf), len, resourceMgr); 281 } 282 if (type == "png" || type == "jpg" || type == "bmp" || type == "svg" || type == "gif" || type == "webp" || 283 type == "astc" || type == "sut") { 284 HILOGD("Create DrawableDescriptor object"); 285 drawableType = DrawableDescriptor::DrawableType::BASE; 286 state = Global::Resource::SUCCESS; 287 return std::make_unique<DrawableDescriptor>(std::move(jsonBuf), len); 288 } 289 HILOGE("unknow resource type: %{public}s", type.c_str()); 290 state = Global::Resource::INVALID_FORMAT; 291 return nullptr; 292 } 293 Create(std::tuple<int32_t,uint32_t,uint32_t> & drawableInfo,const std::shared_ptr<ResourceManager> & resourceMgr,RState & state,DrawableType & drawableType)294 static std::unique_ptr<DrawableDescriptor> Create(std::tuple<int32_t, uint32_t, uint32_t>& drawableInfo, 295 const std::shared_ptr<ResourceManager>& resourceMgr, RState& state, DrawableType& drawableType) 296 { 297 int32_t resId = std::get<0>(drawableInfo); 298 uint32_t iconType = std::get<1>(drawableInfo); 299 uint32_t density = std::get<2>(drawableInfo); 300 std::unique_ptr<uint8_t[]> jsonBuf; 301 std::tuple<std::string, size_t, std::string> info; 302 state = resourceMgr->GetDrawableInfoById(resId, info, jsonBuf, iconType, density); 303 if (state != Global::Resource::SUCCESS) { 304 HILOGW("Failed to get drawable info from resmgr"); 305 return nullptr; 306 } 307 std::string type = std::get<0>(info); 308 size_t len = std::get<1>(info); 309 std::string path = std::get<2>(info); 310 transform(type.begin(), type.end(), type.begin(), ::tolower); 311 if (type == "json") { 312 HILOGD("Create LayeredDrawableDescriptor object"); 313 drawableType = DrawableDescriptor::DrawableType::LAYERED; 314 auto layeredDrawableDescriptor = 315 std::make_unique<LayeredDrawableDescriptor>(std::move(jsonBuf), len, resourceMgr, 316 path, iconType, density); 317 return layeredDrawableDescriptor; 318 } 319 if (type == "png" || type == "jpg" || type == "bmp" || type == "svg" || type == "gif" || type == "webp" || 320 type == "astc" || type == "sut") { 321 HILOGD("Create DrawableDescriptor object"); 322 drawableType = DrawableDescriptor::DrawableType::BASE; 323 return std::make_unique<DrawableDescriptor>(std::move(jsonBuf), len); 324 } 325 HILOGE("unknow resource type: %{public}s", type.c_str()); 326 state = Global::Resource::INVALID_FORMAT; 327 return nullptr; 328 } 329 Create(std::tuple<const char *,uint32_t,uint32_t> & drawableInfo,const std::shared_ptr<ResourceManager> & resourceMgr,RState & state,DrawableType & drawableType)330 static std::unique_ptr<DrawableDescriptor> Create(std::tuple<const char*, uint32_t, uint32_t>& drawableInfo, 331 const std::shared_ptr<ResourceManager>& resourceMgr, RState& state, DrawableType& drawableType) 332 { 333 const char* name = std::get<0>(drawableInfo); 334 uint32_t iconType = std::get<1>(drawableInfo); 335 uint32_t density = std::get<2>(drawableInfo); 336 std::unique_ptr<uint8_t[]> jsonBuf; 337 std::tuple<std::string, size_t, std::string> info; 338 state = resourceMgr->GetDrawableInfoByName(name, info, jsonBuf, iconType, density); 339 if (state != Global::Resource::SUCCESS) { 340 HILOGW("Failed to get drawable info from resmgr"); 341 return nullptr; 342 } 343 std::string type = std::get<0>(info); 344 size_t len = std::get<1>(info); 345 std::string path = std::get<2>(info); 346 transform(type.begin(), type.end(), type.begin(), ::tolower); 347 if (type == "json") { 348 HILOGD("Create LayeredDrawableDescriptor object"); 349 drawableType = DrawableDescriptor::DrawableType::LAYERED; 350 auto layeredDrawableDescriptor = std::make_unique<LayeredDrawableDescriptor>( 351 std::move(jsonBuf), len, resourceMgr, path, iconType, density); 352 return layeredDrawableDescriptor; 353 } 354 if (type == "png" || type == "jpg" || type == "bmp" || type == "svg" || type == "gif" || type == "webp" || 355 type == "astc" || type == "sut") { 356 HILOGD("Create DrawableDescriptor object"); 357 drawableType = DrawableDescriptor::DrawableType::BASE; 358 return std::make_unique<DrawableDescriptor>(std::move(jsonBuf), len); 359 } 360 HILOGE("unknow resource type: %{public}s", type.c_str()); 361 state = Global::Resource::INVALID_FORMAT; 362 return nullptr; 363 } 364 Create(std::pair<std::unique_ptr<uint8_t[]>,size_t> & foregroundInfo,std::pair<std::unique_ptr<uint8_t[]>,size_t> & backgroundInfo,std::string & path,DrawableType & drawableType,const std::shared_ptr<ResourceManager> & resourceMgr)365 static std::unique_ptr<DrawableDescriptor> Create(std::pair<std::unique_ptr<uint8_t[]>, size_t> &foregroundInfo, 366 std::pair<std::unique_ptr<uint8_t[]>, size_t> &backgroundInfo, std::string &path, DrawableType& drawableType, 367 const std::shared_ptr<ResourceManager>& resourceMgr) 368 { 369 std::unique_ptr<uint8_t[]> jsonBuf; 370 drawableType = DrawableDescriptor::DrawableType::LAYERED; 371 auto layeredDrawableDescriptor = std::make_unique<LayeredDrawableDescriptor>( 372 std::move(jsonBuf), 0, resourceMgr, path, 1, foregroundInfo, backgroundInfo); 373 return layeredDrawableDescriptor; 374 } 375 }; 376 } // namespace OHOS::Ace::Napi 377 #endif // FOUNDATION_ACE_INTERFACE_INNERAPI_DRAWABLE_DESCRIPTOR_H 378