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/common/layout/constants.h" 21 #include "core/components/common/properties/alignment.h" 22 #include "core/components/common/properties/border.h" 23 #include "core/components/common/properties/color.h" 24 #include "core/components/common/properties/decoration.h" 25 #include "core/components/common/properties/radius.h" 26 #include "core/image/image_source_info.h" 27 #include "core/pipeline/base/render_node.h" 28 29 namespace OHOS::Ace { 30 31 enum class ImageLoadingStatus { 32 UNLOADED = 0, 33 LOADING, 34 UPDATING, 35 LOAD_SUCCESS, 36 LOAD_FAIL, 37 }; 38 39 class RenderImage : public RenderNode { 40 DECLARE_ACE_TYPE(RenderImage, RenderNode); 41 42 public: 43 static RefPtr<RenderNode> Create(); 44 static bool IsSVG(const std::string& src, InternalResource::ResourceId resourceId); 45 virtual Size Measure() = 0; SetImageComponentSize(const Size & imageComponentSize)46 void SetImageComponentSize(const Size& imageComponentSize) 47 { 48 imageComponentSize_ = imageComponentSize; 49 } GetImageComponentSize()50 const Size& GetImageComponentSize() const 51 { 52 return imageComponentSize_; 53 } SetImageFit(ImageFit imageFit)54 void SetImageFit(ImageFit imageFit) 55 { 56 imageFit_ = imageFit; 57 } GetImageFit()58 ImageFit GetImageFit() const 59 { 60 return imageFit_; 61 } SetImageSrc(const std::string & imageSrc)62 void SetImageSrc(const std::string& imageSrc) 63 { 64 if (imageSrc != sourceInfo_.GetSrc()) { 65 sourceInfo_.SetSrc(imageSrc); 66 FetchImageObject(); 67 } 68 } GetImageSrc()69 const std::string& GetImageSrc() const 70 { 71 return sourceInfo_.GetSrc(); 72 } GetImageAlt()73 const std::string& GetImageAlt() const 74 { 75 return imageAlt_; 76 } GetImageSyncMode()77 bool GetImageSyncMode() const 78 { 79 return syncMode_; 80 } 81 SetMatchTextDirection(bool matchTextDirection)82 void SetMatchTextDirection(bool matchTextDirection) 83 { 84 matchTextDirection_ = matchTextDirection; 85 } SetRotate(double rotate)86 void SetRotate(double rotate) 87 { 88 rotate_ = rotate; 89 } 90 SetImageRepeat(const ImageRepeat & imageRepeat)91 void SetImageRepeat(const ImageRepeat& imageRepeat) 92 { 93 if (imageRepeat_ != imageRepeat) { 94 imageRepeat_ = imageRepeat; 95 MarkNeedLayout(); 96 } 97 } 98 GetImageRepeat()99 ImageRepeat GetImageRepeat() const 100 { 101 return imageRepeat_; 102 } 103 GetImageSourceSize()104 Size GetImageSourceSize() const 105 { 106 return sourceInfo_.GetSourceSize(); 107 } 108 GetImageInterpolation()109 ImageInterpolation GetImageInterpolation() const 110 { 111 return imageInterpolation_; 112 } 113 GetImageRenderMode()114 ImageRenderMode GetImageRenderMode() const 115 { 116 return imageRenderMode_; 117 } 118 119 void SetBgImageSize(BackgroundImageSizeType type, double value = FULL_IMG_SIZE, double directionX = true) 120 { 121 if (background_ && directionX) { 122 if (type != imageSize_.GetSizeTypeX() || !NearEqual(value, imageSize_.GetSizeValueX())) { 123 imageSize_.SetSizeTypeX(type); 124 imageSize_.SetSizeValueX(value); 125 MarkNeedLayout(); 126 } 127 } 128 if (background_ && !directionX) { 129 if (type != imageSize_.GetSizeTypeY() || !NearEqual(value, imageSize_.GetSizeValueY())) { 130 imageSize_.SetSizeTypeY(type); 131 imageSize_.SetSizeValueY(value); 132 MarkNeedLayout(); 133 } 134 } 135 } 136 SetBgImagePosition(const BackgroundImagePosition & imagePosition)137 void SetBgImagePosition(const BackgroundImagePosition& imagePosition) 138 { 139 if (background_ && imagePosition != imagePosition_) { 140 imagePosition_ = imagePosition; 141 MarkNeedLayout(); 142 } 143 } 144 145 using ImageUpdateFunc = std::function<void()>; RegisterImageUpdateFunc(const ImageUpdateFunc & imageUpdateFunc)146 void RegisterImageUpdateFunc(const ImageUpdateFunc& imageUpdateFunc) 147 { 148 imageUpdateFunc_ = imageUpdateFunc; 149 } 150 151 using ImageRenderFunc = std::function<void()>; RegisterImageRenderFunc(const ImageRenderFunc & imageRenderFunc)152 void RegisterImageRenderFunc(const ImageRenderFunc& imageRenderFunc) 153 { 154 imageRenderFunc_ = imageRenderFunc; 155 } 156 SetBackgroundImageFlag(bool backgroundImageFlag)157 void SetBackgroundImageFlag(bool backgroundImageFlag) 158 { 159 if (background_ != backgroundImageFlag) { 160 background_ = backgroundImageFlag; 161 } 162 } 163 GetBackgroundImageFlag()164 bool GetBackgroundImageFlag() const 165 { 166 return background_; 167 } 168 SetAdaptiveFrameRectFlag(bool adaptiveFrameRectFlag)169 void SetAdaptiveFrameRectFlag(bool adaptiveFrameRectFlag) 170 { 171 adaptiveFrameRect_ = adaptiveFrameRectFlag; 172 } 173 GetAdaptiveFrameRectFlag()174 bool GetAdaptiveFrameRectFlag() 175 { 176 return adaptiveFrameRect_; 177 } 178 SetBgImageBoxPaintSize(const Size & boxPaintSize)179 void SetBgImageBoxPaintSize(const Size& boxPaintSize) 180 { 181 if (background_ && boxPaintSize_ != boxPaintSize) { 182 boxPaintSize_ = boxPaintSize; 183 MarkNeedLayout(); 184 } 185 } 186 SetBgImageBoxMarginOffset(const Offset & boxMarginOffset)187 void SetBgImageBoxMarginOffset(const Offset& boxMarginOffset) 188 { 189 if (background_ && boxMarginOffset_ != boxMarginOffset) { 190 boxMarginOffset_ = boxMarginOffset; 191 MarkNeedLayout(); 192 } 193 } 194 195 void SetDirectPaint(bool directPaint = true) 196 { 197 directPaint_ = directPaint; 198 } 199 200 void Update(const RefPtr<Component>& component) override; 201 void PerformLayout() override; FetchImageObject()202 virtual void FetchImageObject() {} 203 void Dump() override; IsSourceWideGamut()204 virtual bool IsSourceWideGamut() const 205 { 206 return false; 207 } RetryLoading()208 virtual bool RetryLoading() 209 { 210 return false; 211 } SetLoadFailCallback(std::function<void ()> && loadFailCallback)212 void SetLoadFailCallback(std::function<void()>&& loadFailCallback) 213 { 214 loadFailCallback_ = std::move(loadFailCallback); 215 } OnAttachContext()216 void OnAttachContext() override 217 { 218 imagePosition_.SetContextAndCallback(context_, [weak = WeakClaim(this)] { 219 auto renderImage = weak.Upgrade(); 220 if (renderImage) { 221 renderImage->MarkNeedLayout(); 222 } 223 }); 224 } 225 PerformLayoutPixmap()226 virtual void PerformLayoutPixmap() {} PerformLayoutSvgImage()227 virtual void PerformLayoutSvgImage() {} 228 MeasureForPixmap()229 virtual Size MeasureForPixmap() 230 { 231 return Size(); 232 } 233 MeasureForSvgImage()234 virtual Size MeasureForSvgImage() 235 { 236 return Size(); 237 } 238 MeasureForNormalImage()239 virtual Size MeasureForNormalImage() 240 { 241 return Size(); 242 } 243 GetImageComponentBorder()244 Border GetImageComponentBorder() 245 { 246 return border_; 247 } 248 249 protected: 250 void ApplyImageFit(Rect& srcRect, Rect& dstRect); 251 void ApplyContain(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& imageComponentSize); 252 void ApplyCover(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& imageComponentSize); 253 void ApplyFitWidth(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& imageComponentSize); 254 void ApplyFitHeight(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& imageComponentSize); 255 void ApplyNone(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& imageComponentSize); 256 void FireLoadEvent(const Size& picSize) const; 257 void SetRadius(const Border& border); 258 void CalculateResizeTarget(); 259 bool NeedResize() const; 260 261 // background image 262 void PerformLayoutBgImage(); 263 void ApplyObjectPosition(); 264 void GenerateImageRects(const Size& srcSize, const BackgroundImageSize& imageSize, ImageRepeat imageRepeat, 265 const BackgroundImagePosition& imagePosition); 266 Size CalculateImageRenderSize(const Size& srcSize, const BackgroundImageSize& imageSize) const; 267 Size CalculateImageRenderSizeWithSingleParam(const Size& srcSize, const BackgroundImageSize& imageSize) const; 268 Size CalculateImageRenderSizeWithDoubleParam(const Size& srcSize, const BackgroundImageSize& imageSize) const; 269 void CalculateImageRenderPosition(const BackgroundImagePosition& imagePosition); 270 void PrintImageLog(const Size& srcSize, const BackgroundImageSize& imageSize, ImageRepeat imageRepeat, 271 const BackgroundImagePosition& imagePosition) const; 272 Size CalculateBackupImageSize(const Size& pictureSize); 273 virtual void ClearRenderObject() override; LayoutImageObject()274 virtual void LayoutImageObject() {} 275 276 std::string imageAlt_; 277 std::function<void(const std::string&)> loadSuccessEvent_; 278 std::function<void(const std::string&)> loadFailEvent_; 279 std::function<void(const std::shared_ptr<BaseEventInfo>&)> loadImgSuccessEvent_; 280 std::function<void(const std::shared_ptr<BaseEventInfo>&)> loadImgFailEvent_; 281 mutable std::function<void()> loadFailCallback_; 282 EventMarker svgAnimatorFinishEvent_; 283 bool fitMaxSize_ = false; 284 bool hasObjectPosition_ = false; 285 bool isImageSizeSet_ = false; 286 bool rawImageSizeUpdated_ = false; 287 bool matchTextDirection_ = false; 288 Size previousLayoutSize_; 289 Size imageComponentSize_; 290 Size formerMaxSize_; 291 Alignment alignment_ = Alignment::CENTER; 292 ImageLoadingStatus imageLoadingStatus_ = ImageLoadingStatus::UNLOADED; 293 294 // Real picture area with px. 295 Rect srcRect_; 296 Rect dstRect_; 297 Rect currentSrcRect_; 298 Rect currentDstRect_; 299 std::list<Rect> currentDstRectList_; 300 std::list<Rect> rectList_; 301 302 ImageObjectPosition imageObjectPosition_; 303 std::optional<Color> color_; 304 double singleWidth_ = 0.0; 305 double displaySrcWidth_ = 0.0; 306 double scale_ = 1.0; 307 double horizontalRepeatNum_ = 1.0; 308 double rotate_ = 0.0; 309 bool keepOffsetZero_ = false; 310 bool resizeCallLoadImage_ = false; 311 int32_t frameCount_ = 0; 312 Radius topLeftRadius_ = Radius(0.0); 313 Radius topRightRadius_ = Radius(0.0); 314 Radius bottomLeftRadius_ = Radius(0.0); 315 Radius bottomRightRadius_ = Radius(0.0); 316 Size resizeScale_; 317 Size resizeTarget_; 318 Size previousResizeTarget_; 319 Size currentResizeScale_; 320 Dimension width_; 321 Dimension height_; 322 Size rawImageSize_; 323 RefPtr<RenderImage> renderAltImage_; 324 325 // background image 326 ImageUpdateFunc imageUpdateFunc_; 327 ImageRenderFunc imageRenderFunc_; 328 bool background_ = false; 329 Size boxPaintSize_; 330 Offset boxMarginOffset_; 331 BackgroundImageSize imageSize_; 332 BackgroundImagePosition imagePosition_; 333 // result for background image 334 Size imageRenderSize_; 335 Offset imageRenderPosition_; 336 337 ImageFit imageFit_ = ImageFit::COVER; 338 ImageInterpolation imageInterpolation_ = ImageInterpolation::NONE; 339 ImageRenderMode imageRenderMode_ = ImageRenderMode::ORIGINAL; 340 ImageRepeat imageRepeat_ = ImageRepeat::NOREPEAT; 341 342 // For RosenRenderImage which need to be painted several times on parent RenderNode. 343 // For Example: RosenRenderRating::PaintImageArea 344 bool adaptiveFrameRect_ = true; 345 346 bool autoResize_ = true; 347 348 bool forceResize_ = false; 349 bool forceReload_ = false; 350 Size imageSizeForEvent_; 351 bool useSkiaSvg_ = true; 352 bool directPaint_ = false; 353 int32_t retryCnt_ = 0; 354 std::list<std::function<void()>> imageLayoutCallbacks_; 355 bool proceedPreviousLoading_ = false; 356 ImageSourceInfo sourceInfo_; 357 void* pixmapRawPtr_ = nullptr; 358 bool syncMode_ = false; 359 Border border_; 360 }; 361 362 } // namespace OHOS::Ace 363 364 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_IMAGE_RENDER_IMAGE_H 365