1 /*
2  * Copyright (c) 2021 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_IMAGE_RENDER_IMAGE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_IMAGE_RENDER_IMAGE_H
18 
19 #include "base/resource/internal_resource.h"
20 #include "core/components/box/drag_drop_event.h"
21 #include "core/common/clipboard/clipboard.h"
22 #include "core/components/common/layout/constants.h"
23 #include "core/components/common/properties/alignment.h"
24 #include "core/components/common/properties/border.h"
25 #include "core/components/common/properties/color.h"
26 #include "core/components/common/properties/decoration.h"
27 #include "core/components/common/properties/radius.h"
28 #include "core/components/text_overlay/text_overlay_manager.h"
29 #include "core/gestures/long_press_recognizer.h"
30 #include "core/image/image_source_info.h"
31 #include "core/pipeline/base/render_node.h"
32 
33 namespace OHOS::Ace {
34 
35 enum class ImageLoadingStatus {
36     UNLOADED = 0,
37     LOADING,
38     UPDATING,
39     LOAD_SUCCESS,
40     LOAD_FAIL,
41 };
42 
43 class RenderImage : public RenderNode, public DragDropEvent, public TextOverlayBase {
44     DECLARE_ACE_TYPE(RenderImage, RenderNode, DragDropEvent, TextOverlayBase);
45 
46 public:
47     ~RenderImage() override;
48 
49     static RefPtr<RenderNode> Create();
50     static bool IsSVG(const std::string& src, InternalResource::ResourceId resourceId);
51     virtual Size Measure() = 0;
SetImageComponentSize(const Size & imageComponentSize)52     void SetImageComponentSize(const Size& imageComponentSize)
53     {
54         imageComponentSize_ = imageComponentSize;
55     }
GetImageComponentSize()56     const Size& GetImageComponentSize() const
57     {
58         return imageComponentSize_;
59     }
SetImageFit(ImageFit imageFit)60     void SetImageFit(ImageFit imageFit)
61     {
62         imageFit_ = imageFit;
63     }
GetImageFit()64     ImageFit GetImageFit() const
65     {
66         return imageFit_;
67     }
SetImageSrc(const std::string & imageSrc)68     void SetImageSrc(const std::string& imageSrc)
69     {
70         if (imageSrc != sourceInfo_.GetSrc()) {
71             sourceInfo_.SetSrc(imageSrc);
72             FetchImageObject();
73         }
74     }
GetImageSrc()75     const std::string& GetImageSrc() const
76     {
77         return sourceInfo_.GetSrc();
78     }
GetImageAlt()79     const std::string& GetImageAlt() const
80     {
81         return imageAlt_;
82     }
GetImageSyncMode()83     bool GetImageSyncMode() const
84     {
85         return syncMode_;
86     }
87 
SetMatchTextDirection(bool matchTextDirection)88     void SetMatchTextDirection(bool matchTextDirection)
89     {
90         matchTextDirection_ = matchTextDirection;
91     }
SetRotate(double rotate)92     void SetRotate(double rotate)
93     {
94         rotate_ = rotate;
95     }
96 
SetImageRepeat(const ImageRepeat & imageRepeat)97     void SetImageRepeat(const ImageRepeat& imageRepeat)
98     {
99         if (imageRepeat_ != imageRepeat) {
100             imageRepeat_ = imageRepeat;
101             MarkNeedLayout();
102         }
103     }
104 
GetImageRepeat()105     ImageRepeat GetImageRepeat() const
106     {
107         return imageRepeat_;
108     }
109 
GetImageSourceSize()110     Size GetImageSourceSize() const
111     {
112         return sourceInfo_.GetSourceSize();
113     }
114 
GetImageInterpolation()115     ImageInterpolation GetImageInterpolation() const
116     {
117         return imageInterpolation_;
118     }
119 
GetImageRenderMode()120     ImageRenderMode GetImageRenderMode() const
121     {
122         return imageRenderMode_;
123     }
124 
125     void SetBgImageSize(BackgroundImageSizeType type, double value = FULL_IMG_SIZE, double directionX = true)
126     {
127         if (background_ && directionX) {
128             if (type != imageSize_.GetSizeTypeX() || !NearEqual(value, imageSize_.GetSizeValueX())) {
129                 imageSize_.SetSizeTypeX(type);
130                 imageSize_.SetSizeValueX(value);
131                 MarkNeedLayout();
132             }
133         }
134         if (background_ && !directionX) {
135             if (type != imageSize_.GetSizeTypeY() || !NearEqual(value, imageSize_.GetSizeValueY())) {
136                 imageSize_.SetSizeTypeY(type);
137                 imageSize_.SetSizeValueY(value);
138                 MarkNeedLayout();
139             }
140         }
141     }
142 
SetBgImagePosition(const BackgroundImagePosition & imagePosition)143     void SetBgImagePosition(const BackgroundImagePosition& imagePosition)
144     {
145         if (background_ && imagePosition != imagePosition_) {
146             imagePosition_ = imagePosition;
147             MarkNeedLayout();
148         }
149     }
150 
151     using ImageUpdateFunc = std::function<void()>;
RegisterImageUpdateFunc(const ImageUpdateFunc & imageUpdateFunc)152     void RegisterImageUpdateFunc(const ImageUpdateFunc& imageUpdateFunc)
153     {
154         imageUpdateFunc_ = imageUpdateFunc;
155     }
156 
157     using ImageRenderFunc = std::function<void()>;
RegisterImageRenderFunc(const ImageRenderFunc & imageRenderFunc)158     void RegisterImageRenderFunc(const ImageRenderFunc& imageRenderFunc)
159     {
160         imageRenderFunc_ = imageRenderFunc;
161     }
162 
SetBackgroundImageFlag(bool backgroundImageFlag)163     void SetBackgroundImageFlag(bool backgroundImageFlag)
164     {
165         if (background_ != backgroundImageFlag) {
166             background_ = backgroundImageFlag;
167         }
168     }
169 
GetBackgroundImageFlag()170     bool GetBackgroundImageFlag() const
171     {
172         return background_;
173     }
174 
SetAdaptiveFrameRectFlag(bool adaptiveFrameRectFlag)175     void SetAdaptiveFrameRectFlag(bool adaptiveFrameRectFlag)
176     {
177         adaptiveFrameRect_ = adaptiveFrameRectFlag;
178     }
179 
GetAdaptiveFrameRectFlag()180     bool GetAdaptiveFrameRectFlag()
181     {
182         return adaptiveFrameRect_;
183     }
184 
SetBgImageBoxPaintSize(const Size & boxPaintSize)185     void SetBgImageBoxPaintSize(const Size& boxPaintSize)
186     {
187         if (background_ && boxPaintSize_ != boxPaintSize) {
188             boxPaintSize_ = boxPaintSize;
189             MarkNeedLayout();
190         }
191     }
192 
SetBgImageBoxMarginOffset(const Offset & boxMarginOffset)193     void SetBgImageBoxMarginOffset(const Offset& boxMarginOffset)
194     {
195         if (background_ && boxMarginOffset_ != boxMarginOffset) {
196             boxMarginOffset_ = boxMarginOffset;
197             MarkNeedLayout();
198         }
199     }
200 
201     void SetDirectPaint(bool directPaint = true)
202     {
203         directPaint_ = directPaint;
204     }
205 
206     void UpdateThemeIcon(ImageSourceInfo& sourceInfo);
207     void Update(const RefPtr<Component>& component) override;
208     void PerformLayout() override;
FetchImageObject()209     virtual void FetchImageObject() {}
210     void Dump() override;
IsSourceWideGamut()211     virtual bool IsSourceWideGamut() const
212     {
213         return false;
214     }
RetryLoading()215     virtual bool RetryLoading()
216     {
217         return false;
218     }
SetLoadFailCallback(std::function<void ()> && loadFailCallback)219     void SetLoadFailCallback(std::function<void()>&& loadFailCallback)
220     {
221         loadFailCallback_ = std::move(loadFailCallback);
222     }
OnAttachContext()223     void OnAttachContext() override
224     {
225         imagePosition_.SetContextAndCallback(context_, [weak = WeakClaim(this)] {
226             auto renderImage = weak.Upgrade();
227             if (renderImage) {
228                 renderImage->MarkNeedLayout();
229             }
230         });
231     }
232 
PerformLayoutPixmap()233     virtual void PerformLayoutPixmap() {}
PerformLayoutSvgImage()234     virtual void PerformLayoutSvgImage() {}
235 
MeasureForPixmap()236     virtual Size MeasureForPixmap()
237     {
238         return Size();
239     }
240 
MeasureForSvgImage()241     virtual Size MeasureForSvgImage()
242     {
243         return Size();
244     }
245 
MeasureForNormalImage()246     virtual Size MeasureForNormalImage()
247     {
248         return Size();
249     }
250 
GetImageComponentBorder()251     Border GetImageComponentBorder()
252     {
253         return border_;
254     }
255 #ifndef USE_ROSEN_DRAWING
GetSkImage()256     virtual void* GetSkImage()
257     {
258         return nullptr;
259     }
260 
GetPixmapFromSkImage()261     virtual RefPtr<PixelMap> GetPixmapFromSkImage()
262     {
263         return nullptr;
264     }
265 #else
GetDrawingImage()266     virtual void* GetDrawingImage()
267     {
268         return nullptr;
269     }
270 
GetPixmapFromDrawingImage()271     virtual RefPtr<PixelMap> GetPixmapFromDrawingImage()
272     {
273         return nullptr;
274     }
275 #endif
276 
277     void OnPaintFinish() override;
278     void OnLongPress(const LongPressInfo& longPressInfo);
279     bool HandleMouseEvent(const MouseEvent& event) override;
280     bool HandleKeyEvent(const KeyEvent& event);
281     void ShowTextOverlay(const Offset& showOffset) override;
282     void RegisterCallbacksToOverlay() override;
283 
GetSelectedContent()284     std::string GetSelectedContent() const override
285     {
286         return "";
287     };
GetHandleOffset(int32_t extend)288     Offset GetHandleOffset(int32_t extend) override
289     {
290         return Offset(0, 0);
291     };
292 
293 protected:
294     void ApplyImageFit(Rect& srcRect, Rect& dstRect);
295     void ApplyContain(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& imageComponentSize);
296     void ApplyCover(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& imageComponentSize);
297     void ApplyFitWidth(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& imageComponentSize);
298     void ApplyFitHeight(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& imageComponentSize);
299     void ApplyNone(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& imageComponentSize);
300     void FireLoadEvent(const Size& picSize, const std::string& errorMsg = "") const;
301     void SetRadius(const Border& border);
302     void CalculateResizeTarget();
303     bool NeedResize() const;
304 
305     // Drag event
306     void OnTouchTestHit(
307         const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result) override;
308     void PanOnActionStart(const GestureEvent& info) override;
309     void PanOnActionUpdate(const GestureEvent& info) override;
310     void PanOnActionEnd(const GestureEvent& info) override;
311     void PanOnActionCancel() override;
312     DragItemInfo GenerateDragItemInfo(const RefPtr<PipelineContext>& context, const GestureEvent& info) override;
313 
314     // background image
315     void PerformLayoutBgImage();
316     void ApplyObjectPosition();
317     void GenerateImageRects(const Size& srcSize, const BackgroundImageSize& imageSize, ImageRepeat imageRepeat,
318         const BackgroundImagePosition& imagePosition);
319     Size CalculateImageRenderSize(const Size& srcSize, const BackgroundImageSize& imageSize) const;
320     Size CalculateImageRenderSizeWithSingleParam(const Size& srcSize, const BackgroundImageSize& imageSize) const;
321     Size CalculateImageRenderSizeWithDoubleParam(const Size& srcSize, const BackgroundImageSize& imageSize) const;
322     void CalculateImageRenderPosition(const BackgroundImagePosition& imagePosition);
323     void PrintImageLog(const Size& srcSize, const BackgroundImageSize& imageSize, ImageRepeat imageRepeat,
324         const BackgroundImagePosition& imagePosition) const;
325     Size CalculateBackupImageSize(const Size& pictureSize);
326     void ClearRenderObject() override;
LayoutImageObject()327     virtual void LayoutImageObject() {}
328 
329     std::string imageAlt_;
330     std::function<void(const std::string&)> loadSuccessEvent_;
331     std::function<void(const std::string&)> loadFailEvent_;
332     std::function<void(const std::shared_ptr<BaseEventInfo>&)> loadImgSuccessEvent_;
333     std::function<void(const std::shared_ptr<BaseEventInfo>&)> loadImgFailEvent_;
334     mutable std::function<void()> loadFailCallback_;
335     EventMarker svgAnimatorFinishEvent_;
336     bool fitMaxSize_ = false;
337     bool hasObjectPosition_ = false;
338     bool isImageSizeSet_ = false;
339     bool rawImageSizeUpdated_ = false;
340     bool matchTextDirection_ = false;
341     Size previousLayoutSize_;
342     Size imageComponentSize_;
343     Size formerMaxSize_;
344     Alignment alignment_ = Alignment::CENTER;
345     ImageLoadingStatus imageLoadingStatus_ = ImageLoadingStatus::UNLOADED;
346 
347     // Real picture area with px.
348     Rect srcRect_;
349     Rect dstRect_;
350     Rect currentSrcRect_;
351     Rect currentDstRect_;
352     std::list<Rect> currentDstRectList_;
353     std::list<Rect> rectList_;
354 
355     ImageObjectPosition imageObjectPosition_;
356     std::optional<Color> color_;
357     double singleWidth_ = 0.0;
358     double displaySrcWidth_ = 0.0;
359     double scale_ = 1.0;
360     double horizontalRepeatNum_ = 1.0;
361     double rotate_ = 0.0;
362     bool keepOffsetZero_ = false;
363     bool resizeCallLoadImage_ = false;
364     int32_t frameCount_ = 0;
365     Radius topLeftRadius_ = Radius(0.0);
366     Radius topRightRadius_ = Radius(0.0);
367     Radius bottomLeftRadius_ = Radius(0.0);
368     Radius bottomRightRadius_ = Radius(0.0);
369     Size resizeScale_;
370     Size resizeTarget_;
371     Size previousResizeTarget_;
372     Size currentResizeScale_;
373     Dimension width_;
374     Dimension height_;
375     Size rawImageSize_;
376     RefPtr<RenderImage> renderAltImage_;
377 
378     // background image
379     ImageUpdateFunc imageUpdateFunc_;
380     ImageRenderFunc imageRenderFunc_;
381     bool background_ = false;
382     Size boxPaintSize_;
383     Offset boxMarginOffset_;
384     BackgroundImageSize imageSize_;
385     BackgroundImagePosition imagePosition_;
386     // result for background image
387     Size imageRenderSize_;
388     Offset imageRenderPosition_;
389 
390     ImageFit imageFit_ = ImageFit::COVER;
391     ImageInterpolation imageInterpolation_ = ImageInterpolation::NONE;
392     ImageRenderMode imageRenderMode_ = ImageRenderMode::ORIGINAL;
393     ImageRepeat imageRepeat_ = ImageRepeat::NO_REPEAT;
394 
395     // For RosenRenderImage which need to be painted several times on parent RenderNode.
396     // For Example: RosenRenderRating::PaintImageArea
397     bool adaptiveFrameRect_ = true;
398 
399     bool autoResize_ = true;
400 
401     bool forceResize_ = false;
402     bool forceReload_ = false;
403     Size imageSizeForEvent_;
404 #ifndef USE_ROSEN_DRAWING
405     bool useSkiaSvg_ = true;
406 #else
407     bool useSkiaSvg_ = false;
408 #endif
409     bool directPaint_ = false;
410     int32_t retryCnt_ = 0;
411     std::list<std::function<void()>> imageLayoutCallbacks_;
412     bool proceedPreviousLoading_ = false;
413     ImageSourceInfo sourceInfo_;
414     void* pixmapRawPtr_ = nullptr;
415     bool syncMode_ = false;
416     Border border_;
417     std::vector<float> colorfilter_;
418     float blurRadius_;
419 private:
420     void UpdateOverlay();
421     void HandleOnCopy();
422     RefPtr<LongPressRecognizer> textOverlayRecognizer_;
423     RefPtr<Clipboard> clipboard_;
424     Offset popOverlayOffset_;
425     CopyOptions copyOption_ = CopyOptions::None;
426     Offset lastDragMoveOffset_;
427 };
428 
429 } // namespace OHOS::Ace
430 
431 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_IMAGE_RENDER_IMAGE_H
432