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