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