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