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