1 /* 2 * Copyright (c) 2022-2023 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_NG_PATTERNS_IMAGE_IMAGE_PATTERN_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_IMAGE_IMAGE_PATTERN_H 18 19 #include <memory> 20 21 #include "base/geometry/offset.h" 22 #include "base/memory/referenced.h" 23 #include "core/animation/animator.h" 24 #include "core/animation/picture_animation.h" 25 #include "core/components/common/layout/constants.h" 26 #include "core/components/declaration/image/image_animator_declaration.h" 27 #include "core/components_ng/event/click_event.h" 28 #include "core/components_ng/manager/select_overlay/selection_host.h" 29 #include "core/components_ng/pattern/image/image_event_hub.h" 30 #include "core/components_ng/pattern/image/image_layout_algorithm.h" 31 #include "core/components_ng/pattern/image/image_layout_property.h" 32 #include "core/components_ng/pattern/image/image_overlay_modifier.h" 33 #include "core/components_ng/pattern/image/image_render_property.h" 34 #include "core/components_ng/pattern/pattern.h" 35 #include "core/components_ng/manager/select_overlay/select_overlay_client.h" 36 #include "core/components_ng/render/canvas_image.h" 37 #include "core/image/image_source_info.h" 38 #include "interfaces/inner_api/ace/ai/image_analyzer.h" 39 40 namespace OHOS::Ace { 41 class ImageAnalyzerManager; 42 } 43 44 namespace OHOS::Ace::NG { 45 class InspectorFilter; 46 47 class ACE_FORCE_EXPORT ImagePattern : public Pattern, public SelectOverlayClient { 48 DECLARE_ACE_TYPE(ImagePattern, Pattern, SelectionHost); 49 50 public: 51 enum class ImageType { 52 BASE, 53 ANIMATION, 54 UNDEFINED, 55 }; 56 57 ImagePattern(); 58 ~ImagePattern() override; 59 GetContextParam()60 std::optional<RenderContext::ContextParam> GetContextParam() const override 61 { 62 return RenderContext::ContextParam { RenderContext::ContextType::CANVAS }; 63 } 64 65 RefPtr<NodePaintMethod> CreateNodePaintMethod() override; 66 CreateLayoutProperty()67 RefPtr<LayoutProperty> CreateLayoutProperty() override 68 { 69 return MakeRefPtr<ImageLayoutProperty>(); 70 } 71 CreatePaintProperty()72 RefPtr<PaintProperty> CreatePaintProperty() override 73 { 74 return MakeRefPtr<ImageRenderProperty>(); 75 } 76 CreateLayoutAlgorithm()77 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override 78 { 79 return MakeRefPtr<ImageLayoutAlgorithm>(loadingCtx_, altLoadingCtx_); 80 } 81 CreateEventHub()82 RefPtr<EventHub> CreateEventHub() override 83 { 84 return MakeRefPtr<ImageEventHub>(); 85 } 86 87 // Called on main thread to check if need rerender of the content. 88 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 89 GetFocusPattern()90 FocusPattern GetFocusPattern() const override 91 { 92 return { FocusType::NODE, false }; 93 } 94 GetCanvasImage()95 const RefPtr<CanvasImage>& GetCanvasImage() 96 { 97 return image_; 98 } 99 GetAltCanvasImage()100 const RefPtr<CanvasImage>& GetAltCanvasImage() 101 { 102 return altImage_; 103 } 104 GetClientHost()105 RefPtr<FrameNode> GetClientHost() const override 106 { 107 return GetHost(); 108 } 109 110 void CreateObscuredImage(); 111 void LoadImageDataIfNeed(); 112 void OnNotifyMemoryLevel(int32_t level) override; 113 void OnWindowHide() override; 114 void OnWindowShow() override; 115 void OnVisibleChange(bool isVisible) override; 116 void OnRecycle() override; 117 void OnReuse() override; 118 119 void OnAreaChangedInner() override; 120 void RemoveAreaChangeInner(); 121 void CalAndUpdateSelectOverlay(); 122 OffsetF GetParentGlobalOffset() const; 123 void CheckHandles(SelectHandleInfo& handleInfo); 124 125 void EnableDrag(); 126 bool BetweenSelectedPosition(const Offset& globalOffset) override; 127 DefaultSupportDrag()128 bool DefaultSupportDrag() override 129 { 130 return true; 131 } 132 SetImageQuality(AIImageQuality imageQuality)133 void SetImageQuality(AIImageQuality imageQuality) 134 { 135 isImageQualityChange_ = (imageQuality_ != imageQuality); 136 imageQuality_ = imageQuality; 137 } 138 GetImageQuality()139 AIImageQuality GetImageQuality() 140 { 141 return imageQuality_; 142 } 143 SetCopyOption(CopyOptions value)144 void SetCopyOption(CopyOptions value) 145 { 146 copyOption_ = value; 147 } 148 SetImageInterpolation(ImageInterpolation value)149 void SetImageInterpolation(ImageInterpolation value) 150 { 151 interpolation_ = value; 152 } 153 GetImageInterpolation()154 std::string GetImageInterpolation() 155 { 156 switch (interpolation_) { 157 case ImageInterpolation::LOW: 158 return "LOW"; 159 case ImageInterpolation::MEDIUM: 160 return "MEDIUM"; 161 case ImageInterpolation::HIGH: 162 return "HIGH"; 163 default: 164 return "NONE"; 165 } 166 } 167 GetDynamicModeString(DynamicRangeMode dynamicMode)168 std::string GetDynamicModeString(DynamicRangeMode dynamicMode) const 169 { 170 switch (dynamicMode) { 171 case DynamicRangeMode::HIGH: 172 return "HIGH"; 173 case DynamicRangeMode::CONSTRAINT: 174 return "CONSTRAINT"; 175 case DynamicRangeMode::STANDARD: 176 return "STANDARD"; 177 default: 178 return "STANDARD"; 179 } 180 } 181 182 std::string GetImageFitStr(ImageFit value); 183 184 std::string GetImageRepeatStr(ImageRepeat value); 185 186 std::string GetImageColorFilterStr(const std::vector<float>& colorFilter); 187 SetSyncLoad(bool value)188 void SetSyncLoad(bool value) 189 { 190 syncLoad_ = value; 191 } 192 GetSyncLoad()193 bool GetSyncLoad() const 194 { 195 return syncLoad_; 196 } 197 SetNeedBorderRadius(bool needBorderRadius)198 void SetNeedBorderRadius(bool needBorderRadius) 199 { 200 needBorderRadius_ = needBorderRadius; 201 } 202 203 void SetImageAnalyzerConfig(const ImageAnalyzerConfig& config); 204 void SetImageAnalyzerConfig(void* config); 205 void SetImageAIOptions(void* options); 206 void BeforeCreatePaintWrapper() override; 207 void DumpInfo() override; 208 void DumpLayoutInfo(); 209 void DumpRenderInfo(); 210 void DumpAdvanceInfo() override; 211 void DumpSvgInfo(); GetImageLoadingContext()212 WeakPtr<ImageLoadingContext> GetImageLoadingContext() 213 { 214 return WeakClaim(AceType::RawPtr(loadingCtx_)); 215 } 216 GetAltImageLoadingContext()217 WeakPtr<ImageLoadingContext> GetAltImageLoadingContext() 218 { 219 return WeakClaim(AceType::RawPtr(altLoadingCtx_)); 220 } 221 void EnableAnalyzer(bool value); 222 bool hasSceneChanged(); 223 void OnSensitiveStyleChange(bool isSensitive) override; 224 SetImageAnimator(bool isImageAnimator)225 void SetImageAnimator(bool isImageAnimator) 226 { 227 isImageAnimator_ = isImageAnimator; 228 } 229 230 //animation 231 struct CacheImageStruct { 232 CacheImageStruct() = default; CacheImageStructCacheImageStruct233 CacheImageStruct(const RefPtr<FrameNode>& imageNode) : imageNode(imageNode) {} 234 virtual ~CacheImageStruct() = default; 235 RefPtr<FrameNode> imageNode; 236 int32_t index = 0; 237 bool isLoaded = false; 238 }; 239 240 void ImageAnimatorPattern(); SetImages(std::vector<ImageProperties> && images)241 void SetImages(std::vector<ImageProperties>&& images) 242 { 243 CHECK_NULL_VOID(images.size()); 244 images_ = std::move(images); 245 durationTotal_ = 0; 246 for (const auto& childImage : images_) { 247 if ((!childImage.src.empty() || childImage.pixelMap != nullptr) && childImage.duration > 0) { 248 durationTotal_ += childImage.duration; 249 } 250 } 251 imagesChangedFlag_ = true; 252 RegisterVisibleAreaChange(); 253 } 254 ResetImages()255 void ResetImages() 256 { 257 images_.clear(); 258 } 259 void ResetImage(); 260 void ResetAltImage(); 261 void ResetImageProperties(); 262 263 void ResetImageAndAlt(); 264 265 void ResetPictureSize(); 266 GetHasSizeChanged()267 bool GetHasSizeChanged() 268 { 269 return hasSizeChanged; 270 } 271 StartAnimation()272 void StartAnimation() 273 { 274 status_ = Animator::Status::RUNNING; 275 } 276 StopAnimation()277 void StopAnimation() 278 { 279 status_ = Animator::Status::STOPPED; 280 OnAnimatedModifyDone(); 281 } 282 SetImageType(ImageType imageType)283 void SetImageType(ImageType imageType) 284 { 285 imageType_ = imageType; 286 } 287 GetImageType()288 ImageType GetImageType() 289 { 290 return imageType_; 291 } 292 GetIsAnimation()293 bool GetIsAnimation() const 294 { 295 return imageType_ == ImageType::ANIMATION; 296 } 297 IsAtomicNode()298 bool IsAtomicNode() const override 299 { 300 return true; 301 } 302 303 bool AllowVisibleAreaCheck() const override; 304 OnInActive()305 void OnInActive() override 306 { 307 if (status_ == Animator::Status::RUNNING) { 308 animator_->Pause(); 309 } 310 } 311 OnActive()312 void OnActive() override 313 { 314 if (status_ == Animator::Status::RUNNING && animator_->GetStatus() != Animator::Status::RUNNING) { 315 if (!animator_->HasScheduler()) { 316 auto context = PipelineContext::GetCurrentContext(); 317 if (context) { 318 animator_->AttachScheduler(context); 319 } else { 320 TAG_LOGW(AceLogTag::ACE_IMAGE, "pipelineContext is null."); 321 } 322 } 323 animator_->Forward(); 324 } 325 } 326 327 void SetDuration(int32_t duration); 328 void SetIteration(int32_t iteration); 329 SetSrcUndefined(bool isUndefined)330 void SetSrcUndefined(bool isUndefined) 331 { 332 isSrcUndefined_ = isUndefined; 333 } 334 GetLoadInVipChannel()335 bool GetLoadInVipChannel() 336 { 337 return loadInVipChannel_; 338 } 339 GetNeedLoadAlt()340 bool GetNeedLoadAlt() 341 { 342 return needLoadAlt_; 343 } 344 SetNeedLoadAlt(bool needLoadAlt)345 void SetNeedLoadAlt(bool needLoadAlt) 346 { 347 needLoadAlt_ = needLoadAlt; 348 } 349 SetLoadInVipChannel(bool loadInVipChannel)350 void SetLoadInVipChannel(bool loadInVipChannel) 351 { 352 loadInVipChannel_ = loadInVipChannel; 353 } 354 355 void SetOnProgressCallback(std::function<void(const uint32_t& dlNow, const uint32_t& dlTotal)>&& onProgress); 356 GetRawImageSize()357 SizeF GetRawImageSize() 358 { 359 if (!loadingCtx_) { 360 return SizeF(-1.0, -1.0); 361 } 362 return loadingCtx_->GetImageSize(); 363 } 364 365 void OnVisibleAreaChange(bool visible = true, double ratio = 0.0); 366 GetDefaultAutoResize()367 bool GetDefaultAutoResize() 368 { 369 return autoResizeDefault_; 370 } 371 GetDefaultInterpolation()372 ImageInterpolation GetDefaultInterpolation() 373 { 374 return interpolationDefault_; 375 } 376 377 void SetIsComponentSnapshotNode(bool isComponentSnapshotNode = true) 378 { 379 isComponentSnapshotNode_ = isComponentSnapshotNode; 380 } 381 protected: 382 void RegisterWindowStateChangedCallback(); 383 void UnregisterWindowStateChangedCallback(); 384 bool isShow_ = true; 385 bool gifAnimation_ = false; 386 RefPtr<ImageOverlayModifier> overlayMod_; 387 388 private: 389 class ObscuredImage : public CanvasImage { DrawToRSCanvas(RSCanvas & canvas,const RSRect & srcRect,const RSRect & dstRect,const BorderRadiusArray & radiusXY)390 void DrawToRSCanvas( 391 RSCanvas& canvas, const RSRect& srcRect, const RSRect& dstRect, const BorderRadiusArray& radiusXY) override 392 {} DrawRect(RSCanvas & canvas,const RSRect & srcRect,const RSRect & dstRect)393 void DrawRect(RSCanvas& canvas, const RSRect& srcRect, const RSRect& dstRect) override 394 {} GetWidth()395 int32_t GetWidth() const override 396 { 397 return 0; 398 } GetHeight()399 int32_t GetHeight() const override 400 { 401 return 0; 402 } 403 }; 404 405 void OnAttachToFrameNode() override; 406 void OnDetachFromFrameNode(FrameNode* frameNode) override; 407 408 void OnModifyDone() override; 409 void UpdateGestureAndDragWhenModify(); 410 IsNeedInitClickEventRecorder()411 bool IsNeedInitClickEventRecorder() const override 412 { 413 return true; 414 } 415 416 void OnLanguageConfigurationUpdate() override; 417 418 /** 419 * @brief Start decoding image after ImageData is ready and dstSize is determined. 420 * 421 * @param dstSize The size of the image to be decoded. 422 */ 423 void StartDecoding(const SizeF& dstSize); 424 bool CheckIfNeedLayout(); 425 void OnImageDataReady(); 426 void OnCompleteInDataReady(); 427 void OnImageLoadFail(const std::string& errorMsg); 428 void OnImageLoadSuccess(); 429 void SetImagePaintConfig(const RefPtr<CanvasImage>& canvasImage, const RectF& srcRect, const RectF& dstRect, 430 const ImageSourceInfo& sourceInfo, int32_t frameCount = 1); 431 void UpdateInternalResource(ImageSourceInfo& sourceInfo); 432 433 void PrepareAnimation(const RefPtr<CanvasImage>& image); 434 void SetRedrawCallback(const RefPtr<CanvasImage>& image); 435 void SetOnFinishCallback(const RefPtr<CanvasImage>& image); 436 void RegisterVisibleAreaChange(bool isCalcClip = true); 437 void TriggerVisibleAreaChangeForChild(const RefPtr<UINode>& node, bool visible, double ratio); 438 439 void InitCopy(); 440 void HandleCopy(); 441 void OpenSelectOverlay(); 442 void CloseSelectOverlay(); 443 444 void TriggerFirstVisibleAreaChange(); 445 446 void UpdateFillColorIfForegroundColor(); 447 void UpdateDragEvent(const RefPtr<OHOS::Ace::DragEvent>& event); 448 449 void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override; 450 451 RectF CalcImageContentPaintSize(const RefPtr<GeometryNode>& geometryNode); 452 453 DataReadyNotifyTask CreateDataReadyCallback(); 454 LoadSuccessNotifyTask CreateLoadSuccessCallback(); 455 LoadFailNotifyTask CreateLoadFailCallback(); 456 OnCompleteInDataReadyNotifyTask CreateCompleteCallBackInDataReady(); 457 458 DataReadyNotifyTask CreateDataReadyCallbackForAlt(); 459 LoadSuccessNotifyTask CreateLoadSuccessCallbackForAlt(); 460 LoadFailNotifyTask CreateLoadFailCallbackForAlt(); 461 462 void OnColorConfigurationUpdate() override; 463 void OnDirectionConfigurationUpdate() override; 464 void OnIconConfigurationUpdate() override; 465 void OnConfigurationUpdate(); 466 void LoadImage(const ImageSourceInfo& src, const PropertyChangeFlag& propertyChangeFlag, VisibleType visibleType); 467 void LoadAltImage(const ImageSourceInfo& altImageSourceInfo); 468 469 void CreateAnalyzerOverlay(); 470 void UpdateAnalyzerOverlay(); 471 void UpdateAnalyzerOverlayLayout(); 472 void UpdateAnalyzerUIConfig(const RefPtr<NG::GeometryNode>& geometryNode); 473 void DestroyAnalyzerOverlay(); 474 void ReleaseImageAnalyzer(); 475 bool IsSupportImageAnalyzerFeature(); 476 void InitDefaultValue(); 477 void ClearAltData(); 478 void UpdateSvgSmoothEdgeValue(); 479 480 //animation 481 RefPtr<PictureAnimation<int32_t>> CreatePictureAnimation(int32_t size); 482 void AdaptSelfSize(); 483 void SetShowingIndex(int32_t index); 484 void UpdateShowingImageInfo(const RefPtr<FrameNode>& imageFrameNode, int32_t index); 485 void UpdateCacheImageInfo(CacheImageStruct& cacheImage, int32_t index); 486 std::list<CacheImageStruct>::iterator FindCacheImageNode(const RefPtr<PixelMap>& src); 487 int32_t GetNextIndex(int32_t preIndex); 488 void GenerateCachedImages(); 489 void AddImageLoadSuccessEvent(const RefPtr<FrameNode>& imageFrameNode); 490 static bool IsShowingSrc(const RefPtr<FrameNode>& imageFrameNode, const RefPtr<PixelMap>& src); 491 bool IsFormRender(); 492 void UpdateFormDurationByRemainder(); 493 void ResetFormAnimationStartTime(); 494 void ResetFormAnimationFlag(); 495 void OnAnimatedModifyDone(); 496 void OnImageModifyDone(); 497 void SetColorFilter(const RefPtr<FrameNode>& imageFrameNode); 498 void SetImageFit(const RefPtr<FrameNode>& imageFrameNode); 499 void ControlAnimation(int32_t index); 500 void SetObscured(); 501 502 CopyOptions copyOption_ = CopyOptions::None; 503 ImageInterpolation interpolation_ = ImageInterpolation::LOW; 504 bool needLoadAlt_ = true; 505 506 RefPtr<ImageLoadingContext> loadingCtx_; 507 RefPtr<CanvasImage> image_; 508 RectF dstRect_; 509 RectF srcRect_; 510 511 RefPtr<CanvasImage> obscuredImage_; 512 513 // clear alt data after [OnImageLoadSuccess] being called 514 RefPtr<ImageLoadingContext> altLoadingCtx_; 515 RefPtr<CanvasImage> altImage_; 516 std::unique_ptr<RectF> altDstRect_; 517 std::unique_ptr<RectF> altSrcRect_; 518 519 RefPtr<LongPressEvent> longPressEvent_; 520 RefPtr<ClickEvent> clickEvent_; 521 RefPtr<InputEvent> mouseEvent_; 522 RefPtr<Clipboard> clipboard_; 523 RefPtr<SelectOverlayProxy> selectOverlay_; 524 std::shared_ptr<ImageAnalyzerManager> imageAnalyzerManager_; 525 526 bool syncLoad_ = false; 527 bool needBorderRadius_ = false; 528 bool loadInVipChannel_ = false; 529 AIImageQuality imageQuality_ = AIImageQuality::NONE; 530 bool isImageQualityChange_ = false; 531 bool isEnableAnalyzer_ = false; 532 bool autoResizeDefault_ = true; 533 bool isSensitive_ = false; 534 ImageInterpolation interpolationDefault_ = ImageInterpolation::NONE; 535 Color selectedColor_; 536 OffsetF parentGlobalOffset_; 537 bool isSelected_ = false; 538 539 ACE_DISALLOW_COPY_AND_MOVE(ImagePattern); 540 bool isImageAnimator_ = false; 541 bool hasSizeChanged = false; 542 543 //animation 544 ImageType imageType_ = ImageType::BASE; 545 RefPtr<Animator> animator_; 546 std::vector<ImageProperties> images_; 547 std::list<CacheImageStruct> cacheImages_; 548 Animator::Status status_ = Animator::Status::IDLE; 549 int32_t durationTotal_ = 0; 550 int32_t nowImageIndex_ = 0; 551 uint64_t repeatCallbackId_ = 0; 552 bool imagesChangedFlag_ = false; 553 bool firstUpdateEvent_ = true; 554 bool isLayouted_ = false; 555 int64_t formAnimationStartTime_ = 0; 556 int32_t formAnimationRemainder_ = 0; 557 bool isFormAnimationStart_ = true; 558 bool isFormAnimationEnd_ = false; 559 bool isPixelMapChanged_ = false; 560 bool isSrcUndefined_ = false; 561 bool isComponentSnapshotNode_ = false; 562 563 std::function<void(const uint32_t& dlNow, const uint32_t& dlTotal)> onProgressCallback_ = nullptr; 564 }; 565 566 } // namespace OHOS::Ace::NG 567 568 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_IMAGE_IMAGE_PATTERN_H 569