• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetSkImage()256     virtual void* GetSkImage() {
257         return nullptr;
258     }
259 
GetPixmapFromSkImage()260     virtual RefPtr<PixelMap> GetPixmapFromSkImage()
261     {
262         return nullptr;
263     }
264 
265     void OnPaintFinish() override;
266     void OnLongPress(const LongPressInfo& longPressInfo);
267     bool HandleMouseEvent(const MouseEvent& event) override;
268     bool HandleKeyEvent(const KeyEvent& event);
269     void ShowTextOverlay(const Offset& showOffset) override;
270     void RegisterCallbacksToOverlay() override;
271 
GetSelectedContent()272     std::string GetSelectedContent() const override
273     {
274         return "";
275     };
GetHandleOffset(int32_t extend)276     Offset GetHandleOffset(int32_t extend) override
277     {
278         return Offset(0, 0);
279     };
280 
281 protected:
282     void ApplyImageFit(Rect& srcRect, Rect& dstRect);
283     void ApplyContain(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& imageComponentSize);
284     void ApplyCover(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& imageComponentSize);
285     void ApplyFitWidth(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& imageComponentSize);
286     void ApplyFitHeight(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& imageComponentSize);
287     void ApplyNone(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& imageComponentSize);
288     void FireLoadEvent(const Size& picSize, const std::string& errorMsg = "") const;
289     void SetRadius(const Border& border);
290     void CalculateResizeTarget();
291     bool NeedResize() const;
292 
293     // Drag event
294     void OnTouchTestHit(
295         const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result) override;
296     void PanOnActionStart(const GestureEvent& info) override;
297     void PanOnActionUpdate(const GestureEvent& info) override;
298     void PanOnActionEnd(const GestureEvent& info) override;
299     void PanOnActionCancel() override;
300     DragItemInfo GenerateDragItemInfo(const RefPtr<PipelineContext>& context, const GestureEvent& info) override;
301 
302     // background image
303     void PerformLayoutBgImage();
304     void ApplyObjectPosition();
305     void GenerateImageRects(const Size& srcSize, const BackgroundImageSize& imageSize, ImageRepeat imageRepeat,
306         const BackgroundImagePosition& imagePosition);
307     Size CalculateImageRenderSize(const Size& srcSize, const BackgroundImageSize& imageSize) const;
308     Size CalculateImageRenderSizeWithSingleParam(const Size& srcSize, const BackgroundImageSize& imageSize) const;
309     Size CalculateImageRenderSizeWithDoubleParam(const Size& srcSize, const BackgroundImageSize& imageSize) const;
310     void CalculateImageRenderPosition(const BackgroundImagePosition& imagePosition);
311     void PrintImageLog(const Size& srcSize, const BackgroundImageSize& imageSize, ImageRepeat imageRepeat,
312         const BackgroundImagePosition& imagePosition) const;
313     Size CalculateBackupImageSize(const Size& pictureSize);
314     void ClearRenderObject() override;
LayoutImageObject()315     virtual void LayoutImageObject() {}
316 
317     std::string imageAlt_;
318     std::function<void(const std::string&)> loadSuccessEvent_;
319     std::function<void(const std::string&)> loadFailEvent_;
320     std::function<void(const std::shared_ptr<BaseEventInfo>&)> loadImgSuccessEvent_;
321     std::function<void(const std::shared_ptr<BaseEventInfo>&)> loadImgFailEvent_;
322     mutable std::function<void()> loadFailCallback_;
323     EventMarker svgAnimatorFinishEvent_;
324     bool fitMaxSize_ = false;
325     bool hasObjectPosition_ = false;
326     bool isImageSizeSet_ = false;
327     bool rawImageSizeUpdated_ = false;
328     bool matchTextDirection_ = false;
329     Size previousLayoutSize_;
330     Size imageComponentSize_;
331     Size formerMaxSize_;
332     Alignment alignment_ = Alignment::CENTER;
333     ImageLoadingStatus imageLoadingStatus_ = ImageLoadingStatus::UNLOADED;
334 
335     // Real picture area with px.
336     Rect srcRect_;
337     Rect dstRect_;
338     Rect currentSrcRect_;
339     Rect currentDstRect_;
340     std::list<Rect> currentDstRectList_;
341     std::list<Rect> rectList_;
342 
343     ImageObjectPosition imageObjectPosition_;
344     std::optional<Color> color_;
345     double singleWidth_ = 0.0;
346     double displaySrcWidth_ = 0.0;
347     double scale_ = 1.0;
348     double horizontalRepeatNum_ = 1.0;
349     double rotate_ = 0.0;
350     bool keepOffsetZero_ = false;
351     bool resizeCallLoadImage_ = false;
352     int32_t frameCount_ = 0;
353     Radius topLeftRadius_ = Radius(0.0);
354     Radius topRightRadius_ = Radius(0.0);
355     Radius bottomLeftRadius_ = Radius(0.0);
356     Radius bottomRightRadius_ = Radius(0.0);
357     Size resizeScale_;
358     Size resizeTarget_;
359     Size previousResizeTarget_;
360     Size currentResizeScale_;
361     Dimension width_;
362     Dimension height_;
363     Size rawImageSize_;
364     RefPtr<RenderImage> renderAltImage_;
365 
366     // background image
367     ImageUpdateFunc imageUpdateFunc_;
368     ImageRenderFunc imageRenderFunc_;
369     bool background_ = false;
370     Size boxPaintSize_;
371     Offset boxMarginOffset_;
372     BackgroundImageSize imageSize_;
373     BackgroundImagePosition imagePosition_;
374     // result for background image
375     Size imageRenderSize_;
376     Offset imageRenderPosition_;
377 
378     ImageFit imageFit_ = ImageFit::COVER;
379     ImageInterpolation imageInterpolation_ = ImageInterpolation::NONE;
380     ImageRenderMode imageRenderMode_ = ImageRenderMode::ORIGINAL;
381     ImageRepeat imageRepeat_ = ImageRepeat::NO_REPEAT;
382 
383     // For RosenRenderImage which need to be painted several times on parent RenderNode.
384     // For Example: RosenRenderRating::PaintImageArea
385     bool adaptiveFrameRect_ = true;
386 
387     bool autoResize_ = true;
388 
389     bool forceResize_ = false;
390     bool forceReload_ = false;
391     Size imageSizeForEvent_;
392     bool useSkiaSvg_ = true;
393     bool directPaint_ = false;
394     int32_t retryCnt_ = 0;
395     std::list<std::function<void()>> imageLayoutCallbacks_;
396     bool proceedPreviousLoading_ = false;
397     ImageSourceInfo sourceInfo_;
398     void* pixmapRawPtr_ = nullptr;
399     bool syncMode_ = false;
400     Border border_;
401     std::vector<float> colorfilter_;
402     float blurRadius_;
403 private:
404     void UpdateOverlay();
405     void HandleOnCopy();
406     RefPtr<LongPressRecognizer> textOverlayRecognizer_;
407     RefPtr<Clipboard> clipboard_;
408     Offset popOverlayOffset_;
409     CopyOptions copyOption_ = CopyOptions::None;
410     Offset lastDragMoveOffset_;
411 };
412 
413 } // namespace OHOS::Ace
414 
415 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_IMAGE_RENDER_IMAGE_H
416