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