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