• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "core/components/image/render_image.h"
17 
18 #include "base/log/dump_log.h"
19 #include "core/common/ace_engine_ext.h"
20 #include "core/components/image/image_event.h"
21 #include "core/components/text_overlay/text_overlay_component.h"
22 #include "core/components/theme/icon_theme.h"
23 
24 namespace OHOS::Ace {
25 namespace {
26 
27 constexpr double RESIZE_AGAIN_THRESHOLD = 1.2;
28 
29 } // namespace
30 
~RenderImage()31 RenderImage::~RenderImage()
32 {
33     auto textOverlayManager = GetTextOverlayManager(context_);
34     if (textOverlayManager) {
35         auto textOverlayBase = textOverlayManager->GetTextOverlayBase();
36         if (textOverlayBase) {
37             auto targetNode = textOverlayManager->GetTargetNode();
38             if (targetNode == this) {
39                 textOverlayManager->PopTextOverlay();
40                 textOverlayBase->MarkIsOverlayShowed(false);
41                 targetNode->MarkNeedRender();
42             }
43         }
44     }
45 }
46 
Update(const RefPtr<Component> & component)47 void RenderImage::Update(const RefPtr<Component>& component)
48 {
49     const RefPtr<ImageComponent> image = AceType::DynamicCast<ImageComponent>(component);
50     if (!image) {
51         LOGE("image component is null!");
52         return;
53     }
54     auto context = context_.Upgrade();
55     if (!context) {
56         return;
57     }
58     if (!clipboard_ && context) {
59         clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(context->GetTaskExecutor());
60     }
61     currentSrcRect_ = srcRect_;
62     currentDstRect_ = dstRect_;
63     currentDstRectList_ = rectList_;
64     colorfilter_ = image->GetColorFilterMatrix();
65     blurRadius_ = image->GetBlurRadius();
66     width_ = image->GetWidth();
67     syncMode_ = image->GetSyncMode();
68     height_ = image->GetHeight();
69     alignment_ = image->GetAlignment();
70     imageObjectPosition_ = image->GetImageObjectPosition();
71     fitMaxSize_ = image->GetFitMaxSize();
72     hasObjectPosition_ = image->GetHasObjectPosition();
73     color_ = image->GetColor();
74     previousLayoutSize_ = Size();
75     SetTextDirection(image->GetTextDirection());
76     matchTextDirection_ = image->IsMatchTextDirection();
77     SetRadius(image->GetBorder());
78     if (context && context->GetIsDeclarative()) {
79         loadImgSuccessEvent_ =
80             AceAsyncEvent<void(const std::shared_ptr<BaseEventInfo>&)>::Create(image->GetLoadSuccessEvent(), context_);
81         loadImgFailEvent_ =
82             AceAsyncEvent<void(const std::shared_ptr<BaseEventInfo>&)>::Create(image->GetLoadFailEvent(), context_);
83     } else {
84         loadSuccessEvent_ = AceAsyncEvent<void(const std::string&)>::Create(image->GetLoadSuccessEvent(), context_);
85         loadFailEvent_ = AceAsyncEvent<void(const std::string&)>::Create(image->GetLoadFailEvent(), context_);
86     }
87     svgAnimatorFinishEvent_ = image->GetSvgAnimatorFinishEvent();
88     imageFit_ = image->GetImageFit();
89     imageInterpolation_ = image->GetImageInterpolation();
90     imageRenderMode_ = image->GetImageRenderMode();
91     imageRepeat_ = image->GetImageRepeat();
92 
93 #ifndef USE_ROSEN_DRAWING
94     useSkiaSvg_ = image->GetUseSkiaSvg();
95 #else
96     useSkiaSvg_ = false;
97 #endif
98     autoResize_ = image->GetAutoResize();
99     imageAlt_ = image->GetAlt();
100     auto inComingSrc = image->GetSrc();
101     ImageSourceInfo inComingSource(inComingSrc, image->GetBundleName(), image->GetModuleName(),
102         image->GetImageSourceSize().first, image->GetImageSourceSize().second,
103         inComingSrc.empty() ? image->GetResourceId() : InternalResource::ResourceId::NO_ID, image->GetPixmap());
104     UpdateThemeIcon(inComingSource);
105     auto fillColor = image->GetImageFill();
106     if (fillColor.has_value()) {
107         inComingSource.SetFillColor(fillColor.value());
108     }
109     border_ = image->GetBorder();
110 
111     onDragStart_ = image->GetOnDragStartId();
112     onDragEnter_ = image->GetOnDragEnterId();
113     onDragMove_ = image->GetOnDragMoveId();
114     onDragLeave_ = image->GetOnDragLeaveId();
115     onDrop_ = image->GetOnDropId();
116     if (onDragStart_) {
117         CreateDragDropRecognizer(context_);
118     }
119 
120     copyOption_ = image->GetCopyOption();
121 
122     // this value is used for update frequency with same image source info.
123     proceedPreviousLoading_ = sourceInfo_.IsValid() && sourceInfo_ == inComingSource;
124     // perform layout only if loading new image
125     if (!proceedPreviousLoading_) {
126         sourceInfo_ = inComingSource;
127         MarkNeedLayout(sourceInfo_.IsSvg());
128     }
129 }
130 
UpdateThemeIcon(ImageSourceInfo & sourceInfo)131 void RenderImage::UpdateThemeIcon(ImageSourceInfo& sourceInfo)
132 {
133     if (sourceInfo.IsInternalResource()) {
134         auto iconTheme = GetTheme<IconTheme>();
135         if (!iconTheme) {
136             LOGW("icon theme is null.");
137             return;
138         }
139         auto iconPath = iconTheme->GetIconPath(sourceInfo.GetResourceId());
140         if (!iconPath.empty()) {
141             sourceInfo.SetSrc(iconPath);
142         }
143     }
144 }
145 
OnPaintFinish()146 void RenderImage::OnPaintFinish()
147 {
148     UpdateOverlay();
149 }
150 
OnTouchTestHit(const Offset & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & result)151 void RenderImage::OnTouchTestHit(
152     const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result)
153 {
154     if (dragDropGesture_) {
155         result.emplace_back(dragDropGesture_);
156     }
157 
158     if (copyOption_ != CopyOptions::None && imageLoadingStatus_ == ImageLoadingStatus::LOAD_SUCCESS &&
159         !sourceInfo_.IsSvg()) {
160         if (!textOverlayRecognizer_) {
161             textOverlayRecognizer_ = AceType::MakeRefPtr<LongPressRecognizer>(context_);
162             textOverlayRecognizer_->SetOnLongPress([weak = WeakClaim(this)](const LongPressInfo& info) {
163                 auto client = weak.Upgrade();
164                 if (client) {
165                     client->OnLongPress(info);
166                 }
167             });
168         }
169         textOverlayRecognizer_->SetCoordinateOffset(coordinateOffset);
170         textOverlayRecognizer_->SetTouchRestrict(touchRestrict);
171         textOverlayRecognizer_->SetUseCatchMode(false);
172         result.emplace_back(textOverlayRecognizer_);
173     }
174 }
175 
OnLongPress(const LongPressInfo & longPressInfo)176 void RenderImage::OnLongPress(const LongPressInfo& longPressInfo)
177 {
178     auto textOverlayManager = GetTextOverlayManager(context_);
179     if (textOverlayManager) {
180         auto textOverlayBase = textOverlayManager->GetTextOverlayBase();
181         if (textOverlayBase) {
182             auto targetNode = textOverlayManager->GetTargetNode();
183             if (targetNode) {
184                 textOverlayManager->PopTextOverlay();
185                 textOverlayBase->MarkIsOverlayShowed(false);
186                 targetNode->MarkNeedRender();
187             }
188         }
189         textOverlayManager->SetTextOverlayBase(AceType::WeakClaim(this));
190     }
191 
192     Offset longPressPosition = longPressInfo.GetGlobalLocation();
193     ShowTextOverlay(longPressPosition);
194 }
195 
HandleMouseEvent(const MouseEvent & event)196 bool RenderImage::HandleMouseEvent(const MouseEvent& event)
197 {
198     if (copyOption_ == CopyOptions::None || imageLoadingStatus_ != ImageLoadingStatus::LOAD_SUCCESS ||
199         sourceInfo_.IsSvg()) {
200         return false;
201     }
202     if (event.button == MouseButton::RIGHT_BUTTON && event.action == MouseAction::PRESS) {
203         Offset rightClickOffset = event.GetOffset();
204         auto textOverlayManager = GetTextOverlayManager(context_);
205         if (textOverlayManager) {
206             auto textOverlayBase = textOverlayManager->GetTextOverlayBase();
207             if (textOverlayBase) {
208                 auto targetNode = textOverlayManager->GetTargetNode();
209                 if (targetNode) {
210                     textOverlayManager->PopTextOverlay();
211                     textOverlayBase->MarkIsOverlayShowed(false);
212                     targetNode->MarkNeedRender();
213                 }
214             }
215             textOverlayManager->SetTextOverlayBase(AceType::WeakClaim(this));
216         }
217         ShowTextOverlay(rightClickOffset);
218         return true;
219     }
220     return false;
221 }
222 
HandleKeyEvent(const KeyEvent & event)223 bool RenderImage::HandleKeyEvent(const KeyEvent& event)
224 {
225     if (event.action != KeyAction::DOWN) {
226         return false;
227     }
228     if (event.IsCtrlWith(KeyCode::KEY_C) && copyOption_ != CopyOptions::None) {
229         HandleOnCopy();
230         return true;
231     }
232     return false;
233 }
234 
ShowTextOverlay(const Offset & showOffset)235 void RenderImage::ShowTextOverlay(const Offset& showOffset)
236 {
237     popOverlayOffset_ = showOffset;
238     Offset startHandleOffset = popOverlayOffset_;
239     Offset endHandleOffset = popOverlayOffset_;
240     if (isOverlayShowed_ && updateHandlePosition_) {
241         OverlayShowOption option { .showMenu = isOverlayShowed_,
242             .updateOverlayType = UpdateOverlayType::LONG_PRESS,
243             .startHandleOffset = startHandleOffset,
244             .endHandleOffset = endHandleOffset };
245         updateHandlePosition_(option);
246         if (!animator_) {
247             LOGE("Show textOverlay error, animator is nullptr");
248             return;
249         }
250         if (!animator_->IsStopped()) {
251             animator_->Stop();
252         }
253         animator_->Play();
254         return;
255     }
256 
257     textOverlay_ =
258         AceType::MakeRefPtr<TextOverlayComponent>(GetThemeManager(), context_.Upgrade()->GetAccessibilityManager());
259     textOverlay_->SetWeakImage(WeakClaim(this));
260     textOverlay_->SetNeedCilpRect(false);
261     textOverlay_->SetStartHandleOffset(startHandleOffset);
262     textOverlay_->SetEndHandleOffset(endHandleOffset);
263     textOverlay_->SetContext(context_);
264     InitAnimation(context_);
265     RegisterCallbacksToOverlay();
266     MarkNeedRender();
267 }
268 
RegisterCallbacksToOverlay()269 void RenderImage::RegisterCallbacksToOverlay()
270 {
271     if (!textOverlay_) {
272         return;
273     }
274 
275     textOverlay_->SetOnCopy([weak = AceType::WeakClaim(this)] {
276         auto image = weak.Upgrade();
277         if (image) {
278             image->HandleOnCopy();
279         }
280     });
281 
282     auto callback = [weak = WeakClaim(this), pipelineContext = context_, textOverlay = textOverlay_](
283                         const RefPtr<PixelMap>& pixmap) {
284         auto context = pipelineContext.Upgrade();
285         if (!context) {
286             return;
287         }
288         auto textOverlayManager = context->GetTextOverlayManager();
289         if (!textOverlayManager) {
290             return;
291         }
292         textOverlayManager->PushTextOverlayToStack(textOverlay, pipelineContext);
293 
294         auto image = weak.Upgrade();
295         if (!image) {
296             return;
297         }
298         image->UpdateOverlay();
299         image->MarkIsOverlayShowed(true);
300     };
301     if (clipboard_) {
302         clipboard_->GetPixelMapData(callback);
303     }
304 }
305 
UpdateOverlay()306 void RenderImage::UpdateOverlay()
307 {
308     if (isOverlayShowed_ && updateHandlePosition_) {
309         OverlayShowOption option { .showMenu = isOverlayShowed_,
310             .updateOverlayType = UpdateOverlayType::LONG_PRESS,
311             .startHandleOffset = popOverlayOffset_,
312             .endHandleOffset = popOverlayOffset_ };
313         updateHandlePosition_(option);
314     }
315 }
316 
HandleOnCopy()317 void RenderImage::HandleOnCopy()
318 {
319     if (!clipboard_) {
320         return;
321     }
322     auto renderImage = AceType::Claim(this);
323     auto type = sourceInfo_.GetSrcType();
324     switch (type) {
325         case SrcType::PIXMAP: {
326             clipboard_->SetPixelMapData(sourceInfo_.GetPixmap(), copyOption_);
327             break;
328         }
329         case SrcType::BASE64: {
330             clipboard_->SetData(sourceInfo_.GetSrc(), copyOption_);
331             break;
332         }
333         case SrcType::DATA_ABILITY_DECODED:
334         case SrcType::DATA_ABILITY: {
335             clipboard_->SetData(sourceInfo_.GetSrc(), copyOption_);
336             break;
337         }
338         default: {
339 #ifndef USE_ROSEN_DRAWING
340             clipboard_->SetPixelMapData(renderImage->GetPixmapFromSkImage(), copyOption_);
341 #else
342             clipboard_->SetPixelMapData(renderImage->GetPixmapFromDrawingImage(), copyOption_);
343 #endif
344             break;
345         }
346     }
347 
348     auto textOverlayManager = GetTextOverlayManager(context_);
349     if (textOverlayManager) {
350         textOverlayManager->PopTextOverlay();
351     }
352     isOverlayShowed_ = false;
353     MarkNeedRender();
354 }
355 
PerformLayout()356 void RenderImage::PerformLayout()
357 {
358     if (background_) {
359         PerformLayoutBgImage();
360         if (imageRenderFunc_) {
361             imageRenderFunc_();
362         }
363         return;
364     }
365 
366     auto context = context_.Upgrade();
367     if (!context) {
368         return;
369     }
370     scale_ = context->GetViewScale();
371     if (LessOrEqual(scale_, 0)) {
372         scale_ = 1.0;
373     }
374     if (width_.IsValid() && height_.IsValid()) {
375         imageComponentSize_ = Size(NormalizeToPx(width_), NormalizeToPx(height_));
376         isImageSizeSet_ = true;
377     }
378     // Divided by the true pixel ratio to apply image fit.
379     Size pictureSize = Measure() * (1.0 / scale_);
380     auto maxSize = GetLayoutParam().GetMaxSize();
381     if (fitMaxSize_ && (!imageComponentSize_.IsValid() || (!isImageSizeSet_ && maxSize != formerMaxSize_))) {
382         imageComponentSize_ = maxSize;
383         formerMaxSize_ = imageComponentSize_;
384     }
385     SetLayoutSize(GetLayoutParam().Constrain(imageComponentSize_.IsValid() && !imageComponentSize_.IsInfinite()
386                                                  ? imageComponentSize_
387                                                  : CalculateBackupImageSize(pictureSize)));
388     if (rawImageSizeUpdated_) {
389         previousLayoutSize_ = GetLayoutSize();
390     }
391     srcRect_.SetRect(Offset(), pictureSize);
392     dstRect_.SetRect(Offset(), GetLayoutSize());
393     ApplyImageFit(srcRect_, dstRect_);
394     // Restore image size.
395     srcRect_.ApplyScale(scale_);
396     if (!imageComponentSize_.IsValid()) {
397         SetLayoutSize(dstRect_.GetSize());
398     }
399     decltype(imageLayoutCallbacks_) imageLayoutCallbacks(std::move(imageLayoutCallbacks_));
400     std::for_each(
401         imageLayoutCallbacks.begin(), imageLayoutCallbacks.end(), [](std::function<void()> callback) { callback(); });
402     LayoutImageObject();
403     if (renderAltImage_) {
404         LayoutParam altLayoutParam;
405         altLayoutParam.SetFixedSize(GetLayoutSize());
406         renderAltImage_->Layout(altLayoutParam);
407     }
408 
409     CalculateResizeTarget();
410     if (hasObjectPosition_) {
411         ApplyObjectPosition();
412     }
413 }
414 
CalculateBackupImageSize(const Size & pictureSize)415 Size RenderImage::CalculateBackupImageSize(const Size& pictureSize)
416 {
417     // Since the return value of this function is used to determine the layout size of Image Component, it is essential
418     // to guarantee that there is no infinite edge to avoid thread stuck that may occur.
419     //
420     // Generally speaking, the size of the picture will not be infinite, but the size of the svg picture is equal to the
421     // maximum value of the layout parameters, so there is the possibility of infinity.
422     //
423     // Note that [pictureSize] has been scaled by [scale_], so we need to obtain the original picture size via
424     // [Measure()] to verify whether or not it has infinite edge.
425     auto rawPicSize = Measure();
426     if (!rawPicSize.IsValid() || rawPicSize.IsInfinite()) {
427         return Size();
428     }
429     uint8_t infiniteStatus = (static_cast<uint8_t>(imageComponentSize_.IsWidthInfinite()) << 1) |
430                              static_cast<uint8_t>(imageComponentSize_.IsHeightInfinite());
431     double pictureSizeRatio = pictureSize.Width() / pictureSize.Height();
432     Size backupImageSize = imageComponentSize_;
433     switch (infiniteStatus) {
434         case 0b00: // both width and height are infinite
435             backupImageSize = pictureSize;
436             break;
437         case 0b01: // only height is infinite
438             backupImageSize.SetHeight(imageComponentSize_.Width() / pictureSizeRatio);
439             break;
440         case 0b10: // only width is infinite
441             backupImageSize.SetWidth(imageComponentSize_.Height() * pictureSizeRatio);
442             break;
443         default:
444             backupImageSize = imageComponentSize_;
445             break;
446     }
447     return backupImageSize;
448 }
449 
NeedResize() const450 bool RenderImage::NeedResize() const
451 {
452     if (!resizeTarget_.IsValid()) {
453         return false;
454     }
455     if (!previousResizeTarget_.IsValid()) {
456         return true;
457     }
458     if (resizeTarget_ < previousResizeTarget_) {
459         return false;
460     }
461     double widthEnlargedBy = resizeTarget_.Width() / previousResizeTarget_.Width();
462     double heightEnlargedBy = resizeTarget_.Height() / previousResizeTarget_.Height();
463     if (widthEnlargedBy > RESIZE_AGAIN_THRESHOLD || heightEnlargedBy > RESIZE_AGAIN_THRESHOLD) {
464         return true;
465     }
466     return false;
467 }
468 
CalculateResizeTarget()469 void RenderImage::CalculateResizeTarget()
470 {
471     if (!srcRect_.IsValid()) {
472         return;
473     }
474     if (!autoResize_) {
475         resizeTarget_ = rawImageSize_;
476         resizeScale_ = Size(1.0, 1.0);
477         return;
478     }
479     double widthScale = dstRect_.Width() / srcRect_.Width() * scale_;
480     double heightScale = dstRect_.Height() / srcRect_.Height() * scale_;
481     if (widthScale < 1.0 && heightScale < 1.0) {
482         resizeScale_ = Size(widthScale, heightScale);
483     } else {
484         resizeScale_ = Size(1.0, 1.0);
485     }
486     resizeTarget_ = Size(rawImageSize_.Width() * resizeScale_.Width(), rawImageSize_.Height() * resizeScale_.Height());
487 }
488 
ApplyImageFit(Rect & srcRect,Rect & dstRect)489 void RenderImage::ApplyImageFit(Rect& srcRect, Rect& dstRect)
490 {
491     Size rawPicSize = srcRect.GetSize();
492     Size layoutSize = GetLayoutSize();
493     switch (imageFit_) {
494         case ImageFit::FILL:
495             break;
496         case ImageFit::NONE:
497             ApplyNone(srcRect, dstRect, rawPicSize, layoutSize);
498             break;
499         case ImageFit::COVER:
500             ApplyCover(srcRect, dstRect, rawPicSize, layoutSize);
501             break;
502         case ImageFit::FITWIDTH:
503             ApplyFitWidth(srcRect, dstRect, rawPicSize, layoutSize);
504             break;
505         case ImageFit::FITHEIGHT:
506             ApplyFitHeight(srcRect, dstRect, rawPicSize, layoutSize);
507             break;
508         case ImageFit::SCALE_DOWN:
509             if (srcRect.GetSize() < dstRect.GetSize()) {
510                 ApplyNone(srcRect, dstRect, rawPicSize, layoutSize);
511             } else {
512                 ApplyContain(srcRect, dstRect, rawPicSize, layoutSize);
513             }
514             break;
515         case ImageFit::CONTAIN:
516             ApplyContain(srcRect, dstRect, rawPicSize, layoutSize);
517             break;
518         default:
519             ApplyContain(srcRect, dstRect, rawPicSize, layoutSize);
520             break;
521     }
522 }
523 
ApplyContain(Rect & srcRect,Rect & dstRect,const Size & rawPicSize,const Size & layoutSize)524 void RenderImage::ApplyContain(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& layoutSize)
525 {
526     if (!rawPicSize.IsValid()) {
527         return;
528     }
529     if (Size::CalcRatio(srcRect) > Size::CalcRatio(dstRect)) {
530         dstRect.SetSize(rawPicSize * (layoutSize.Width() / rawPicSize.Width()));
531     } else {
532         dstRect.SetSize(rawPicSize * (layoutSize.Height() / rawPicSize.Height()));
533     }
534     dstRect.SetOffset(Alignment::GetAlignPosition(layoutSize, dstRect.GetSize(), alignment_));
535 }
536 
ApplyCover(Rect & srcRect,Rect & dstRect,const Size & rawPicSize,const Size & layoutSize)537 void RenderImage::ApplyCover(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& layoutSize)
538 {
539     if (Size::CalcRatio(srcRect) > Size::CalcRatio(dstRect)) {
540         srcRect.SetSize(layoutSize * (rawPicSize.Height() / layoutSize.Height()));
541     } else {
542         srcRect.SetSize(layoutSize * (rawPicSize.Width() / layoutSize.Width()));
543     }
544     srcRect.SetOffset(Alignment::GetAlignPosition(rawPicSize, srcRect.GetSize(), alignment_));
545 }
546 
ApplyFitWidth(Rect & srcRect,Rect & dstRect,const Size & rawPicSize,const Size & layoutSize)547 void RenderImage::ApplyFitWidth(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& layoutSize)
548 {
549     if (Size::CalcRatio(srcRect) > Size::CalcRatio(dstRect)) {
550         dstRect.SetSize(rawPicSize * (layoutSize.Width() / rawPicSize.Width()));
551         dstRect.SetOffset(Alignment::GetAlignPosition(layoutSize, dstRect.GetSize(), alignment_));
552     } else {
553         srcRect.SetSize(layoutSize * (rawPicSize.Width() / layoutSize.Width()));
554         srcRect.SetOffset(Alignment::GetAlignPosition(rawPicSize, srcRect.GetSize(), alignment_));
555     }
556 }
557 
ApplyFitHeight(Rect & srcRect,Rect & dstRect,const Size & rawPicSize,const Size & layoutSize)558 void RenderImage::ApplyFitHeight(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& layoutSize)
559 {
560     if (Size::CalcRatio(srcRect) > Size::CalcRatio(dstRect)) {
561         srcRect.SetSize(layoutSize * (rawPicSize.Height() / layoutSize.Height()));
562         srcRect.SetOffset(Alignment::GetAlignPosition(rawPicSize, srcRect.GetSize(), alignment_));
563     } else {
564         dstRect.SetSize(rawPicSize * (layoutSize.Height() / rawPicSize.Height()));
565         dstRect.SetOffset(Alignment::GetAlignPosition(layoutSize, dstRect.GetSize(), alignment_));
566     }
567 }
568 
ApplyNone(Rect & srcRect,Rect & dstRect,const Size & rawPicSize,const Size & layoutSize)569 void RenderImage::ApplyNone(Rect& srcRect, Rect& dstRect, const Size& rawPicSize, const Size& layoutSize)
570 {
571     Size srcSize =
572         Size(std::min(layoutSize.Width(), rawPicSize.Width()), std::min(layoutSize.Height(), rawPicSize.Height()));
573     dstRect.SetRect(Alignment::GetAlignPosition(layoutSize, srcSize, alignment_), srcSize);
574     srcRect.SetRect(Alignment::GetAlignPosition(rawPicSize, srcSize, alignment_), srcSize);
575 }
576 
FireLoadEvent(const Size & picSize,const std::string & errorMsg) const577 void RenderImage::FireLoadEvent(const Size& picSize, const std::string& errorMsg) const
578 {
579     auto context = context_.Upgrade();
580     if (context && context->GetIsDeclarative()) {
581         if (loadImgSuccessEvent_ && (imageLoadingStatus_ == ImageLoadingStatus::LOAD_SUCCESS)) {
582             // here the last param of [loadImgSuccessEvent_] is [1],
583             // which means the callback is triggered by [OnLoadSuccess]
584             loadImgSuccessEvent_(std::make_shared<LoadImageSuccessEvent>(
585                 picSize.Width(), picSize.Height(), GetLayoutSize().Width(), GetLayoutSize().Height(), 1));
586         }
587         if (loadImgFailEvent_ && (imageLoadingStatus_ == ImageLoadingStatus::LOAD_FAIL)) {
588             loadImgFailEvent_(
589                 std::make_shared<LoadImageFailEvent>(GetLayoutSize().Width(), GetLayoutSize().Height(), errorMsg));
590         }
591         return;
592     }
593     std::string param;
594     if (loadSuccessEvent_ && (imageLoadingStatus_ == ImageLoadingStatus::LOAD_SUCCESS)) {
595         param = std::string("\"complete\",{\"width\":")
596                     .append(std::to_string(picSize.Width()))
597                     .append(",\"height\":")
598                     .append(std::to_string(picSize.Height()))
599                     .append("}");
600         loadSuccessEvent_(param);
601     }
602     if (loadFailEvent_ && (imageLoadingStatus_ == ImageLoadingStatus::LOAD_FAIL)) {
603         param = std::string("\"error\",{\"width\":")
604                     .append(std::to_string(picSize.Width()))
605                     .append(",\"height\":")
606                     .append(std::to_string(picSize.Height()))
607                     .append("}");
608         loadFailEvent_(param);
609     }
610     if (loadFailCallback_ && (imageLoadingStatus_ == ImageLoadingStatus::LOAD_FAIL)) {
611         loadFailCallback_();
612         loadFailCallback_ = nullptr;
613     }
614 }
615 
SetRadius(const Border & border)616 void RenderImage::SetRadius(const Border& border)
617 {
618     auto leftEdgeWidth = border.Left().GetWidth();
619     auto topEdgeWidth = border.Top().GetWidth();
620     auto rightEdgeWidth = border.Right().GetWidth();
621     auto bottomEdgeWidth = border.Bottom().GetWidth();
622     topLeftRadius_ = Radius(border.TopLeftRadius() - Radius(topEdgeWidth, leftEdgeWidth));
623     topRightRadius_ = Radius(border.TopRightRadius() - Radius(topEdgeWidth, rightEdgeWidth));
624     bottomLeftRadius_ = Radius(border.BottomLeftRadius() - Radius(bottomEdgeWidth, leftEdgeWidth));
625     bottomRightRadius_ = Radius(border.BottomRightRadius() - Radius(bottomEdgeWidth, rightEdgeWidth));
626 }
627 
IsSVG(const std::string & src,InternalResource::ResourceId resourceId)628 bool RenderImage::IsSVG(const std::string& src, InternalResource::ResourceId resourceId)
629 {
630     return ImageComponent::IsSvgSuffix(src) || (src.empty() && resourceId > InternalResource::ResourceId::SVG_START &&
631                                                    resourceId < InternalResource::ResourceId::SVG_END);
632 }
633 
PerformLayoutBgImage()634 void RenderImage::PerformLayoutBgImage()
635 {
636     if (!background_) {
637         return;
638     }
639     if (!rawImageSize_.IsValid()) {
640         return;
641     }
642 
643     GenerateImageRects(rawImageSize_, imageSize_, imageRepeat_, imagePosition_);
644     srcRect_.SetOffset(Offset());
645     srcRect_.SetSize(rawImageSize_);
646     dstRect_.SetOffset(Offset());
647     dstRect_.SetSize(imageRenderSize_);
648 }
649 
650 // objectPosition
ApplyObjectPosition()651 void RenderImage::ApplyObjectPosition()
652 {
653     Size layoutSize = GetLayoutSize();
654     Offset offset;
655     if (imageObjectPosition_.GetSizeTypeX() == BackgroundImagePositionType::PX) {
656         offset.SetX((layoutSize.Width() - dstRect_.Width()) / 2 - imageObjectPosition_.GetSizeValueX());
657     } else {
658         offset.SetX((layoutSize.Width() - dstRect_.Width()) / 2 - // 2: left & right border of width
659                     imageObjectPosition_.GetSizeValueX() * (layoutSize.Width() - dstRect_.Width()) / PERCENT_TRANSLATE);
660     }
661 
662     if (imageObjectPosition_.GetSizeTypeY() == BackgroundImagePositionType::PX) {
663         offset.SetY((layoutSize.Height() - dstRect_.Height()) / 2 - imageObjectPosition_.GetSizeValueY());
664     } else {
665         offset.SetY((layoutSize.Height() - dstRect_.Height()) / 2 - imageObjectPosition_.GetSizeValueY() *
666                                                                         (layoutSize.Height() - dstRect_.Height()) /
667                                                                         PERCENT_TRANSLATE);
668     }
669     imageRenderPosition_ = offset;
670 }
671 
GenerateImageRects(const Size & srcSize,const BackgroundImageSize & imageSize,ImageRepeat imageRepeat,const BackgroundImagePosition & imagePosition)672 void RenderImage::GenerateImageRects(const Size& srcSize, const BackgroundImageSize& imageSize, ImageRepeat imageRepeat,
673     const BackgroundImagePosition& imagePosition)
674 {
675     rectList_.clear();
676     if (NearEqual(boxPaintSize_.Width(), Size::INFINITE_SIZE) ||
677         NearEqual(boxPaintSize_.Height(), Size::INFINITE_SIZE)) {
678         boxPaintSize_ = viewPort_;
679     }
680 
681     // Different with Image Repeat
682     imageRenderSize_ = CalculateImageRenderSize(srcSize, imageSize);
683     if (NearZero(imageRenderSize_.Width()) || NearZero(imageRenderSize_.Height())) {
684         return;
685     }
686     // Ceil render size
687     imageRenderSize_ = Size(ceil(imageRenderSize_.Width()), ceil(imageRenderSize_.Height()));
688 
689     CalculateImageRenderPosition(imagePosition);
690 
691     int32_t minX = 0;
692     int32_t minY = 0;
693     int32_t maxX = 0;
694     int32_t maxY = 0;
695     if (imageRepeat == ImageRepeat::REPEAT || imageRepeat == ImageRepeat::REPEAT_X) {
696         if (LessOrEqual(imageRenderPosition_.GetX(), 0.0)) {
697             minX = 0;
698             maxX = std::ceil((boxPaintSize_.Width() - imageRenderPosition_.GetX()) / imageRenderSize_.Width());
699         } else {
700             minX = std::floor((-imageRenderPosition_.GetX()) / imageRenderSize_.Width());
701             maxX = std::ceil((boxPaintSize_.Width() - imageRenderPosition_.GetX()) / imageRenderSize_.Width());
702         }
703     }
704 
705     if (imageRepeat == ImageRepeat::REPEAT || imageRepeat == ImageRepeat::REPEAT_Y) {
706         if (LessOrEqual(imageRenderPosition_.GetY(), 0.0)) {
707             minY = 0;
708             maxY = std::ceil((boxPaintSize_.Height() - imageRenderPosition_.GetY()) / imageRenderSize_.Height());
709         } else {
710             minY = std::floor((-imageRenderPosition_.GetY()) / imageRenderSize_.Height());
711             maxY = std::ceil((boxPaintSize_.Height() - imageRenderPosition_.GetY()) / imageRenderSize_.Height());
712         }
713     }
714 
715     Rect imageCell = Rect(imageRenderPosition_, Size(imageRenderSize_.Width(), imageRenderSize_.Height()));
716     for (int32_t i = minY; i <= maxY; ++i) {
717         for (int32_t j = minX; j <= maxX; ++j) {
718             rectList_.emplace_back(imageCell + Offset(j * imageRenderSize_.Width(), i * imageRenderSize_.Height()));
719         }
720     }
721 
722     if (imageLoadingStatus_ == ImageLoadingStatus::LOAD_SUCCESS) {
723         currentDstRectList_ = rectList_;
724     }
725 }
726 
CalculateImageRenderSize(const Size & srcSize,const BackgroundImageSize & imageSize) const727 Size RenderImage::CalculateImageRenderSize(const Size& srcSize, const BackgroundImageSize& imageSize) const
728 {
729     Size renderSize;
730     if (NearZero(srcSize.Width()) || NearZero(srcSize.Height()) || NearZero(boxPaintSize_.Width()) ||
731         NearZero(boxPaintSize_.Height())) {
732         return renderSize;
733     }
734 
735     if (!imageSize.IsValid()) {
736         return renderSize;
737     }
738 
739     if (imageSize.GetSizeTypeX() == BackgroundImageSizeType::CONTAIN ||
740         imageSize.GetSizeTypeX() == BackgroundImageSizeType::COVER) {
741         renderSize = CalculateImageRenderSizeWithSingleParam(srcSize, imageSize);
742     } else {
743         renderSize = CalculateImageRenderSizeWithDoubleParam(srcSize, imageSize);
744     }
745 
746     return renderSize;
747 }
748 
CalculateImageRenderSizeWithSingleParam(const Size & srcSize,const BackgroundImageSize & imageSize) const749 Size RenderImage::CalculateImageRenderSizeWithSingleParam(
750     const Size& srcSize, const BackgroundImageSize& imageSize) const
751 {
752     Size sizeRet;
753     if (NearZero(srcSize.Width()) || NearZero(srcSize.Height()) || NearZero(boxPaintSize_.Width()) ||
754         NearZero(boxPaintSize_.Height())) {
755         return sizeRet;
756     }
757     double renderSizeX = 0.0;
758     double renderSizeY = 0.0;
759     if (imageSize.GetSizeTypeX() == BackgroundImageSizeType::CONTAIN) {
760         double srcAspectRatio = srcSize.Width() / srcSize.Height();
761         double paintAspectRatio = boxPaintSize_.Width() / boxPaintSize_.Height();
762         renderSizeX = paintAspectRatio >= srcAspectRatio ? srcSize.Width() * (boxPaintSize_.Height() / srcSize.Height())
763                                                          : boxPaintSize_.Width();
764         renderSizeY = paintAspectRatio >= srcAspectRatio ? boxPaintSize_.Height()
765                                                          : srcSize.Height() * (boxPaintSize_.Width() / srcSize.Width());
766     } else if (imageSize.GetSizeTypeX() == BackgroundImageSizeType::COVER) {
767         double srcAspectRatio = srcSize.Width() / srcSize.Height();
768         double paintAspectRatio = boxPaintSize_.Width() / boxPaintSize_.Height();
769         renderSizeX = paintAspectRatio >= srcAspectRatio
770                           ? boxPaintSize_.Width()
771                           : srcSize.Width() * (boxPaintSize_.Height() / srcSize.Height());
772         renderSizeY = paintAspectRatio >= srcAspectRatio ? srcSize.Height() * (boxPaintSize_.Width() / srcSize.Width())
773                                                          : boxPaintSize_.Height();
774     }
775 
776     sizeRet.SetWidth(renderSizeX);
777     sizeRet.SetHeight(renderSizeY);
778     return sizeRet;
779 }
780 
CalculateImageRenderSizeWithDoubleParam(const Size & srcSize,const BackgroundImageSize & imageSize) const781 Size RenderImage::CalculateImageRenderSizeWithDoubleParam(
782     const Size& srcSize, const BackgroundImageSize& imageSize) const
783 {
784     Size sizeRet;
785     if (NearZero(srcSize.Width()) || NearZero(srcSize.Height()) || NearZero(boxPaintSize_.Width()) ||
786         NearZero(boxPaintSize_.Height())) {
787         return sizeRet;
788     }
789 
790     double renderSizeX = 0.0;
791     double renderSizeY = 0.0;
792     if (imageSize.GetSizeTypeX() == BackgroundImageSizeType::LENGTH) {
793         renderSizeX = imageSize.GetSizeValueX();
794     } else if (imageSize.GetSizeTypeX() == BackgroundImageSizeType::PERCENT) {
795         renderSizeX = boxPaintSize_.Width() * imageSize.GetSizeValueX() / PERCENT_TRANSLATE;
796     }
797 
798     if (imageSize.GetSizeTypeY() == BackgroundImageSizeType::LENGTH) {
799         renderSizeY = imageSize.GetSizeValueY();
800     } else if (imageSize.GetSizeTypeY() == BackgroundImageSizeType::PERCENT) {
801         renderSizeY = boxPaintSize_.Height() * imageSize.GetSizeValueY() / PERCENT_TRANSLATE;
802     }
803 
804     if (imageSize.GetSizeTypeX() == BackgroundImageSizeType::AUTO &&
805         imageSize.GetSizeTypeY() == BackgroundImageSizeType::AUTO) {
806         renderSizeX = srcSize.Width();
807         renderSizeY = srcSize.Height();
808     } else if (imageSize.GetSizeTypeX() == BackgroundImageSizeType::AUTO) {
809         renderSizeX = srcSize.Width() * (renderSizeY / srcSize.Height());
810     } else if (imageSize.GetSizeTypeY() == BackgroundImageSizeType::AUTO) {
811         renderSizeY = srcSize.Height() * (renderSizeX / srcSize.Width());
812     }
813 
814     sizeRet.SetWidth(renderSizeX);
815     sizeRet.SetHeight(renderSizeY);
816     if (!sizeRet.IsValid()) {
817         sizeRet = Size();
818     }
819     return sizeRet;
820 }
821 
CalculateImageRenderPosition(const BackgroundImagePosition & imagePosition)822 void RenderImage::CalculateImageRenderPosition(const BackgroundImagePosition& imagePosition)
823 {
824     Offset offset;
825 
826     if (imagePosition.GetSizeTypeX() == BackgroundImagePositionType::PX) {
827         offset.SetX(imagePosition.GetSizeValueX());
828     } else {
829         offset.SetX(
830             imagePosition.GetSizeValueX() * (boxPaintSize_.Width() - imageRenderSize_.Width()) / PERCENT_TRANSLATE);
831     }
832 
833     if (imagePosition.GetSizeTypeY() == BackgroundImagePositionType::PX) {
834         offset.SetY(imagePosition.GetSizeValueY());
835     } else {
836         offset.SetY(
837             imagePosition.GetSizeValueY() * (boxPaintSize_.Height() - imageRenderSize_.Height()) / PERCENT_TRANSLATE);
838     }
839 
840     imageRenderPosition_ = offset;
841 }
842 
ClearRenderObject()843 void RenderImage::ClearRenderObject()
844 {
845     RenderNode::ClearRenderObject();
846 
847     isImageSizeSet_ = false;
848     rawImageSizeUpdated_ = false;
849     matchTextDirection_ = false;
850     imageComponentSize_ = Size();
851     formerMaxSize_ = Size();
852     alignment_ = Alignment::CENTER;
853     imageLoadingStatus_ = ImageLoadingStatus::UNLOADED;
854 
855     imageFit_ = ImageFit::COVER;
856     imageRepeat_ = ImageRepeat::NO_REPEAT;
857     rectList_.clear();
858     color_.reset();
859     sourceInfo_.Reset();
860     singleWidth_ = 0.0;
861     displaySrcWidth_ = 0.0;
862     scale_ = 1.0;
863     horizontalRepeatNum_ = 1.0;
864     rotate_ = 0.0;
865     keepOffsetZero_ = false;
866     resizeCallLoadImage_ = false;
867     frameCount_ = 0;
868     topLeftRadius_ = Radius(0.0);
869     topRightRadius_ = Radius(0.0);
870     bottomLeftRadius_ = Radius(0.0);
871     bottomRightRadius_ = Radius(0.0);
872     resizeScale_ = Size();
873     resizeTarget_ = Size();
874     previousResizeTarget_ = Size();
875     currentResizeScale_ = Size();
876     width_ = Dimension();
877     height_ = Dimension();
878     rawImageSize_ = Size();
879     renderAltImage_ = nullptr;
880     proceedPreviousLoading_ = false;
881     imageUpdateFunc_ = nullptr;
882     imageRenderFunc_ = nullptr;
883     background_ = false;
884     boxPaintSize_ = Size();
885     boxMarginOffset_ = Offset();
886     imageSize_ = BackgroundImageSize();
887     imagePosition_ = BackgroundImagePosition();
888     imageObjectPosition_ = ImageObjectPosition();
889     imageRenderSize_ = Size();
890     imageRenderPosition_ = Offset();
891     forceResize_ = false;
892     forceReload_ = false;
893     imageSizeForEvent_ = { 0.0, 0.0 };
894     retryCnt_ = 0;
895 }
896 
PrintImageLog(const Size & srcSize,const BackgroundImageSize & imageSize,ImageRepeat imageRepeat,const BackgroundImagePosition & imagePosition) const897 void RenderImage::PrintImageLog(const Size& srcSize, const BackgroundImageSize& imageSize, ImageRepeat imageRepeat,
898     const BackgroundImagePosition& imagePosition) const
899 {}
900 
Dump()901 void RenderImage::Dump()
902 {
903     DumpLog::GetInstance().AddDesc(std::string("UsingWideGamut: ").append(IsSourceWideGamut() ? "true" : "false"));
904 }
905 
GenerateDragItemInfo(const RefPtr<PipelineContext> & context,const GestureEvent & info)906 DragItemInfo RenderImage::GenerateDragItemInfo(const RefPtr<PipelineContext>& context, const GestureEvent& info)
907 {
908     RefPtr<DragEvent> event = AceType::MakeRefPtr<DragEvent>();
909     event->SetX(context->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
910     event->SetY(context->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
911     selectedItemSize_ = GetLayoutSize();
912     auto extraParams = JsonUtil::Create(true);
913 
914     return onDragStart_(event, extraParams->ToString());
915 }
916 
PanOnActionStart(const GestureEvent & info)917 void RenderImage::PanOnActionStart(const GestureEvent& info)
918 {
919     if (!onDragStart_) {
920         return;
921     }
922 
923     auto pipelineContext = context_.Upgrade();
924     if (!pipelineContext) {
925         LOGE("Context is null.");
926         return;
927     }
928 
929     GestureEvent newInfo = info;
930     Point newPoint = UpdatePoint(pipelineContext, startPoint_);
931     newInfo.SetGlobalPoint(newPoint);
932     auto dragItemInfo = GenerateDragItemInfo(pipelineContext, newInfo);
933 #if !defined(PREVIEW)
934     if (!dragItemInfo.pixelMap && !dragItemInfo.customComponent) {
935         auto initRenderNode = AceType::Claim(this);
936         isDragDropNode_ = true;
937         pipelineContext->SetInitRenderNode(initRenderNode);
938 
939         AddDataToClipboard(pipelineContext, dragItemInfo.extraInfo, "", GetImageSrc());
940         if (!dragWindow_) {
941             auto rect = pipelineContext->GetCurrentWindowRect();
942             dragWindow_ = DragWindow::CreateDragWindow("APP_DRAG_WINDOW",
943                 static_cast<int32_t>(info.GetGlobalPoint().GetX() + rect.Left()),
944                 static_cast<int32_t>(info.GetGlobalPoint().GetY() + rect.Top()),
945                 static_cast<uint32_t>(initRenderNode->GetPaintRect().Width()),
946                 static_cast<uint32_t>(initRenderNode->GetPaintRect().Height()));
947             dragWindow_->SetOffset(static_cast<int32_t>(rect.Left()), static_cast<int32_t>(rect.Top()));
948 #ifndef USE_ROSEN_DRAWING
949             auto image = initRenderNode->GetSkImage();
950 #else
951             auto image = initRenderNode->GetDrawingImage();
952 #endif
953             dragWindow_->DrawImage(image);
954         }
955         if (dragWindow_) {
956             AceEngineExt::GetInstance().DragStartExt();
957         }
958         return;
959     }
960 
961     if (dragItemInfo.pixelMap) {
962         auto initRenderNode = AceType::Claim(this);
963         isDragDropNode_ = true;
964         pipelineContext->SetInitRenderNode(initRenderNode);
965 
966         AddDataToClipboard(pipelineContext, dragItemInfo.extraInfo, "", GetImageSrc());
967         if (!dragWindow_) {
968             auto rect = pipelineContext->GetCurrentWindowRect();
969             dragWindow_ = DragWindow::CreateDragWindow("APP_DRAG_WINDOW",
970                 static_cast<int32_t>(info.GetGlobalPoint().GetX()) + rect.Left(),
971                 static_cast<int32_t>(info.GetGlobalPoint().GetY()) + rect.Top(), dragItemInfo.pixelMap->GetWidth(),
972                 dragItemInfo.pixelMap->GetHeight());
973             dragWindow_->SetOffset(rect.Left(), rect.Top());
974             dragWindow_->DrawPixelMap(dragItemInfo.pixelMap);
975         }
976         if (dragWindow_) {
977             AceEngineExt::GetInstance().DragStartExt();
978         }
979         return;
980     }
981 #endif
982     if (!dragItemInfo.customComponent) {
983         LOGW("the drag custom component is null");
984         return;
985     }
986 
987     hasDragItem_ = true;
988     auto positionedComponent = AceType::MakeRefPtr<PositionedComponent>(dragItemInfo.customComponent);
989     positionedComponent->SetTop(Dimension(GetGlobalOffset().GetY()));
990     positionedComponent->SetLeft(Dimension(GetGlobalOffset().GetX()));
991     SetLocalPoint(startPoint_ - GetGlobalOffset());
992     auto updatePosition = [renderBox = AceType::Claim(this)](
993                               const std::function<void(const Dimension&, const Dimension&)>& func) {
994         if (!renderBox) {
995             return;
996         }
997         renderBox->SetUpdateBuilderFuncId(func);
998     };
999     positionedComponent->SetUpdatePositionFuncId(updatePosition);
1000     auto stackElement = pipelineContext->GetLastStack();
1001     stackElement->PushComponent(positionedComponent);
1002 }
1003 
PanOnActionUpdate(const GestureEvent & info)1004 void RenderImage::PanOnActionUpdate(const GestureEvent& info)
1005 {
1006 #if !defined(PREVIEW)
1007     if (isDragDropNode_ && dragWindow_) {
1008         int32_t x = static_cast<int32_t>(info.GetGlobalPoint().GetX());
1009         int32_t y = static_cast<int32_t>(info.GetGlobalPoint().GetY());
1010         if (lastDragMoveOffset_ == Offset(x, y)) {
1011             return;
1012         }
1013         lastDragMoveOffset_ = Offset(x, y);
1014         if (dragWindow_) {
1015             dragWindow_->MoveTo(x, y);
1016         }
1017         return;
1018     }
1019 #endif
1020     auto pipelineContext = context_.Upgrade();
1021     if (!pipelineContext) {
1022         LOGE("Context is null.");
1023         return;
1024     }
1025 
1026     RefPtr<DragEvent> event = AceType::MakeRefPtr<DragEvent>();
1027     event->SetX(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
1028     event->SetY(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
1029 
1030     Offset offset = info.GetGlobalPoint() - GetLocalPoint();
1031     if (GetUpdateBuilderFuncId()) {
1032         GetUpdateBuilderFuncId()(Dimension(offset.GetX()), Dimension(offset.GetY()));
1033     }
1034 
1035     auto extraParams = JsonUtil::Create(true);
1036     auto targetDragDropNode = FindDragDropNode(pipelineContext, info);
1037     auto preDragDropNode = GetPreDragDropNode();
1038     if (preDragDropNode == targetDragDropNode) {
1039         if (targetDragDropNode && targetDragDropNode->GetOnDragMove()) {
1040             (targetDragDropNode->GetOnDragMove())(event, extraParams->ToString());
1041         }
1042         return;
1043     }
1044     if (preDragDropNode && preDragDropNode->GetOnDragLeave()) {
1045         (preDragDropNode->GetOnDragLeave())(event, extraParams->ToString());
1046     }
1047     if (targetDragDropNode && targetDragDropNode->GetOnDragEnter()) {
1048         (targetDragDropNode->GetOnDragEnter())(event, extraParams->ToString());
1049     }
1050     SetPreDragDropNode(targetDragDropNode);
1051 }
1052 
PanOnActionEnd(const GestureEvent & info)1053 void RenderImage::PanOnActionEnd(const GestureEvent& info)
1054 {
1055     auto pipelineContext = context_.Upgrade();
1056     if (!pipelineContext) {
1057         LOGE("Context is null.");
1058         return;
1059     }
1060 #if !defined(PREVIEW)
1061     if (isDragDropNode_) {
1062         isDragDropNode_ = false;
1063         RestoreCilpboardData(pipelineContext);
1064 
1065         if (GetOnDrop()) {
1066             RefPtr<DragEvent> event = AceType::MakeRefPtr<DragEvent>();
1067             RefPtr<PasteData> pasteData = AceType::MakeRefPtr<PasteData>();
1068             event->SetPasteData(pasteData);
1069             event->SetX(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
1070             event->SetY(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
1071 
1072             auto extraParams = JsonUtil::Create(true);
1073             (GetOnDrop())(event, extraParams->ToString());
1074             pipelineContext->SetInitRenderNode(nullptr);
1075         }
1076     }
1077 
1078     if (dragWindow_) {
1079         dragWindow_->Destroy();
1080         dragWindow_ = nullptr;
1081         return;
1082     }
1083 #endif
1084     RefPtr<DragEvent> event = AceType::MakeRefPtr<DragEvent>();
1085     RefPtr<PasteData> pasteData = AceType::MakeRefPtr<PasteData>();
1086     event->SetPasteData(pasteData);
1087     event->SetX(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
1088     event->SetY(pipelineContext->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
1089 
1090     Offset offset = info.GetGlobalPoint() - GetLocalPoint();
1091     if (GetUpdateBuilderFuncId()) {
1092         GetUpdateBuilderFuncId()(Dimension(offset.GetX()), Dimension(offset.GetY()));
1093     }
1094     if (hasDragItem_) {
1095         auto stackElement = pipelineContext->GetLastStack();
1096         stackElement->PopComponent();
1097     }
1098     hasDragItem_ = false;
1099 
1100     ACE_DCHECK(GetPreDragDropNode() == FindTargetRenderNode<DragDropEvent>(pipelineContext, info));
1101     auto targetDragDropNode = GetPreDragDropNode();
1102     if (!targetDragDropNode) {
1103         return;
1104     }
1105     if (targetDragDropNode->GetOnDrop()) {
1106         auto extraParams = JsonUtil::Create(true);
1107         (targetDragDropNode->GetOnDrop())(event, extraParams->ToString());
1108     }
1109     SetPreDragDropNode(nullptr);
1110 }
1111 
PanOnActionCancel(const GestureEvent & info)1112 void RenderImage::PanOnActionCancel(const GestureEvent& info)
1113 {
1114     auto pipelineContext = context_.Upgrade();
1115     if (!pipelineContext) {
1116         LOGE("Context is null.");
1117         return;
1118     }
1119 
1120 #if !defined(PREVIEW)
1121     if (isDragDropNode_) {
1122         isDragDropNode_ = false;
1123         RestoreCilpboardData(pipelineContext);
1124     }
1125 
1126     if (dragWindow_) {
1127         dragWindow_->Destroy();
1128         dragWindow_ = nullptr;
1129     }
1130 #endif
1131     if (hasDragItem_) {
1132         auto stackElement = pipelineContext->GetLastStack();
1133         stackElement->PopComponent();
1134         hasDragItem_ = false;
1135     }
1136     SetPreDragDropNode(nullptr);
1137 }
1138 
1139 } // namespace OHOS::Ace
1140