1 /*
2 * Copyright (c) 2022-2023 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 #include "core/components_ng/image_provider/image_loading_context.h"
17
18 #include "base/utils/utils.h"
19 #include "core/components/common/layout/constants.h"
20 #include "core/components_ng/image_provider/image_utils.h"
21 #include "core/components_ng/image_provider/pixel_map_image_object.h"
22 #include "core/components_ng/image_provider/static_image_object.h"
23 #include "core/components_ng/render/image_painter.h"
24 #include "core/image/image_file_cache.h"
25 #include "core/image/image_loader.h"
26 #include "core/pipeline_ng/pipeline_context.h"
27 #ifdef USE_ROSEN_DRAWING
28 #include "core/components_ng/image_provider/adapter/rosen/drawing_image_data.h"
29 #endif
30
31 namespace OHOS::Ace::NG {
32
33 namespace {
QueryDataFromCache(const ImageSourceInfo & src,bool & dataHit)34 RefPtr<ImageData> QueryDataFromCache(const ImageSourceInfo& src, bool& dataHit)
35 {
36 ACE_FUNCTION_TRACE();
37 #ifndef USE_ROSEN_DRAWING
38 auto cachedData = ImageLoader::QueryImageDataFromImageCache(src);
39 if (cachedData) {
40 dataHit = true;
41 return NG::ImageData::MakeFromDataWrapper(&cachedData);
42 }
43 auto skData = ImageLoader::LoadDataFromCachedFile(src.GetSrc());
44 if (skData) {
45 sk_sp<SkData> data = SkData::MakeWithCopy(skData->data(), skData->size());
46
47 return NG::ImageData::MakeFromDataWrapper(&data);
48 }
49 #else
50 std::shared_ptr<RSData> rsData = nullptr;
51 rsData = ImageLoader::QueryImageDataFromImageCache(src);
52 if (rsData) {
53 TAG_LOGD(AceLogTag::ACE_IMAGE, "%{private}s hit the memory Cache.", src.GetSrc().c_str());
54 dataHit = true;
55 return AceType::MakeRefPtr<NG::DrawingImageData>(rsData);
56 }
57 auto drawingData = ImageLoader::LoadDataFromCachedFile(src.GetSrc());
58 if (drawingData) {
59 TAG_LOGD(AceLogTag::ACE_IMAGE, "%{private}s hit the disk Cache, and the data size is %{public}d.",
60 src.GetSrc().c_str(), static_cast<int32_t>(drawingData->GetSize()));
61 auto data = std::make_shared<RSData>();
62 data->BuildWithCopy(drawingData->GetData(), drawingData->GetSize());
63 return AceType::MakeRefPtr<NG::DrawingImageData>(data);
64 }
65 #endif
66 return nullptr;
67 }
68 } // namespace
69
ImageLoadingContext(const ImageSourceInfo & src,LoadNotifier && loadNotifier,bool syncLoad)70 ImageLoadingContext::ImageLoadingContext(const ImageSourceInfo& src, LoadNotifier&& loadNotifier, bool syncLoad)
71 : src_(src), notifiers_(std::move(loadNotifier)), containerId_(Container::CurrentId()), syncLoad_(syncLoad)
72 {
73 stateManager_ = MakeRefPtr<ImageStateManager>(WeakClaim(this));
74
75 if (!AceApplicationInfo::GetInstance().GreatOrEqualTargetAPIVersion(PlatformVersion::VERSION_TWELVE) &&
76 src_.GetSrcType() == SrcType::PIXMAP) {
77 syncLoad_ = true;
78 }
79 }
80
~ImageLoadingContext()81 ImageLoadingContext::~ImageLoadingContext()
82 {
83 if (!syncLoad_) {
84 auto state = stateManager_->GetCurrentState();
85 if (state == ImageLoadingState::DATA_LOADING) {
86 // cancel CreateImgObj task
87 ImageProvider::CancelTask(src_.GetKey(), WeakClaim(this));
88 if (Downloadable()) {
89 DownloadManager::GetInstance()->RemoveDownloadTask(src_.GetSrc(), nodeId_);
90 }
91 } else if (state == ImageLoadingState::MAKE_CANVAS_IMAGE) {
92 // cancel MakeCanvasImage task
93 if (InstanceOf<StaticImageObject>(imageObj_)) {
94 ImageProvider::CancelTask(canvasKey_, WeakClaim(this));
95 }
96 }
97 }
98 }
99
CalculateTargetSize(const SizeF & srcSize,const SizeF & dstSize,const SizeF & rawImageSize)100 SizeF ImageLoadingContext::CalculateTargetSize(const SizeF& srcSize, const SizeF& dstSize, const SizeF& rawImageSize)
101 {
102 if (!srcSize.IsPositive()) {
103 return rawImageSize;
104 }
105
106 SizeF targetSize = rawImageSize;
107 auto context = PipelineContext::GetCurrentContext();
108 auto viewScale = context ? context->GetViewScale() : 1.0;
109 double widthScale = dstSize.Width() / srcSize.Width() * viewScale;
110 double heightScale = dstSize.Height() / srcSize.Height() * viewScale;
111 if (widthScale < 1.0 && heightScale < 1.0) {
112 targetSize = SizeF(targetSize.Width() * widthScale, targetSize.Height() * heightScale);
113 }
114 return targetSize;
115 }
116
OnUnloaded()117 void ImageLoadingContext::OnUnloaded()
118 {
119 imageObj_ = nullptr;
120 canvasImage_ = nullptr;
121 srcRect_ = RectF();
122 dstRect_ = RectF();
123 dstSize_ = SizeF();
124 }
125
OnLoadSuccess()126 void ImageLoadingContext::OnLoadSuccess()
127 {
128 if (DynamicCast<StaticImageObject>(imageObj_)) {
129 imageObj_->ClearData();
130 }
131 if (notifiers_.onLoadSuccess_) {
132 notifiers_.onLoadSuccess_(src_);
133 }
134 ImageUtils::PostToUI(std::move(pendingMakeCanvasImageTask_), "ArkUIImageMakeCanvasImage");
135 }
136
OnLoadFail()137 void ImageLoadingContext::OnLoadFail()
138 {
139 if (notifiers_.onLoadFail_) {
140 notifiers_.onLoadFail_(src_, errorMsg_);
141 }
142 }
143
OnDataReady()144 void ImageLoadingContext::OnDataReady()
145 {
146 if (notifiers_.onDataReady_) {
147 notifiers_.onDataReady_(src_);
148 }
149 }
150
OnDataReadyOnCompleteCallBack()151 void ImageLoadingContext::OnDataReadyOnCompleteCallBack()
152 {
153 if (notifiers_.onDataReadyComplete_) {
154 notifiers_.onDataReadyComplete_(src_);
155 }
156 }
157
SetOnProgressCallback(std::function<void (const uint32_t & dlNow,const uint32_t & dlTotal)> && onProgress)158 void ImageLoadingContext::SetOnProgressCallback(
159 std::function<void(const uint32_t& dlNow, const uint32_t& dlTotal)>&& onProgress)
160 {
161 onProgressCallback_ = onProgress;
162 }
163
OnDataLoading()164 void ImageLoadingContext::OnDataLoading()
165 {
166 auto obj = ImageProvider::QueryImageObjectFromCache(src_);
167 if (obj) {
168 TAG_LOGD(AceLogTag::ACE_IMAGE, "%{private}s hit cache, not need create object", src_.GetSrc().c_str());
169 DataReadyCallback(obj);
170 return;
171 }
172 if (Downloadable()) {
173 if (syncLoad_) {
174 DownloadImage();
175 } else {
176 auto task = [weak = AceType::WeakClaim(this)]() {
177 auto ctx = weak.Upgrade();
178 CHECK_NULL_VOID(ctx);
179 ctx->DownloadImage();
180 };
181 NG::ImageUtils::PostToBg(task, "ArkUIImageDownload");
182 }
183 return;
184 }
185 ImageProvider::CreateImageObject(src_, WeakClaim(this), syncLoad_);
186 }
187
NotifyReadyIfCacheHit()188 bool ImageLoadingContext::NotifyReadyIfCacheHit()
189 {
190 bool dataHit = false;
191 auto cachedImageData = QueryDataFromCache(src_, dataHit);
192 CHECK_NULL_RETURN(cachedImageData, false);
193 auto notifyDataReadyTask = [weak = AceType::WeakClaim(this), data = std::move(cachedImageData), dataHit] {
194 auto ctx = weak.Upgrade();
195 CHECK_NULL_VOID(ctx);
196 auto src = ctx->GetSourceInfo();
197 // if find data or file cache only, build and cache object, cache data if file cache hit
198 RefPtr<ImageObject> imageObj = ImageProvider::BuildImageObject(src, data);
199 ImageProvider::CacheImageObject(imageObj);
200 if (!dataHit) {
201 ImageLoader::CacheImageData(ctx->GetSourceInfo().GetKey(), data);
202 }
203 ctx->DataReadyCallback(imageObj);
204 };
205 if (syncLoad_) {
206 notifyDataReadyTask();
207 } else {
208 ImageUtils::PostToUI(std::move(notifyDataReadyTask), "ArkUIImageNotifyDataReady");
209 }
210 return true;
211 }
212
Downloadable()213 bool ImageLoadingContext::Downloadable()
214 {
215 return src_.GetSrcType() == SrcType::NETWORK && SystemProperties::GetDownloadByNetworkEnabled();
216 }
217
DownloadImage()218 void ImageLoadingContext::DownloadImage()
219 {
220 if (NotifyReadyIfCacheHit()) {
221 TAG_LOGD(AceLogTag::ACE_IMAGE, "%{private}s hit the Cache, not need DownLoad.", src_.GetSrc().c_str());
222 return;
223 }
224 PerformDownload();
225 }
226
PerformDownload()227 void ImageLoadingContext::PerformDownload()
228 {
229 ACE_SCOPED_TRACE("PerformDownload %s", src_.GetSrc().c_str());
230 DownloadCallback downloadCallback;
231 downloadCallback.successCallback = [weak = AceType::WeakClaim(this)](
232 const std::string&& imageData, bool async, int32_t instanceId) {
233 ContainerScope scope(instanceId);
234 auto callback = [weak = weak, data = std::move(imageData)]() {
235 auto ctx = weak.Upgrade();
236 CHECK_NULL_VOID(ctx);
237 ctx->DownloadImageSuccess(data);
238 };
239 async ? NG::ImageUtils::PostToUI(callback, "ArkUIImageDownloadSuccess") : callback();
240 };
241 downloadCallback.failCallback = [weak = AceType::WeakClaim(this)](
242 std::string errorMessage, bool async, int32_t instanceId) {
243 ContainerScope scope(instanceId);
244 auto callback = [weak = weak, errorMessage = errorMessage]() {
245 auto ctx = weak.Upgrade();
246 CHECK_NULL_VOID(ctx);
247 ctx->DownloadImageFailed(errorMessage);
248 };
249 async ? NG::ImageUtils::PostToUI(callback, "ArkUIImageDownloadFailed") : callback();
250 };
251 downloadCallback.cancelCallback = downloadCallback.failCallback;
252 if (onProgressCallback_) {
253 downloadCallback.onProgressCallback = [weak = AceType::WeakClaim(this)](
254 uint32_t dlTotal, uint32_t dlNow, bool async, int32_t instanceId) {
255 ContainerScope scope(instanceId);
256 auto callback = [weak = weak, dlTotal = dlTotal, dlNow = dlNow]() {
257 auto ctx = weak.Upgrade();
258 CHECK_NULL_VOID(ctx);
259 ctx->DownloadOnProgress(dlNow, dlTotal);
260 };
261 async ? NG::ImageUtils::PostToUI(callback, "ArkUIImageDownloadOnProcess") : callback();
262 };
263 }
264 NetworkImageLoader::DownloadImage(std::move(downloadCallback), src_.GetSrc(), syncLoad_, nodeId_);
265 }
266
CacheDownloadedImage()267 void ImageLoadingContext::CacheDownloadedImage()
268 {
269 CHECK_NULL_VOID(Downloadable());
270 ImageProvider::CacheImageObject(imageObj_);
271 if (imageObj_->GetData()) {
272 ImageLoader::CacheImageData(GetSourceInfo().GetKey(), imageObj_->GetData());
273 }
274 if (!downloadedUrlData_.empty()) {
275 ImageLoader::WriteCacheToFile(GetSourceInfo().GetSrc(), downloadedUrlData_);
276 }
277 }
278
DownloadImageSuccess(const std::string & imageData)279 void ImageLoadingContext::DownloadImageSuccess(const std::string& imageData)
280 {
281 TAG_LOGI(AceLogTag::ACE_IMAGE, "Download image successfully, srcInfo = %{private}s, ImageData length=%{public}zu",
282 GetSrc().ToString().c_str(), imageData.size());
283 ACE_LAYOUT_SCOPED_TRACE("DownloadImageSuccess[src:%s]", GetSrc().ToString().c_str());
284 if (!Positive(imageData.size())) {
285 FailCallback("The length of imageData from netStack is not positive");
286 return;
287 }
288 auto data = ImageData::MakeFromDataWithCopy(imageData.data(), imageData.size());
289 // if downloading is necessary, cache object, data to file
290 RefPtr<ImageObject> imageObj = ImageProvider::BuildImageObject(GetSourceInfo(), data);
291 if (!imageObj) {
292 FailCallback("After download successful, imageObject Create fail");
293 return;
294 }
295 downloadedUrlData_ = imageData;
296 DataReadyCallback(imageObj);
297 }
298
DownloadImageFailed(const std::string & errorMessage)299 void ImageLoadingContext::DownloadImageFailed(const std::string& errorMessage)
300 {
301 TAG_LOGI(AceLogTag::ACE_IMAGE, "Download image failed, the error message is %{private}s", errorMessage.c_str());
302 FailCallback(errorMessage);
303 }
304
DownloadOnProgress(const uint32_t & dlNow,const uint32_t & dlTotal)305 void ImageLoadingContext::DownloadOnProgress(const uint32_t& dlNow, const uint32_t& dlTotal)
306 {
307 if (onProgressCallback_) {
308 onProgressCallback_(dlNow, dlTotal);
309 }
310 }
311
OnMakeCanvasImage()312 void ImageLoadingContext::OnMakeCanvasImage()
313 {
314 CHECK_NULL_VOID(imageObj_);
315
316 // only update params when entered MakeCanvasImage state successfully
317 if (updateParamsCallback_) {
318 updateParamsCallback_();
319 updateParamsCallback_ = nullptr;
320 }
321 auto userDefinedSize = GetSourceSize();
322 SizeF targetSize;
323 if (userDefinedSize) {
324 ImagePainter::ApplyImageFit(imageFit_, *userDefinedSize, dstSize_, srcRect_, dstRect_);
325 targetSize = *userDefinedSize;
326 } else {
327 auto imageSize = GetImageSize();
328 // calculate the srcRect based on original image size
329 ImagePainter::ApplyImageFit(imageFit_, imageSize, dstSize_, srcRect_, dstRect_);
330
331 bool isPixelMapResource = (SrcType::DATA_ABILITY_DECODED == GetSourceInfo().GetSrcType());
332 if (autoResize_ && !isPixelMapResource) {
333 targetSize = CalculateTargetSize(srcRect_.GetSize(), dstRect_.GetSize(), imageSize);
334 // calculate real srcRect used for paint based on resized image size
335 ImagePainter::ApplyImageFit(imageFit_, targetSize, dstSize_, srcRect_, dstRect_);
336 }
337
338 // upscale targetSize if size level is mapped
339 if (targetSize.IsPositive() && sizeLevel_ > targetSize.Width()) {
340 targetSize.ApplyScale(sizeLevel_ / targetSize.Width());
341 }
342 }
343
344 // step4: [MakeCanvasImage] according to [targetSize]
345 canvasKey_ = ImageUtils::GenerateImageKey(src_, targetSize);
346 imageObj_->MakeCanvasImage(Claim(this), targetSize, userDefinedSize.has_value(), syncLoad_, GetLoadInVipChannel());
347 }
348
ResizableCalcDstSize()349 void ImageLoadingContext::ResizableCalcDstSize()
350 {
351 auto userDefinedSize = GetSourceSize();
352 if (userDefinedSize) {
353 ImagePainter::ApplyImageFit(imageFit_, *userDefinedSize, dstSize_, srcRect_, dstRect_);
354 return;
355 }
356 auto imageSize = GetImageSize();
357 // calculate the srcRect based on original image size
358 ImagePainter::ApplyImageFit(imageFit_, imageSize, dstSize_, srcRect_, dstRect_);
359
360 bool isPixelMapResource = (SrcType::DATA_ABILITY_DECODED == GetSourceInfo().GetSrcType());
361 if (autoResize_ && !isPixelMapResource) {
362 SizeF targetSize = CalculateTargetSize(srcRect_.GetSize(), dstRect_.GetSize(), imageSize);
363 // calculate real srcRect used for paint based on resized image size
364 ImagePainter::ApplyImageFit(imageFit_, targetSize, dstSize_, srcRect_, dstRect_);
365 }
366 }
367
DataReadyCallback(const RefPtr<ImageObject> & imageObj)368 void ImageLoadingContext::DataReadyCallback(const RefPtr<ImageObject>& imageObj)
369 {
370 CHECK_NULL_VOID(imageObj);
371 imageObj_ = imageObj->Clone();
372 if (measureFinish_) {
373 OnDataReadyOnCompleteCallBack();
374 } else {
375 needDataReadyCallBack_ = true;
376 }
377 stateManager_->HandleCommand(ImageLoadingCommand::LOAD_DATA_SUCCESS);
378 }
379
SuccessCallback(const RefPtr<CanvasImage> & canvasImage)380 void ImageLoadingContext::SuccessCallback(const RefPtr<CanvasImage>& canvasImage)
381 {
382 canvasImage_ = canvasImage;
383 CacheDownloadedImage();
384 stateManager_->HandleCommand(ImageLoadingCommand::MAKE_CANVAS_IMAGE_SUCCESS);
385 }
386
FailCallback(const std::string & errorMsg)387 void ImageLoadingContext::FailCallback(const std::string& errorMsg)
388 {
389 errorMsg_ = errorMsg;
390 needErrorCallBack_ = true;
391 CHECK_NULL_VOID(measureFinish_);
392 TAG_LOGW(AceLogTag::ACE_IMAGE, "Image LoadFail, source = %{private}s, reason: %{public}s", src_.ToString().c_str(),
393 errorMsg.c_str());
394 if (Downloadable()) {
395 ImageFileCache::GetInstance().EraseCacheFile(GetSourceInfo().GetSrc());
396 }
397 stateManager_->HandleCommand(ImageLoadingCommand::LOAD_FAIL);
398 needErrorCallBack_ = false;
399 }
400
CallbackAfterMeasureIfNeed()401 void ImageLoadingContext::CallbackAfterMeasureIfNeed()
402 {
403 if (needErrorCallBack_) {
404 stateManager_->HandleCommand(ImageLoadingCommand::LOAD_FAIL);
405 needErrorCallBack_ = false;
406 }
407 if (needDataReadyCallBack_) {
408 OnDataReadyOnCompleteCallBack();
409 needDataReadyCallBack_ = false;
410 }
411 }
412
GetDstRect() const413 const RectF& ImageLoadingContext::GetDstRect() const
414 {
415 return dstRect_;
416 }
417
GetSrcRect() const418 const RectF& ImageLoadingContext::GetSrcRect() const
419 {
420 return srcRect_;
421 }
422
MoveCanvasImage()423 RefPtr<CanvasImage> ImageLoadingContext::MoveCanvasImage()
424 {
425 return std::move(canvasImage_);
426 }
427
MoveImageObject()428 RefPtr<ImageObject> ImageLoadingContext::MoveImageObject()
429 {
430 return std::move(imageObj_);
431 }
432
LoadImageData()433 void ImageLoadingContext::LoadImageData()
434 {
435 stateManager_->HandleCommand(ImageLoadingCommand::LOAD_DATA);
436 }
437
RoundUp(int32_t value)438 int32_t ImageLoadingContext::RoundUp(int32_t value)
439 {
440 CHECK_NULL_RETURN(imageObj_, -1);
441 auto res = imageObj_->GetImageSize().Width();
442 CHECK_NULL_RETURN(value > 0 && res > 0, -1);
443 while (res / 2 >= value) {
444 res /= 2;
445 }
446 return res;
447 }
448
MakeCanvasImageIfNeed(const SizeF & dstSize,bool autoResize,ImageFit imageFit,const std::optional<SizeF> & sourceSize,bool hasValidSlice)449 bool ImageLoadingContext::MakeCanvasImageIfNeed(const SizeF& dstSize, bool autoResize, ImageFit imageFit,
450 const std::optional<SizeF>& sourceSize, bool hasValidSlice)
451 {
452 bool res = autoResize != autoResize_ || imageFit != imageFit_ || sourceSize != GetSourceSize() || firstLoadImage_;
453
454 /* When function is called with a changed dstSize, assume the image will be resized frequently. To minimize
455 * MakeCanvasImage operations, map dstSize to size levels in log_2. Only Remake when the size level changes.
456 */
457 if (SizeChanging(dstSize)) {
458 res |= RoundUp(dstSize.Width()) != sizeLevel_;
459 } else if (dstSize_ == SizeF()) {
460 res |= dstSize.IsPositive();
461 }
462 if (!res && hasValidSlice) {
463 dstSize_ = dstSize;
464 }
465 CHECK_NULL_RETURN(res, res);
466 if (stateManager_->GetCurrentState() == ImageLoadingState::MAKE_CANVAS_IMAGE) {
467 pendingMakeCanvasImageTask_ = [weak = AceType::WeakClaim(this), dstSize, autoResize, imageFit, sourceSize]() {
468 auto ctx = weak.Upgrade();
469 CHECK_NULL_VOID(ctx);
470 CHECK_NULL_VOID(ctx->SizeChanging(dstSize));
471 ctx->MakeCanvasImage(dstSize, autoResize, imageFit, sourceSize);
472 };
473 } else {
474 MakeCanvasImage(dstSize, autoResize, imageFit, sourceSize);
475 }
476 return res;
477 }
478
MakeCanvasImage(const SizeF & dstSize,bool autoResize,ImageFit imageFit,const std::optional<SizeF> & sourceSize)479 void ImageLoadingContext::MakeCanvasImage(
480 const SizeF& dstSize, bool autoResize, ImageFit imageFit, const std::optional<SizeF>& sourceSize)
481 {
482 // Because calling of this interface does not guarantee the execution of [MakeCanvasImage], so in order to avoid
483 // updating params before they are not actually used, capture the params in a function. This function will only run
484 // when it actually do [MakeCanvasImage], i.e. doing the update in [OnMakeCanvasImageTask]
485 updateParamsCallback_ = [wp = WeakClaim(this), dstSize, autoResize, imageFit, sourceSize]() {
486 auto ctx = wp.Upgrade();
487 CHECK_NULL_VOID(ctx);
488 if (ctx->SizeChanging(dstSize) || ctx->firstLoadImage_) {
489 ctx->sizeLevel_ = ctx->RoundUp(dstSize.Width());
490 }
491 ctx->firstLoadImage_ = false;
492 ctx->dstSize_ = dstSize;
493 ctx->imageFit_ = imageFit;
494 ctx->autoResize_ = autoResize;
495 ctx->SetSourceSize(sourceSize);
496 };
497 // send command to [StateManager] and waiting the callback from it to determine next step
498 stateManager_->HandleCommand(ImageLoadingCommand::MAKE_CANVAS_IMAGE);
499 }
500
GetImageSize() const501 SizeF ImageLoadingContext::GetImageSize() const
502 {
503 CHECK_NULL_RETURN(imageObj_, SizeF(-1.0, -1.0));
504 auto imageSize = imageObj_->GetImageSize();
505 auto orientation = imageObj_->GetOrientation();
506 if (orientation == ImageRotateOrientation::LEFT || orientation == ImageRotateOrientation::RIGHT) {
507 return {imageSize.Height(), imageSize.Width()};
508 }
509 return imageSize;
510 }
511
GetOriginImageSize() const512 SizeF ImageLoadingContext::GetOriginImageSize() const
513 {
514 return imageObj_ ? imageObj_->GetImageSize() : SizeF(-1, -1);
515 }
516
GetImageFit() const517 ImageFit ImageLoadingContext::GetImageFit() const
518 {
519 return imageFit_;
520 }
521
SetImageFit(ImageFit imageFit)522 void ImageLoadingContext::SetImageFit(ImageFit imageFit)
523 {
524 imageFit_ = imageFit;
525 }
526
GetSourceInfo() const527 const ImageSourceInfo& ImageLoadingContext::GetSourceInfo() const
528 {
529 return src_;
530 }
531
SetAutoResize(bool autoResize)532 void ImageLoadingContext::SetAutoResize(bool autoResize)
533 {
534 autoResize_ = autoResize;
535 }
536
GetDstSize() const537 const SizeF& ImageLoadingContext::GetDstSize() const
538 {
539 return dstSize_;
540 }
541
GetAutoResize() const542 bool ImageLoadingContext::GetAutoResize() const
543 {
544 return autoResize_;
545 }
546
SetSourceSize(const std::optional<SizeF> & sourceSize)547 void ImageLoadingContext::SetSourceSize(const std::optional<SizeF>& sourceSize)
548 {
549 if (sourceSize.has_value()) {
550 sourceSizePtr_ = std::make_unique<SizeF>(sourceSize.value());
551 }
552 }
553
GetSourceSize() const554 std::optional<SizeF> ImageLoadingContext::GetSourceSize() const
555 {
556 CHECK_NULL_RETURN(sourceSizePtr_, std::nullopt);
557 if (sourceSizePtr_->Width() <= 0.0 || sourceSizePtr_->Height() <= 0.0) {
558 TAG_LOGW(AceLogTag::ACE_IMAGE,
559 "Property SourceSize is at least One invalid! Use the Image Size to calculate resize target");
560 return std::nullopt;
561 }
562 return { *sourceSizePtr_ };
563 }
564
NeedAlt() const565 bool ImageLoadingContext::NeedAlt() const
566 {
567 auto state = stateManager_->GetCurrentState();
568 return state != ImageLoadingState::LOAD_SUCCESS;
569 }
570
GetSvgFillColor() const571 const std::optional<Color>& ImageLoadingContext::GetSvgFillColor() const
572 {
573 return src_.GetFillColor();
574 }
575
ResetLoading()576 void ImageLoadingContext::ResetLoading()
577 {
578 stateManager_->HandleCommand(ImageLoadingCommand::RESET_STATE);
579 }
580
ResumeLoading()581 void ImageLoadingContext::ResumeLoading()
582 {
583 stateManager_->HandleCommand(ImageLoadingCommand::LOAD_DATA);
584 }
585
GetCurrentLoadingState()586 const std::string ImageLoadingContext::GetCurrentLoadingState()
587 {
588 ImageLoadingState state = ImageLoadingState::UNLOADED;
589 if (stateManager_) {
590 state = stateManager_->GetCurrentState();
591 }
592 switch (state) {
593 case ImageLoadingState::DATA_LOADING:
594 return "DATA_LOADING";
595 case ImageLoadingState::DATA_READY:
596 return "DATA_READY";
597 case ImageLoadingState::MAKE_CANVAS_IMAGE:
598 return "MAKE_CANVAS_IMAGE";
599 case ImageLoadingState::LOAD_SUCCESS:
600 return "LOAD_SUCCESS";
601 case ImageLoadingState::LOAD_FAIL:
602 return "LOAD_FAIL";
603
604 default:
605 return "UNLOADED";
606 }
607 }
608
GetFrameCount() const609 int32_t ImageLoadingContext::GetFrameCount() const
610 {
611 return imageObj_ ? imageObj_->GetFrameCount() : 0;
612 }
613
614 } // namespace OHOS::Ace::NG
615