• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/render/adapter/rosen_render_context.h"
17 
18 #include <algorithm>
19 #include <cstddef>
20 #include <cstdint>
21 #include <memory>
22 
23 #include "common/rs_vector2.h"
24 #include "include/utils/SkParsePath.h"
25 #include "modifier/rs_property.h"
26 #include "render_service_base/include/property/rs_properties_def.h"
27 #include "render_service_client/core/modifier/rs_property_modifier.h"
28 #include "render_service_client/core/pipeline/rs_node_map.h"
29 #include "render_service_client/core/transaction/rs_interfaces.h"
30 #include "render_service_client/core/ui/rs_canvas_drawing_node.h"
31 #include "render_service_client/core/ui/rs_canvas_node.h"
32 #include "render_service_client/core/ui/rs_effect_node.h"
33 #include "render_service_client/core/ui/rs_root_node.h"
34 #include "render_service_client/core/ui/rs_surface_node.h"
35 #include "rosen_render_context.h"
36 
37 #include "base/geometry/dimension.h"
38 #include "base/geometry/matrix4.h"
39 #include "base/geometry/ng/offset_t.h"
40 #include "base/geometry/ng/rect_t.h"
41 #include "base/log/dump_log.h"
42 #include "base/memory/ace_type.h"
43 #include "base/memory/referenced.h"
44 #include "base/utils/utils.h"
45 #include "core/animation/native_curve_helper.h"
46 #include "core/animation/page_transition_common.h"
47 #include "core/animation/spring_curve.h"
48 #include "core/common/container.h"
49 #include "core/common/rosen/rosen_convert_helper.h"
50 #include "core/components/common/properties/decoration.h"
51 #include "core/components/theme/app_theme.h"
52 #include "core/components_ng/base/frame_node.h"
53 #include "core/components_ng/base/geometry_node.h"
54 #include "core/components_ng/base/view_stack_processor.h"
55 #include "core/components_ng/event/event_hub.h"
56 #include "core/components_ng/pattern/stage/page_pattern.h"
57 #include "core/components_ng/pattern/stage/stage_pattern.h"
58 #include "core/components_ng/property/calc_length.h"
59 #include "core/components_ng/property/measure_utils.h"
60 #include "core/components_ng/render/adapter/background_modifier.h"
61 #include "core/components_ng/render/adapter/border_image_modifier.h"
62 #include "core/components_ng/render/adapter/component_snapshot.h"
63 #include "core/components_ng/render/adapter/debug_boundary_modifier.h"
64 #include "core/components_ng/render/adapter/focus_state_modifier.h"
65 #include "core/components_ng/render/adapter/gradient_style_modifier.h"
66 #include "core/components_ng/render/adapter/graphic_modifier.h"
67 #include "core/components_ng/render/adapter/moon_progress_modifier.h"
68 #include "core/components_ng/render/adapter/mouse_select_modifier.h"
69 #include "core/components_ng/render/adapter/overlay_modifier.h"
70 #include "core/components_ng/render/adapter/pixelmap_image.h"
71 #include "core/components_ng/render/adapter/rosen_modifier_adapter.h"
72 #include "core/components_ng/render/adapter/rosen_transition_effect.h"
73 #if defined(ANDROID_PLATFORM)  || defined(IOS_PLATFORM)
74 #include "render_service_client/core/pipeline/rs_render_thread.h"
75 #endif
76 #ifndef USE_ROSEN_DRAWING
77 #include "core/components_ng/render/adapter/skia_decoration_painter.h"
78 #include "core/components_ng/render/adapter/skia_image.h"
79 #else
80 #include "core/components_ng/render/adapter/rosen/drawing_decoration_painter.h"
81 #include "core/components_ng/render/adapter/rosen/drawing_image.h"
82 #endif
83 #include "core/components_ng/render/animation_utils.h"
84 #include "core/components_ng/render/border_image_painter.h"
85 #include "core/components_ng/render/debug_boundary_painter.h"
86 #include "core/components_ng/render/drawing.h"
87 #include "core/components_ng/render/drawing_prop_convertor.h"
88 #include "core/components_ng/render/image_painter.h"
89 #include "core/pipeline_ng/pipeline_context.h"
90 
91 namespace OHOS::Ace::NG {
92 
93 using namespace OHOS::Rosen;
94 namespace {
95 RefPtr<PixelMap> g_pixelMap {};
96 std::mutex g_mutex;
97 std::condition_variable thumbnailGet;
98 constexpr std::chrono::duration<int, std::milli> PIXELMAP_TIMEOUT_DURATION(1000);
99 constexpr float ANIMATION_CURVE_VELOCITY_LIGHT_OR_MIDDLE = 10.0f;
100 constexpr float ANIMATION_CURVE_VELOCITY_HEAVY = 0.0f;
101 constexpr float ANIMATION_CURVE_MASS = 1.0f;
102 constexpr float ANIMATION_CURVE_STIFFNESS_LIGHT = 410.0f;
103 constexpr float ANIMATION_CURVE_STIFFNESS_MIDDLE = 350.0f;
104 constexpr float ANIMATION_CURVE_STIFFNESS_HEAVY = 240.0f;
105 constexpr float ANIMATION_CURVE_DAMPING_LIGHT = 38.0f;
106 constexpr float ANIMATION_CURVE_DAMPING_MIDDLE = 35.0f;
107 constexpr float ANIMATION_CURVE_DAMPING_HEAVY = 28.0f;
108 constexpr float DEFAULT_SCALE_LIGHT = 0.9f;
109 constexpr float DEFAULT_SCALE_MIDDLE_OR_HEAVY = 0.95f;
110 constexpr int32_t DEFAULT_OPTION_DURATION = 100;
111 constexpr int32_t PLATFORM_VERSION_TEN = 10;
112 constexpr int32_t PARTICLE_DEFAULT_COLOR = 0xFFFFFFFF;
113 constexpr float PARTICLE_DEFAULT_OPACITY = 1.0f;
114 constexpr float PARTICLE_DEFAULT_SCALE = 1.0f;
115 constexpr float PARTICLE_DEFAULT_SPEED = 0.0f;
116 constexpr float PARTICLE_DEFAULT_ANGLE = 0.0f;
117 constexpr float PARTICLE_DEFAULT_SPIN = 0.0f;
118 constexpr int64_t PARTICLE_DEFAULT_LIFETIME = 1000;
119 constexpr int32_t PARTICLE_DEFAULT_EMITTER_RATE = 5;
120 
GetRosenGravity(RenderFit renderFit)121 Rosen::Gravity GetRosenGravity(RenderFit renderFit)
122 {
123     static const LinearEnumMapNode<RenderFit, Rosen::Gravity> gravityMap[] = {
124         { RenderFit::CENTER, Rosen::Gravity::CENTER },
125         { RenderFit::TOP, Rosen::Gravity::TOP },
126         { RenderFit::BOTTOM, Rosen::Gravity::BOTTOM },
127         { RenderFit::LEFT, Rosen::Gravity::LEFT },
128         { RenderFit::RIGHT, Rosen::Gravity::RIGHT },
129         { RenderFit::TOP_LEFT, Rosen::Gravity::TOP_LEFT },
130         { RenderFit::TOP_RIGHT, Rosen::Gravity::TOP_RIGHT },
131         { RenderFit::BOTTOM_LEFT, Rosen::Gravity::BOTTOM_LEFT },
132         { RenderFit::BOTTOM_RIGHT, Rosen::Gravity::BOTTOM_RIGHT },
133         { RenderFit::RESIZE_FILL, Rosen::Gravity::RESIZE },
134         { RenderFit::RESIZE_CONTAIN, Rosen::Gravity::RESIZE_ASPECT },
135         { RenderFit::RESIZE_CONTAIN_TOP_LEFT, Rosen::Gravity::RESIZE_ASPECT_TOP_LEFT },
136         { RenderFit::RESIZE_CONTAIN_BOTTOM_RIGHT, Rosen::Gravity::RESIZE_ASPECT_BOTTOM_RIGHT },
137         { RenderFit::RESIZE_COVER, Rosen::Gravity::RESIZE_ASPECT_FILL },
138         { RenderFit::RESIZE_COVER_TOP_LEFT, Rosen::Gravity::RESIZE_ASPECT_FILL_TOP_LEFT },
139         { RenderFit::RESIZE_COVER_BOTTOM_RIGHT, Rosen::Gravity::RESIZE_ASPECT_FILL_BOTTOM_RIGHT },
140     };
141     int64_t idx = BinarySearchFindIndex(gravityMap, ArraySize(gravityMap), renderFit);
142     return idx != -1 ? gravityMap[idx].value : Rosen::Gravity::DEFAULT;
143 }
144 } // namespace
145 
ConvertDimensionToScaleBySize(const Dimension & dimension,float size)146 float RosenRenderContext::ConvertDimensionToScaleBySize(const Dimension& dimension, float size)
147 {
148     if (dimension.Unit() == DimensionUnit::PERCENT) {
149         return static_cast<float>(dimension.Value());
150     }
151     return size > 0.0f ? static_cast<float>(dimension.ConvertToPx() / size) : 0.5f;
152 }
153 
~RosenRenderContext()154 RosenRenderContext::~RosenRenderContext()
155 {
156     StopRecordingIfNeeded();
157     if (transitionEffect_) {
158         transitionEffect_->Detach(this);
159     }
160 }
161 
StartRecording()162 void RosenRenderContext::StartRecording()
163 {
164     CHECK_NULL_VOID(rsNode_);
165     auto rsCanvasNode = rsNode_->ReinterpretCastTo<Rosen::RSCanvasNode>();
166     CHECK_NULL_VOID_NOLOG(rsCanvasNode);
167     rsCanvasNode->BeginRecording(ceil(rsCanvasNode->GetPaintWidth()), ceil(rsCanvasNode->GetPaintHeight()));
168 }
169 
StopRecordingIfNeeded()170 void RosenRenderContext::StopRecordingIfNeeded()
171 {
172     auto rsCanvasNode = Rosen::RSNode::ReinterpretCast<Rosen::RSCanvasNode>(rsNode_);
173     if (rsCanvasNode) {
174         rsCanvasNode->FinishRecording();
175     }
176 }
177 
OnNodeAppear(bool recursive)178 void RosenRenderContext::OnNodeAppear(bool recursive)
179 {
180     isDisappearing_ = false;
181     auto host = GetHost();
182     CHECK_NULL_VOID(host);
183     // restore eventHub state when node appears.
184     host->GetEventHub<EventHub>()->RestoreEnabled();
185     if (recursive && !propTransitionAppearing_ && !transitionEffect_) {
186         // recursive and has no transition, no need to handle transition.
187         return;
188     }
189 
190     isBreakingPoint_ = !recursive;
191     if (isSynced_) {
192         // has set size before, trigger transition directly.
193         auto rect = GetPaintRectWithoutTransform();
194         NotifyTransitionInner(rect.GetSize(), true);
195         return;
196     }
197     // pending transition in animation, will start on first layout
198     firstTransitionIn_ = true;
199 }
200 
OnNodeDisappear(bool recursive)201 void RosenRenderContext::OnNodeDisappear(bool recursive)
202 {
203     isDisappearing_ = true;
204     bool noneOrDefaultTransition = !propTransitionDisappearing_ && (!transitionEffect_ || hasDefaultTransition_);
205     if (recursive && noneOrDefaultTransition) {
206         // recursive, and has no transition or has default transition, no need to trigger transition.
207         return;
208     }
209     CHECK_NULL_VOID(rsNode_);
210     auto host = GetHost();
211     if (!recursive && host && host->GetEventHub<EventHub>()) {
212         host->GetEventHub<EventHub>()->SetEnabledInternal(false);
213     }
214     auto rect = GetPaintRectWithoutTransform();
215     // only start default transition on the break point of render node tree.
216     isBreakingPoint_ = !recursive;
217     NotifyTransitionInner(rect.GetSize(), false);
218 }
219 
SetPivot(float xPivot,float yPivot,float zPivot)220 void RosenRenderContext::SetPivot(float xPivot, float yPivot, float zPivot)
221 {
222     // change pivot without animation
223     CHECK_NULL_VOID(rsNode_);
224     if (pivotProperty_) {
225         pivotProperty_->Set({ xPivot, yPivot });
226     } else {
227         pivotProperty_ = std::make_shared<Rosen::RSProperty<Rosen::Vector2f>>(Rosen::Vector2f(xPivot, yPivot));
228         auto modifier = std::make_shared<Rosen::RSPivotModifier>(pivotProperty_);
229         rsNode_->AddModifier(modifier);
230     }
231     rsNode_->SetPivotZ(zPivot);
232 }
233 
SetTransitionPivot(const SizeF & frameSize,bool transitionIn)234 void RosenRenderContext::SetTransitionPivot(const SizeF& frameSize, bool transitionIn)
235 {
236     auto& transitionEffect = transitionIn ? propTransitionAppearing_ : propTransitionDisappearing_;
237     CHECK_NULL_VOID_NOLOG(transitionEffect);
238     float xPivot = 0.0f;
239     float yPivot = 0.0f;
240     float zPivot = 0.0f;
241     if (transitionEffect->HasRotate()) {
242         xPivot = ConvertDimensionToScaleBySize(transitionEffect->GetRotateValue().centerX, frameSize.Width());
243         yPivot = ConvertDimensionToScaleBySize(transitionEffect->GetRotateValue().centerY, frameSize.Height());
244         zPivot = static_cast<float>(transitionEffect->GetRotateValue().centerZ.ConvertToVp());
245     } else if (transitionEffect->HasScale()) {
246         xPivot = ConvertDimensionToScaleBySize(transitionEffect->GetScaleValue().centerX, frameSize.Width());
247         yPivot = ConvertDimensionToScaleBySize(transitionEffect->GetScaleValue().centerY, frameSize.Height());
248     } else {
249         return;
250     }
251     SetPivot(xPivot, yPivot, zPivot);
252 }
253 
SetSurfaceChangedCallBack(const std::function<void (float,float,float,float)> & callback)254 void RosenRenderContext::SetSurfaceChangedCallBack(
255     const std::function<void(float, float, float, float)>& callback)
256 {
257 #if defined(ANDROID_PLATFORM)  || defined(IOS_PLATFORM)
258     if (rsNode_) {
259         RSRenderThread::Instance().AddSurfaceChangedCallBack(rsNode_->GetId(), callback);
260     }
261 #endif
262 }
263 
RemoveSurfaceChangedCallBack()264 void RosenRenderContext::RemoveSurfaceChangedCallBack()
265 {
266 #if defined(ANDROID_PLATFORM)  || defined(IOS_PLATFORM)
267     if (rsNode_) {
268         RSRenderThread::Instance().RemoveSurfaceChangedCallBack(rsNode_->GetId());
269     }
270 #endif
271 }
272 
InitContext(bool isRoot,const std::optional<ContextParam> & param)273 void RosenRenderContext::InitContext(bool isRoot, const std::optional<ContextParam>& param)
274 {
275     // skip if node already created
276     CHECK_NULL_VOID_NOLOG(!rsNode_);
277     if (isRoot) {
278         rsNode_ = Rosen::RSRootNode::Create();
279         return;
280     } else if (!param.has_value()) {
281         rsNode_ = Rosen::RSCanvasNode::Create();
282         return;
283     }
284 
285     // create proper RSNode base on input
286     switch (param->type) {
287         case ContextType::CANVAS:
288             rsNode_ = Rosen::RSCanvasNode::Create();
289             break;
290         case ContextType::ROOT:
291             rsNode_ = Rosen::RSRootNode::Create();
292             break;
293         case ContextType::SURFACE: {
294             Rosen::RSSurfaceNodeConfig surfaceNodeConfig = { .SurfaceNodeName = param->surfaceName.value_or("") };
295             rsNode_ = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, false);
296             break;
297         }
298         case ContextType::HARDWARE_SURFACE: {
299             Rosen::RSSurfaceNodeConfig surfaceNodeConfig = { .SurfaceNodeName = param->surfaceName.value_or("") };
300             auto surfaceNode = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, false);
301             if (surfaceNode) {
302                 surfaceNode->SetHardwareEnabled(true);
303             }
304             rsNode_ = surfaceNode;
305             break;
306         }
307         case ContextType::EFFECT:
308             rsNode_ = Rosen::RSEffectNode::Create();
309             break;
310         case ContextType::INCREMENTAL_CANVAS:
311             rsNode_ = Rosen::RSCanvasDrawingNode::Create();
312             break;
313         case ContextType::EXTERNAL:
314             break;
315         default:
316             LOGE("invalid context type");
317             break;
318     }
319 }
320 
SetSandBox(const std::optional<OffsetF> & parentPosition)321 void RosenRenderContext::SetSandBox(const std::optional<OffsetF>& parentPosition)
322 {
323     CHECK_NULL_VOID(rsNode_);
324     if (parentPosition.has_value()) {
325         sandBoxCount_++;
326         Rosen::Vector2f value = { parentPosition.value().GetX(), parentPosition.value().GetY() };
327         rsNode_->SetSandBox(value);
328     } else {
329         sandBoxCount_--;
330         if (sandBoxCount_ > 0) {
331             return;
332         }
333         sandBoxCount_ = 0;
334         rsNode_->SetSandBox(std::nullopt);
335     }
336 }
337 
SyncGeometryProperties(GeometryNode *)338 void RosenRenderContext::SyncGeometryProperties(GeometryNode* /*geometryNode*/)
339 {
340     CHECK_NULL_VOID(rsNode_);
341     auto paintRect = AdjustPaintRect();
342     SyncGeometryProperties(paintRect);
343 }
344 
SyncGeometryProperties(const RectF & paintRect)345 void RosenRenderContext::SyncGeometryProperties(const RectF& paintRect)
346 {
347     CHECK_NULL_VOID(rsNode_);
348     if (isDisappearing_ && !paintRect.IsValid()) {
349         return;
350     }
351     rsNode_->SetBounds(paintRect.GetX(), paintRect.GetY(), paintRect.Width(), paintRect.Height());
352     if (useContentRectForRSFrame_) {
353         SetContentRectToFrame(paintRect);
354     } else {
355         rsNode_->SetFrame(paintRect.GetX(), paintRect.GetY(), paintRect.Width(), paintRect.Height());
356     }
357     if (!isSynced_) {
358         isSynced_ = true;
359         auto borderRadius = GetBorderRadius();
360         if (borderRadius.has_value()) {
361             OnBorderRadiusUpdate(borderRadius.value());
362         }
363     }
364 
365     if (firstTransitionIn_) {
366         // need to perform transitionIn early so not influence the following SetPivot
367         NotifyTransitionInner(paintRect.GetSize(), true);
368         firstTransitionIn_ = false;
369     }
370 
371     if (propTransform_ && propTransform_->HasTransformCenter()) {
372         auto vec = propTransform_->GetTransformCenterValue();
373         float xPivot = ConvertDimensionToScaleBySize(vec.GetX(), paintRect.Width());
374         float yPivot = ConvertDimensionToScaleBySize(vec.GetY(), paintRect.Height());
375         if (vec.GetZ().has_value()) {
376             float zPivot = static_cast<float>(vec.GetZ().value().ConvertToVp());
377             SetPivot(xPivot, yPivot, zPivot);
378         } else {
379             SetPivot(xPivot, yPivot);
380         }
381     }
382 
383     if (propTransform_ && propTransform_->HasTransformTranslate()) {
384         // if translate unit is percent, it is related with frameSize
385         OnTransformTranslateUpdate(propTransform_->GetTransformTranslateValue());
386     }
387 
388     if (bgLoadingCtx_ && bgImage_) {
389         PaintBackground();
390     }
391 
392     if (bdImageLoadingCtx_ && bdImage_) {
393         PaintBorderImage();
394     }
395 
396     if (GetBorderImageGradient()) {
397         PaintBorderImageGradient();
398     }
399 
400     if (propGradient_) {
401         PaintGradient(paintRect.GetSize());
402     }
403 
404     if (propClip_) {
405         PaintClip(paintRect.GetSize());
406     }
407 
408     if (propGraphics_) {
409         PaintGraphics();
410     }
411 
412     if (propOverlay_) {
413         PaintOverlayText();
414     }
415 
416     if (NeedDebugBoundary() && SystemProperties::GetDebugBoundaryEnabled()) {
417         PaintDebugBoundary();
418     }
419 
420     if (propParticleOptionArray_.has_value()) {
421         if (!measureTriggered_ || particleAnimationPlaying_) {
422             measureTriggered_ = true;
423             OnParticleOptionArrayUpdate(propParticleOptionArray_.value());
424         }
425     }
426 }
427 
PaintDebugBoundary()428 void RosenRenderContext::PaintDebugBoundary()
429 {
430     CHECK_NULL_VOID(rsNode_);
431     auto host = GetHost();
432     CHECK_NULL_VOID(host);
433     auto geometryNode = host->GetGeometryNode();
434     auto paintTask = [contentSize = geometryNode->GetFrameSize(), frameSize = geometryNode->GetMarginFrameSize(),
435                          offset = geometryNode->GetMarginFrameOffset(),
436                          frameOffset = geometryNode->GetFrameOffset()](RSCanvas& rsCanvas) mutable {
437         DebugBoundaryPainter painter(contentSize, frameSize);
438         painter.SetFrameOffset(frameOffset);
439         painter.DrawDebugBoundaries(rsCanvas, offset);
440     };
441 
442     if (!debugBoundaryModifier_ && rsNode_->IsInstanceOf<Rosen::RSCanvasNode>()) {
443         debugBoundaryModifier_ = std::make_shared<DebugBoundaryModifier>();
444         debugBoundaryModifier_->SetPaintTask(std::move(paintTask));
445         rsNode_->AddModifier(debugBoundaryModifier_);
446     }
447     if (debugBoundaryModifier_) {
448         debugBoundaryModifier_->SetCustomData(true);
449     }
450 }
451 
OnBackgroundColorUpdate(const Color & value)452 void RosenRenderContext::OnBackgroundColorUpdate(const Color& value)
453 {
454     CHECK_NULL_VOID(rsNode_);
455     rsNode_->SetBackgroundColor(value.GetValue());
456     RequestNextFrame();
457 }
458 
OnForegroundColorUpdate(const Color & value)459 void RosenRenderContext::OnForegroundColorUpdate(const Color& value)
460 {
461     CHECK_NULL_VOID(rsNode_);
462     rsNode_->SetEnvForegroundColor(value.GetValue());
463     RequestNextFrame();
464 }
465 
OnForegroundColorStrategyUpdate(const ForegroundColorStrategy & value)466 void RosenRenderContext::OnForegroundColorStrategyUpdate(const ForegroundColorStrategy& value)
467 {
468     CHECK_NULL_VOID(rsNode_);
469     Rosen::ForegroundColorStrategyType rsStrategy = Rosen::ForegroundColorStrategyType::INVALID;
470     switch (value) {
471         case ForegroundColorStrategy::INVERT:
472             rsStrategy = Rosen::ForegroundColorStrategyType::INVERT_BACKGROUNDCOLOR;
473             break;
474         default:
475             break;
476     }
477     rsNode_->SetEnvForegroundColorStrategy(rsStrategy);
478     RequestNextFrame();
479 }
480 
CreateBgImageDataReadyCallback()481 DataReadyNotifyTask RosenRenderContext::CreateBgImageDataReadyCallback()
482 {
483     auto task = [weak = WeakClaim(this)](const ImageSourceInfo& sourceInfo) {
484         auto rosenRenderContext = weak.Upgrade();
485         CHECK_NULL_VOID(rosenRenderContext);
486         auto imageSourceInfo = rosenRenderContext->GetBackgroundImage().value_or(ImageSourceInfo(""));
487         if (imageSourceInfo != sourceInfo) {
488             LOGW("sourceInfo does not match, ignore current callback. current: %{public}s vs callback's: %{public}s",
489                 imageSourceInfo.ToString().c_str(), sourceInfo.ToString().c_str());
490             return;
491         }
492         LOGD("bgImage data ready %{public}s", sourceInfo.ToString().c_str());
493         rosenRenderContext->bgLoadingCtx_->MakeCanvasImage(SizeF(), true, ImageFit::NONE);
494     };
495     return task;
496 }
497 
CreateBgImageLoadSuccessCallback()498 LoadSuccessNotifyTask RosenRenderContext::CreateBgImageLoadSuccessCallback()
499 {
500     auto task = [weak = WeakClaim(this)](const ImageSourceInfo& sourceInfo) {
501         auto ctx = weak.Upgrade();
502         CHECK_NULL_VOID(ctx);
503         auto imageSourceInfo = ctx->GetBackgroundImage().value_or(ImageSourceInfo(""));
504         if (imageSourceInfo != sourceInfo) {
505             LOGW("sourceInfo does not match, ignore current callback. current: %{public}s vs callback's: %{public}s",
506                 imageSourceInfo.ToString().c_str(), sourceInfo.ToString().c_str());
507             return;
508         }
509         ctx->bgImage_ = ctx->bgLoadingCtx_->MoveCanvasImage();
510         CHECK_NULL_VOID(ctx->bgImage_);
511         LOGI("bgImage load success %{public}s", sourceInfo.ToString().c_str());
512         if (ctx->GetHost()->GetGeometryNode()->GetFrameSize().IsPositive()) {
513             ctx->PaintBackground();
514             ctx->RequestNextFrame();
515         }
516     };
517     return task;
518 }
519 
PaintBackground()520 void RosenRenderContext::PaintBackground()
521 {
522     if (InstanceOf<PixelMapImage>(bgImage_)) {
523         PaintPixmapBgImage();
524 #ifndef USE_ROSEN_DRAWING
525     } else if (InstanceOf<SkiaImage>(bgImage_)) {
526         PaintSkBgImage();
527 #else
528     } else if (InstanceOf<DrawingImage>(bgImage_)) {
529         PaintRSBgImage();
530 #endif
531     } else {
532         return;
533     }
534 
535     SizeF renderSize = ImagePainter::CalculateBgImageSize(
536         GetHost()->GetGeometryNode()->GetFrameSize(), bgLoadingCtx_->GetImageSize(), GetBackgroundImageSize());
537     OffsetF positionOffset = ImagePainter::CalculateBgImagePosition(
538         GetHost()->GetGeometryNode()->GetFrameSize(), renderSize, GetBackgroundImagePosition());
539     rsNode_->SetBgImageWidth(renderSize.Width());
540     rsNode_->SetBgImageHeight(renderSize.Height());
541     rsNode_->SetBgImagePositionX(positionOffset.GetX());
542     rsNode_->SetBgImagePositionY(positionOffset.GetY());
543 }
544 
OnBackgroundImageUpdate(const ImageSourceInfo & src)545 void RosenRenderContext::OnBackgroundImageUpdate(const ImageSourceInfo& src)
546 {
547     CHECK_NULL_VOID(rsNode_);
548     if (src.GetSrc().empty()) {
549         return;
550     }
551     if (!bgLoadingCtx_ || src != bgLoadingCtx_->GetSourceInfo()) {
552         LoadNotifier bgLoadNotifier(CreateBgImageDataReadyCallback(), CreateBgImageLoadSuccessCallback(), nullptr);
553         bgLoadingCtx_ = AceType::MakeRefPtr<ImageLoadingContext>(src, std::move(bgLoadNotifier));
554         CHECK_NULL_VOID(bgLoadingCtx_);
555         bgLoadingCtx_->LoadImageData();
556     }
557 }
558 
OnBackgroundImageRepeatUpdate(const ImageRepeat &)559 void RosenRenderContext::OnBackgroundImageRepeatUpdate(const ImageRepeat& /*imageRepeat*/)
560 {
561     CHECK_NULL_VOID(rsNode_);
562     PaintBackground();
563 }
564 
OnBackgroundImageSizeUpdate(const BackgroundImageSize &)565 void RosenRenderContext::OnBackgroundImageSizeUpdate(const BackgroundImageSize& /*bgImgSize*/)
566 {
567     CHECK_NULL_VOID(rsNode_);
568     PaintBackground();
569 }
570 
OnBackgroundImagePositionUpdate(const BackgroundImagePosition &)571 void RosenRenderContext::OnBackgroundImagePositionUpdate(const BackgroundImagePosition& /*bgImgPosition*/)
572 {
573     CHECK_NULL_VOID(rsNode_);
574     PaintBackground();
575 }
576 
SetBackBlurFilter()577 void RosenRenderContext::SetBackBlurFilter()
578 {
579     auto context = PipelineBase::GetCurrentContext();
580     CHECK_NULL_VOID(context);
581     const auto& background = GetBackground();
582     CHECK_NULL_VOID(background);
583     const auto& blurStyle = background->propBlurStyleOption;
584     std::shared_ptr<Rosen::RSFilter> backFilter;
585     auto dipScale_ = context->GetDipScale();
586     if (!blurStyle.has_value()) {
587         const auto& radius = background->propBlurRadius;
588         if (radius.has_value() && radius->IsValid()) {
589             float radiusPx = context->NormalizeToPx(radius.value());
590 #ifndef USE_ROSEN_DRAWING
591             float backblurRadius = SkiaDecorationPainter::ConvertRadiusToSigma(radiusPx);
592 #else
593             float backblurRadius = DrawingDecorationPainter::ConvertRadiusToSigma(radiusPx);
594 #endif
595             backFilter = Rosen::RSFilter::CreateBlurFilter(backblurRadius, backblurRadius);
596         }
597     } else if (GetRosenBlurStyleValue(blurStyle.value()) == MATERIAL_BLUR_STYLE::NO_MATERIAL) {
598         backFilter = nullptr;
599     } else {
600         backFilter = Rosen::RSFilter::CreateMaterialFilter(static_cast<int>(GetRosenBlurStyleValue(blurStyle.value())),
601             static_cast<float>(dipScale_), static_cast<Rosen::BLUR_COLOR_MODE>(blurStyle->adaptiveColor),
602             static_cast<float>(blurStyle->scale));
603     }
604     rsNode_->SetBackgroundFilter(backFilter);
605 }
606 
SetFrontBlurFilter()607 void RosenRenderContext::SetFrontBlurFilter()
608 {
609     auto context = PipelineBase::GetCurrentContext();
610     CHECK_NULL_VOID(context);
611     const auto& foreground = GetForeground();
612     CHECK_NULL_VOID(foreground);
613     const auto& blurStyle = foreground->propBlurStyleOption;
614     std::shared_ptr<Rosen::RSFilter> frontFilter;
615     auto dipScale_ = context->GetDipScale();
616     if (!blurStyle.has_value()) {
617         const auto& radius = foreground->propBlurRadius;
618         if (radius.has_value() && radius->IsValid()) {
619             float radiusPx = context->NormalizeToPx(radius.value());
620 #ifndef USE_ROSEN_DRAWING
621             float backblurRadius = SkiaDecorationPainter::ConvertRadiusToSigma(radiusPx);
622 #else
623             float backblurRadius = DrawingDecorationPainter::ConvertRadiusToSigma(radiusPx);
624 #endif
625             frontFilter = Rosen::RSFilter::CreateBlurFilter(backblurRadius, backblurRadius);
626         }
627     } else if (GetRosenBlurStyleValue(blurStyle.value()) == MATERIAL_BLUR_STYLE::NO_MATERIAL) {
628         frontFilter = nullptr;
629     } else {
630         frontFilter = Rosen::RSFilter::CreateMaterialFilter(static_cast<int>(GetRosenBlurStyleValue(blurStyle.value())),
631             static_cast<float>(dipScale_), static_cast<Rosen::BLUR_COLOR_MODE>(blurStyle->adaptiveColor),
632             static_cast<float>(blurStyle->scale));
633     }
634 
635     rsNode_->SetFilter(frontFilter);
636 }
637 
UpdateBackBlurStyle(const std::optional<BlurStyleOption> & bgBlurStyle)638 void RosenRenderContext::UpdateBackBlurStyle(const std::optional<BlurStyleOption>& bgBlurStyle)
639 {
640     const auto& groupProperty = GetOrCreateBackground();
641     if (groupProperty->CheckBlurStyleOption(bgBlurStyle)) {
642         // Same with previous value.
643         // If colorMode is following system and has valid blurStyle, still needs updating
644         if (bgBlurStyle->colorMode != ThemeColorMode::SYSTEM) {
645             return;
646         }
647     } else {
648         groupProperty->propBlurStyleOption = bgBlurStyle;
649     }
650     SetBackBlurFilter();
651 }
652 
UpdateBackgroundEffect(const std::optional<EffectOption> & effectOption)653 void RosenRenderContext::UpdateBackgroundEffect(const std::optional<EffectOption>& effectOption)
654 {
655     const auto& groupProperty = GetOrCreateBackground();
656     if (groupProperty->CheckEffectOption(effectOption)) {
657         return;
658     }
659     groupProperty->propEffectOption = effectOption;
660     if (!effectOption.has_value()) {
661         return;
662     }
663     auto context = PipelineBase::GetCurrentContext();
664     CHECK_NULL_VOID(context);
665     float radiusPx = context->NormalizeToPx(effectOption->radius);
666 #ifndef USE_ROSEN_DRAWING
667     float backblurRadius = SkiaDecorationPainter::ConvertRadiusToSigma(radiusPx);
668 #else
669     float backblurRadius = DrawingDecorationPainter::ConvertRadiusToSigma(radiusPx);
670 #endif
671     std::shared_ptr<Rosen::RSFilter> backFilter = Rosen::RSFilter::CreateMaterialFilter(
672         backblurRadius, static_cast<float>(effectOption->saturation),
673         static_cast<float>(effectOption->brightness), effectOption->color.GetValue());
674     rsNode_->SetBackgroundFilter(backFilter);
675 }
676 
UpdateFrontBlurStyle(const std::optional<BlurStyleOption> & fgBlurStyle)677 void RosenRenderContext::UpdateFrontBlurStyle(const std::optional<BlurStyleOption>& fgBlurStyle)
678 {
679     const auto& groupProperty = GetOrCreateForeground();
680     if (groupProperty->CheckBlurStyleOption(fgBlurStyle)) {
681         // Same with previous value.
682         // If colorMode is following system and has valid blurStyle, still needs updating
683         if (fgBlurStyle->colorMode != ThemeColorMode::SYSTEM) {
684             return;
685         }
686     } else {
687         groupProperty->propBlurStyleOption = fgBlurStyle;
688     }
689     SetFrontBlurFilter();
690 }
691 
ResetBackBlurStyle()692 void RosenRenderContext::ResetBackBlurStyle()
693 {
694     const auto& groupProperty = GetOrCreateBackground();
695     groupProperty->propBlurStyleOption.reset();
696     SetBackBlurFilter();
697 }
698 
OnSphericalEffectUpdate(double radio)699 void RosenRenderContext::OnSphericalEffectUpdate(double radio)
700 {
701     CHECK_NULL_VOID(rsNode_);
702     rsNode_->SetSpherizeDegree(static_cast<float>(radio));
703     RequestNextFrame();
704 }
705 
OnPixelStretchEffectUpdate(const PixStretchEffectOption & option)706 void RosenRenderContext::OnPixelStretchEffectUpdate(const PixStretchEffectOption& option)
707 {
708     CHECK_NULL_VOID(rsNode_);
709     Rosen::Vector4f pixStretchVector;
710     if (option.IsPercentOption()) {
711         pixStretchVector.SetValues(static_cast<float>(option.left.Value()), static_cast<float>(option.top.Value()),
712             static_cast<float>(option.right.Value()), static_cast<float>(option.bottom.Value()));
713         rsNode_->SetPixelStretchPercent(pixStretchVector);
714     } else {
715         pixStretchVector.SetValues(static_cast<float>(option.left.ConvertToPx()),
716             static_cast<float>(option.top.ConvertToPx()), static_cast<float>(option.right.ConvertToPx()),
717             static_cast<float>(option.bottom.ConvertToPx()));
718         rsNode_->SetPixelStretch(pixStretchVector);
719     }
720     RequestNextFrame();
721 }
722 
OnLightUpEffectUpdate(double radio)723 void RosenRenderContext::OnLightUpEffectUpdate(double radio)
724 {
725     CHECK_NULL_VOID(rsNode_);
726     rsNode_->SetLightUpEffectDegree(static_cast<float>(radio));
727     RequestNextFrame();
728 }
729 
OnParticleOptionArrayUpdate(const std::list<ParticleOption> & optionList)730 void RosenRenderContext::OnParticleOptionArrayUpdate(const std::list<ParticleOption>& optionList)
731 {
732     CHECK_NULL_VOID(rsNode_);
733     RectF rect = GetPaintRectWithoutTransform();
734     if (rect.IsEmpty()) {
735         return;
736     }
737     if (NeedPreloadImage(optionList, rect)) {
738         return;
739     }
740     particleAnimationPlaying_ = true;
741     std::vector<OHOS::Rosen::ParticleParams> particleParams;
742     for (auto& item : optionList) {
743         particleParams.emplace_back(ConvertParticleOptionToParams(item, rect));
744     }
745     auto finishCallback = [weak = WeakClaim(this)]() {
746         auto renderContext = weak.Upgrade();
747         CHECK_NULL_VOID(renderContext);
748         renderContext->particleAnimationPlaying_ = false;
749     };
750     rsNode_->SetParticleParams(particleParams, finishCallback);
751     RequestNextFrame();
752 }
753 
NeedPreloadImage(const std::list<ParticleOption> & optionList,RectF & rect)754 bool RosenRenderContext::NeedPreloadImage(const std::list<ParticleOption>& optionList, RectF& rect)
755 {
756     bool flag = false;
757     std::vector<OHOS::Rosen::ParticleParams> particleParams;
758     for (auto& item : optionList) {
759         auto emitterOption = item.GetEmitterOption();
760         auto particle = emitterOption.GetParticle();
761         auto particleType = particle.GetParticleType();
762         auto particleConfig = particle.GetConfig();
763         if (particleType == ParticleType::IMAGE) {
764             auto imageParameter = particleConfig.GetImageParticleParameter();
765             auto imageSize = imageParameter.GetSize();
766             auto imageWidth = Dimension(ConvertDimensionToPx(imageSize.first, rect.Width()), DimensionUnit::PX);
767             auto imageHeight = Dimension(ConvertDimensionToPx(imageSize.second, rect.Height()), DimensionUnit::PX);
768             if (particleImageMap_.find(imageParameter.GetImageSource()) == particleImageMap_.end()) {
769                 LoadParticleImage(imageParameter.GetImageSource(), imageWidth, imageHeight);
770                 flag = true;
771             }
772         }
773     }
774     return flag;
775 }
776 
ConvertParticleOptionToParams(const ParticleOption & particleOption,const RectF & rect)777 Rosen::ParticleParams RosenRenderContext::ConvertParticleOptionToParams(
778     const ParticleOption& particleOption, const RectF& rect)
779 {
780     auto emitterOption = particleOption.GetEmitterOption();
781     auto colorOptionOpt = particleOption.GetParticleColorOption();
782     auto opacityOptionOpt = particleOption.GetParticleOpacityOption();
783     auto scaleOptionOpt = particleOption.GetParticleScaleOption();
784     auto velocityOptionOpt = particleOption.GetParticleVelocityOption();
785     auto accelerationOpt = particleOption.GetParticleAccelerationOption();
786     auto spinOptionOpt = particleOption.GetParticleSpinOption();
787     auto rsEmitterConfig = ConvertParticleEmitterOption(emitterOption, rect);
788     std::optional<OHOS::Rosen::ParticleColorParaType> rsColorOpt;
789     std::optional<OHOS::Rosen::ParticleParaType<float>> rsSpinOpt;
790     std::optional<OHOS::Rosen::ParticleVelocity> rsVelocityOpt;
791     std::optional<OHOS::Rosen::ParticleParaType<float>> rsOpacityOpt;
792     std::optional<OHOS::Rosen::ParticleParaType<float>> rsScaleOpt;
793     std::optional<OHOS::Rosen::ParticleAcceleration> rsAccelerationOpt;
794     if (colorOptionOpt.has_value()) {
795         rsColorOpt = ConvertParticleColorOption(colorOptionOpt.value());
796     } else {
797         rsColorOpt = ConvertParticleDefaultColorOption(std::nullopt);
798     }
799     if (opacityOptionOpt.has_value()) {
800         rsOpacityOpt = ConvertParticleFloatOption(opacityOptionOpt.value());
801     } else {
802         OHOS::Rosen::Range<float> rsInitRange(PARTICLE_DEFAULT_OPACITY, PARTICLE_DEFAULT_OPACITY);
803         rsOpacityOpt = ConvertParticleDefaultFloatOption(rsInitRange);
804     }
805     if (scaleOptionOpt.has_value()) {
806         rsScaleOpt = ConvertParticleFloatOption(scaleOptionOpt.value());
807     } else {
808         OHOS::Rosen::Range<float> rsInitRange(PARTICLE_DEFAULT_SCALE, PARTICLE_DEFAULT_SCALE);
809         rsScaleOpt = ConvertParticleDefaultFloatOption(rsInitRange);
810     }
811     if (velocityOptionOpt.has_value()) {
812         rsVelocityOpt = ConvertParticleVelocityOption(velocityOptionOpt.value());
813     } else {
814         rsVelocityOpt = ConvertParticleDefaultVelocityOption();
815     }
816     if (accelerationOpt.has_value()) {
817         rsAccelerationOpt = ConvertParticleAccelerationOption(accelerationOpt.value());
818     } else {
819         rsAccelerationOpt = ConvertParticleDefaultAccelerationOption();
820     }
821     if (spinOptionOpt.has_value()) {
822         rsSpinOpt = ConvertParticleFloatOption(spinOptionOpt.value());
823     } else {
824         OHOS::Rosen::Range<float> rsInitRange(PARTICLE_DEFAULT_SPIN, PARTICLE_DEFAULT_SPIN);
825         rsSpinOpt = ConvertParticleDefaultFloatOption(rsInitRange);
826     }
827     return OHOS::Rosen::ParticleParams(rsEmitterConfig, rsVelocityOpt.value(), rsAccelerationOpt.value(),
828         rsColorOpt.value(), rsOpacityOpt.value(), rsScaleOpt.value(), rsSpinOpt.value());
829 }
830 
ConvertParticleEmitterOption(const EmitterOption & emitterOption,const RectF & rect)831 Rosen::EmitterConfig RosenRenderContext::ConvertParticleEmitterOption(
832     const EmitterOption& emitterOption, const RectF& rect)
833 {
834     auto emitterRateOpt = emitterOption.GetEmitterRate();
835     auto pointOpt = emitterOption.GetPosition();
836     auto sizeOpt = emitterOption.GetSize();
837     auto shapeOpt = emitterOption.GetShape();
838     auto particle = emitterOption.GetParticle();
839     auto particleType = particle.GetParticleType();
840     auto particleConfig = particle.GetConfig();
841     auto particleCount = particle.GetCount();
842     auto lifeTimeOpt = particle.GetLifeTime();
843     auto rsPoint = pointOpt.has_value()
844                        ? OHOS::Rosen::Vector2f(ConvertDimensionToPx(pointOpt.value().first, rect.Width()),
845                              ConvertDimensionToPx(pointOpt.value().second, rect.Height()))
846                        : OHOS::Rosen::Vector2f(0.0f, 0.0f);
847     auto rsSize = sizeOpt.has_value() ? OHOS::Rosen::Vector2f(ConvertDimensionToPx(sizeOpt.value().first, rect.Width()),
848                                             ConvertDimensionToPx(sizeOpt.value().second, rect.Height()))
849                                       : OHOS::Rosen::Vector2f(rect.Width(), rect.Height());
850     auto shapeInt = static_cast<int32_t>(shapeOpt.value_or(ParticleEmitterShape::RECTANGLE));
851     if (particleType == ParticleType::IMAGE) {
852         auto imageParameter = particleConfig.GetImageParticleParameter();
853         auto imageSource = imageParameter.GetImageSource();
854         auto imageSize = imageParameter.GetSize();
855         auto imageWidth = Dimension(ConvertDimensionToPx(imageSize.first, rect.Width()), DimensionUnit::PX);
856         auto imageHeight = Dimension(ConvertDimensionToPx(imageSize.second, rect.Height()), DimensionUnit::PX);
857         auto rsImagePtr = std::make_shared<Rosen::RSImage>();
858         if (particleImageMap_.find(imageSource) != particleImageMap_.end()) {
859             SetRsParticleImage(rsImagePtr, imageSource);
860         }
861         rsImagePtr->SetImageFit(static_cast<int32_t>(imageParameter.GetImageFit().value_or(ImageFit::COVER)));
862         OHOS::Rosen::Vector2f rsImageSize(imageWidth.ConvertToPx(), imageHeight.ConvertToPx());
863         return OHOS::Rosen::EmitterConfig(emitterRateOpt.value_or(PARTICLE_DEFAULT_EMITTER_RATE),
864             static_cast<OHOS::Rosen::ShapeType>(shapeInt), rsPoint, rsSize, particleCount,
865             lifeTimeOpt.value_or(PARTICLE_DEFAULT_LIFETIME), OHOS::Rosen::ParticleType::IMAGES, 0.0f, rsImagePtr,
866             rsImageSize);
867     } else {
868         auto pointParameter = particleConfig.GetPointParticleParameter();
869         auto radius = pointParameter.GetRadius();
870         return OHOS::Rosen::EmitterConfig(emitterRateOpt.value_or(PARTICLE_DEFAULT_EMITTER_RATE),
871             static_cast<OHOS::Rosen::ShapeType>(shapeInt), rsPoint, rsSize, particleCount,
872             lifeTimeOpt.value_or(PARTICLE_DEFAULT_LIFETIME), OHOS::Rosen::ParticleType::POINTS, radius,
873             std::make_shared<OHOS::Rosen::RSImage>(), OHOS::Rosen::Vector2f());
874     }
875 }
876 
SetRsParticleImage(std::shared_ptr<Rosen::RSImage> & rsImagePtr,std::string & imageSource)877 void RosenRenderContext::SetRsParticleImage(std::shared_ptr<Rosen::RSImage>& rsImagePtr, std::string& imageSource)
878 {
879     if (particleImageMap_.find(imageSource) == particleImageMap_.end()) {
880         return;
881     }
882     auto image = particleImageMap_[imageSource];
883     CHECK_NULL_VOID_NOLOG(image);
884 
885     if (InstanceOf<PixelMapImage>(image)) {
886         auto pixmap = image->GetPixelMap();
887         CHECK_NULL_VOID_NOLOG(pixmap);
888         auto pixMapPtr = pixmap->GetPixelMapSharedPtr();
889         rsImagePtr->SetPixelMap(pixMapPtr);
890         if (pixMapPtr) {
891             rsImagePtr->SetSrcRect(Rosen::RectF(0, 0, pixMapPtr->GetWidth(), pixMapPtr->GetHeight()));
892         }
893 #ifndef USE_ROSEN_DRAWING
894     } else if (InstanceOf<SkiaImage>(image)) {
895         auto skiaImage = DynamicCast<SkiaImage>(image);
896         CHECK_NULL_VOID_NOLOG(skiaImage);
897         auto compressData = skiaImage->GetCompressData();
898         if (compressData) {
899             rsImagePtr->SetCompressData(
900                 compressData, skiaImage->GetUniqueID(), skiaImage->GetCompressWidth(), skiaImage->GetCompressHeight());
901             rsImagePtr->SetSrcRect(Rosen::RectF(0, 0, skiaImage->GetCompressWidth(), skiaImage->GetCompressHeight()));
902         } else {
903             rsImagePtr->SetImage(skiaImage->GetImage());
904             if (skiaImage->GetImage()) {
905                 rsImagePtr->SetSrcRect(
906                     Rosen::RectF(0, 0, skiaImage->GetImage()->width(), skiaImage->GetImage()->height()));
907             }
908         }
909         rsImagePtr->SetImageRepeat(static_cast<int>(GetBackgroundImageRepeat().value_or(ImageRepeat::NO_REPEAT)));
910 #else
911     } else if (InstanceOf<DrawingImage>(image)) {
912         auto drawingImage = DynamicCast<DrawingImage>(image);
913         CHECK_NULL_VOID_NOLOG(drawingImage);
914         auto compressData = drawingImage->GetCompressData();
915         if (compressData) {
916             rsImagePtr->SetCompressData(compressData, drawingImage->GetUniqueID(), drawingImage->GetCompressWidth(),
917                 drawingImage->GetCompressHeight());
918             rsImagePtr->SetSrcRect(
919                 Rosen::RectF(0, 0, drawingImage->GetCompressWidth(), drawingImage->GetCompressHeight()));
920         } else {
921             rsImagePtr->SetImage(drawingImage->GetImage());
922             if (drawingImage->GetImage()) {
923                 rsImagePtr->SetSrcRect(
924                     Rosen::RectF(0, 0, drawingImage->GetImage()->width(), drawingImage->GetImage()->height()));
925             }
926         }
927         rsImagePtr->SetImageRepeat(static_cast<int>(GetBackgroundImageRepeat().value_or(ImageRepeat::NO_REPEAT)));
928 #endif
929     }
930 }
931 
LoadParticleImage(const std::string & src,Dimension & width,Dimension & height)932 void RosenRenderContext::LoadParticleImage(const std::string& src, Dimension& width, Dimension& height)
933 {
934     if (particleImageContextMap_.find(src) != particleImageContextMap_.end()) {
935         return;
936     }
937     ImageSourceInfo imageSourceInfo(src, width, height);
938     imageSourceInfo.SetNeedCache(false);
939     auto preLoadCallback = [weak = WeakClaim(this), imageSrc = src](const ImageSourceInfo& sourceInfo) {
940         auto renderContent = weak.Upgrade();
941         CHECK_NULL_VOID(renderContent);
942         auto& imageContext = renderContent->particleImageContextMap_[imageSrc];
943         CHECK_NULL_VOID(imageContext);
944         imageContext->MakeCanvasImage(SizeF(), true, ImageFit::NONE);
945     };
946     auto loadingSuccessCallback = [weak = WeakClaim(this), imageSrc = src](const ImageSourceInfo& sourceInfo) {
947         auto renderContent = weak.Upgrade();
948         CHECK_NULL_VOID(renderContent);
949         auto& imageContext = renderContent->particleImageContextMap_[imageSrc];
950         CHECK_NULL_VOID(imageContext);
951         auto imagePtr = imageContext->MoveCanvasImage();
952         renderContent->OnParticleImageLoaded(imageSrc, imagePtr);
953     };
954     auto loadingErrorCallback = [weak = WeakClaim(this), imageSrc = src](const ImageSourceInfo& sourceInfo) {
955         auto renderContent = weak.Upgrade();
956         CHECK_NULL_VOID(renderContent);
957         renderContent->OnParticleImageLoaded(imageSrc, nullptr);
958     };
959     LoadNotifier loadNotifier(preLoadCallback, loadingSuccessCallback, loadingErrorCallback);
960     auto particleImageLoadingCtx = AceType::MakeRefPtr<ImageLoadingContext>(imageSourceInfo, std::move(loadNotifier));
961     imageSourceInfo.SetSrc(src, Color(0x00000000));
962     particleImageLoadingCtx->LoadImageData();
963     particleImageContextMap_.try_emplace(src, particleImageLoadingCtx);
964 }
965 
OnParticleImageLoaded(const std::string & src,RefPtr<CanvasImage> canvasImage)966 void RosenRenderContext::OnParticleImageLoaded(const std::string& src, RefPtr<CanvasImage> canvasImage)
967 {
968     particleImageMap_.try_emplace(src, canvasImage);
969     if (particleImageContextMap_.find(src) != particleImageContextMap_.end()) {
970         particleImageContextMap_.erase(src);
971     }
972     if (particleImageContextMap_.empty() && propParticleOptionArray_.has_value()) {
973         OnParticleOptionArrayUpdate(propParticleOptionArray_.value());
974     }
975 }
976 
ConvertDimensionToPx(Dimension & src,float size)977 float RosenRenderContext::ConvertDimensionToPx(Dimension& src, float size)
978 {
979     if (src.Unit() == DimensionUnit::PERCENT) {
980         return src.ConvertToPxWithSize(size);
981     }
982     return src.ConvertToPx();
983 }
984 
ConvertParticleVelocityOption(const VelocityProperty & velocity)985 Rosen::ParticleVelocity RosenRenderContext::ConvertParticleVelocityOption(const VelocityProperty& velocity)
986 {
987     auto rsSpeedRange = OHOS::Rosen::Range<float>(velocity.GetSpeedRange().first, velocity.GetSpeedRange().second);
988     auto rsAngleRange = OHOS::Rosen::Range<float>(velocity.GetAngleRange().first, velocity.GetAngleRange().second);
989     return OHOS::Rosen::ParticleVelocity(rsSpeedRange, rsAngleRange);
990 }
991 
ConvertParticleDefaultVelocityOption()992 Rosen::ParticleVelocity RosenRenderContext::ConvertParticleDefaultVelocityOption()
993 {
994     auto rsSpeedRange = OHOS::Rosen::Range<float>(PARTICLE_DEFAULT_SPEED, PARTICLE_DEFAULT_SPEED);
995     auto rsAngleRange = OHOS::Rosen::Range<float>(PARTICLE_DEFAULT_ANGLE, PARTICLE_DEFAULT_ANGLE);
996     return OHOS::Rosen::ParticleVelocity(rsSpeedRange, rsAngleRange);
997 }
998 
ConvertParticleAccelerationOption(const AccelerationProperty & acceleration)999 Rosen::ParticleAcceleration RosenRenderContext::ConvertParticleAccelerationOption(
1000     const AccelerationProperty& acceleration)
1001 {
1002     auto speedOpt = acceleration.GetSpeed();
1003     auto angleOpt = acceleration.GetAngle();
1004     std::optional<OHOS::Rosen::ParticleParaType<float>> rsSpeedOpt;
1005     std::optional<OHOS::Rosen::ParticleParaType<float>> rsAngleOpt;
1006     OHOS::Rosen::Range<float> rsInitSpeedRange(PARTICLE_DEFAULT_SPEED, PARTICLE_DEFAULT_SPEED);
1007     if (speedOpt.has_value()) {
1008         rsSpeedOpt = ConvertParticleFloatOption(speedOpt.value());
1009     } else {
1010         rsSpeedOpt = ConvertParticleDefaultFloatOption(rsInitSpeedRange);
1011     }
1012     OHOS::Rosen::Range<float> rsInitAngleRange(PARTICLE_DEFAULT_ANGLE, PARTICLE_DEFAULT_ANGLE);
1013     if (angleOpt.has_value()) {
1014         rsAngleOpt = ConvertParticleFloatOption(angleOpt.value());
1015     } else {
1016         rsAngleOpt = ConvertParticleDefaultFloatOption(rsInitAngleRange);
1017     }
1018     return OHOS::Rosen::ParticleAcceleration(rsSpeedOpt.value(), rsAngleOpt.value());
1019 }
1020 
ConvertParticleDefaultAccelerationOption()1021 Rosen::ParticleAcceleration RosenRenderContext::ConvertParticleDefaultAccelerationOption()
1022 {
1023     OHOS::Rosen::Range<float> rsInitRange(PARTICLE_DEFAULT_SPEED, PARTICLE_DEFAULT_SPEED);
1024     return OHOS::Rosen::ParticleAcceleration(
1025         ConvertParticleDefaultFloatOption(rsInitRange), ConvertParticleDefaultFloatOption(rsInitRange));
1026 }
1027 
ConvertParticleColorOption(const ParticleColorPropertyOption & colorOption)1028 Rosen::ParticleColorParaType RosenRenderContext::ConvertParticleColorOption(
1029     const ParticleColorPropertyOption& colorOption)
1030 {
1031     auto initRange = colorOption.GetRange();
1032     auto updaterOpt = colorOption.GetUpdater();
1033     OHOS::Rosen::Range<OHOS::Rosen::RSColor> rsInitRange(
1034         OHOS::Rosen::RSColor(initRange.first.GetRed(), initRange.first.GetGreen(), initRange.first.GetBlue(),
1035             initRange.first.GetAlpha()),
1036         OHOS::Rosen::RSColor(initRange.second.GetRed(), initRange.second.GetGreen(), initRange.second.GetBlue(),
1037             initRange.second.GetAlpha()));
1038     if (updaterOpt.has_value()) {
1039         auto updater = updaterOpt.value();
1040         auto updateType = updater.GetUpdateType();
1041         auto config = updater.GetConfig();
1042         if (updateType == UpdaterType::RANDOM) {
1043             auto randomConfig = config.GetRandomConfig();
1044             auto redRandom = randomConfig.GetRedRandom();
1045             auto greenRandom = randomConfig.GetGreenRandom();
1046             auto blueRandom = randomConfig.GetBlueRandom();
1047             auto alphaRandom = randomConfig.GetAlphaRandom();
1048             OHOS::Rosen::Range<float> rsRedRandom(redRandom.first, redRandom.second);
1049             OHOS::Rosen::Range<float> rsGreenRandom(greenRandom.first, greenRandom.second);
1050             OHOS::Rosen::Range<float> rsBlueRandom(blueRandom.first, blueRandom.second);
1051             OHOS::Rosen::Range<float> rsAlphaRandom(alphaRandom.first, alphaRandom.second);
1052             std::vector<OHOS::Rosen::Change<OHOS::Rosen::RSColor>> invalidCurve;
1053             return OHOS::Rosen::ParticleColorParaType(rsInitRange, OHOS::Rosen::ParticleUpdator::RANDOM, rsRedRandom,
1054                 rsGreenRandom, rsBlueRandom, rsAlphaRandom, invalidCurve);
1055         } else if (updateType == UpdaterType::CURVE) {
1056             auto& curveConfig = config.GetAnimationArray();
1057             std::vector<OHOS::Rosen::Change<OHOS::Rosen::RSColor>> valChangeOverLife;
1058             for (const auto& colorAnimationConfig : curveConfig) {
1059                 auto fromColor = colorAnimationConfig.GetFrom();
1060                 auto toColor = colorAnimationConfig.GetTo();
1061                 auto startMills = colorAnimationConfig.GetStartMills();
1062                 auto endMills = colorAnimationConfig.GetEndMills();
1063                 auto curve = colorAnimationConfig.GetCurve();
1064                 auto rsCurve = NativeCurveHelper::ToNativeCurve(curve);
1065                 valChangeOverLife.emplace_back(OHOS::Rosen::Change<OHOS::Rosen::RSColor>(
1066                     OHOS::Rosen::RSColor(
1067                         fromColor.GetRed(), fromColor.GetGreen(), fromColor.GetBlue(), fromColor.GetAlpha()),
1068                     OHOS::Rosen::RSColor(toColor.GetRed(), toColor.GetGreen(), toColor.GetBlue(), toColor.GetAlpha()),
1069                     startMills, endMills, rsCurve));
1070             }
1071             return OHOS::Rosen::ParticleColorParaType(rsInitRange, ParticleUpdator::CURVE, OHOS::Rosen::Range<float>(),
1072                 OHOS::Rosen::Range<float>(), OHOS::Rosen::Range<float>(), OHOS::Rosen::Range<float>(),
1073                 valChangeOverLife);
1074         }
1075     }
1076     return ConvertParticleDefaultColorOption(rsInitRange);
1077 }
1078 
ConvertParticleDefaultColorOption(std::optional<OHOS::Rosen::Range<OHOS::Rosen::RSColor>> rsInitRangeOpt)1079 Rosen::ParticleColorParaType RosenRenderContext::ConvertParticleDefaultColorOption(
1080     std::optional<OHOS::Rosen::Range<OHOS::Rosen::RSColor>> rsInitRangeOpt)
1081 {
1082     std::vector<OHOS::Rosen::Change<OHOS::Rosen::RSColor>> invalidCurve;
1083     if (rsInitRangeOpt.has_value()) {
1084         return OHOS::Rosen::ParticleColorParaType(rsInitRangeOpt.value(), OHOS::Rosen::ParticleUpdator::NONE,
1085             OHOS::Rosen::Range<float>(), OHOS::Rosen::Range<float>(), OHOS::Rosen::Range<float>(),
1086             OHOS::Rosen::Range<float>(), invalidCurve);
1087     }
1088     return OHOS::Rosen::ParticleColorParaType(
1089         OHOS::Rosen::Range<OHOS::Rosen::RSColor>(
1090             OHOS::Rosen::RSColor(PARTICLE_DEFAULT_COLOR), OHOS::Rosen::RSColor(PARTICLE_DEFAULT_COLOR)),
1091         OHOS::Rosen::ParticleUpdator::NONE, OHOS::Rosen::Range<float>(), OHOS::Rosen::Range<float>(),
1092         OHOS::Rosen::Range<float>(), OHOS::Rosen::Range<float>(), invalidCurve);
1093 }
1094 
ConvertParticleFloatOption(const ParticleFloatPropertyOption & floatOption)1095 Rosen::ParticleParaType<float> RosenRenderContext::ConvertParticleFloatOption(
1096     const ParticleFloatPropertyOption& floatOption)
1097 {
1098     auto initRange = floatOption.GetRange();
1099     OHOS::Rosen::Range<float> rsInitRange(initRange.first, initRange.second);
1100     auto updaterOpt = floatOption.GetUpdater();
1101     if (updaterOpt.has_value()) {
1102         auto updater = updaterOpt.value();
1103         auto updateType = updater.GetUpdaterType();
1104         auto& config = updater.GetConfig();
1105         if (updateType == UpdaterType::RANDOM) {
1106             auto& randomRangeConfig = config.GetRandomConfig();
1107             std::vector<OHOS::Rosen::Change<float>> invalidChangeInOverLifeArray;
1108             return OHOS::Rosen::ParticleParaType<float>(rsInitRange, OHOS::Rosen::ParticleUpdator::RANDOM,
1109                 OHOS::Rosen::Range<float>(randomRangeConfig.first, randomRangeConfig.second),
1110                 invalidChangeInOverLifeArray);
1111         } else if (updateType == UpdaterType::CURVE) {
1112             auto curveConfig = config.GetAnimations();
1113             std::vector<OHOS::Rosen::Change<float>> valChangeOverLife;
1114             for (auto& animationConfig : curveConfig) {
1115                 auto from = animationConfig.GetFrom();
1116                 auto to = animationConfig.GetTo();
1117                 auto startMills = animationConfig.GetStartMills();
1118                 auto endMills = animationConfig.GetEndMills();
1119                 auto rsCurve = NativeCurveHelper::ToNativeCurve(animationConfig.GetCurve());
1120                 valChangeOverLife.emplace_back(OHOS::Rosen::Change<float>(from, to, startMills, endMills, rsCurve));
1121             }
1122             OHOS::Rosen::Range<float> rsInvalidRange;
1123             return OHOS::Rosen::ParticleParaType<float>(
1124                 rsInitRange, OHOS::Rosen::ParticleUpdator::CURVE, rsInvalidRange, valChangeOverLife);
1125         }
1126     }
1127     return ConvertParticleDefaultFloatOption(rsInitRange);
1128 }
1129 
ConvertParticleDefaultFloatOption(OHOS::Rosen::Range<float> & rsInitRange)1130 Rosen::ParticleParaType<float> RosenRenderContext::ConvertParticleDefaultFloatOption(
1131     OHOS::Rosen::Range<float>& rsInitRange)
1132 {
1133     std::vector<OHOS::Rosen::Change<float>> invalidChangeInOverLifeArray;
1134     return OHOS::Rosen::ParticleParaType<float>(
1135         rsInitRange, OHOS::Rosen::ParticleUpdator::NONE, OHOS::Rosen::Range<float>(), invalidChangeInOverLifeArray);
1136 }
1137 
OnOpacityUpdate(double opacity)1138 void RosenRenderContext::OnOpacityUpdate(double opacity)
1139 {
1140     CHECK_NULL_VOID(rsNode_);
1141     rsNode_->SetAlpha(opacity);
1142     RequestNextFrame();
1143 }
1144 
1145 class DrawDragThumbnailCallback : public SurfaceCaptureCallback {
1146 public:
OnSurfaceCapture(std::shared_ptr<Media::PixelMap> pixelMap)1147     void OnSurfaceCapture(std::shared_ptr<Media::PixelMap> pixelMap) override
1148     {
1149         if (pixelMap == nullptr) {
1150             LOGE("%{public}s: failed to get pixelmap, return nullptr", __func__);
1151             thumbnailGet.notify_all();
1152             return;
1153         }
1154         std::unique_lock<std::mutex> lock(g_mutex);
1155 #ifdef PIXEL_MAP_SUPPORTED
1156         g_pixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
1157 #endif // PIXEL_MAP_SUPPORTED
1158         thumbnailGet.notify_all();
1159         LOGI("Get pixelmap success");
1160     }
1161 };
1162 
GetThumbnailPixelMap()1163 RefPtr<PixelMap> RosenRenderContext::GetThumbnailPixelMap()
1164 {
1165     if (rsNode_ == nullptr) {
1166         LOGE("rsNode is nullptr");
1167         return nullptr;
1168     }
1169     std::shared_ptr<DrawDragThumbnailCallback> drawDragThumbnailCallback =
1170         std::make_shared<DrawDragThumbnailCallback>();
1171     auto ret = RSInterfaces::GetInstance().TakeSurfaceCaptureForUI(rsNode_, drawDragThumbnailCallback, 1, 1);
1172     if (!ret) {
1173         LOGE("GetThumbnailPixelMap false, return nullptr");
1174         return nullptr;
1175     }
1176     std::unique_lock<std::mutex> lock(g_mutex);
1177     if (thumbnailGet.wait_for(lock, PIXELMAP_TIMEOUT_DURATION) == std::cv_status::timeout) {
1178         LOGW("Create GetThumbnailPixelMap false, wait lock timeout");
1179         return nullptr;
1180     }
1181     return g_pixelMap;
1182 }
1183 
1184 #ifndef USE_ROSEN_DRAWING
GetBitmap(SkBitmap & bitmap,std::shared_ptr<OHOS::Rosen::DrawCmdList> drawCmdList)1185 bool RosenRenderContext::GetBitmap(SkBitmap& bitmap, std::shared_ptr<OHOS::Rosen::DrawCmdList> drawCmdList)
1186 #else
1187 bool RosenRenderContext::GetBitmap(RSBitmap& bitmap, std::shared_ptr<RSDrawCmdList> drawCmdList)
1188 #endif
1189 {
1190     auto rsCanvasDrawingNode = Rosen::RSNode::ReinterpretCast<Rosen::RSCanvasDrawingNode>(rsNode_);
1191     if (!rsCanvasDrawingNode) {
1192         return false;
1193     }
1194     return rsCanvasDrawingNode->GetBitmap(bitmap, drawCmdList);
1195 }
1196 
1197 #ifndef USE_ROSEN_DRAWING
GetPixelMap(const std::shared_ptr<Media::PixelMap> & pixelMap,std::shared_ptr<OHOS::Rosen::DrawCmdList> drawCmdList,SkRect * rect)1198 bool RosenRenderContext::GetPixelMap(const std::shared_ptr<Media::PixelMap>& pixelMap,
1199     std::shared_ptr<OHOS::Rosen::DrawCmdList> drawCmdList, SkRect* rect)
1200 {
1201     auto rsCanvasDrawingNode = Rosen::RSNode::ReinterpretCast<Rosen::RSCanvasDrawingNode>(rsNode_);
1202     if (!rsCanvasDrawingNode) {
1203         return false;
1204     }
1205     return rsCanvasDrawingNode->GetPixelmap(pixelMap, drawCmdList, rect);
1206 }
1207 #endif
1208 
OnTransformScaleUpdate(const VectorF & scale)1209 void RosenRenderContext::OnTransformScaleUpdate(const VectorF& scale)
1210 {
1211     CHECK_NULL_VOID(rsNode_);
1212     rsNode_->SetScale(scale.x, scale.y);
1213     RequestNextFrame();
1214 }
1215 
OnTransformTranslateUpdate(const TranslateOptions & translate)1216 void RosenRenderContext::OnTransformTranslateUpdate(const TranslateOptions& translate)
1217 {
1218     CHECK_NULL_VOID(rsNode_);
1219     float xValue = 0.0f;
1220     float yValue = 0.0f;
1221     if (translate.x.Unit() == DimensionUnit::PERCENT || translate.y.Unit() == DimensionUnit::PERCENT) {
1222         auto rect = GetPaintRectWithoutTransform();
1223         if (rect.IsEmpty()) {
1224             // size is not determined yet
1225             return;
1226         }
1227         xValue = translate.x.ConvertToPxWithSize(rect.Width());
1228         yValue = translate.y.ConvertToPxWithSize(rect.Height());
1229     } else {
1230         xValue = translate.x.ConvertToPx();
1231         yValue = translate.y.ConvertToPx();
1232     }
1233     // translateZ doesn't support percentage
1234     float zValue = translate.z.ConvertToPx();
1235     rsNode_->SetTranslate(xValue, yValue, zValue);
1236     RequestNextFrame();
1237 }
1238 
OnTransformRotateUpdate(const Vector5F & rotate)1239 void RosenRenderContext::OnTransformRotateUpdate(const Vector5F& rotate)
1240 {
1241     CHECK_NULL_VOID(rsNode_);
1242     float norm = std::sqrt(std::pow(rotate.x, 2) + std::pow(rotate.y, 2) + std::pow(rotate.z, 2));
1243     if (NearZero(norm)) {
1244         LOGW("rotate vector is near zero, please check");
1245         norm = 1.0f;
1246     }
1247     // for rosen backend, the rotation angles in the x and y directions should be set to opposite angles
1248     rsNode_->SetRotation(-rotate.w * rotate.x / norm, -rotate.w * rotate.y / norm, rotate.w * rotate.z / norm);
1249     // set camera distance
1250     rsNode_->SetCameraDistance(rotate.v);
1251     RequestNextFrame();
1252 }
1253 
OnTransformCenterUpdate(const DimensionOffset & center)1254 void RosenRenderContext::OnTransformCenterUpdate(const DimensionOffset& center)
1255 {
1256     RectF rect = GetPaintRectWithoutTransform();
1257     if (!RectIsNull()) {
1258         float xPivot = ConvertDimensionToScaleBySize(center.GetX(), rect.Width());
1259         float yPivot = ConvertDimensionToScaleBySize(center.GetY(), rect.Height());
1260         float zPivot = 0.0f;
1261         auto& z = center.GetZ();
1262         if (z.has_value()) {
1263             zPivot = static_cast<float>(z.value().ConvertToVp());
1264         }
1265         SetPivot(xPivot, yPivot, zPivot);
1266     }
1267     RequestNextFrame();
1268 }
1269 
OnTransformMatrixUpdate(const Matrix4 & matrix)1270 void RosenRenderContext::OnTransformMatrixUpdate(const Matrix4& matrix)
1271 {
1272     CHECK_NULL_VOID(rsNode_);
1273     if (!transformMatrixModifier_.has_value()) {
1274         transformMatrixModifier_ = TransformMatrixModifier();
1275     }
1276     DecomposedTransform transform;
1277     if (!TransformUtil::DecomposeTransform(transform, matrix)) {
1278         // fallback to basic matrix decompose
1279         Rosen::Vector2f xyTranslateValue { static_cast<float>(matrix.Get(0, 3)), static_cast<float>(matrix.Get(1, 3)) };
1280         Rosen::Vector2f scaleValue { 0.0f, 0.0f };
1281         AddOrChangeTranslateModifier(rsNode_, transformMatrixModifier_->translateXY,
1282             transformMatrixModifier_->translateXYValue, xyTranslateValue);
1283         AddOrChangeScaleModifier(
1284             rsNode_, transformMatrixModifier_->scaleXY, transformMatrixModifier_->scaleXYValue, scaleValue);
1285     } else {
1286         Rosen::Vector2f xyTranslateValue { transform.translate[0], transform.translate[1] };
1287         Rosen::Quaternion quaternion { static_cast<float>(transform.quaternion.GetX()),
1288             static_cast<float>(transform.quaternion.GetY()), static_cast<float>(transform.quaternion.GetZ()),
1289             static_cast<float>(transform.quaternion.GetW()) };
1290         Rosen::Vector2f scaleValue { transform.scale[0], transform.scale[1] };
1291         AddOrChangeTranslateModifier(rsNode_, transformMatrixModifier_->translateXY,
1292             transformMatrixModifier_->translateXYValue, xyTranslateValue);
1293         AddOrChangeScaleModifier(
1294             rsNode_, transformMatrixModifier_->scaleXY, transformMatrixModifier_->scaleXYValue, scaleValue);
1295         AddOrChangeQuaternionModifier(
1296             rsNode_, transformMatrixModifier_->quaternion, transformMatrixModifier_->quaternionValue, quaternion);
1297     }
1298     RequestNextFrame();
1299 }
1300 
1301 RectF gRect;
1302 
Degree2Radian(int32_t degree)1303 double Degree2Radian(int32_t degree)
1304 {
1305     const float pi = 3.14159265;
1306     degree = degree % 360;
1307     if (degree < 0) {
1308         degree += 360;
1309     }
1310     return degree * pi / 180;
1311 }
1312 
SetCorner(double & x,double & y,double width,double height,int32_t degree)1313 void SetCorner(double& x, double& y, double width, double height, int32_t degree)
1314 {
1315     if (degree == 90) {
1316         x = 0;
1317         y = height;
1318     } else if (degree == 180) {
1319         x = width;
1320         y = height;
1321     } else if (degree == 270) {
1322         x = width;
1323         y = 0;
1324     }
1325 }
1326 
GetPaintRectWithTransform()1327 RectF RosenRenderContext::GetPaintRectWithTransform()
1328 {
1329     RectF rect;
1330 
1331     CHECK_NULL_RETURN(rsNode_, rect);
1332     rect = GetPaintRectWithoutTransform();
1333     auto translate = rsNode_->GetStagingProperties().GetTranslate();
1334     auto scale = rsNode_->GetStagingProperties().GetScale();
1335     auto center = rsNode_->GetStagingProperties().GetPivot();
1336     auto degree = rsNode_->GetStagingProperties().GetRotation();
1337     // calculate new pos.
1338     auto centOffset = OffsetF(center[0] * rect.Width(), center[1] * rect.Height());
1339     auto centerPos = rect.GetOffset() + centOffset;
1340     auto newPos = centerPos - OffsetF(centOffset.GetX() * scale[0], centOffset.GetY() * scale[1]);
1341     newPos = newPos + OffsetF(translate[0], translate[1]);
1342     rect.SetOffset(newPos);
1343     // calculate new size.
1344     auto oldSize = rect.GetSize();
1345     auto newSize = SizeF(oldSize.Width() * scale[0], oldSize.Height() * scale[1]);
1346     rect.SetSize(newSize);
1347     transInfo_ = { scale[0], scale[1], centerPos.GetX(), centerPos.GetY(), rect.GetX(), rect.GetY(), translate[0],
1348         translate[1], degree };
1349     // calculate rotate
1350     degree = static_cast<int32_t>(degree) % 360;
1351     auto radian = Degree2Radian(degree);
1352     if (degree != 0) {
1353         auto newRect = GetPaintRectWithoutTransform();
1354         double leftX = 0.0;
1355         double leftY = 0.0;
1356         degree = degree < 0 ? degree + 360 : degree;
1357         SetCorner(leftX, leftY, oldSize.Width(), oldSize.Height(), degree);
1358         double centerX = oldSize.Width() * center[0];
1359         double centerY = oldSize.Height() * center[1];
1360         auto tmp = leftX;
1361         leftX = (leftX - centerX) * cos(-1 * radian) + (leftY - centerY) * sin(-1 * radian);
1362         leftY = -1 * (tmp - centerX) * sin(-1 * radian) + (leftY - centerY) * cos(-1 * radian);
1363         auto leftXCalc = leftX + centerX;
1364         auto leftYCalc = leftY + centerY;
1365         leftX = newRect.GetOffset().GetX() + leftXCalc;
1366         leftY = newRect.GetOffset().GetY() + leftYCalc;
1367         auto offset = OffsetF(leftX + translate[0], leftY + translate[1]);
1368         rect.SetOffset(offset);
1369         if (degree == 180) {
1370             newSize = SizeF(oldSize.Width() * scale[0], oldSize.Height() * scale[1]);
1371         } else {
1372             newSize = SizeF(oldSize.Height() * scale[1], oldSize.Width() * scale[0]);
1373         }
1374         rect.SetSize(newSize);
1375     }
1376     gRect = rect;
1377     return rect;
1378 }
1379 
GetTrans()1380 std::vector<double> RosenRenderContext::GetTrans()
1381 {
1382     return transInfo_;
1383 }
1384 
GetPaintRectWithTranslate()1385 RectF RosenRenderContext::GetPaintRectWithTranslate()
1386 {
1387     RectF rect;
1388     CHECK_NULL_RETURN(rsNode_, rect);
1389     rect = GetPaintRectWithoutTransform();
1390     auto translate = rsNode_->GetStagingProperties().GetTranslate();
1391     rect.SetOffset(rect.GetOffset() + OffsetF(translate[0], translate[1]));
1392     return rect;
1393 }
1394 
GetPointWithRevert(PointF & point)1395 void RosenRenderContext::GetPointWithRevert(PointF& point)
1396 {
1397     auto center = rsNode_->GetStagingProperties().GetPivot();
1398     int32_t degree = rsNode_->GetStagingProperties().GetRotation();
1399     auto translate = rsNode_->GetStagingProperties().GetTranslate();
1400     auto scale = rsNode_->GetStagingProperties().GetScale();
1401 
1402     RectF rect = GetPaintRectWithoutTransform();
1403     auto centOffset = OffsetF(center[0] * rect.Width(), center[1] * rect.Height());
1404     auto centerPos = rect.GetOffset() + centOffset;
1405 
1406     auto translateMat = Matrix4::CreateTranslate(translate[0], translate[1], 0);
1407     auto rotationMat = Matrix4::CreateTranslate(centerPos.GetX(), centerPos.GetY(), 0) *
1408         Matrix4::CreateRotate(degree, 0, 0, 1) *
1409         Matrix4::CreateTranslate(-centerPos.GetX(), -centerPos.GetY(), 0);
1410     auto scaleMat = Matrix4::CreateTranslate(centerPos.GetX(), centerPos.GetY(), 0) *
1411         Matrix4::CreateScale(scale[0], scale[1], 1) *
1412         Matrix4::CreateTranslate(-centerPos.GetX(), -centerPos.GetY(), 0);
1413 
1414     auto invertMat = Matrix4::Invert(translateMat * rotationMat * scaleMat);
1415     Point tmp(point.GetX(), point.GetY());
1416     auto invertPoint = invertMat * tmp;
1417     point.SetX(invertPoint.GetX());
1418     point.SetY(invertPoint.GetY());
1419 }
1420 
GetPointWithTransform(PointF & point)1421 void RosenRenderContext::GetPointWithTransform(PointF& point)
1422 {
1423     // TODO: add rotation and center support
1424     auto translate = rsNode_->GetStagingProperties().GetTranslate();
1425     auto scale = rsNode_->GetStagingProperties().GetScale();
1426     point = PointF(point.GetX() / scale[0], point.GetY() / scale[1]);
1427     RectF rect = GetPaintRectWithoutTransform();
1428     auto center = rsNode_->GetStagingProperties().GetPivot();
1429     int32_t degree = rsNode_->GetStagingProperties().GetRotation();
1430     degree = degree % 360;
1431     auto radian = Degree2Radian(degree);
1432     if (degree != 0) {
1433         point = point + gRect.GetOffset();
1434         point = point - OffsetF(translate[0], translate[1]);
1435         auto centOffset = OffsetF(center[0] * gRect.Width(), center[1] * gRect.Height());
1436         auto centerPos = gRect.GetOffset() + centOffset - OffsetF(translate[0], translate[1]);
1437         auto centerX = centerPos.GetX();
1438         auto centerY = centerPos.GetY();
1439 
1440         double currentPointX = (point.GetX() - centerX) * cos(radian) + (point.GetY() - centerY) * sin(radian);
1441         double currentPointY = -1 * (point.GetX() - centerX) * sin(radian) + (point.GetY() - centerY) * cos(radian);
1442         currentPointX = currentPointX + centerX;
1443         currentPointY = currentPointY + centerY;
1444         point.SetX(currentPointX - rect.Left());
1445         point.SetY(currentPointY - rect.Top());
1446     }
1447 }
1448 
1449 
GetPaintRectWithoutTransform()1450 RectF RosenRenderContext::GetPaintRectWithoutTransform()
1451 {
1452     RectF rect;
1453     CHECK_NULL_RETURN(rsNode_, rect);
1454     auto paintRectVector = rsNode_->GetStagingProperties().GetBounds();
1455     rect.SetRect(paintRectVector[0], paintRectVector[1], paintRectVector[2], paintRectVector[3]);
1456     return rect;
1457 }
1458 
UpdateTranslateInXY(const OffsetF & offset)1459 void RosenRenderContext::UpdateTranslateInXY(const OffsetF& offset)
1460 {
1461     CHECK_NULL_VOID(rsNode_);
1462     auto xValue = offset.GetX();
1463     auto yValue = offset.GetY();
1464     if (translateXY_) {
1465         auto propertyXY = std::static_pointer_cast<RSAnimatableProperty<Vector2f>>(translateXY_->GetProperty());
1466         if (propertyXY) {
1467             propertyXY->Set({ xValue, yValue });
1468         } else {
1469             LOGE("fail to get translateXY property");
1470         }
1471     } else {
1472         auto propertyXY = std::make_shared<RSAnimatableProperty<Vector2f>>(Vector2f(xValue, yValue));
1473         translateXY_ = std::make_shared<Rosen::RSTranslateModifier>(propertyXY);
1474         rsNode_->AddModifier(translateXY_);
1475     }
1476 }
1477 
GetShowingTranslateProperty()1478 OffsetF RosenRenderContext::GetShowingTranslateProperty()
1479 {
1480     OffsetF offset;
1481     CHECK_NULL_RETURN(translateXY_, offset);
1482     auto property = std::static_pointer_cast<RSAnimatableProperty<Vector2f>>(translateXY_->GetProperty());
1483     CHECK_NULL_RETURN(property, offset);
1484     auto result = property->GetShowingValueAndCancelAnimation();
1485     if (!result) {
1486         LOGW("fail to stop current property animation");
1487         return offset;
1488     }
1489     auto translate = property->Get();
1490     offset.SetX(translate[0]);
1491     offset.SetY(translate[1]);
1492     return offset;
1493 }
1494 
NotifyTransitionInner(const SizeF & frameSize,bool isTransitionIn)1495 void RosenRenderContext::NotifyTransitionInner(const SizeF& frameSize, bool isTransitionIn)
1496 {
1497     CHECK_NULL_VOID(rsNode_);
1498     if (propTransitionAppearing_ || propTransitionDisappearing_) {
1499         // old transition
1500         auto& transOptions = isTransitionIn ? propTransitionAppearing_ : propTransitionDisappearing_;
1501         auto effect = GetRSTransitionWithoutType(transOptions, frameSize);
1502         CHECK_NULL_VOID_NOLOG(effect);
1503         SetTransitionPivot(frameSize, isTransitionIn);
1504         // notice that we have been in animateTo, so do not need to use Animation closure to notify transition.
1505         rsNode_->NotifyTransition(effect, isTransitionIn);
1506         return;
1507     }
1508     // add default transition effect on the 'breaking point' of render tree, if no user-defined transition effect
1509     // and triggered in AnimateTo closure.
1510     // Note: this default transition effect will be removed after all transitions finished, implemented in
1511     // OnTransitionInFinish. and OnTransitionOutFinish.
1512     auto pipeline = PipelineBase::GetCurrentContext();
1513     CHECK_NULL_VOID(pipeline);
1514     if (isBreakingPoint_ && !transitionEffect_ &&
1515         (pipeline->GetSyncAnimationOption().IsValid() ||
1516             ViewStackProcessor::GetInstance()->GetImplicitAnimationOption().IsValid())) {
1517         hasDefaultTransition_ = true;
1518         transitionEffect_ = RosenTransitionEffect::CreateDefaultRosenTransitionEffect();
1519         RSNode::ExecuteWithoutAnimation([this, isTransitionIn]() {
1520             // transitionIn effects should be initialized as active if is transitionIn.
1521             transitionEffect_->Attach(Claim(this), isTransitionIn);
1522         });
1523     }
1524     NotifyTransition(isTransitionIn);
1525 }
1526 
OpacityAnimation(const AnimationOption & option,double begin,double end)1527 void RosenRenderContext::OpacityAnimation(const AnimationOption& option, double begin, double end)
1528 {
1529     CHECK_NULL_VOID(rsNode_);
1530     rsNode_->SetAlpha(begin);
1531     AnimationUtils::Animate(
1532         option,
1533         [rsNode = rsNode_, endAlpha = end]() {
1534             CHECK_NULL_VOID_NOLOG(rsNode);
1535             rsNode->SetAlpha(endAlpha);
1536         },
1537         option.GetOnFinishEvent());
1538 }
1539 
ScaleAnimation(const AnimationOption & option,double begin,double end)1540 void RosenRenderContext::ScaleAnimation(const AnimationOption& option, double begin, double end)
1541 {
1542     CHECK_NULL_VOID(rsNode_);
1543     rsNode_->SetScale(begin);
1544     AnimationUtils::Animate(
1545         option,
1546         [rsNode = rsNode_, endScale = end]() {
1547             CHECK_NULL_VOID_NOLOG(rsNode);
1548             rsNode->SetScale(endScale);
1549         },
1550         option.GetOnFinishEvent());
1551 }
1552 
OnBorderRadiusUpdate(const BorderRadiusProperty & value)1553 void RosenRenderContext::OnBorderRadiusUpdate(const BorderRadiusProperty& value)
1554 {
1555     if (!isSynced_) {
1556         return;
1557     }
1558     CHECK_NULL_VOID(rsNode_);
1559     auto paintRect = AdjustPaintRect();
1560     if (isDisappearing_ && !paintRect.IsValid()) {
1561         return;
1562     }
1563     double radiusX = paintRect.Width();
1564     Rosen::Vector4f cornerRadius;
1565     // When the unit of radius is percent, the length and width of rect should be calculated at the same time,
1566     // but currently SetCornerRadius only supports Vector4f parameter passing.
1567     // Graphic should provide support .
1568     cornerRadius.SetValues(static_cast<float>(value.radiusTopLeft.value_or(Dimension()).ConvertToPxWithSize(radiusX)),
1569         static_cast<float>(value.radiusTopRight.value_or(Dimension()).ConvertToPxWithSize(radiusX)),
1570         static_cast<float>(value.radiusBottomRight.value_or(Dimension()).ConvertToPxWithSize(radiusX)),
1571         static_cast<float>(value.radiusBottomLeft.value_or(Dimension()).ConvertToPxWithSize(radiusX)));
1572     rsNode_->SetCornerRadius(cornerRadius);
1573     RequestNextFrame();
1574 }
1575 
OnBorderColorUpdate(const BorderColorProperty & value)1576 void RosenRenderContext::OnBorderColorUpdate(const BorderColorProperty& value)
1577 {
1578     CHECK_NULL_VOID(rsNode_);
1579     rsNode_->SetBorderColor(value.leftColor.value_or(Color::BLACK).GetValue(),
1580         value.topColor.value_or(Color::BLACK).GetValue(), value.rightColor.value_or(Color::BLACK).GetValue(),
1581         value.bottomColor.value_or(Color::BLACK).GetValue());
1582     RequestNextFrame();
1583 }
1584 
UpdateBorderWidthF(const BorderWidthPropertyF & value)1585 void RosenRenderContext::UpdateBorderWidthF(const BorderWidthPropertyF& value)
1586 {
1587     CHECK_NULL_VOID(rsNode_);
1588     Rosen::Vector4f cornerBorderWidth;
1589     cornerBorderWidth.SetValues(value.leftDimen.value_or(0), static_cast<float>(value.topDimen.value_or(0)),
1590         static_cast<float>(value.rightDimen.value_or(0)), static_cast<float>(value.bottomDimen.value_or(0)));
1591     rsNode_->SetBorderWidth(cornerBorderWidth);
1592     RequestNextFrame();
1593 }
1594 
OnBorderStyleUpdate(const BorderStyleProperty & value)1595 void RosenRenderContext::OnBorderStyleUpdate(const BorderStyleProperty& value)
1596 {
1597     CHECK_NULL_VOID(rsNode_);
1598     rsNode_->SetBorderStyle(static_cast<uint32_t>(value.styleLeft.value_or(BorderStyle::SOLID)),
1599         static_cast<uint32_t>(value.styleTop.value_or(BorderStyle::SOLID)),
1600         static_cast<uint32_t>(value.styleRight.value_or(BorderStyle::SOLID)),
1601         static_cast<uint32_t>(value.styleBottom.value_or(BorderStyle::SOLID)));
1602     RequestNextFrame();
1603 }
1604 
OnAccessibilityFocusUpdate(bool isAccessibilityFocus)1605 void RosenRenderContext::OnAccessibilityFocusUpdate(bool isAccessibilityFocus)
1606 {
1607     auto uiNode = GetHost();
1608     CHECK_NULL_VOID(uiNode);
1609     UpdateAccessibilityFocus(isAccessibilityFocus);
1610     if (isAccessibilityFocus) {
1611         PaintAccessibilityFocus();
1612     } else {
1613         ClearAccessibilityFocus();
1614     }
1615     uiNode->OnAccessibilityEvent(isAccessibilityFocus ? AccessibilityEventType::ACCESSIBILITY_FOCUSED
1616                                                       : AccessibilityEventType::ACCESSIBILITY_FOCUS_CLEARED);
1617 }
1618 
OnUseEffectUpdate(bool useEffect)1619 void RosenRenderContext::OnUseEffectUpdate(bool useEffect)
1620 {
1621     CHECK_NULL_VOID(rsNode_);
1622     rsNode_->SetUseEffect(useEffect);
1623 }
1624 
OnFreezeUpdate(bool isFreezed)1625 void RosenRenderContext::OnFreezeUpdate(bool isFreezed)
1626 {
1627     CHECK_NULL_VOID(rsNode_);
1628     rsNode_->SetFreeze(isFreezed);
1629 }
1630 
PaintAccessibilityFocus()1631 void RosenRenderContext::PaintAccessibilityFocus()
1632 {
1633     CHECK_NULL_VOID(rsNode_);
1634     Dimension focusPaddingVp = Dimension(0.0, DimensionUnit::VP);
1635     constexpr uint32_t ACCESSIBILITY_FOCUS_COLOR = 0xbf39b500;
1636     constexpr double ACCESSIBILITY_FOCUS_WIDTH = 4.0;
1637     Color paintColor(ACCESSIBILITY_FOCUS_COLOR);
1638     Dimension paintWidth(ACCESSIBILITY_FOCUS_WIDTH, DimensionUnit::PX);
1639     const auto& bounds = rsNode_->GetStagingProperties().GetBounds();
1640     RoundRect frameRect;
1641     frameRect.SetRect(RectF(0.0, 0.0, bounds.z_, bounds.w_));
1642     PaintFocusState(frameRect, focusPaddingVp, paintColor, paintWidth, true);
1643 }
1644 
ClearAccessibilityFocus()1645 void RosenRenderContext::ClearAccessibilityFocus()
1646 {
1647     CHECK_NULL_VOID(rsNode_);
1648     auto context = PipelineBase::GetCurrentContext();
1649     CHECK_NULL_VOID(context);
1650     CHECK_NULL_VOID(accessibilityFocusStateModifier_);
1651     rsNode_->RemoveModifier(accessibilityFocusStateModifier_);
1652     RequestNextFrame();
1653 }
1654 
BdImagePaintTask(RSCanvas & canvas)1655 void RosenRenderContext::BdImagePaintTask(RSCanvas& canvas)
1656 {
1657     CHECK_NULL_VOID(GetBorderImage());
1658     auto paintRect = GetPaintRectWithoutTransform();
1659     if (NearZero(paintRect.Width()) || NearZero(paintRect.Height())) {
1660         return;
1661     }
1662 
1663     auto host = GetHost();
1664     CHECK_NULL_VOID(host);
1665     auto layoutProps = host->GetLayoutProperty();
1666     CHECK_NULL_VOID(layoutProps);
1667     const auto& widthProp = layoutProps->GetBorderWidthProperty();
1668 
1669     auto pipeline = host->GetContext();
1670     CHECK_NULL_VOID(pipeline);
1671     auto dipScale = pipeline->GetDipScale();
1672 
1673     CHECK_NULL_VOID(bdImage_);
1674 #ifndef USE_ROSEN_DRAWING
1675     sk_sp<SkImage> image;
1676     if (InstanceOf<SkiaImage>(bdImage_)) {
1677         image = DynamicCast<SkiaImage>(bdImage_)->GetImage();
1678     } else if (InstanceOf<PixelMapImage>(bdImage_)) {
1679         auto pixmap = DynamicCast<PixelMapImage>(bdImage_)->GetPixelMap();
1680         CHECK_NULL_VOID(pixmap);
1681         image = SkiaImage::MakeSkImageFromPixmap(pixmap);
1682     } else {
1683         return;
1684     }
1685 #else
1686     std::shared_ptr<RSImage> image;
1687     if (InstanceOf<DrawingImage>(bdImage_)) {
1688         image = DynamicCast<DrawingImage>(bdImage_)->GetImage();
1689     } else if (InstanceOf<PixelMapImage>(bdImage_)) {
1690         auto pixmap = DynamicCast<PixelMapImage>(bdImage_)->GetPixelMap();
1691         CHECK_NULL_VOID(pixmap);
1692         image = DrawingImage::MakeRSImageFromPixmap(pixmap);
1693     } else {
1694         return;
1695     }
1696 #endif
1697     CHECK_NULL_VOID(image);
1698     RSImage rsImage(&image);
1699     BorderImagePainter borderImagePainter(*GetBdImage(), widthProp, paintRect.GetSize(), rsImage, dipScale);
1700     borderImagePainter.PaintBorderImage(OffsetF(0.0, 0.0), canvas);
1701 }
1702 
PaintBorderImage()1703 void RosenRenderContext::PaintBorderImage()
1704 {
1705     CHECK_NULL_VOID(rsNode_);
1706 
1707     auto paintTask = [weak = WeakClaim(this)](RSCanvas& canvas) {
1708         auto ctx = weak.Upgrade();
1709         CHECK_NULL_VOID(ctx);
1710         ctx->BdImagePaintTask(canvas);
1711     };
1712 
1713     if (!borderImageModifier_) {
1714         borderImageModifier_ = std::make_shared<BorderImageModifier>();
1715         rsNode_->AddModifier(borderImageModifier_);
1716     }
1717     borderImageModifier_->SetPaintTask(std::move(paintTask));
1718     borderImageModifier_->Modify();
1719 }
1720 
CreateBorderImageDataReadyCallback()1721 DataReadyNotifyTask RosenRenderContext::CreateBorderImageDataReadyCallback()
1722 {
1723     return [weak = WeakClaim(this)](const ImageSourceInfo& sourceInfo) {
1724         auto rosenRenderContext = weak.Upgrade();
1725         CHECK_NULL_VOID(rosenRenderContext);
1726         auto imageSourceInfo = rosenRenderContext->GetBorderImageSource().value_or(ImageSourceInfo(""));
1727         if (imageSourceInfo != sourceInfo) {
1728             LOGW("sourceInfo does not match, ignore current callback. current: %{public}s vs callback's: %{public}s",
1729                 imageSourceInfo.ToString().c_str(), sourceInfo.ToString().c_str());
1730             return;
1731         }
1732         LOGI("borderImage data ready %{public}s", sourceInfo.ToString().c_str());
1733         rosenRenderContext->bdImageLoadingCtx_->MakeCanvasImage(SizeF(), true, ImageFit::NONE);
1734     };
1735 }
1736 
CreateBorderImageLoadSuccessCallback()1737 LoadSuccessNotifyTask RosenRenderContext::CreateBorderImageLoadSuccessCallback()
1738 {
1739     return [weak = WeakClaim(this)](const ImageSourceInfo& sourceInfo) {
1740         auto ctx = weak.Upgrade();
1741         CHECK_NULL_VOID(ctx);
1742         auto imageSourceInfo = ctx->GetBorderImageSource().value_or(ImageSourceInfo(""));
1743         if (imageSourceInfo != sourceInfo) {
1744             LOGW("sourceInfo does not match, ignore current callback. current: %{public}s vs callback's: %{public}s",
1745                 imageSourceInfo.ToString().c_str(), sourceInfo.ToString().c_str());
1746             return;
1747         }
1748         ctx->bdImage_ = ctx->bdImageLoadingCtx_->MoveCanvasImage();
1749         CHECK_NULL_VOID(ctx->bdImage_);
1750         LOGI("borderImage load success %{public}s", sourceInfo.ToString().c_str());
1751         if (ctx->GetHost()->GetGeometryNode()->GetFrameSize().IsPositive()) {
1752             ctx->PaintBorderImage();
1753             ctx->RequestNextFrame();
1754         }
1755     };
1756 }
1757 
OnBackgroundAlignUpdate(const Alignment & align)1758 void RosenRenderContext::OnBackgroundAlignUpdate(const Alignment& align)
1759 {
1760     CHECK_NULL_VOID(rsNode_);
1761     if (!backgroundModifier_) {
1762         backgroundModifier_ = std::make_shared<BackgroundModifier>();
1763         rsNode_->AddModifier(backgroundModifier_);
1764     }
1765     backgroundModifier_->SetAlign(align);
1766     backgroundModifier_->Modify();
1767     RequestNextFrame();
1768 }
1769 
OnBackgroundPixelMapUpdate(const RefPtr<PixelMap> & pixelMap)1770 void RosenRenderContext::OnBackgroundPixelMapUpdate(const RefPtr<PixelMap>& pixelMap)
1771 {
1772     CHECK_NULL_VOID(rsNode_);
1773     if (!backgroundModifier_) {
1774         backgroundModifier_ = std::make_shared<BackgroundModifier>();
1775         rsNode_->AddModifier(backgroundModifier_);
1776     }
1777     auto node = GetHost();
1778     auto nodeWidth = node->GetGeometryNode()->GetFrameSize().Width();
1779     auto nodeHeight = node->GetGeometryNode()->GetFrameSize().Height();
1780     backgroundModifier_->SetInitialNodeSize(nodeWidth, nodeHeight);
1781     backgroundModifier_->SetPixelMap(pixelMap);
1782     backgroundModifier_->Modify();
1783     RequestNextFrame();
1784 }
1785 
CreateBackgroundPixelMap(const RefPtr<FrameNode> & customNode)1786 void RosenRenderContext::CreateBackgroundPixelMap(const RefPtr<FrameNode>& customNode)
1787 {
1788     NG::ComponentSnapshot::JsCallback callback = [weak = WeakPtr(GetHost()),
1789                                                      containerId = Container::CurrentId()](
1790                                                      std::shared_ptr<Media::PixelMap> pixmap, int32_t errCode) {
1791         CHECK_NULL_VOID(pixmap);
1792         auto frameNode = weak.Upgrade();
1793         CHECK_NULL_VOID(frameNode);
1794         ContainerScope scope(containerId);
1795         std::shared_ptr<Media::PixelMap> pmap = std::move(pixmap);
1796         auto pixelmap = PixelMap::CreatePixelMap(&pmap);
1797         auto task = [pixelmap, containerId = containerId, frameNode]() {
1798             auto context = frameNode->GetRenderContext();
1799             if (context) {
1800                 context->UpdateBackgroundPixelMap(pixelmap);
1801                 context->RequestNextFrame();
1802             }
1803         };
1804         auto taskExecutor = Container::CurrentTaskExecutor();
1805         CHECK_NULL_VOID(taskExecutor);
1806         taskExecutor->PostTask(task, TaskExecutor::TaskType::UI);
1807     };
1808     NG::ComponentSnapshot::Create(customNode, std::move(callback));
1809 }
1810 
OnBorderImageUpdate(const RefPtr<BorderImage> &)1811 void RosenRenderContext::OnBorderImageUpdate(const RefPtr<BorderImage>& /*borderImage*/)
1812 {
1813     CHECK_NULL_VOID(rsNode_);
1814     if (bdImageLoadingCtx_ && bdImage_) {
1815         PaintBorderImage();
1816         RequestNextFrame();
1817     }
1818 }
1819 
OnBorderImageSourceUpdate(const ImageSourceInfo & borderImageSourceInfo)1820 void RosenRenderContext::OnBorderImageSourceUpdate(const ImageSourceInfo& borderImageSourceInfo)
1821 {
1822     CHECK_NULL_VOID(rsNode_);
1823     if (!bdImageLoadingCtx_ || borderImageSourceInfo != bdImageLoadingCtx_->GetSourceInfo()) {
1824         LoadNotifier bgLoadNotifier(
1825             CreateBorderImageDataReadyCallback(), CreateBorderImageLoadSuccessCallback(), nullptr);
1826         bdImageLoadingCtx_ = AceType::MakeRefPtr<ImageLoadingContext>(borderImageSourceInfo, std::move(bgLoadNotifier));
1827         CHECK_NULL_VOID(bdImageLoadingCtx_);
1828         bdImageLoadingCtx_->LoadImageData();
1829     }
1830     RequestNextFrame();
1831 }
1832 
OnBorderImageGradientUpdate(const Gradient & gradient)1833 void RosenRenderContext::OnBorderImageGradientUpdate(const Gradient& gradient)
1834 {
1835     CHECK_NULL_VOID(rsNode_);
1836     if (!gradient.IsValid()) {
1837         LOGE("Gradient not valid");
1838         return;
1839     }
1840     if (GetHost()->GetGeometryNode()->GetFrameSize().IsPositive()) {
1841         PaintBorderImageGradient();
1842     }
1843     RequestNextFrame();
1844 }
1845 
PaintBorderImageGradient()1846 void RosenRenderContext::PaintBorderImageGradient()
1847 {
1848     CHECK_NULL_VOID(rsNode_);
1849     CHECK_NULL_VOID(GetBorderImage());
1850     CHECK_NULL_VOID(GetBorderImageGradient());
1851     auto gradient = GetBorderImageGradient().value();
1852     if (!gradient.IsValid()) {
1853         LOGE("Gradient not valid");
1854         return;
1855     }
1856     auto paintSize = GetPaintRectWithoutTransform().GetSize();
1857     if (NearZero(paintSize.Width()) || NearZero(paintSize.Height())) {
1858         return;
1859     }
1860     auto layoutProperty = GetHost()->GetLayoutProperty();
1861     CHECK_NULL_VOID(layoutProperty);
1862 
1863     auto borderImageProperty = *GetBdImage();
1864     auto&& borderWidthProperty = layoutProperty->GetBorderWidthProperty();
1865     auto paintTask = [paintSize, borderImageProperty, &borderWidthProperty, gradient](RSCanvas& rsCanvas) mutable {
1866 #ifndef USE_ROSEN_DRAWING
1867         auto rsImage = SkiaDecorationPainter::CreateBorderImageGradient(gradient, paintSize);
1868 #else
1869         auto rsImage = DrawingDecorationPainter::CreateBorderImageGradient(gradient, paintSize);
1870 #endif
1871         BorderImagePainter borderImagePainter(borderImageProperty, borderWidthProperty, paintSize, rsImage,
1872             PipelineBase::GetCurrentContext()->GetDipScale());
1873         borderImagePainter.PaintBorderImage(OffsetF(0.0, 0.0), rsCanvas);
1874     };
1875 
1876     if (!borderImageModifier_) {
1877         borderImageModifier_ = std::make_shared<BorderImageModifier>();
1878         rsNode_->AddModifier(borderImageModifier_);
1879     }
1880     borderImageModifier_->SetPaintTask(std::move(paintTask));
1881     borderImageModifier_->Modify();
1882 }
1883 
OnModifyDone()1884 void RosenRenderContext::OnModifyDone()
1885 {
1886     auto frameNode = GetHost();
1887     CHECK_NULL_VOID(frameNode);
1888     CHECK_NULL_VOID(rsNode_);
1889     if (HasClickEffectLevel()) {
1890         InitEventClickEffect();
1891     }
1892 }
1893 
GetPropertyOfPosition()1894 RectF RosenRenderContext::GetPropertyOfPosition()
1895 {
1896     return AdjustPaintRect();
1897 }
1898 
AdjustPaintRect()1899 RectF RosenRenderContext::AdjustPaintRect()
1900 {
1901     RectF rect;
1902     auto frameNode = GetHost();
1903     CHECK_NULL_RETURN(frameNode, rect);
1904     CHECK_NULL_RETURN(rsNode_, rect);
1905     const auto& geometryNode = frameNode->GetGeometryNode();
1906     rect = geometryNode->GetFrameRect();
1907     if (!rect.GetSize().IsPositive()) {
1908         LOGD("paint size is zero");
1909         return rect;
1910     }
1911     const auto& layoutConstraint = frameNode->GetGeometryNode()->GetParentLayoutConstraint();
1912     auto widthPercentReference = layoutConstraint.has_value() ? layoutConstraint->percentReference.Width()
1913                                                               : PipelineContext::GetCurrentRootWidth();
1914     auto heightPercentReference = layoutConstraint.has_value() ? layoutConstraint->percentReference.Height()
1915                                                                : PipelineContext::GetCurrentRootHeight();
1916     auto anchor = GetAnchorValue({});
1917     auto anchorWidthReference = rect.Width();
1918     auto anchorHeightReference = rect.Height();
1919     auto anchorX = ConvertToPx(anchor.GetX(), ScaleProperty::CreateScaleProperty(), anchorWidthReference);
1920     auto anchorY = ConvertToPx(anchor.GetY(), ScaleProperty::CreateScaleProperty(), anchorHeightReference);
1921     Dimension resultX;
1922     Dimension resultY;
1923     Dimension parentPaddingLeft;
1924     Dimension parentPaddingTop;
1925     GetPaddingOfFirstFrameNodeParent(parentPaddingLeft, parentPaddingTop);
1926     // Position properties take precedence over offset locations.
1927     if (HasPosition() && IsUsingPosition(frameNode)) {
1928         CombineMarginAndPosition(
1929             resultX, resultY, parentPaddingLeft, parentPaddingTop, widthPercentReference, heightPercentReference);
1930         rect.SetLeft(resultX.ConvertToPx() - anchorX.value_or(0));
1931         rect.SetTop(resultY.ConvertToPx() - anchorY.value_or(0));
1932         return rect;
1933     }
1934     if (HasOffset()) {
1935         auto offset = GetOffsetValue({});
1936         if (PipelineBase::GetCurrentContext() &&
1937             PipelineBase::GetCurrentContext()->GetMinPlatformVersion() < PLATFORM_VERSION_TEN) {
1938             offset += OffsetT<Dimension>(parentPaddingLeft, parentPaddingTop);
1939         }
1940         auto offsetX = ConvertToPx(offset.GetX(), ScaleProperty::CreateScaleProperty(), widthPercentReference);
1941         auto offsetY = ConvertToPx(offset.GetY(), ScaleProperty::CreateScaleProperty(), heightPercentReference);
1942         rect.SetLeft(rect.GetX() + offsetX.value_or(0) - anchorX.value_or(0));
1943         rect.SetTop(rect.GetY() + offsetY.value_or(0) - anchorY.value_or(0));
1944         return rect;
1945     }
1946     rect.SetLeft(rect.GetX() - anchorX.value_or(0));
1947     rect.SetTop(rect.GetY() - anchorY.value_or(0));
1948     return rect;
1949 }
1950 
CombineMarginAndPosition(Dimension & resultX,Dimension & resultY,const Dimension & parentPaddingLeft,const Dimension & parentPaddingTop,float widthPercentReference,float heightPercentReference)1951 void RosenRenderContext::CombineMarginAndPosition(Dimension& resultX, Dimension& resultY,
1952     const Dimension& parentPaddingLeft, const Dimension& parentPaddingTop, float widthPercentReference,
1953     float heightPercentReference)
1954 {
1955     Dimension selfMarginLeft;
1956     Dimension selfMarginTop;
1957     auto frameNode = GetHost();
1958     if (frameNode && frameNode->GetLayoutProperty() && frameNode->GetLayoutProperty()->GetMarginProperty()) {
1959         auto& margin = frameNode->GetLayoutProperty()->GetMarginProperty();
1960         if (margin->left.has_value()) {
1961             selfMarginLeft = margin->left.value().GetDimension();
1962         }
1963         if (margin->top.has_value()) {
1964             selfMarginTop = margin->top.value().GetDimension();
1965         }
1966     }
1967     // to distinguish cases ex. margin has percentage unit and padding has vp unit
1968     // final rect offset will be affected by parent padding, self margin and position property
1969     if (selfMarginLeft.Unit() != GetPositionValue({}).GetX().Unit() ||
1970         selfMarginLeft.Unit() != parentPaddingLeft.Unit() ||
1971         parentPaddingLeft.Unit() != GetPositionValue({}).GetX().Unit()) {
1972         resultX = Dimension(
1973             ConvertToPx(parentPaddingLeft, ScaleProperty::CreateScaleProperty(), widthPercentReference).value_or(0) +
1974                 ConvertToPx(selfMarginLeft, ScaleProperty::CreateScaleProperty(), widthPercentReference).value_or(0) +
1975                 ConvertToPx(GetPositionValue({}).GetX(), ScaleProperty::CreateScaleProperty(), widthPercentReference)
1976                     .value_or(0),
1977             DimensionUnit::PX);
1978     } else {
1979         resultX = selfMarginLeft + GetPositionValue({}).GetX() + parentPaddingLeft;
1980     }
1981     if (selfMarginTop.Unit() != GetPositionValue({}).GetY().Unit() || selfMarginTop.Unit() != parentPaddingTop.Unit() ||
1982         parentPaddingTop.Unit() != GetPositionValue({}).GetY().Unit()) {
1983         resultY = Dimension(
1984             ConvertToPx(parentPaddingTop, ScaleProperty::CreateScaleProperty(), heightPercentReference).value_or(0) +
1985                 ConvertToPx(selfMarginTop, ScaleProperty::CreateScaleProperty(), heightPercentReference).value_or(0) +
1986                 ConvertToPx(GetPositionValue({}).GetY(), ScaleProperty::CreateScaleProperty(), heightPercentReference)
1987                     .value_or(0),
1988             DimensionUnit::PX);
1989     } else {
1990         resultY = selfMarginTop + GetPositionValue({}).GetY() + parentPaddingTop;
1991     }
1992 }
1993 
IsUsingPosition(const RefPtr<FrameNode> & frameNode)1994 bool RosenRenderContext::IsUsingPosition(const RefPtr<FrameNode>& frameNode)
1995 {
1996     auto layoutProperty = frameNode->GetLayoutProperty();
1997     bool isUsingPosition = true;
1998     if (layoutProperty) {
1999         isUsingPosition = layoutProperty->IsUsingPosition();
2000     }
2001     return isUsingPosition;
2002 }
2003 
GetPaddingOfFirstFrameNodeParent(Dimension & parentPaddingLeft,Dimension & parentPaddingTop)2004 void RosenRenderContext::GetPaddingOfFirstFrameNodeParent(Dimension& parentPaddingLeft, Dimension& parentPaddingTop)
2005 {
2006     auto frameNode = GetHost();
2007     CHECK_NULL_VOID(frameNode);
2008     auto frameNodeParent = frameNode->GetAncestorNodeOfFrame();
2009     CHECK_NULL_VOID_NOLOG(frameNodeParent);
2010     auto layoutProperty = frameNodeParent->GetLayoutProperty();
2011     if (layoutProperty && layoutProperty->GetPaddingProperty()) {
2012         parentPaddingLeft =
2013             layoutProperty->GetPaddingProperty()->left.value_or(CalcLength(Dimension(0))).GetDimension();
2014         parentPaddingTop = layoutProperty->GetPaddingProperty()->top.value_or(CalcLength(Dimension(0))).GetDimension();
2015     }
2016 }
SetPositionToRSNode()2017 void RosenRenderContext::SetPositionToRSNode()
2018 {
2019     auto frameNode = GetHost();
2020     CHECK_NULL_VOID(frameNode);
2021     CHECK_NULL_VOID(rsNode_);
2022     const auto& size = frameNode->GetGeometryNode()->GetFrameSize();
2023     if (!size.IsPositive()) {
2024         LOGD("first modify, make change in SyncGeometryProperties");
2025         return;
2026     }
2027     auto rect = AdjustPaintRect();
2028     if (!rect.GetSize().IsPositive()) {
2029         return;
2030     }
2031     rsNode_->SetBounds(rect.GetX(), rect.GetY(), rect.Width(), rect.Height());
2032     if (useContentRectForRSFrame_) {
2033         SetContentRectToFrame(rect);
2034     } else {
2035         rsNode_->SetFrame(rect.GetX(), rect.GetY(), rect.Width(), rect.Height());
2036     }
2037 }
2038 
OnPositionUpdate(const OffsetT<Dimension> &)2039 void RosenRenderContext::OnPositionUpdate(const OffsetT<Dimension>& /*value*/)
2040 {
2041     SetPositionToRSNode();
2042 }
2043 
OnOffsetUpdate(const OffsetT<Dimension> &)2044 void RosenRenderContext::OnOffsetUpdate(const OffsetT<Dimension>& /*value*/)
2045 {
2046     SetPositionToRSNode();
2047 }
2048 
OnAnchorUpdate(const OffsetT<Dimension> &)2049 void RosenRenderContext::OnAnchorUpdate(const OffsetT<Dimension>& /*value*/)
2050 {
2051     SetPositionToRSNode();
2052 }
2053 
OnZIndexUpdate(int32_t value)2054 void RosenRenderContext::OnZIndexUpdate(int32_t value)
2055 {
2056     CHECK_NULL_VOID(rsNode_);
2057     rsNode_->SetPositionZ(static_cast<float>(value));
2058 }
2059 
ResetBlendBgColor()2060 void RosenRenderContext::ResetBlendBgColor()
2061 {
2062     CHECK_NULL_VOID(rsNode_);
2063     blendColor_ = Color::TRANSPARENT;
2064     auto blendColor =
2065         GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(blendColor_).BlendColor(hoveredColor_);
2066     rsNode_->SetBackgroundColor(blendColor.GetValue());
2067     RequestNextFrame();
2068 }
2069 
BlendBgColor(const Color & color)2070 void RosenRenderContext::BlendBgColor(const Color& color)
2071 {
2072     CHECK_NULL_VOID(rsNode_);
2073     blendColor_ = color;
2074     auto blendColor =
2075         GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(blendColor_).BlendColor(hoveredColor_);
2076     rsNode_->SetBackgroundColor(blendColor.GetValue());
2077     RequestNextFrame();
2078 }
2079 
ResetBlendBorderColor()2080 void RosenRenderContext::ResetBlendBorderColor()
2081 {
2082     CHECK_NULL_VOID(rsNode_);
2083     auto leftColor = (Color::TRANSPARENT).GetValue();
2084     auto topColor = (Color::TRANSPARENT).GetValue();
2085     auto rightColor = (Color::TRANSPARENT).GetValue();
2086     auto bottomColor = (Color::TRANSPARENT).GetValue();
2087     if (GetBorderColor().has_value()) {
2088         leftColor = GetBorderColor()->leftColor.value_or(Color::TRANSPARENT).GetValue();
2089         topColor = GetBorderColor()->topColor.value_or(Color::TRANSPARENT).GetValue();
2090         rightColor = GetBorderColor()->rightColor.value_or(Color::TRANSPARENT).GetValue();
2091         bottomColor = GetBorderColor()->bottomColor.value_or(Color::TRANSPARENT).GetValue();
2092     }
2093     rsNode_->SetBorderColor(leftColor, topColor, rightColor, bottomColor);
2094     RequestNextFrame();
2095 }
2096 
BlendBorderColor(const Color & color)2097 void RosenRenderContext::BlendBorderColor(const Color& color)
2098 {
2099     CHECK_NULL_VOID(rsNode_);
2100     auto leftColor = color.GetValue();
2101     auto topColor = color.GetValue();
2102     auto rightColor = color.GetValue();
2103     auto bottomColor = color.GetValue();
2104     if (GetBorderColor().has_value()) {
2105         leftColor = (GetBorderColor()->leftColor.value_or(Color::TRANSPARENT).BlendColor(color)).GetValue();
2106         topColor = (GetBorderColor()->topColor.value_or(Color::TRANSPARENT).BlendColor(color)).GetValue();
2107         rightColor = (GetBorderColor()->rightColor.value_or(Color::TRANSPARENT).BlendColor(color)).GetValue();
2108         bottomColor = (GetBorderColor()->bottomColor.value_or(Color::TRANSPARENT).BlendColor(color)).GetValue();
2109     }
2110     rsNode_->SetBorderColor(leftColor, topColor, rightColor, bottomColor);
2111     RequestNextFrame();
2112 }
2113 
PaintFocusState(const RoundRect & paintRect,const Color & paintColor,const Dimension & paintWidth,bool isAccessibilityFocus)2114 void RosenRenderContext::PaintFocusState(
2115     const RoundRect& paintRect, const Color& paintColor, const Dimension& paintWidth, bool isAccessibilityFocus)
2116 {
2117     LOGD("PaintFocusState rect is (%{public}f, %{public}f, %{public}f, %{public}f). Color is %{public}s, PainWidth is "
2118          "%{public}s",
2119         paintRect.GetRect().Left(), paintRect.GetRect().Top(), paintRect.GetRect().Width(),
2120         paintRect.GetRect().Height(), paintColor.ColorToString().c_str(), paintWidth.ToString().c_str());
2121     CHECK_NULL_VOID_NOLOG(paintRect.GetRect().IsValid());
2122     CHECK_NULL_VOID(rsNode_);
2123 
2124     auto borderWidthPx = static_cast<float>(paintWidth.ConvertToPx());
2125 
2126     auto paintTask = [paintColor, borderWidthPx](const RSRoundRect& rrect, RSCanvas& rsCanvas) mutable {
2127         RSPen pen;
2128         pen.SetAntiAlias(true);
2129         pen.SetColor(ToRSColor(paintColor));
2130         pen.SetWidth(borderWidthPx);
2131         rsCanvas.AttachPen(pen);
2132         rsCanvas.DrawRoundRect(rrect);
2133     };
2134     std::shared_ptr<Rosen::RectF> overlayRect = std::make_shared<Rosen::RectF>(
2135         paintRect.GetRect().Left() - borderWidthPx / 2, paintRect.GetRect().Top() - borderWidthPx / 2,
2136         paintRect.GetRect().Width() + borderWidthPx, paintRect.GetRect().Height() + borderWidthPx);
2137     if (isAccessibilityFocus) {
2138         if (!accessibilityFocusStateModifier_) {
2139             accessibilityFocusStateModifier_ = std::make_shared<FocusStateModifier>();
2140         }
2141         accessibilityFocusStateModifier_->SetRoundRect(paintRect, borderWidthPx);
2142         accessibilityFocusStateModifier_->SetPaintTask(std::move(paintTask));
2143         rsNode_->SetDrawRegion(overlayRect);
2144         rsNode_->AddModifier(accessibilityFocusStateModifier_);
2145     } else {
2146         if (!focusStateModifier_) {
2147             // TODO: Add property data
2148             focusStateModifier_ = std::make_shared<FocusStateModifier>();
2149         }
2150         focusStateModifier_->SetRoundRect(paintRect, borderWidthPx);
2151         focusStateModifier_->SetPaintTask(std::move(paintTask));
2152         rsNode_->SetDrawRegion(overlayRect);
2153         rsNode_->AddModifier(focusStateModifier_);
2154     }
2155     RequestNextFrame();
2156 }
2157 
PaintFocusState(const RoundRect & paintRect,const Dimension & focusPaddingVp,const Color & paintColor,const Dimension & paintWidth,bool isAccessibilityFocus)2158 void RosenRenderContext::PaintFocusState(const RoundRect& paintRect, const Dimension& focusPaddingVp,
2159     const Color& paintColor, const Dimension& paintWidth, bool isAccessibilityFocus)
2160 {
2161     LOGD("PaintFocusState rect is (%{public}f, %{public}f, %{public}f, %{public}f). focusPadding is %{public}s, Color "
2162          "is %{public}s, PainWidth is %{public}s",
2163         paintRect.GetRect().Left(), paintRect.GetRect().Top(), paintRect.GetRect().Width(),
2164         paintRect.GetRect().Height(), focusPaddingVp.ToString().c_str(), paintColor.ColorToString().c_str(),
2165         paintWidth.ToString().c_str());
2166 
2167     auto paintWidthPx = static_cast<float>(paintWidth.ConvertToPx());
2168     auto borderPaddingPx = static_cast<float>(focusPaddingVp.ConvertToPx());
2169     auto focusPaintRectLeft = paintRect.GetRect().Left() - borderPaddingPx - paintWidthPx / 2;
2170     auto focusPaintRectTop = paintRect.GetRect().Top() - borderPaddingPx - paintWidthPx / 2;
2171     auto focusPaintRectWidth = paintRect.GetRect().Width() + 2 * borderPaddingPx + paintWidthPx;
2172     auto focusPaintRectHeight = paintRect.GetRect().Height() + 2 * borderPaddingPx + paintWidthPx;
2173 
2174     EdgeF diffRadius = { borderPaddingPx + paintWidthPx / 2, borderPaddingPx + paintWidthPx / 2 };
2175     auto focusPaintCornerTopLeft = paintRect.GetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS) + diffRadius;
2176     auto focusPaintCornerTopRight = paintRect.GetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS) + diffRadius;
2177     auto focusPaintCornerBottomLeft = paintRect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS) + diffRadius;
2178     auto focusPaintCornerBottomRight = paintRect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS) + diffRadius;
2179 
2180     RoundRect focusPaintRect;
2181     focusPaintRect.SetRect(RectF(focusPaintRectLeft, focusPaintRectTop, focusPaintRectWidth, focusPaintRectHeight));
2182     focusPaintRect.SetCornerRadius(
2183         RoundRect::CornerPos::TOP_LEFT_POS, focusPaintCornerTopLeft.x, focusPaintCornerTopLeft.y);
2184     focusPaintRect.SetCornerRadius(
2185         RoundRect::CornerPos::TOP_RIGHT_POS, focusPaintCornerTopRight.x, focusPaintCornerTopRight.y);
2186     focusPaintRect.SetCornerRadius(
2187         RoundRect::CornerPos::BOTTOM_LEFT_POS, focusPaintCornerBottomLeft.x, focusPaintCornerBottomLeft.y);
2188     focusPaintRect.SetCornerRadius(
2189         RoundRect::CornerPos::BOTTOM_RIGHT_POS, focusPaintCornerBottomRight.x, focusPaintCornerBottomRight.y);
2190 
2191     PaintFocusState(focusPaintRect, paintColor, paintWidth, isAccessibilityFocus);
2192 }
2193 
PaintFocusState(const Dimension & focusPaddingVp,const Color & paintColor,const Dimension & paintWidth)2194 void RosenRenderContext::PaintFocusState(
2195     const Dimension& focusPaddingVp, const Color& paintColor, const Dimension& paintWidth)
2196 {
2197     const auto& bounds = rsNode_->GetStagingProperties().GetBounds();
2198     const auto& radius = rsNode_->GetStagingProperties().GetCornerRadius();
2199 
2200     RoundRect frameRect;
2201     frameRect.SetRect(RectF(0, 0, bounds.z_, bounds.w_));
2202     frameRect.SetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS, radius.x_, radius.x_);
2203     frameRect.SetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS, radius.y_, radius.y_);
2204     frameRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS, radius.z_, radius.z_);
2205     frameRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS, radius.w_, radius.w_);
2206 
2207     PaintFocusState(frameRect, focusPaddingVp, paintColor, paintWidth);
2208 }
2209 
ClearFocusState()2210 void RosenRenderContext::ClearFocusState()
2211 {
2212     LOGD("ClearFocusState in.");
2213     CHECK_NULL_VOID(rsNode_);
2214     auto context = PipelineBase::GetCurrentContext();
2215     CHECK_NULL_VOID(context);
2216     CHECK_NULL_VOID_NOLOG(focusStateModifier_);
2217     rsNode_->RemoveModifier(focusStateModifier_);
2218     RequestNextFrame();
2219 }
2220 
FlushContentDrawFunction(CanvasDrawFunction && contentDraw)2221 void RosenRenderContext::FlushContentDrawFunction(CanvasDrawFunction&& contentDraw)
2222 {
2223     CHECK_NULL_VOID(rsNode_);
2224     CHECK_NULL_VOID(contentDraw);
2225     rsNode_->DrawOnNode(
2226 #ifndef USE_ROSEN_DRAWING
2227         Rosen::RSModifierType::CONTENT_STYLE, [contentDraw = std::move(contentDraw)](std::shared_ptr<SkCanvas> canvas) {
2228             RSCanvas rsCanvas(&canvas);
2229             contentDraw(rsCanvas);
2230 #else
2231         Rosen::RSModifierType::CONTENT_STYLE,
2232         [contentDraw = std::move(contentDraw)](std::shared_ptr<RSCanvas> canvas) {
2233             CHECK_NULL_VOID(canvas);
2234             contentDraw(*canvas);
2235 #endif
2236         });
2237 }
2238 
2239 void RosenRenderContext::FlushContentModifier(const RefPtr<Modifier>& modifier)
2240 {
2241     CHECK_NULL_VOID(rsNode_);
2242     CHECK_NULL_VOID(modifier);
2243     auto modifierAdapter = std::static_pointer_cast<ContentModifierAdapter>(ConvertContentModifier(modifier));
2244     auto contentModifier = AceType::DynamicCast<ContentModifier>(modifier);
2245     CHECK_NULL_VOID(contentModifier);
2246     auto rect = contentModifier->GetBoundsRect();
2247     if (rect.has_value()) {
2248         std::shared_ptr<Rosen::RectF> overlayRect =
2249             std::make_shared<Rosen::RectF>(rect->GetX(), rect->GetY(), rect->Width(), rect->Height());
2250         rsNode_->SetDrawRegion(overlayRect);
2251     }
2252     rsNode_->SetIsCustomTextType(contentModifier->GetIsCustomFont());
2253     rsNode_->AddModifier(modifierAdapter);
2254     modifierAdapter->AttachProperties();
2255 }
2256 
2257 void RosenRenderContext::FlushForegroundDrawFunction(CanvasDrawFunction&& foregroundDraw)
2258 {
2259     CHECK_NULL_VOID(rsNode_);
2260     CHECK_NULL_VOID(foregroundDraw);
2261     rsNode_->DrawOnNode(Rosen::RSModifierType::FOREGROUND_STYLE,
2262 #ifndef USE_ROSEN_DRAWING
2263         [foregroundDraw = std::move(foregroundDraw)](std::shared_ptr<SkCanvas> canvas) {
2264             RSCanvas rsCanvas(&canvas);
2265             foregroundDraw(rsCanvas);
2266 #else
2267         [foregroundDraw = std::move(foregroundDraw)](std::shared_ptr<RSCanvas> canvas) {
2268             CHECK_NULL_VOID(canvas);
2269             foregroundDraw(*canvas);
2270 #endif
2271         });
2272 }
2273 
2274 void RosenRenderContext::FlushOverlayDrawFunction(CanvasDrawFunction&& overlayDraw)
2275 {
2276     CHECK_NULL_VOID(rsNode_);
2277     CHECK_NULL_VOID(overlayDraw);
2278     rsNode_->DrawOnNode(
2279 #ifndef USE_ROSEN_DRAWING
2280         Rosen::RSModifierType::OVERLAY_STYLE, [overlayDraw = std::move(overlayDraw)](std::shared_ptr<SkCanvas> canvas) {
2281             RSCanvas rsCanvas(&canvas);
2282             overlayDraw(rsCanvas);
2283 #else
2284         Rosen::RSModifierType::OVERLAY_STYLE,
2285         [overlayDraw = std::move(overlayDraw)](std::shared_ptr<RSCanvas> canvas) {
2286             CHECK_NULL_VOID(canvas);
2287             overlayDraw(*canvas);
2288 #endif
2289         });
2290 }
2291 
2292 void RosenRenderContext::FlushOverlayModifier(const RefPtr<Modifier>& modifier)
2293 {
2294     CHECK_NULL_VOID(rsNode_);
2295     CHECK_NULL_VOID(modifier);
2296     auto modifierAdapter = std::static_pointer_cast<OverlayModifierAdapter>(ConvertOverlayModifier(modifier));
2297     auto overlayModifier = AceType::DynamicCast<OverlayModifier>(modifier);
2298     CHECK_NULL_VOID(overlayModifier);
2299     auto rect = overlayModifier->GetBoundsRect();
2300     std::shared_ptr<Rosen::RectF> overlayRect =
2301         std::make_shared<Rosen::RectF>(rect.GetX(), rect.GetY(), rect.Width(), rect.Height());
2302     rsNode_->SetDrawRegion(overlayRect);
2303     rsNode_->AddModifier(modifierAdapter);
2304     modifierAdapter->AttachProperties();
2305 }
2306 
2307 const std::shared_ptr<Rosen::RSNode>& RosenRenderContext::GetRSNode()
2308 {
2309     return rsNode_;
2310 }
2311 
2312 void RosenRenderContext::RebuildFrame(FrameNode* /*self*/, const std::list<RefPtr<FrameNode>>& children)
2313 {
2314     ReCreateRsNodeTree(children);
2315     RequestNextFrame();
2316 }
2317 
2318 std::list<std::shared_ptr<Rosen::RSNode>> RosenRenderContext::GetChildrenRSNodes(
2319     const std::list<RefPtr<FrameNode>>& frameChildren)
2320 {
2321     std::list<std::shared_ptr<Rosen::RSNode>> rsNodes;
2322     for (const auto& child : frameChildren) {
2323         if (!child) {
2324             continue;
2325         }
2326         auto rosenRenderContext = DynamicCast<RosenRenderContext>(child->renderContext_);
2327         if (!rosenRenderContext) {
2328             continue;
2329         }
2330         auto rsnode = rosenRenderContext->GetRSNode();
2331         if (rsnode) {
2332             rsNodes.emplace_back(rsnode);
2333         }
2334     }
2335     return rsNodes;
2336 }
2337 
2338 void RosenRenderContext::ReCreateRsNodeTree(const std::list<RefPtr<FrameNode>>& children)
2339 {
2340     CHECK_NULL_VOID(rsNode_);
2341     auto nowRSNodes = GetChildrenRSNodes(children);
2342     std::vector<OHOS::Rosen::NodeId> childNodeIds;
2343     for (auto& child : nowRSNodes) {
2344         childNodeIds.emplace_back(child->GetId());
2345     }
2346     if (childNodeIds == rsNode_->GetChildren()) {
2347         return;
2348     }
2349     rsNode_->ClearChildren();
2350     for (const auto& rsnode : nowRSNodes) {
2351         rsNode_->AddChild(rsnode, -1);
2352     }
2353 }
2354 
2355 void RosenRenderContext::AddFrameChildren(FrameNode* /*self*/, const std::list<RefPtr<FrameNode>>& children)
2356 {
2357     CHECK_NULL_VOID(rsNode_);
2358     for (const auto& child : children) {
2359         if (!child) {
2360             continue;
2361         }
2362         auto rosenRenderContext = DynamicCast<RosenRenderContext>(child->renderContext_);
2363         if (!rosenRenderContext) {
2364             continue;
2365         }
2366         auto rsNode = rosenRenderContext->GetRSNode();
2367         if (rsNode) {
2368             rsNode_->AddChild(rsNode, -1);
2369         }
2370     }
2371 }
2372 
2373 void RosenRenderContext::RemoveFrameChildren(FrameNode* /*self*/, const std::list<RefPtr<FrameNode>>& children)
2374 {
2375     CHECK_NULL_VOID(rsNode_);
2376     for (const auto& child : children) {
2377         if (!child) {
2378             continue;
2379         }
2380         auto rosenRenderContext = DynamicCast<RosenRenderContext>(child->renderContext_);
2381         if (!rosenRenderContext) {
2382             continue;
2383         }
2384         auto rsNode = rosenRenderContext->GetRSNode();
2385         if (rsNode) {
2386             rsNode_->RemoveChild(rsNode);
2387         }
2388     }
2389 }
2390 
2391 void RosenRenderContext::MoveFrame(FrameNode* /*self*/, const RefPtr<FrameNode>& child, int32_t index)
2392 {
2393     CHECK_NULL_VOID(rsNode_);
2394     CHECK_NULL_VOID(child);
2395     auto rosenRenderContext = DynamicCast<RosenRenderContext>(child->renderContext_);
2396     CHECK_NULL_VOID(rosenRenderContext);
2397     auto rsNode = rosenRenderContext->GetRSNode();
2398     // no need to check nullptr since MoveChild will take care of it
2399     rsNode_->MoveChild(rsNode, index);
2400 }
2401 
2402 void RosenRenderContext::AnimateHoverEffectScale(bool isHovered)
2403 {
2404     LOGD("HoverEffect.Scale: isHovered = %{public}d", isHovered);
2405     if ((isHovered && isHoveredScale_) || (!isHovered && !isHoveredScale_)) {
2406         return;
2407     }
2408     CHECK_NULL_VOID(rsNode_);
2409     auto pipeline = PipelineBase::GetCurrentContext();
2410     CHECK_NULL_VOID(pipeline);
2411     auto appTheme = pipeline->GetTheme<AppTheme>();
2412     CHECK_NULL_VOID(appTheme);
2413 
2414     float hoverScaleFrom = isHovered ? appTheme->GetHoverScaleStart() : appTheme->GetHoverScaleEnd();
2415     float hoverColorTo = isHovered ? appTheme->GetHoverScaleEnd() : appTheme->GetHoverScaleStart();
2416     float scaleStart = hoverScaleFrom;
2417     float scaleEnd = hoverColorTo;
2418     int32_t themeDuration = appTheme->GetHoverDuration();
2419 
2420     LOGD("HoverEffect.Scale: scale from %{public}f to %{public}f", scaleStart, scaleEnd);
2421     rsNode_->SetScale(scaleStart);
2422     Rosen::RSAnimationTimingProtocol protocol;
2423     protocol.SetDuration(themeDuration);
2424     RSNode::Animate(protocol, Rosen::RSAnimationTimingCurve::CreateCubicCurve(0.2f, 0.0f, 0.2f, 1.0f),
2425         [rsNode = rsNode_, scaleEnd]() {
2426             if (rsNode) {
2427                 rsNode->SetScale(scaleEnd);
2428             }
2429         });
2430     isHoveredScale_ = isHovered;
2431 }
2432 
2433 void RosenRenderContext::AnimateHoverEffectBoard(bool isHovered)
2434 {
2435     LOGD("HoverEffect.Highlight: isHovered = %{public}d", isHovered);
2436     if ((isHovered && isHoveredBoard_) || (!isHovered && !isHoveredBoard_)) {
2437         return;
2438     }
2439     CHECK_NULL_VOID(rsNode_);
2440     auto pipeline = PipelineBase::GetCurrentContext();
2441     CHECK_NULL_VOID(pipeline);
2442     auto appTheme = pipeline->GetTheme<AppTheme>();
2443     CHECK_NULL_VOID(appTheme);
2444 
2445     Color hoverColorFrom = isHovered ? appTheme->GetHoverHighlightStart() : appTheme->GetHoverHighlightEnd();
2446     Color hoverColorTo = isHovered ? appTheme->GetHoverHighlightEnd() : appTheme->GetHoverHighlightStart();
2447     Color highlightStart =
2448         GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(blendColor_).BlendColor(hoverColorFrom);
2449     Color highlightEnd =
2450         GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(blendColor_).BlendColor(hoverColorTo);
2451     int32_t themeDuration = appTheme->GetHoverDuration();
2452 
2453     LOGD("HoverEffect.Highlight: background color from %{public}x to %{public}x", highlightStart.GetValue(),
2454         highlightEnd.GetValue());
2455     rsNode_->SetBackgroundColor(highlightStart.GetValue());
2456     Rosen::RSAnimationTimingProtocol protocol;
2457     protocol.SetDuration(themeDuration);
2458     RSNode::Animate(protocol, Rosen::RSAnimationTimingCurve::CreateCubicCurve(0.2f, 0.0f, 0.2f, 1.0f),
2459         [rsNode = rsNode_, highlightEnd]() {
2460             CHECK_NULL_VOID_NOLOG(rsNode);
2461             rsNode->SetBackgroundColor(highlightEnd.GetValue());
2462         });
2463     hoveredColor_ = hoverColorTo;
2464     isHoveredBoard_ = isHovered;
2465 }
2466 
2467 void RosenRenderContext::UpdateBackBlurRadius(const Dimension& radius)
2468 {
2469     const auto& groupProperty = GetOrCreateBackground();
2470     if (groupProperty->CheckBlurRadius(radius)) {
2471         // Same with previous value
2472         return;
2473     }
2474     groupProperty->propBlurRadius = radius;
2475     SetBackBlurFilter();
2476 }
2477 
2478 void RosenRenderContext::UpdateFrontBlurRadius(const Dimension& radius)
2479 {
2480     const auto& groupProperty = GetOrCreateForeground();
2481     if (groupProperty->CheckBlurRadius(radius)) {
2482         // Same with previous value
2483         return;
2484     }
2485     groupProperty->propBlurRadius = radius;
2486     SetFrontBlurFilter();
2487 }
2488 
2489 void RosenRenderContext::OnBackShadowUpdate(const Shadow& shadow)
2490 {
2491     CHECK_NULL_VOID(rsNode_);
2492     if (!shadow.IsValid()) {
2493         if (shadow.GetHardwareAcceleration()) {
2494             rsNode_->SetShadowElevation(0.0);
2495         } else {
2496             rsNode_->SetShadowRadius(0.0);
2497         }
2498         RequestNextFrame();
2499         return;
2500     }
2501     rsNode_->SetShadowColor(shadow.GetColor().GetValue());
2502     rsNode_->SetShadowOffsetX(shadow.GetOffset().GetX());
2503     rsNode_->SetShadowOffsetY(shadow.GetOffset().GetY());
2504     rsNode_->SetShadowMask(shadow.GetShadowType() == ShadowType::BLUR);
2505     if (shadow.GetHardwareAcceleration()) {
2506         rsNode_->SetShadowElevation(shadow.GetElevation());
2507     } else {
2508 #ifndef USE_ROSEN_DRAWING
2509         rsNode_->SetShadowRadius(SkiaDecorationPainter::ConvertRadiusToSigma(shadow.GetBlurRadius()));
2510 #else
2511         rsNode_->SetShadowRadius(DrawingDecorationPainter::ConvertRadiusToSigma(shadow.GetBlurRadius()));
2512 #endif
2513     }
2514     RequestNextFrame();
2515 }
2516 
2517 // called when frameNode size changes
2518 void RosenRenderContext::PaintGraphics()
2519 {
2520     CHECK_NULL_VOID(rsNode_);
2521     auto&& graphicProps = GetOrCreateGraphics();
2522 
2523     if (!graphics_) {
2524         graphics_ = std::make_unique<GraphicModifiers>();
2525     }
2526     if (graphicProps->HasFrontGrayScale()) {
2527         auto grayScale = graphicProps->GetFrontGrayScaleValue();
2528         OnFrontGrayScaleUpdate(grayScale);
2529     }
2530 
2531     if (graphicProps->HasFrontBrightness()) {
2532         auto brightness = graphicProps->GetFrontBrightnessValue();
2533         OnFrontBrightnessUpdate(brightness);
2534     }
2535 
2536     if (graphicProps->HasFrontContrast()) {
2537         auto contrast = graphicProps->GetFrontContrastValue();
2538         OnFrontContrastUpdate(contrast);
2539     }
2540 
2541     if (graphicProps->HasFrontSaturate()) {
2542         auto saturate = graphicProps->GetFrontSaturateValue();
2543         OnFrontSaturateUpdate(saturate);
2544     }
2545 
2546     if (graphicProps->HasFrontSepia()) {
2547         auto sepia = graphicProps->GetFrontSepiaValue();
2548         OnFrontSepiaUpdate(sepia);
2549     }
2550 
2551     if (graphicProps->HasFrontInvert()) {
2552         auto invert = graphicProps->GetFrontInvertValue();
2553         OnFrontInvertUpdate(invert);
2554     }
2555 
2556     if (graphicProps->HasFrontHueRotate()) {
2557         auto hueRotate = graphicProps->GetFrontHueRotateValue();
2558         OnFrontHueRotateUpdate(hueRotate);
2559     }
2560 
2561     if (graphicProps->HasFrontColorBlend()) {
2562         auto colorBlend = graphicProps->GetFrontColorBlendValue();
2563         OnFrontColorBlendUpdate(colorBlend);
2564     }
2565 }
2566 
2567 // helper function to check if frame react is valid
2568 bool RosenRenderContext::RectIsNull()
2569 {
2570     RectF rect = GetPaintRectWithoutTransform();
2571     return NearZero(rect.Width()) || NearZero(rect.Height());
2572 }
2573 
2574 template<typename T, typename D>
2575 void RosenRenderContext::SetGraphicModifier(std::shared_ptr<T>& modifier, D data)
2576 {
2577     if (!modifier) {
2578         LOGD("create new modifier");
2579         modifier = std::make_shared<T>();
2580         rsNode_->AddModifier(modifier);
2581     }
2582     modifier->SetCustomData(data);
2583 
2584     auto borderRadius = GetBorderRadius();
2585     if (borderRadius.has_value()) {
2586         Rosen::Vector4f rsRadius;
2587         ConvertRadius(*borderRadius, rsRadius);
2588         modifier->SetCornerRadius(rsRadius);
2589     }
2590 }
2591 
2592 void RosenRenderContext::AddModifier(const std::shared_ptr<Rosen::RSModifier>& modifier)
2593 {
2594     CHECK_NULL_VOID(modifier);
2595     rsNode_->AddModifier(modifier);
2596 }
2597 
2598 void RosenRenderContext::RemoveModifier(const std::shared_ptr<Rosen::RSModifier>& modifier)
2599 {
2600     CHECK_NULL_VOID(modifier);
2601     rsNode_->RemoveModifier(modifier);
2602 }
2603 
2604 // helper function to update one of the graphic effects
2605 template<typename T, typename D>
2606 void RosenRenderContext::UpdateGraphic(std::shared_ptr<T>& modifier, D data)
2607 {
2608     CHECK_NULL_VOID_NOLOG(!RectIsNull());
2609     LOGD("updating graphic effect");
2610     SetGraphicModifier(modifier, data);
2611     RequestNextFrame();
2612 }
2613 
2614 void RosenRenderContext::OnFrontBrightnessUpdate(const Dimension& brightness)
2615 {
2616     CHECK_NULL_VOID(rsNode_);
2617     rsNode_->SetBrightness(brightness.Value());
2618     RequestNextFrame();
2619 }
2620 
2621 void RosenRenderContext::OnFrontGrayScaleUpdate(const Dimension& grayScale)
2622 {
2623     CHECK_NULL_VOID(rsNode_);
2624     rsNode_->SetGrayScale(grayScale.Value());
2625     RequestNextFrame();
2626 }
2627 
2628 void RosenRenderContext::OnFrontContrastUpdate(const Dimension& contrast)
2629 {
2630     CHECK_NULL_VOID(rsNode_);
2631     rsNode_->SetContrast(contrast.Value());
2632     RequestNextFrame();
2633 }
2634 
2635 void RosenRenderContext::OnFrontSaturateUpdate(const Dimension& saturate)
2636 {
2637     CHECK_NULL_VOID(rsNode_);
2638     rsNode_->SetSaturate(saturate.Value());
2639     RequestNextFrame();
2640 }
2641 
2642 void RosenRenderContext::OnFrontSepiaUpdate(const Dimension& sepia)
2643 {
2644     CHECK_NULL_VOID(rsNode_);
2645     rsNode_->SetSepia(sepia.Value());
2646     RequestNextFrame();
2647 }
2648 
2649 void RosenRenderContext::OnFrontInvertUpdate(const Dimension& invert)
2650 {
2651     CHECK_NULL_VOID(rsNode_);
2652     rsNode_->SetInvert(invert.Value());
2653     RequestNextFrame();
2654 }
2655 
2656 void RosenRenderContext::OnFrontHueRotateUpdate(float hueRotate)
2657 {
2658     CHECK_NULL_VOID(rsNode_);
2659     rsNode_->SetHueRotate(hueRotate);
2660     RequestNextFrame();
2661 }
2662 
2663 void RosenRenderContext::OnFrontColorBlendUpdate(const Color& colorBlend)
2664 {
2665     CHECK_NULL_VOID(rsNode_);
2666     rsNode_->SetColorBlend(colorBlend.GetValue());
2667     RequestNextFrame();
2668 }
2669 
2670 void RosenRenderContext::OnLinearGradientBlurUpdate(const NG::LinearGradientBlurPara& blurPara)
2671 {
2672     float blurRadius = 0.0f;
2673     if (blurPara.blurRadius_.IsValid()) {
2674         float radiusPx = blurPara.blurRadius_.ConvertToPx();
2675         blurRadius = radiusPx;
2676     }
2677 
2678     CHECK_NULL_VOID(rsNode_);
2679     std::shared_ptr<Rosen::RSLinearGradientBlurPara> rsLinearGradientBlurPara(
2680         std::make_shared<Rosen::RSLinearGradientBlurPara>(
2681             blurRadius, blurPara.fractionStops_, static_cast<Rosen::GradientDirection>(blurPara.direction_)));
2682 
2683     rsNode_->SetLinearGradientBlurPara(rsLinearGradientBlurPara);
2684     RequestNextFrame();
2685 }
2686 
2687 void RosenRenderContext::OnDynamicLightUpRateUpdate(const float rate)
2688 {
2689     CHECK_NULL_VOID(rsNode_);
2690     rsNode_->SetDynamicLightUpRate(rate);
2691     RequestNextFrame();
2692 }
2693 
2694 void RosenRenderContext::OnDynamicLightUpDegreeUpdate(const float degree)
2695 {
2696     CHECK_NULL_VOID(rsNode_);
2697     rsNode_->SetDynamicLightUpDegree(degree);
2698     RequestNextFrame();
2699 }
2700 
2701 void RosenRenderContext::UpdateTransition(const TransitionOptions& options)
2702 {
2703     CHECK_NULL_VOID(rsNode_);
2704     if (options.Type == TransitionType::ALL || options.Type == TransitionType::APPEARING) {
2705         if (!propTransitionAppearing_) {
2706             propTransitionAppearing_ = std::make_unique<TransitionOptions>(options);
2707         } else {
2708             *propTransitionAppearing_ = options;
2709         }
2710         propTransitionAppearing_->Type = TransitionType::APPEARING;
2711     }
2712     if (options.Type == TransitionType::ALL || options.Type == TransitionType::DISAPPEARING) {
2713         if (!propTransitionDisappearing_) {
2714             propTransitionDisappearing_ = std::make_unique<TransitionOptions>(options);
2715         } else {
2716             *propTransitionDisappearing_ = options;
2717         }
2718         propTransitionDisappearing_->Type = TransitionType::DISAPPEARING;
2719     }
2720 }
2721 
2722 std::shared_ptr<Rosen::RSTransitionEffect> RosenRenderContext::GetRSTransitionWithoutType(
2723     const std::unique_ptr<TransitionOptions>& options, const SizeF& frameSize)
2724 {
2725     if (options == nullptr) {
2726         return nullptr;
2727     }
2728     std::shared_ptr<Rosen::RSTransitionEffect> effect = Rosen::RSTransitionEffect::Create();
2729     if (options->HasOpacity()) {
2730         effect = effect->Opacity(options->GetOpacityValue());
2731     }
2732     if (options->HasTranslate()) {
2733         const auto& translate = options->GetTranslateValue();
2734         effect = effect->Translate({ static_cast<float>(translate.x.ConvertToPxWithSize(frameSize.Width())),
2735             static_cast<float>(translate.y.ConvertToPxWithSize(frameSize.Height())),
2736             static_cast<float>(translate.z.ConvertToPx()) });
2737     }
2738     if (options->HasScale()) {
2739         const auto& scale = options->GetScaleValue();
2740         effect = effect->Scale({ scale.xScale, scale.yScale, scale.zScale });
2741     }
2742     if (options->HasRotate()) {
2743         const auto& rotate = options->GetRotateValue();
2744         effect = effect->Rotate({ rotate.xDirection, rotate.yDirection, rotate.zDirection, rotate.angle });
2745     }
2746     return effect;
2747 }
2748 
2749 void RosenRenderContext::PaintGradient(const SizeF& frameSize)
2750 {
2751     CHECK_NULL_VOID(rsNode_);
2752     auto& gradientProperty = GetOrCreateGradient();
2753     Gradient gradient;
2754     if (gradientProperty->HasLinearGradient()) {
2755         gradient = gradientProperty->GetLinearGradientValue();
2756     }
2757     if (gradientProperty->HasRadialGradient()) {
2758         gradient = gradientProperty->GetRadialGradientValue();
2759     }
2760     if (gradientProperty->HasSweepGradient()) {
2761         gradient = gradientProperty->GetSweepGradientValue();
2762     }
2763     auto shader = SkiaDecorationPainter::CreateGradientShader(gradient, frameSize);
2764     rsNode_->SetBackgroundShader(RSShader::CreateRSShader(shader));
2765 }
2766 
2767 void RosenRenderContext::OnLinearGradientUpdate(const NG::Gradient& gradient)
2768 {
2769     RectF rect = GetPaintRectWithoutTransform();
2770     if (!RectIsNull()) {
2771         PaintGradient(rect.GetSize());
2772     }
2773     RequestNextFrame();
2774 }
2775 
2776 void RosenRenderContext::OnRadialGradientUpdate(const NG::Gradient& gradient)
2777 {
2778     RectF rect = GetPaintRectWithoutTransform();
2779     if (!RectIsNull()) {
2780         PaintGradient(rect.GetSize());
2781     }
2782     RequestNextFrame();
2783 }
2784 
2785 void RosenRenderContext::OnSweepGradientUpdate(const NG::Gradient& gradient)
2786 {
2787     RectF rect = GetPaintRectWithoutTransform();
2788     if (!RectIsNull()) {
2789         PaintGradient(rect.GetSize());
2790     }
2791     RequestNextFrame();
2792 }
2793 
2794 void RosenRenderContext::PaintClipShape(const std::unique_ptr<ClipProperty>& clip, const SizeF& frameSize)
2795 {
2796     auto basicShape = clip->GetClipShapeValue();
2797 #ifndef USE_ROSEN_DRAWING
2798     auto skPath = SkiaDecorationPainter::SkiaCreateSkPath(basicShape, frameSize);
2799     auto shapePath = Rosen::RSPath::CreateRSPath(skPath);
2800     if (!clipBoundModifier_) {
2801         auto prop = std::make_shared<RSProperty<std::shared_ptr<Rosen::RSPath>>>(shapePath);
2802         clipBoundModifier_ = std::make_shared<Rosen::RSClipBoundsModifier>(prop);
2803         rsNode_->AddModifier(clipBoundModifier_);
2804     } else {
2805         auto property = std::static_pointer_cast<RSProperty<std::shared_ptr<Rosen::RSPath>>>(
2806             clipBoundModifier_->GetProperty());
2807         property->Set(shapePath);
2808     }
2809 #else
2810     auto rsPath = DrawingDecorationPainter::DrawingCreatePath(basicShape, frameSize);
2811     auto shapePath = Rosen::RSPath::CreateRSPath(rsPath);
2812     if (!clipBoundModifier_) {
2813         auto prop = std::make_shared<RSProperty<RSPath>>(shapePath);
2814         clipBoundModifier_ = std::make_shared<Rosen::RSClipBoundsModifier>(prop);
2815         rsNode_->AddModifier(clipBoundModifier_);
2816     } else {
2817         auto property = std::static_pointer_cast<RSProperty<std::shared_ptr<RSPath>>>(
2818             clipBoundModifier_->GetProperty());
2819         property->Set(shapePath);
2820     }
2821 #endif
2822 }
2823 
2824 void RosenRenderContext::PaintClipMask(const std::unique_ptr<ClipProperty>& clip, const SizeF& frameSize)
2825 {
2826     if (moonProgressModifier_) {
2827         auto modifierAdapter =
2828             std::static_pointer_cast<OverlayModifierAdapter>(ConvertOverlayModifier(moonProgressModifier_));
2829         rsNode_->RemoveModifier(modifierAdapter);
2830         moonProgressModifier_ = nullptr;
2831     }
2832     auto basicShape = clip->GetClipMaskValue();
2833 #ifndef USE_ROSEN_DRAWING
2834     auto skPath = SkiaDecorationPainter::SkiaCreateSkPath(basicShape, frameSize);
2835     auto maskPath = Rosen::RSMask::CreatePathMask(skPath, SkiaDecorationPainter::CreateMaskSkPaint(basicShape));
2836     if (!clipMaskModifier_) {
2837         auto prop = std::make_shared<RSProperty<std::shared_ptr<Rosen::RSMask>>>(maskPath);
2838         clipMaskModifier_ = std::make_shared<Rosen::RSMaskModifier>(prop);
2839         rsNode_->AddModifier(clipMaskModifier_);
2840     } else {
2841         auto property = std::static_pointer_cast<RSProperty<std::shared_ptr<Rosen::RSMask>>>(
2842             clipMaskModifier_->GetProperty());
2843         property->Set(maskPath);
2844     }
2845 #else
2846     auto rsPath = DrawingDecorationPainter::DrawingCreatePath(basicShape, frameSize);
2847     auto maskPath = Rosen::RSMask::CreatePathMask(
2848         rsPath, DrawingDecorationPainter::CreateMaskDrawingBrush(basicShape));
2849     if (!clipMaskModifier_) {
2850         auto prop = std::make_shared<RSProperty<RSMask>>(maskPath);
2851         clipMaskModifier_ = std::make_shared<Rosen::RSMaskModifier>(prop);
2852         rsNode_->AddModifier(clipMaskModifier_);
2853     } else {
2854         auto property = std::static_pointer_cast<RSProperty<std::shared_ptr<RSMask>>>(
2855             clipMaskModifier_->GetProperty());
2856         property->Set(maskPath);
2857     }
2858 #endif
2859 }
2860 
2861 
2862 void RosenRenderContext::PaintClip(const SizeF& frameSize)
2863 {
2864     CHECK_NULL_VOID(rsNode_);
2865     auto& clip = GetOrCreateClip();
2866     if (clip->HasClipShape()) {
2867         PaintClipShape(clip, frameSize);
2868     }
2869 
2870     if (clip->HasClipMask()) {
2871         PaintClipMask(clip, frameSize);
2872     }
2873 }
2874 
2875 void RosenRenderContext::PaintProgressMask()
2876 {
2877     if (clipMaskModifier_) {
2878         rsNode_->RemoveModifier(clipMaskModifier_);
2879         clipMaskModifier_ = nullptr;
2880     }
2881     if (!moonProgressModifier_) {
2882         moonProgressModifier_ = AceType::MakeRefPtr<MoonProgressModifier>();
2883         auto modifierAdapter =
2884             std::static_pointer_cast<OverlayModifierAdapter>(ConvertOverlayModifier(moonProgressModifier_));
2885         rsNode_->AddModifier(modifierAdapter);
2886         modifierAdapter->AttachProperties();
2887     }
2888     auto progress = GetProgressMaskValue();
2889     moonProgressModifier_->SetMaskColor(LinearColor(progress->GetColor()));
2890     moonProgressModifier_->SetMaxValue(progress->GetMaxValue());
2891     if (progress->GetValue() > moonProgressModifier_->GetMaxValue()) {
2892         progress->SetValue(moonProgressModifier_->GetMaxValue());
2893     }
2894     moonProgressModifier_->SetValue(progress->GetValue());
2895 }
2896 
2897 void RosenRenderContext::SetClipBoundsWithCommands(const std::string& commands)
2898 {
2899     CHECK_NULL_VOID(rsNode_);
2900 #ifndef USE_ROSEN_DRAWING
2901     SkPath skPath;
2902     SkParsePath::FromSVGString(commands.c_str(), &skPath);
2903     rsNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(skPath));
2904 #else
2905     RSRecordingPath rsPath;
2906     rsPath.BuildFromSVGString(commands);
2907     rsNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(rsPath));
2908 #endif
2909 }
2910 
2911 void RosenRenderContext::ClipWithRect(const RectF& rectF)
2912 {
2913     CHECK_NULL_VOID(rsNode_);
2914 #ifndef USE_ROSEN_DRAWING
2915     SkPath skPath;
2916     skPath.addRect(rectF.GetX(), rectF.GetY(), rectF.GetX() + rectF.Width(), rectF.GetY() + rectF.Height());
2917     rsNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(skPath));
2918 #else
2919     RSRecordingPath rsPath;
2920     rsPath.AddRect({ rectF.GetX(), rectF.GetY(), rectF.GetX() + rectF.Width(), rectF.GetY() + rectF.Height() });
2921     rsNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(rsPath));
2922 #endif
2923 }
2924 
2925 void RosenRenderContext::ClipWithRRect(const RectF& rectF, const RadiusF& radiusF)
2926 {
2927     CHECK_NULL_VOID(rsNode_);
2928     Rosen::Vector4f rect;
2929     Rosen::Vector4f radius;
2930     rect.SetValues(rectF.GetX(), rectF.GetY(), rectF.GetX() + rectF.Width(), rectF.GetY() + rectF.Height());
2931     radius.SetValues(radiusF.GetCorner(RoundRect::CornerPos::TOP_LEFT_POS).x,
2932         radiusF.GetCorner(RoundRect::CornerPos::TOP_RIGHT_POS).x,
2933         radiusF.GetCorner(RoundRect::CornerPos::BOTTOM_LEFT_POS).x,
2934         radiusF.GetCorner(RoundRect::CornerPos::BOTTOM_RIGHT_POS).x);
2935     rsNode_->SetClipRRect(rect, radius);
2936     RequestNextFrame();
2937 }
2938 
2939 void RosenRenderContext::OnClipShapeUpdate(const RefPtr<BasicShape>& /*basicShape*/)
2940 {
2941     RectF rect = GetPaintRectWithoutTransform();
2942     if (!RectIsNull()) {
2943         PaintClip(SizeF(rect.Width(), rect.Height()));
2944     }
2945     RequestNextFrame();
2946 }
2947 
2948 void RosenRenderContext::OnClipEdgeUpdate(bool isClip)
2949 {
2950     CHECK_NULL_VOID(rsNode_);
2951     if (isClip) {
2952         rsNode_->SetClipToBounds(true);
2953     } else {
2954         // In the internal implementation, some nodes call SetClipToBounds(true), some call SetClipToFrame(true).
2955         // If the developer set clip to false, we should disable all internal clips
2956         // so that the child component can go beyond the parent component
2957         rsNode_->SetClipToBounds(false);
2958         rsNode_->SetClipToFrame(false);
2959     }
2960     RequestNextFrame();
2961 }
2962 
2963 void RosenRenderContext::OnClipMaskUpdate(const RefPtr<BasicShape>& /*basicShape*/)
2964 {
2965     RectF rect = GetPaintRectWithoutTransform();
2966     if (!RectIsNull()) {
2967         PaintClip(SizeF(rect.Width(), rect.Height()));
2968     }
2969     RequestNextFrame();
2970 }
2971 
2972 void RosenRenderContext::OnProgressMaskUpdate(const RefPtr<ProgressMaskProperty>& /* progress */)
2973 {
2974     PaintProgressMask();
2975     CHECK_NULL_VOID(rsNode_);
2976     rsNode_->SetClipToBounds(true);
2977     RequestNextFrame();
2978 }
2979 
2980 RefPtr<PageTransitionEffect> RosenRenderContext::GetDefaultPageTransition(PageTransitionType type)
2981 {
2982     auto resultEffect = AceType::MakeRefPtr<PageTransitionEffect>(type, PageTransitionOption());
2983     resultEffect->SetScaleEffect(ScaleOptions(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct));
2984     TranslateOptions translate;
2985     auto rect = GetPaintRectWithoutTransform();
2986     switch (type) {
2987         case PageTransitionType::ENTER_PUSH:
2988         case PageTransitionType::EXIT_POP:
2989             translate.x = Dimension(rect.Width());
2990             break;
2991         case PageTransitionType::ENTER_POP:
2992         case PageTransitionType::EXIT_PUSH:
2993             translate.x = Dimension(-rect.Width());
2994             break;
2995         default:
2996             LOGI("unexpected transition type");
2997             break;
2998     }
2999     resultEffect->SetTranslateEffect(translate);
3000     resultEffect->SetOpacityEffect(1);
3001     return resultEffect;
3002 }
3003 
3004 RefPtr<PageTransitionEffect> RosenRenderContext::GetPageTransitionEffect(const RefPtr<PageTransitionEffect>& transition)
3005 {
3006     auto resultEffect = AceType::MakeRefPtr<PageTransitionEffect>(
3007         transition->GetPageTransitionType(), transition->GetPageTransitionOption());
3008     resultEffect->SetScaleEffect(
3009         transition->GetScaleEffect().value_or(ScaleOptions(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct)));
3010     TranslateOptions translate;
3011     // slide and translate, only one can be effective
3012     if (transition->GetSlideEffect().has_value()) {
3013         auto rect = GetPaintRectWithoutTransform();
3014         switch (transition->GetSlideEffect().value()) {
3015             case SlideEffect::LEFT:
3016                 translate.x = Dimension(-rect.Width());
3017                 break;
3018             case SlideEffect::RIGHT:
3019                 translate.x = Dimension(rect.Width());
3020                 break;
3021             case SlideEffect::BOTTOM:
3022                 translate.y = Dimension(rect.Height());
3023                 break;
3024             case SlideEffect::TOP:
3025                 translate.y = Dimension(-rect.Height());
3026                 break;
3027             default:
3028                 LOGW("unexpected slide effect");
3029                 break;
3030         }
3031     } else if (transition->GetTranslateEffect().has_value()) {
3032         auto rect = GetPaintRectWithoutTransform();
3033         const auto& translateOptions = transition->GetTranslateEffect();
3034         translate.x = Dimension(translateOptions->x.ConvertToPxWithSize(rect.Width()));
3035         translate.y = Dimension(translateOptions->y.ConvertToPxWithSize(rect.Height()));
3036         translate.z = Dimension(translateOptions->z.ConvertToPx());
3037     }
3038     resultEffect->SetTranslateEffect(translate);
3039     resultEffect->SetOpacityEffect(transition->GetOpacityEffect().value_or(1));
3040     return resultEffect;
3041 }
3042 
3043 bool RosenRenderContext::TriggerPageTransition(PageTransitionType type, const std::function<void()>& onFinish)
3044 {
3045     bool transitionIn = true;
3046     if (type == PageTransitionType::ENTER_PUSH || type == PageTransitionType::ENTER_POP) {
3047         transitionIn = true;
3048     } else if (type == PageTransitionType::EXIT_PUSH || type == PageTransitionType::EXIT_POP) {
3049         transitionIn = false;
3050     } else {
3051         LOGW("unexpected transition type");
3052         return false;
3053     }
3054     CHECK_NULL_RETURN(rsNode_, false);
3055     auto host = GetHost();
3056     CHECK_NULL_RETURN(host, false);
3057     auto pattern = host->GetPattern<PagePattern>();
3058     CHECK_NULL_RETURN(pattern, false);
3059     auto transition = pattern->FindPageTransitionEffect(type);
3060     RefPtr<PageTransitionEffect> effect;
3061     AnimationOption option;
3062     if (transition) {
3063         effect = GetPageTransitionEffect(transition);
3064         option.SetCurve(transition->GetCurve());
3065         option.SetDuration(transition->GetDuration());
3066         option.SetDelay(transition->GetDelay());
3067     } else {
3068         effect = GetDefaultPageTransition(type);
3069         const int32_t pageTransitionDuration = 300;
3070         option.SetCurve(Curves::LINEAR);
3071         option.SetDuration(pageTransitionDuration);
3072 #ifdef QUICK_PUSH_TRANSITION
3073         auto pipeline = PipelineBase::GetCurrentContext();
3074         if (pipeline) {
3075             const int32_t nanoToMilliSeconds = 1000000;
3076             const int32_t minTransitionDuration = pageTransitionDuration / 2;
3077             const int32_t frameDelayTime = 32;
3078             int32_t startDelayTime =
3079                 static_cast<int32_t>(pipeline->GetTimeFromExternalTimer() - pipeline->GetLastTouchTime()) /
3080                 nanoToMilliSeconds;
3081             startDelayTime = std::max(0, startDelayTime);
3082             int32_t delayedDuration = pageTransitionDuration > startDelayTime ? pageTransitionDuration - startDelayTime
3083                                                                               : pageTransitionDuration;
3084             delayedDuration = std::max(minTransitionDuration, delayedDuration - frameDelayTime);
3085             LOGI("Use quick push delayedDuration:%{public}d", delayedDuration);
3086             option.SetDuration(delayedDuration);
3087         }
3088 #endif
3089     }
3090     const auto& scaleOptions = effect->GetScaleEffect();
3091     const auto& translateOptions = effect->GetTranslateEffect();
3092     UpdateTransformCenter(DimensionOffset(scaleOptions->centerX, scaleOptions->centerY));
3093 
3094     if (transitionIn) {
3095         UpdateTransformScale(VectorF(scaleOptions->xScale, scaleOptions->yScale));
3096         UpdateTransformTranslate(translateOptions.value());
3097         UpdateOpacity(effect->GetOpacityEffect().value());
3098         AnimationUtils::OpenImplicitAnimation(option, option.GetCurve(), onFinish);
3099         UpdateTransformScale(VectorF(1.0f, 1.0f));
3100         UpdateTransformTranslate({ 0.0f, 0.0f, 0.0f });
3101         UpdateOpacity(1.0);
3102         AnimationUtils::CloseImplicitAnimation();
3103         return true;
3104     }
3105     UpdateTransformScale(VectorF(1.0f, 1.0f));
3106     UpdateTransformTranslate({ 0.0f, 0.0f, 0.0f });
3107     UpdateOpacity(1.0);
3108     AnimationUtils::OpenImplicitAnimation(option, option.GetCurve(), onFinish);
3109     UpdateTransformScale(VectorF(scaleOptions->xScale, scaleOptions->yScale));
3110     UpdateTransformTranslate(translateOptions.value());
3111     UpdateOpacity(effect->GetOpacityEffect().value());
3112     AnimationUtils::CloseImplicitAnimation();
3113     return true;
3114 }
3115 
3116 void RosenRenderContext::PaintOverlayText()
3117 {
3118     CHECK_NULL_VOID(rsNode_);
3119     auto& overlay = GetOrCreateOverlay();
3120     if (overlay->HasOverlayText()) {
3121         auto overlayText = overlay->GetOverlayTextValue();
3122         auto paintRect = GetPaintRectWithTransform();
3123         std::shared_ptr<Rosen::RectF> overlayRect;
3124         if (modifier_) {
3125             modifier_->SetCustomData(NG::OverlayTextData(overlayText));
3126             auto overlayOffset = modifier_->GetOverlayOffset();
3127             overlayRect = std::make_shared<Rosen::RectF>(paintRect.GetX(), paintRect.GetY(),
3128                 paintRect.Width() + overlayOffset.GetX(), paintRect.Height() + overlayOffset.GetY());
3129             rsNode_->SetDrawRegion(overlayRect);
3130         } else {
3131             modifier_ = std::make_shared<OverlayTextModifier>();
3132             rsNode_->AddModifier(modifier_);
3133             modifier_->SetCustomData(NG::OverlayTextData(overlayText));
3134             auto overlayOffset = modifier_->GetOverlayOffset();
3135             overlayRect = std::make_shared<Rosen::RectF>(paintRect.GetX(), paintRect.GetY(),
3136                 paintRect.Width() + overlayOffset.GetX(), paintRect.Height() + overlayOffset.GetY());
3137             rsNode_->SetDrawRegion(overlayRect);
3138         }
3139     }
3140 }
3141 
3142 void RosenRenderContext::OnOverlayTextUpdate(const OverlayOptions& overlay)
3143 {
3144     if (!RectIsNull()) {
3145         PaintOverlayText();
3146     }
3147     RequestNextFrame();
3148 }
3149 
3150 void RosenRenderContext::OnMotionPathUpdate(const MotionPathOption& motionPath)
3151 {
3152     CHECK_NULL_VOID(rsNode_);
3153     if (!motionPath.IsValid()) {
3154         rsNode_->SetMotionPathOption(nullptr);
3155         return;
3156     }
3157     auto motionOption = Rosen::RSMotionPathOption(motionPath.GetPath());
3158     motionOption.SetBeginFraction(motionPath.GetBegin());
3159     motionOption.SetEndFraction(motionPath.GetEnd());
3160     motionOption.SetRotationMode(
3161         motionPath.GetRotate() ? Rosen::RotationMode::ROTATE_AUTO : Rosen::RotationMode::ROTATE_NONE);
3162     motionOption.SetPathNeedAddOrigin(HasOffset());
3163     rsNode_->SetMotionPathOption(std::make_shared<Rosen::RSMotionPathOption>(motionOption));
3164     RequestNextFrame();
3165 }
3166 
3167 void RosenRenderContext::SetSharedTranslate(float xTranslate, float yTranslate)
3168 {
3169     if (!sharedTransitionModifier_) {
3170         sharedTransitionModifier_ = std::make_unique<SharedTransitionModifier>();
3171     }
3172     AddOrChangeTranslateModifier(rsNode_, sharedTransitionModifier_->translateXY,
3173         sharedTransitionModifier_->translateXYValue, { xTranslate, yTranslate });
3174 }
3175 
3176 void RosenRenderContext::ResetSharedTranslate()
3177 {
3178     CHECK_NULL_VOID_NOLOG(sharedTransitionModifier_);
3179     CHECK_NULL_VOID_NOLOG(sharedTransitionModifier_->translateXY);
3180     CHECK_NULL_VOID_NOLOG(rsNode_);
3181     rsNode_->RemoveModifier(sharedTransitionModifier_->translateXY);
3182     sharedTransitionModifier_->translateXYValue = nullptr;
3183     sharedTransitionModifier_->translateXY = nullptr;
3184 }
3185 
3186 void RosenRenderContext::ResetPageTransitionEffect()
3187 {
3188     UpdateTransformScale(VectorF(1.0f, 1.0f));
3189     UpdateTransformTranslate({ 0.0f, 0.0f, 0.0f });
3190     UpdateOpacity(1.0);
3191 }
3192 
3193 void RosenRenderContext::AddChild(const RefPtr<RenderContext>& renderContext, int index)
3194 {
3195     CHECK_NULL_VOID(rsNode_);
3196     auto rosenRenderContext = AceType::DynamicCast<RosenRenderContext>(renderContext);
3197     CHECK_NULL_VOID(rosenRenderContext);
3198     auto child = rosenRenderContext->GetRSNode();
3199     rsNode_->AddChild(child, index);
3200 }
3201 
3202 void RosenRenderContext::RemoveChild(const RefPtr<RenderContext>& renderContext)
3203 {
3204     CHECK_NULL_VOID(rsNode_);
3205     auto rosenRenderContext = AceType::DynamicCast<RosenRenderContext>(renderContext);
3206     CHECK_NULL_VOID(rosenRenderContext);
3207     auto child = rosenRenderContext->GetRSNode();
3208     rsNode_->RemoveChild(child);
3209 }
3210 
3211 void RosenRenderContext::ClearChildren()
3212 {
3213     CHECK_NULL_VOID(rsNode_);
3214     rsNode_->ClearChildren();
3215 }
3216 
3217 void RosenRenderContext::SetBounds(float positionX, float positionY, float width, float height)
3218 {
3219     CHECK_NULL_VOID(rsNode_);
3220     rsNode_->SetBounds(positionX, positionY, width, height);
3221 }
3222 
3223 void RosenRenderContext::SetUsingContentRectForRenderFrame(bool value)
3224 {
3225     useContentRectForRSFrame_ = value;
3226 }
3227 
3228 void RosenRenderContext::SetFrameGravity(OHOS::Rosen::Gravity gravity)
3229 {
3230     CHECK_NULL_VOID(rsNode_);
3231     rsNode_->SetFrameGravity(gravity);
3232 }
3233 
3234 void RosenRenderContext::ClearDrawCommands()
3235 {
3236     StartRecording();
3237     StopRecordingIfNeeded();
3238 }
3239 
3240 void RosenRenderContext::SetRSNode(const std::shared_ptr<RSNode>& externalNode)
3241 {
3242     // Update rsNode_ to externalNode.
3243     if (externalNode == rsNode_) {
3244         return;
3245     }
3246     rsNode_ = externalNode;
3247 
3248     // TODO: need move property to new rs node.
3249     ResetTransform();
3250     ResetTransformMatrix();
3251 
3252     // after update, tell parent to update RSNode hierarchy.
3253     auto uiNode = GetHost();
3254     CHECK_NULL_VOID(uiNode);
3255     auto parentUINode = uiNode->GetParent();
3256     CHECK_NULL_VOID(parentUINode);
3257     parentUINode->MarkNeedSyncRenderTree();
3258     parentUINode->RebuildRenderContextTree();
3259 }
3260 
3261 void RosenRenderContext::OnMouseSelectUpdate(bool isSelected, const Color& fillColor, const Color& strokeColor)
3262 {
3263     auto host = GetHost();
3264     CHECK_NULL_VOID(host);
3265 
3266     RectF rect = RectF();
3267     if (isSelected) {
3268         auto geometryNode = host->GetGeometryNode();
3269         CHECK_NULL_VOID(geometryNode);
3270         rect = geometryNode->GetFrameRect();
3271         rect.SetOffset(OffsetF());
3272     }
3273 
3274     UpdateMouseSelectWithRect(rect, fillColor, strokeColor);
3275 }
3276 
3277 void RosenRenderContext::UpdateMouseSelectWithRect(const RectF& rect, const Color& fillColor, const Color& strokeColor)
3278 {
3279     if (!rect.IsValid()) {
3280         LOGE("UpdateMouseSelectWithRect: selected rect not valid");
3281         return;
3282     }
3283     PaintMouseSelectRect(rect, fillColor, strokeColor);
3284     RequestNextFrame();
3285 }
3286 
3287 void RosenRenderContext::PaintMouseSelectRect(const RectF& rect, const Color& fillColor, const Color& strokeColor)
3288 {
3289     if (mouseSelectModifier_) {
3290         mouseSelectModifier_->SetSelectRect(rect);
3291         return;
3292     }
3293 
3294     auto paintTask = [&fillColor, &strokeColor](const RectF& rect, RSCanvas& rsCanvas) mutable {
3295         RSBrush brush;
3296         brush.SetColor(ToRSColor(fillColor));
3297         rsCanvas.AttachBrush(brush);
3298         rsCanvas.DrawRect(ToRSRect(rect));
3299         rsCanvas.DetachBrush();
3300         RSPen pen;
3301         pen.SetColor(ToRSColor(strokeColor));
3302         rsCanvas.AttachPen(pen);
3303         rsCanvas.DrawRect(ToRSRect(rect));
3304     };
3305 
3306     mouseSelectModifier_ = std::make_shared<MouseSelectModifier>();
3307     mouseSelectModifier_->SetPaintTask(std::move(paintTask));
3308     rsNode_->AddModifier(mouseSelectModifier_);
3309 }
3310 
3311 void RosenRenderContext::DumpInfo() const
3312 {
3313     if (rsNode_) {
3314         DumpLog::GetInstance().AddDesc(rsNode_->DumpNode(0));
3315     }
3316 }
3317 
3318 void RosenRenderContext::MarkContentChanged(bool isChanged)
3319 {
3320     CHECK_NULL_VOID(rsNode_);
3321     rsNode_->MarkContentChanged(isChanged);
3322 }
3323 
3324 void RosenRenderContext::MarkDrivenRender(bool flag)
3325 {
3326     CHECK_NULL_VOID(rsNode_);
3327     rsNode_->MarkDrivenRender(flag);
3328 }
3329 
3330 void RosenRenderContext::MarkDrivenRenderItemIndex(int32_t index)
3331 {
3332     CHECK_NULL_VOID(rsNode_);
3333     rsNode_->MarkDrivenRenderItemIndex(index);
3334 }
3335 
3336 void RosenRenderContext::MarkDrivenRenderFramePaintState(bool flag)
3337 {
3338     CHECK_NULL_VOID(rsNode_);
3339     rsNode_->MarkDrivenRenderFramePaintState(flag);
3340 }
3341 
3342 void RosenRenderContext::UpdateChainedTransition(const RefPtr<NG::ChainedTransitionEffect>& effect)
3343 {
3344     if (transitionEffect_) {
3345         // use effect to update rosenTransitionEffect activeValue
3346         if (RosenTransitionEffect::UpdateRosenTransitionEffect(transitionEffect_, effect)) {
3347             return;
3348         }
3349         LOGD("transition effect struct changed");
3350         transitionEffect_->Detach(this);
3351     }
3352     transitionEffect_ = RosenTransitionEffect::ConvertToRosenTransitionEffect(effect);
3353     hasDefaultTransition_ = false;
3354     CHECK_NULL_VOID(transitionEffect_);
3355     auto frameNode = GetHost();
3356     CHECK_NULL_VOID(frameNode);
3357     bool isOnTheTree = frameNode->IsOnMainTree();
3358     // transition effects should be initialized without animation.
3359     RSNode::ExecuteWithoutAnimation([this, isOnTheTree, &frameNode]() {
3360         // transitionIn effects should be initialized as active if currently not on the tree.
3361         transitionEffect_->Attach(Claim(this), !isOnTheTree);
3362     });
3363 }
3364 
3365 void RosenRenderContext::NotifyTransition(bool isTransitionIn)
3366 {
3367     CHECK_NULL_VOID_NOLOG(transitionEffect_);
3368 
3369     auto frameNode = GetHost();
3370     CHECK_NULL_VOID(frameNode);
3371     LOGD("RosenTransitionEffect::NotifyTransition transition BEGIN, node %{public}d, isTransitionIn: %{public}d",
3372         frameNode->GetId(), isTransitionIn);
3373 
3374     RSNode::ExecuteWithoutAnimation([this, &frameNode, isTransitionIn]() {
3375         if (isTransitionIn && disappearingTransitionCount_ == 0) {
3376             // transitionIn, reset to state before attaching in case of node reappear
3377             transitionEffect_->Attach(Claim(this), true);
3378         }
3379         auto pipeline = PipelineBase::GetCurrentContext();
3380         CHECK_NULL_VOID(pipeline);
3381         SizeF rootSize(pipeline->GetRootWidth(), pipeline->GetRootHeight());
3382         auto parentOffset = frameNode->GetPaintRectOffset(true);
3383         auto rect = GetPaintRectWithoutTransform();
3384         // Do not consider the position after its own transform, as the transition modifier also affects the transform
3385         rect.SetOffset(parentOffset + rect.GetOffset());
3386 
3387         transitionEffect_->UpdateTransitionContext(Claim(this), rect, rootSize);
3388     });
3389 
3390     if (isTransitionIn) {
3391         // Isolate the animation callback function, to avoid changing the callback timing of current implicit animation.
3392         AnimationUtils::AnimateWithCurrentOptions(
3393             [this]() {
3394                 transitionEffect_->Appear();
3395                 ++appearingTransitionCount_;
3396             },
3397             [weakThis = WeakClaim(this), nodeId = frameNode->GetId(), id = Container::CurrentId()]() {
3398                 auto context = weakThis.Upgrade();
3399                 CHECK_NULL_VOID(context);
3400                 ContainerScope scope(id);
3401                 LOGD("RosenTransitionEffect::NotifyTransition transition END, node %{public}d, isTransitionIn: IN",
3402                     nodeId);
3403                 context->OnTransitionInFinish();
3404             },
3405             false);
3406     } else {
3407         // Re-use current implicit animation timing params, only replace the finish callback function.
3408         // The finish callback function will perform all the necessary cleanup work.
3409         // Important Note on timing:
3410         // 1. If any transition animations are created, the finish callback function will only be called when ALL
3411         //    animations have finished. This is accomplished by sharing the same shared_ptr<AnimationFinishCallback>
3412         //    among all animations.
3413         // 2. If no transition animations are created, the finish callback function will be called IMMEDIATELY. This
3414         //    is accomplished by setting the last param (timing sensitive) to false, which avoids creating an empty
3415         //    'timer' animation.
3416         AnimationUtils::AnimateWithCurrentOptions(
3417             [this]() {
3418                 transitionEffect_->Disappear();
3419                 // update transition out count
3420                 ++disappearingTransitionCount_;
3421             },
3422             [weakThis = WeakClaim(this), nodeId = frameNode->GetId(), id = Container::CurrentId()]() {
3423                 auto context = weakThis.Upgrade();
3424                 CHECK_NULL_VOID(context);
3425                 ContainerScope scope(id);
3426                 auto pipeline = PipelineBase::GetCurrentContext();
3427                 CHECK_NULL_VOID(pipeline);
3428                 auto taskExecutor = pipeline->GetTaskExecutor();
3429                 CHECK_NULL_VOID(taskExecutor);
3430                 taskExecutor->PostTask(
3431                     [id, nodeId, context]() {
3432                         ContainerScope scope(id);
3433                         LOGD("RosenTransitionEffect::NotifyTransition transition END, node %{public}d, "
3434                              "isTransitionIn: OUT",
3435                             nodeId);
3436                         // update transition out count
3437                         context->OnTransitionOutFinish();
3438                     },
3439                     TaskExecutor::TaskType::UI);
3440             },
3441             false);
3442     }
3443 }
3444 
3445 void RosenRenderContext::RemoveDefaultTransition()
3446 {
3447     if (hasDefaultTransition_ && transitionEffect_ && disappearingTransitionCount_ == 0 &&
3448         appearingTransitionCount_ == 0) {
3449         transitionEffect_->Detach(this);
3450         transitionEffect_ = nullptr;
3451         hasDefaultTransition_ = false;
3452     }
3453 }
3454 
3455 void RosenRenderContext::OnTransitionInFinish()
3456 {
3457     --appearingTransitionCount_;
3458     // make sure we are the last transition out animation, if not, return.
3459     if (appearingTransitionCount_ > 0) {
3460         LOGD("RosenTransitionEffect: appearingTransitionCount_ is %{public}d, not the last transition out animation",
3461             appearingTransitionCount_);
3462         return;
3463     }
3464     if (appearingTransitionCount_ < 0) {
3465         LOGW("RosenTransitionEffect: appearingTransitionCount_ should not be less than 0");
3466         appearingTransitionCount_ = 0;
3467     }
3468     // when all transition in/out animations are finished, we should remove the default transition effect.
3469     RemoveDefaultTransition();
3470 }
3471 
3472 void RosenRenderContext::OnTransitionOutFinish()
3473 {
3474     // update transition out count
3475     --disappearingTransitionCount_;
3476     // make sure we are the last transition out animation, if not, return.
3477     if (disappearingTransitionCount_ > 0) {
3478         LOGD("RosenTransitionEffect: disappearingTransitionCount_ is %{public}d, not the last transition out animation",
3479             disappearingTransitionCount_);
3480         return;
3481     }
3482     if (disappearingTransitionCount_ < 0) {
3483         LOGW("RosenTransitionEffect: disappearingTransitionCount_ should not be less than 0");
3484         disappearingTransitionCount_ = 0;
3485     }
3486     // when all transition in/out animations are finished, we should remove the default transition effect.
3487     RemoveDefaultTransition();
3488     auto host = GetHost();
3489     CHECK_NULL_VOID(host);
3490     auto parent = host->GetParent();
3491     CHECK_NULL_VOID(parent);
3492     if (!host->IsVisible()) {
3493         // trigger transition through visibility
3494         parent->MarkNeedSyncRenderTree();
3495         parent->RebuildRenderContextTree();
3496         return;
3497     }
3498     RefPtr<UINode> breakPointChild = host;
3499     RefPtr<UINode> breakPointParent = breakPointChild->GetParent();
3500     while (breakPointParent && !breakPointChild->IsDisappearing()) {
3501         // recursively looking up the node tree, until we reach the breaking point (IsDisappearing() == true).
3502         // Because when trigger transition, only the breakPoint will be marked as disappearing and
3503         // moved to disappearingChildren.
3504         breakPointChild = breakPointParent;
3505         breakPointParent = breakPointParent->GetParent();
3506     }
3507     // if can not find the breakPoint, means the node is not disappearing (reappear?), return.
3508     if (!breakPointParent) {
3509         LOGI("RosenTransitionEffect: node is not disappearing, skip, id: %{public}d", host->GetId());
3510         return;
3511     }
3512     if (breakPointChild->RemoveImmediately()) {
3513         LOGD("RosenTransitionEffect: transition out finish, node %{public}d, break point %{public}d, break point tag: "
3514              "%{public}s",
3515             host->GetId(), breakPointChild->GetId(), breakPointChild->GetTag().c_str());
3516         breakPointChild->OnRemoveFromParent(false);
3517         // remove breakPoint
3518         breakPointParent->RemoveDisappearingChild(breakPointChild);
3519         breakPointParent->MarkNeedSyncRenderTree();
3520         breakPointParent->RebuildRenderContextTree();
3521     } else {
3522         LOGD("RosenTransitionEffect: transition out finish, node %{public}d, node tag: %{public}s", host->GetId(),
3523             host->GetTag().c_str());
3524         // When host's transition is done, RemoveImmediately must return true, so this branch means
3525         // host is different from breakPointChild. It will be removed when breakPoint is removed.
3526     }
3527     if (isModalRootNode_ && breakPointParent->GetChildren().empty()) {
3528         auto grandParent = breakPointParent->GetParent();
3529         CHECK_NULL_VOID(grandParent);
3530         grandParent->RemoveChild(breakPointParent);
3531         grandParent->RebuildRenderContextTree();
3532     }
3533 }
3534 
3535 void RosenRenderContext::SetActualForegroundColor(const Color& value)
3536 {
3537     CHECK_NULL_VOID(rsNode_);
3538     rsNode_->SetForegroundColor(value.GetValue());
3539     RequestNextFrame();
3540 }
3541 
3542 void RosenRenderContext::AttachNodeAnimatableProperty(RefPtr<NodeAnimatablePropertyBase> property)
3543 {
3544     CHECK_NULL_VOID(rsNode_);
3545     CHECK_NULL_VOID(property);
3546     if (!property->GetModifyImpl()) {
3547         auto nodeModifierImpl = std::make_shared<RSNodeModifierImpl>();
3548         CHECK_NULL_VOID(nodeModifierImpl);
3549         property->SetModifyImpl(nodeModifierImpl);
3550         rsNode_->AddModifier(nodeModifierImpl);
3551         nodeModifierImpl->AddProperty(property->GetProperty());
3552     }
3553 }
3554 
3555 void RosenRenderContext::InitEventClickEffect()
3556 {
3557     if (touchListener_) {
3558         return;
3559     }
3560     auto host = GetHost();
3561     CHECK_NULL_VOID(host);
3562     auto gesture = host->GetOrCreateGestureEventHub();
3563     CHECK_NULL_VOID(gesture);
3564     auto touchCallback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
3565         auto renderContext = weak.Upgrade();
3566         CHECK_NULL_VOID(renderContext);
3567         renderContext->ClickEffectPlayAnimation(info.GetTouches().front().GetTouchType());
3568     };
3569     touchListener_ = MakeRefPtr<TouchEventImpl>(std::move(touchCallback));
3570     gesture->AddTouchEvent(touchListener_);
3571 }
3572 
3573 void RosenRenderContext::ClickEffectPlayAnimation(const TouchType& touchType)
3574 {
3575     if (touchType != TouchType::DOWN && touchType != TouchType::UP && touchType != TouchType::CANCEL) {
3576         return;
3577     }
3578     auto value = GetClickEffectLevelValue();
3579     auto level = value.level;
3580     auto scaleValue = value.scaleNumber;
3581     auto springCurve = UpdatePlayAnimationValue(level, scaleValue);
3582 
3583     AnimationOption option;
3584     option.SetCurve(springCurve);
3585     option.SetDuration(DEFAULT_OPTION_DURATION);
3586 
3587     if (touchType == TouchType::DOWN && level != ClickEffectLevel::UNDEFINED) {
3588         if (isTouchUpFinished_) {
3589             auto defaultScale = VectorF(1.0f, 1.0f);
3590             auto currentScale = GetTransformScaleValue(defaultScale);
3591             currentScale_ = currentScale;
3592             UpdateTransformScale(currentScale_);
3593 
3594             AnimationUtils::OpenImplicitAnimation(option, springCurve, nullptr);
3595             VectorF valueScale(scaleValue, scaleValue);
3596             UpdateTransformScale(valueScale);
3597             AnimationUtils::CloseImplicitAnimation();
3598         }
3599         isTouchUpFinished_ = false;
3600     }
3601 
3602     if ((touchType == TouchType::UP || touchType == TouchType::CANCEL) && level != ClickEffectLevel::UNDEFINED) {
3603         AnimationUtils::OpenImplicitAnimation(option, springCurve, nullptr);
3604         UpdateTransformScale(currentScale_);
3605         AnimationUtils::CloseImplicitAnimation();
3606         isTouchUpFinished_ = true;
3607     }
3608 }
3609 
3610 RefPtr<Curve> RosenRenderContext::UpdatePlayAnimationValue(const ClickEffectLevel& level, float& scaleValue)
3611 {
3612     float velocity = 0.0f;
3613     float mass = 0.0f;
3614     float stiffness = 0.0f;
3615     float damping = 0.0f;
3616     if (level == ClickEffectLevel::LIGHT) {
3617         velocity = ANIMATION_CURVE_VELOCITY_LIGHT_OR_MIDDLE;
3618         mass = ANIMATION_CURVE_MASS;
3619         stiffness = ANIMATION_CURVE_STIFFNESS_LIGHT;
3620         damping = ANIMATION_CURVE_DAMPING_LIGHT;
3621         if (GreatOrEqual(scaleValue, 0.0) && LessOrEqual(scaleValue, 1.0)) {
3622             scaleValue = sqrt(scaleValue);
3623         } else {
3624             scaleValue = sqrt(DEFAULT_SCALE_LIGHT);
3625         }
3626     } else if (level == ClickEffectLevel::MIDDLE) {
3627         velocity = ANIMATION_CURVE_VELOCITY_LIGHT_OR_MIDDLE;
3628         mass = ANIMATION_CURVE_MASS;
3629         stiffness = ANIMATION_CURVE_STIFFNESS_MIDDLE;
3630         damping = ANIMATION_CURVE_DAMPING_MIDDLE;
3631         if (GreatOrEqual(scaleValue, 0.0) && LessOrEqual(scaleValue, 1.0)) {
3632             scaleValue = sqrt(scaleValue);
3633         } else {
3634             scaleValue = sqrt(DEFAULT_SCALE_MIDDLE_OR_HEAVY);
3635         }
3636     } else if (level == ClickEffectLevel::HEAVY) {
3637         velocity = ANIMATION_CURVE_VELOCITY_HEAVY;
3638         mass = ANIMATION_CURVE_MASS;
3639         stiffness = ANIMATION_CURVE_STIFFNESS_HEAVY;
3640         damping = ANIMATION_CURVE_DAMPING_HEAVY;
3641         if (GreatOrEqual(scaleValue, 0.0) && LessOrEqual(scaleValue, 1.0)) {
3642             scaleValue = sqrt(scaleValue);
3643         } else {
3644             scaleValue = sqrt(DEFAULT_SCALE_MIDDLE_OR_HEAVY);
3645         }
3646     }
3647     return AceType::MakeRefPtr<InterpolatingSpring>(velocity, mass, stiffness, damping);
3648 }
3649 
3650 void RosenRenderContext::RegisterSharedTransition(const RefPtr<RenderContext>& other)
3651 {
3652     auto otherContext = AceType::DynamicCast<RosenRenderContext>(other);
3653     if (!otherContext) {
3654         LOGE("RosenRenderContext::RegisterSharedTransition: other is not RosenRenderContext");
3655         return;
3656     }
3657     RSNode::RegisterTransitionPair(rsNode_->GetId(), otherContext->rsNode_->GetId());
3658 }
3659 
3660 void RosenRenderContext::UnregisterSharedTransition(const RefPtr<RenderContext>& other)
3661 {
3662     auto otherContext = AceType::DynamicCast<RosenRenderContext>(other);
3663     if (!otherContext) {
3664         // the paired node is already destroyed, we don't need to unregister it, Rosen will handle it.
3665         return;
3666     }
3667     RSNode::UnregisterTransitionPair(rsNode_->GetId(), otherContext->rsNode_->GetId());
3668 }
3669 
3670 inline void RosenRenderContext::ConvertRadius(const BorderRadiusProperty& value, Rosen::Vector4f& cornerRadius)
3671 {
3672     cornerRadius.SetValues(static_cast<float>(value.radiusTopLeft.value_or(Dimension()).ConvertToPx()),
3673         static_cast<float>(value.radiusTopRight.value_or(Dimension()).ConvertToPx()),
3674         static_cast<float>(value.radiusBottomRight.value_or(Dimension()).ConvertToPx()),
3675         static_cast<float>(value.radiusBottomLeft.value_or(Dimension()).ConvertToPx()));
3676 }
3677 
3678 #ifndef USE_ROSEN_DRAWING
3679 void RosenRenderContext::PaintSkBgImage()
3680 {
3681     auto image = DynamicCast<NG::SkiaImage>(bgImage_);
3682 #else
3683 void RosenRenderContext::PaintRSBgImage()
3684 {
3685     auto image = DynamicCast<NG::DrawingImage>(bgImage_);
3686 #endif
3687     CHECK_NULL_VOID(bgLoadingCtx_ && image);
3688 
3689     auto rosenImage = std::make_shared<Rosen::RSImage>();
3690     auto compressData = image->GetCompressData();
3691     if (compressData) {
3692         rosenImage->SetCompressData(
3693             compressData, image->GetUniqueID(), image->GetCompressWidth(), image->GetCompressHeight());
3694     } else {
3695         rosenImage->SetImage(image->GetImage());
3696     }
3697     rosenImage->SetImageRepeat(static_cast<int>(GetBackgroundImageRepeat().value_or(ImageRepeat::NO_REPEAT)));
3698     rsNode_->SetBgImage(rosenImage);
3699 }
3700 
3701 void RosenRenderContext::PaintPixmapBgImage()
3702 {
3703     auto image = DynamicCast<NG::PixelMapImage>(bgImage_);
3704     CHECK_NULL_VOID(bgLoadingCtx_ && image);
3705     auto pixmap = image->GetPixelMap();
3706     CHECK_NULL_VOID(pixmap);
3707 
3708     auto rosenImage = std::make_shared<Rosen::RSImage>();
3709     rosenImage->SetPixelMap(pixmap->GetPixelMapSharedPtr());
3710     rosenImage->SetImageRepeat(static_cast<int>(GetBackgroundImageRepeat().value_or(ImageRepeat::NO_REPEAT)));
3711     rsNode_->SetBgImage(rosenImage);
3712 }
3713 
3714 void RosenRenderContext::OnRenderGroupUpdate(bool isRenderGroup)
3715 {
3716     CHECK_NULL_VOID(rsNode_);
3717     rsNode_->MarkNodeGroup(isRenderGroup);
3718 }
3719 
3720 void RosenRenderContext::OnRenderFitUpdate(RenderFit renderFit)
3721 {
3722     CHECK_NULL_VOID(rsNode_);
3723     rsNode_->SetFrameGravity(GetRosenGravity(renderFit));
3724 }
3725 
3726 void RosenRenderContext::SetContentRectToFrame(RectF rect)
3727 {
3728     auto host = GetHost();
3729     CHECK_NULL_VOID(host);
3730     auto&& padding = host->GetGeometryNode()->GetPadding();
3731     // minus padding to get contentRect
3732     if (padding) {
3733         rect.SetOffset(rect.GetOffset() + OffsetF { padding->left.value_or(0), padding->top.value_or(0) });
3734         auto size = rect.GetSize();
3735         MinusPaddingToSize(*padding, size);
3736         rect.SetSize(size);
3737     }
3738     rsNode_->SetFrame(rect.GetX(), rect.GetY(), rect.Width(), rect.Height());
3739 }
3740 
3741 } // namespace OHOS::Ace::NG
3742