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