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