• 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 "include/utils/SkParsePath.h"
19 #include "modifier/rs_property.h"
20 #include "render_service_base/include/property/rs_properties_def.h"
21 #include "render_service_base/include/render/rs_mask.h"
22 #include "render_service_client/core/modifier/rs_property_modifier.h"
23 #include "render_service_client/core/pipeline/rs_node_map.h"
24 #include "render_service_client/core/transaction/rs_interfaces.h"
25 #include "render_service_client/core/ui/rs_canvas_drawing_node.h"
26 #include "render_service_client/core/ui/rs_canvas_node.h"
27 #include "render_service_client/core/ui/rs_effect_node.h"
28 #include "render_service_client/core/ui/rs_root_node.h"
29 #include "render_service_client/core/ui/rs_node.h"
30 #include "render_service_client/core/ui/rs_surface_node.h"
31 #include "rosen_render_context.h"
32 #include "base/geometry/calc_dimension.h"
33 #include "base/geometry/dimension.h"
34 #include "base/geometry/matrix4.h"
35 #include "base/log/dump_log.h"
36 #include "core/animation/native_curve_helper.h"
37 #include "core/components/theme/app_theme.h"
38 #include "core/components/theme/blur_style_theme.h"
39 #include "core/components_ng/pattern/particle/particle_pattern.h"
40 #include "core/components_ng/pattern/stage/page_pattern.h"
41 #include "core/components_ng/render/adapter/background_modifier.h"
42 #include "core/components_ng/render/adapter/border_image_modifier.h"
43 #include "core/components_ng/render/adapter/component_snapshot.h"
44 #include "core/components_ng/render/adapter/debug_boundary_modifier.h"
45 #include "core/components_ng/render/adapter/focus_state_modifier.h"
46 #include "core/components_ng/render/adapter/gradient_style_modifier.h"
47 #include "core/components_ng/render/adapter/mouse_select_modifier.h"
48 #include "core/components_ng/render/adapter/overlay_modifier.h"
49 #include "core/components_ng/render/adapter/pixelmap_image.h"
50 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
51 #include "render_service_client/core/pipeline/rs_render_thread.h"
52 #endif
53 #ifndef USE_ROSEN_DRAWING
54 #include "core/components_ng/render/adapter/skia_decoration_painter.h"
55 #include "core/components_ng/render/adapter/skia_image.h"
56 #else
57 #include "core/components_ng/render/adapter/rosen/drawing_decoration_painter.h"
58 #include "core/components_ng/render/adapter/rosen/drawing_image.h"
59 #endif
60 #include "core/components_ng/pattern/checkbox/checkbox_paint_property.h"
61 #include "core/components_ng/render/border_image_painter.h"
62 #include "core/components_ng/render/debug_boundary_painter.h"
63 #include "core/components_ng/render/image_painter.h"
64 
65 namespace OHOS::Ace::NG {
66 
67 using namespace OHOS::Rosen;
68 namespace {
69 RefPtr<PixelMap> g_pixelMap {};
70 std::mutex g_mutex;
71 std::condition_variable thumbnailGet;
72 constexpr std::chrono::duration<int, std::milli> PIXELMAP_TIMEOUT_DURATION(1000);
73 constexpr float ANIMATION_CURVE_VELOCITY_LIGHT_OR_MIDDLE = 10.0f;
74 constexpr float ANIMATION_CURVE_VELOCITY_HEAVY = 0.0f;
75 constexpr float ANIMATION_CURVE_MASS = 1.0f;
76 constexpr float ANIMATION_CURVE_STIFFNESS_LIGHT = 410.0f;
77 constexpr float ANIMATION_CURVE_STIFFNESS_MIDDLE = 350.0f;
78 constexpr float ANIMATION_CURVE_STIFFNESS_HEAVY = 240.0f;
79 constexpr float ANIMATION_CURVE_DAMPING_LIGHT = 38.0f;
80 constexpr float ANIMATION_CURVE_DAMPING_MIDDLE = 35.0f;
81 constexpr float ANIMATION_CURVE_DAMPING_HEAVY = 28.0f;
82 constexpr float DEFAULT_SCALE_LIGHT = 0.9f;
83 constexpr float DEFAULT_SCALE_MIDDLE_OR_HEAVY = 0.95f;
84 constexpr int32_t DEFAULT_OPTION_DURATION = 100;
85 constexpr int32_t PLATFORM_VERSION_TEN = 10;
86 constexpr int32_t PARTICLE_DEFAULT_COLOR = 0xFFFFFFFF;
87 constexpr float PARTICLE_DEFAULT_OPACITY = 1.0f;
88 constexpr float PARTICLE_DEFAULT_SCALE = 1.0f;
89 constexpr float PARTICLE_DEFAULT_SPEED = 0.0f;
90 constexpr float PARTICLE_DEFAULT_ANGLE = 0.0f;
91 constexpr float PARTICLE_DEFAULT_SPIN = 0.0f;
92 constexpr int64_t PARTICLE_DEFAULT_LIFETIME = 1000;
93 constexpr int32_t PARTICLE_DEFAULT_EMITTER_RATE = 5;
94 constexpr double HALF = 0.5;
95 constexpr double PARENT_PAGE_OFFSET = 0.2;
96 constexpr int32_t MASK_DURATION = 350;
97 constexpr int32_t DEFAULT_ANIMATION_DURATION = 450;
98 constexpr float REMOVE_CLIP_SIZE = 10000.0f;
99 constexpr uint32_t DRAW_REGION_CONTENT_MODIFIER_INDEX = 0;
100 constexpr uint32_t DRAW_REGION_OVERLAY_MODIFIER_INDEX = 1;
101 constexpr uint32_t DRAW_REGION_FOCUS_MODIFIER_INDEX = 2;
102 constexpr uint32_t DRAW_REGION_ACCESSIBILITY_FOCUS_MODIFIER_INDEX = 3;
103 constexpr uint32_t DRAW_REGION_OVERLAY_TEXT_MODIFIER_INDEX = 4;
104 constexpr uint32_t DRAW_REGION_DEBUG_BOUNDARY_MODIFIER_INDEX = 5;
105 constexpr uint32_t DRAW_REGION_FOREGROUND_MODIFIER_INDEX = 6;
106 constexpr int32_t RIGHT_ANGLE = 90;
107 constexpr int32_t STRAIGHT_ANGLE = 180;
108 constexpr int32_t REFLEX_ANGLE = 270;
109 constexpr int32_t FULL_ROTATION = 360;
110 constexpr int32_t ACCESSIBILITY_FOCUS_WITHOUT_EVENT = -2100001;
111 const Color MASK_COLOR = Color::FromARGB(25, 0, 0, 0);
112 const Color DEFAULT_MASK_COLOR = Color::FromARGB(0, 0, 0, 0);
113 constexpr Dimension DASH_GEP_WIDTH = -1.0_px;
114 
GetRosenGravity(RenderFit renderFit)115 Rosen::Gravity GetRosenGravity(RenderFit renderFit)
116 {
117     static const LinearEnumMapNode<RenderFit, Rosen::Gravity> gravityMap[] = {
118         { RenderFit::CENTER, Rosen::Gravity::CENTER },
119         { RenderFit::TOP, Rosen::Gravity::TOP },
120         { RenderFit::BOTTOM, Rosen::Gravity::BOTTOM },
121         { RenderFit::LEFT, Rosen::Gravity::LEFT },
122         { RenderFit::RIGHT, Rosen::Gravity::RIGHT },
123         { RenderFit::TOP_LEFT, Rosen::Gravity::TOP_LEFT },
124         { RenderFit::TOP_RIGHT, Rosen::Gravity::TOP_RIGHT },
125         { RenderFit::BOTTOM_LEFT, Rosen::Gravity::BOTTOM_LEFT },
126         { RenderFit::BOTTOM_RIGHT, Rosen::Gravity::BOTTOM_RIGHT },
127         { RenderFit::RESIZE_FILL, Rosen::Gravity::RESIZE },
128         { RenderFit::RESIZE_CONTAIN, Rosen::Gravity::RESIZE_ASPECT },
129         { RenderFit::RESIZE_CONTAIN_TOP_LEFT, Rosen::Gravity::RESIZE_ASPECT_TOP_LEFT },
130         { RenderFit::RESIZE_CONTAIN_BOTTOM_RIGHT, Rosen::Gravity::RESIZE_ASPECT_BOTTOM_RIGHT },
131         { RenderFit::RESIZE_COVER, Rosen::Gravity::RESIZE_ASPECT_FILL },
132         { RenderFit::RESIZE_COVER_TOP_LEFT, Rosen::Gravity::RESIZE_ASPECT_FILL_TOP_LEFT },
133         { RenderFit::RESIZE_COVER_BOTTOM_RIGHT, Rosen::Gravity::RESIZE_ASPECT_FILL_BOTTOM_RIGHT },
134     };
135     int64_t idx = BinarySearchFindIndex(gravityMap, ArraySize(gravityMap), renderFit);
136     return idx != -1 ? gravityMap[idx].value : Rosen::Gravity::DEFAULT;
137 }
138 
GetResourceColorMode(PipelineContext * pipeline)139 ColorMode GetResourceColorMode(PipelineContext* pipeline)
140 {
141     auto themeManager = pipeline->GetThemeManager();
142     CHECK_NULL_RETURN(themeManager, ColorMode::LIGHT);
143     auto themeConstants = themeManager->GetThemeConstants();
144     CHECK_NULL_RETURN(themeConstants, ColorMode::LIGHT);
145     auto resourceAdapter = themeConstants->GetResourceAdapter();
146     CHECK_NULL_RETURN(resourceAdapter, ColorMode::LIGHT);
147     return resourceAdapter->GetResourceColorMode();
148 }
149 
CreateRSMaterialFilter(const BlurStyleOption & blurStyleOption,PipelineContext * pipeline)150 std::shared_ptr<Rosen::RSFilter> CreateRSMaterialFilter(
151     const BlurStyleOption& blurStyleOption, PipelineContext* pipeline)
152 {
153     auto blurStyleTheme = pipeline->GetTheme<BlurStyleTheme>();
154     if (!blurStyleTheme) {
155         LOGW("cannot find theme of blurStyle, create blurStyle failed");
156         return nullptr;
157     }
158     ThemeColorMode colorMode = blurStyleOption.colorMode;
159     if (blurStyleOption.colorMode == ThemeColorMode::SYSTEM) {
160         colorMode = GetResourceColorMode(pipeline) == ColorMode::DARK ? ThemeColorMode::DARK : ThemeColorMode::LIGHT;
161     }
162     auto blurParam = blurStyleTheme->GetBlurParameter(blurStyleOption.blurStyle, colorMode);
163     CHECK_NULL_RETURN(blurParam, nullptr);
164     auto ratio = blurStyleOption.scale;
165     auto maskColor = blurParam->maskColor.BlendOpacity(ratio);
166     auto radiusPx = blurParam->radius * pipeline->GetDipScale();
167 #ifndef USE_ROSEN_DRAWING
168     auto radiusBlur = SkiaDecorationPainter::ConvertRadiusToSigma(radiusPx) * ratio;
169 #else
170     auto radiusBlur = DrawingDecorationPainter::ConvertRadiusToSigma(radiusPx) * ratio;
171 #endif
172     auto saturation = (blurParam->saturation - 1) * ratio + 1.0;
173     auto brightness = (blurParam->brightness - 1) * ratio + 1.0;
174     return Rosen::RSFilter::CreateMaterialFilter(radiusBlur, saturation, brightness, maskColor.GetValue(),
175         static_cast<Rosen::BLUR_COLOR_MODE>(blurStyleOption.adaptiveColor));
176 }
177 
GetRsPen(uint32_t strokeColor,float strokeWidth)178 RSPen GetRsPen(uint32_t strokeColor, float strokeWidth)
179 {
180     RSColor rsStrokeColor;
181     rsStrokeColor.SetColorQuad(strokeColor);
182 
183     RSPen pen;
184     pen.SetColor(rsStrokeColor);
185     pen.SetWidth(strokeWidth);
186 
187     return pen;
188 }
189 
GetRsBrush(uint32_t fillColor)190 RSBrush GetRsBrush(uint32_t fillColor)
191 {
192     RSColor color;
193     color.SetColorQuad(fillColor);
194     RSBrush brush(color);
195 
196     return brush;
197 }
198 
199 template<typename ModifierName, typename T>
GetAnimatablePropertyStagingValue(std::shared_ptr<ModifierName> & modifier)200 T GetAnimatablePropertyStagingValue(std::shared_ptr<ModifierName>& modifier)
201 {
202     CHECK_NULL_RETURN(modifier, {});
203     auto property = std::static_pointer_cast<Rosen::RSAnimatableProperty<T>>(modifier->GetProperty());
204     CHECK_NULL_RETURN(property, {});
205     return property->GetStagingValue();
206 }
207 
SlideTransitionEffect(const SlideEffect & effect,const RectF & rect,TranslateOptions & translate)208 void SlideTransitionEffect(const SlideEffect& effect, const RectF& rect, TranslateOptions& translate)
209 {
210     switch (effect) {
211         case SlideEffect::LEFT:
212             translate.x = Dimension(-rect.Width());
213             break;
214         case SlideEffect::RIGHT:
215             translate.x = Dimension(rect.Width());
216             break;
217         case SlideEffect::BOTTOM:
218             translate.y = Dimension(rect.Height());
219             break;
220         case SlideEffect::TOP:
221             translate.y = Dimension(-rect.Height());
222             break;
223         case SlideEffect::START:
224             if (AceApplicationInfo::GetInstance().IsRightToLeft()) {
225                 translate.x = Dimension(rect.Width());
226                 break;
227             }
228             translate.x = Dimension(-rect.Width());
229             break;
230         case SlideEffect::END:
231             if (AceApplicationInfo::GetInstance().IsRightToLeft()) {
232                 translate.x = Dimension(-rect.Width());
233                 break;
234             }
235             translate.x = Dimension(rect.Width());
236             break;
237         default:
238             break;
239     }
240 }
241 } // namespace
242 
ConvertDimensionToScaleBySize(const Dimension & dimension,float size)243 float RosenRenderContext::ConvertDimensionToScaleBySize(const Dimension& dimension, float size)
244 {
245     if (dimension.Unit() == DimensionUnit::PERCENT) {
246         return static_cast<float>(dimension.Value());
247     }
248     return size > 0.0f ? static_cast<float>(dimension.ConvertToPx() / size) : 0.5f;
249 }
250 
~RosenRenderContext()251 RosenRenderContext::~RosenRenderContext()
252 {
253     StopRecordingIfNeeded();
254     DetachModifiers();
255 }
256 
DetachModifiers()257 void RosenRenderContext::DetachModifiers()
258 {
259     auto pipeline = PipelineContext::GetCurrentContextPtrSafelyWithCheck();
260     if (pipeline && densityChangedCallbackId_ != DEFAULT_CALLBACK_ID) {
261         pipeline->UnregisterDensityChangedCallback(densityChangedCallbackId_);
262     }
263     CHECK_NULL_VOID(rsNode_ && rsNode_->GetType() == Rosen::RSUINodeType::SURFACE_NODE);
264     if (transitionEffect_) {
265         transitionEffect_->Detach(this);
266     }
267     if (translateXYUserModifier_) {
268         rsNode_->RemoveModifier(translateXYUserModifier_);
269     }
270     if (translateZUserModifier_) {
271         rsNode_->RemoveModifier(translateZUserModifier_);
272     }
273     if (scaleXYUserModifier_) {
274         rsNode_->RemoveModifier(scaleXYUserModifier_);
275     }
276     if (pipeline) {
277         pipeline->RequestFrame();
278     }
279 }
280 
StartRecording()281 void RosenRenderContext::StartRecording()
282 {
283     CHECK_NULL_VOID(rsNode_);
284     auto rsCanvasNode = rsNode_->ReinterpretCastTo<Rosen::RSCanvasNode>();
285     CHECK_NULL_VOID(rsCanvasNode);
286     rsCanvasNode->BeginRecording(ceil(rsCanvasNode->GetPaintWidth()), ceil(rsCanvasNode->GetPaintHeight()));
287 }
288 
StopRecordingIfNeeded()289 void RosenRenderContext::StopRecordingIfNeeded()
290 {
291     auto rsCanvasNode = Rosen::RSNode::ReinterpretCast<Rosen::RSCanvasNode>(rsNode_);
292     if (rsCanvasNode) {
293         rsCanvasNode->FinishRecording();
294     }
295 }
296 
OnNodeAppear(bool recursive)297 void RosenRenderContext::OnNodeAppear(bool recursive)
298 {
299     isDisappearing_ = false;
300     auto host = GetHost();
301     CHECK_NULL_VOID(host);
302     // restore eventHub state when node appears.
303     host->GetEventHub<EventHub>()->RestoreEnabled();
304     if (recursive && !propTransitionAppearing_ && !transitionEffect_) {
305         // recursive and has no transition, no need to handle transition.
306         return;
307     }
308 
309     isBreakingPoint_ = !recursive;
310     if (isSynced_) {
311         // has set size before, trigger transition directly.
312         auto rect = GetPaintRectWithoutTransform();
313         NotifyTransitionInner(rect.GetSize(), true);
314         return;
315     }
316     // pending transition in animation, will start on first layout
317     firstTransitionIn_ = true;
318 }
319 
OnNodeDisappear(bool recursive)320 void RosenRenderContext::OnNodeDisappear(bool recursive)
321 {
322     isDisappearing_ = true;
323     bool noneOrDefaultTransition = !propTransitionDisappearing_ && (!transitionEffect_ || hasDefaultTransition_);
324     if (recursive && noneOrDefaultTransition) {
325         // recursive, and has no transition or has default transition, no need to trigger transition.
326         return;
327     }
328     CHECK_NULL_VOID(rsNode_);
329     auto host = GetHost();
330     if (!recursive && host && host->GetEventHub<EventHub>()) {
331         host->GetEventHub<EventHub>()->SetEnabledInternal(false);
332     }
333     auto rect = GetPaintRectWithoutTransform();
334     // only start default transition on the break point of render node tree.
335     isBreakingPoint_ = !recursive;
336     NotifyTransitionInner(rect.GetSize(), false);
337 }
338 
SetPivot(float xPivot,float yPivot,float zPivot)339 void RosenRenderContext::SetPivot(float xPivot, float yPivot, float zPivot)
340 {
341     // change pivot without animation
342     CHECK_NULL_VOID(rsNode_);
343     auto changed = true;
344     if (pivotProperty_) {
345         changed = pivotProperty_->Get().x_ != xPivot || pivotProperty_->Get().y_ != yPivot;
346         pivotProperty_->Set({ xPivot, yPivot });
347     } else {
348         pivotProperty_ = std::make_shared<Rosen::RSProperty<Rosen::Vector2f>>(Rosen::Vector2f(xPivot, yPivot));
349         auto modifier = std::make_shared<Rosen::RSPivotModifier>(pivotProperty_);
350         rsNode_->AddModifier(modifier);
351     }
352     rsNode_->SetPivotZ(zPivot);
353     NotifyHostTransformUpdated(changed);
354 }
355 
SetTransitionPivot(const SizeF & frameSize,bool transitionIn)356 void RosenRenderContext::SetTransitionPivot(const SizeF& frameSize, bool transitionIn)
357 {
358     auto& transitionEffect = transitionIn ? propTransitionAppearing_ : propTransitionDisappearing_;
359     CHECK_NULL_VOID(transitionEffect);
360     float xPivot = 0.0f;
361     float yPivot = 0.0f;
362     float zPivot = 0.0f;
363     if (transitionEffect->HasRotate()) {
364         xPivot = ConvertDimensionToScaleBySize(transitionEffect->GetRotateValue().centerX, frameSize.Width());
365         yPivot = ConvertDimensionToScaleBySize(transitionEffect->GetRotateValue().centerY, frameSize.Height());
366         zPivot = static_cast<float>(transitionEffect->GetRotateValue().centerZ.ConvertToVp());
367     } else if (transitionEffect->HasScale()) {
368         xPivot = ConvertDimensionToScaleBySize(transitionEffect->GetScaleValue().centerX, frameSize.Width());
369         yPivot = ConvertDimensionToScaleBySize(transitionEffect->GetScaleValue().centerY, frameSize.Height());
370     } else {
371         return;
372     }
373     SetPivot(xPivot, yPivot, zPivot);
374 }
375 
SetSurfaceChangedCallBack(const std::function<void (float,float,float,float)> & callback)376 void RosenRenderContext::SetSurfaceChangedCallBack(const std::function<void(float, float, float, float)>& callback)
377 {
378 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
379     if (rsNode_) {
380         RSRenderThread::Instance().AddSurfaceChangedCallBack(rsNode_->GetId(), callback);
381     }
382 #endif
383 }
384 
RemoveSurfaceChangedCallBack()385 void RosenRenderContext::RemoveSurfaceChangedCallBack()
386 {
387 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
388     if (rsNode_) {
389         RSRenderThread::Instance().RemoveSurfaceChangedCallBack(rsNode_->GetId());
390     }
391 #endif
392 }
393 
AddFrameNodeInfoToRsNode()394 void RosenRenderContext::AddFrameNodeInfoToRsNode()
395 {
396     if (rsNode_) {
397         rsNode_->SetInstanceId(Container::CurrentId());
398         auto frameNodePtr = GetHost();
399         CHECK_NULL_VOID(frameNodePtr);
400         rsNode_->SetFrameNodeInfo(frameNodePtr->GetId(), frameNodePtr->GetTag());
401     }
402 }
403 
SetHostNode(const WeakPtr<FrameNode> & host)404 void RosenRenderContext::SetHostNode(const WeakPtr<FrameNode>& host)
405 {
406     RenderContext::SetHostNode(host);
407     AddFrameNodeInfoToRsNode();
408 }
409 
InitContext(bool isRoot,const std::optional<ContextParam> & param,bool isLayoutNode)410 void RosenRenderContext::InitContext(bool isRoot, const std::optional<ContextParam>& param, bool isLayoutNode)
411 {
412     if (isLayoutNode) {
413         return;
414     }
415     InitContext(isRoot, param);
416 }
417 
InitContext(bool isRoot,const std::optional<ContextParam> & param)418 void RosenRenderContext::InitContext(bool isRoot, const std::optional<ContextParam>& param)
419 {
420     // skip if node already created
421     CHECK_NULL_VOID(!rsNode_);
422     auto isTextureExportNode = ViewStackProcessor::GetInstance()->IsExportTexture();
423     if (isRoot) {
424         rsNode_ = Rosen::RSRootNode::Create(false, isTextureExportNode);
425         AddFrameNodeInfoToRsNode();
426         return;
427     } else if (!param.has_value()) {
428         rsNode_ = Rosen::RSCanvasNode::Create(false, isTextureExportNode);
429         AddFrameNodeInfoToRsNode();
430         return;
431     }
432 
433     // create proper RSNode base on input
434     switch (param->type) {
435         case ContextType::CANVAS:
436             rsNode_ = Rosen::RSCanvasNode::Create(false, isTextureExportNode);
437             break;
438         case ContextType::ROOT:
439             rsNode_ = Rosen::RSRootNode::Create(false, isTextureExportNode);
440             break;
441         case ContextType::SURFACE: {
442             Rosen::RSSurfaceNodeConfig surfaceNodeConfig = { .SurfaceNodeName = param->surfaceName.value_or(""),
443                 .isTextureExportNode = isTextureExportNode };
444             rsNode_ = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, false);
445             break;
446         }
447         case ContextType::HARDWARE_SURFACE: {
448             rsNode_ = CreateHardwareSurface(param, isTextureExportNode);
449             break;
450         }
451 #ifdef RENDER_EXTRACT_SUPPORTED
452         case ContextType::HARDWARE_TEXTURE: {
453             rsNode_ = CreateHardwareTexture(param, isTextureExportNode);
454             break;
455         }
456 #endif
457         case ContextType::EFFECT:
458             rsNode_ = Rosen::RSEffectNode::Create(false, isTextureExportNode);
459             break;
460         case ContextType::INCREMENTAL_CANVAS:
461             rsNode_ = Rosen::RSCanvasDrawingNode::Create(false, isTextureExportNode);
462             break;
463         case ContextType::EXTERNAL:
464             break;
465         default:
466             break;
467     }
468 
469     AddFrameNodeInfoToRsNode();
470 }
471 
CreateHardwareSurface(const std::optional<ContextParam> & param,bool isTextureExportNode)472 std::shared_ptr<Rosen::RSNode> RosenRenderContext::CreateHardwareSurface(
473     const std::optional<ContextParam>& param, bool isTextureExportNode)
474 {
475     Rosen::RSSurfaceNodeConfig surfaceNodeConfig = { .SurfaceNodeName = param->surfaceName.value_or(""),
476         .isTextureExportNode = isTextureExportNode };
477     auto surfaceNode = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, false);
478     if (surfaceNode) {
479         surfaceNode->SetHardwareEnabled(true);
480     }
481     return surfaceNode;
482 }
483 
484 #ifdef RENDER_EXTRACT_SUPPORTED
CreateHardwareTexture(const std::optional<ContextParam> & param,bool isTextureExportNode)485 std::shared_ptr<Rosen::RSNode> RosenRenderContext::CreateHardwareTexture(
486     const std::optional<ContextParam>& param, bool isTextureExportNode)
487 {
488     Rosen::RSSurfaceNodeConfig surfaceNodeConfig = { .SurfaceNodeName = param->surfaceName.value_or(""),
489         .isTextureExportNode = isTextureExportNode };
490     auto surfaceNode = Rosen::RSSurfaceNode::Create(surfaceNodeConfig,
491         RSSurfaceNodeType::SURFACE_TEXTURE_NODE, false);
492     return surfaceNode;
493 }
494 #endif
495 
SetSandBox(const std::optional<OffsetF> & parentPosition,bool force)496 void RosenRenderContext::SetSandBox(const std::optional<OffsetF>& parentPosition, bool force)
497 {
498     CHECK_NULL_VOID(rsNode_);
499     auto host = GetHost();
500     CHECK_NULL_VOID(host);
501     if (parentPosition.has_value()) {
502         if (!force) {
503             sandBoxCount_++;
504         }
505         Rosen::Vector2f value = { parentPosition.value().GetX(), parentPosition.value().GetY() };
506         TAG_LOGI(AceLogTag::ACE_GEOMETRY_TRANSITION, "node[%{public}s] Set SandBox",
507             std::to_string(rsNode_->GetId()).c_str());
508         rsNode_->SetSandBox(value);
509     } else {
510         if (!force) {
511             sandBoxCount_--;
512             if (sandBoxCount_ > 0) {
513                 return;
514             }
515         }
516         TAG_LOGI(AceLogTag::ACE_GEOMETRY_TRANSITION, "node[%{public}s] Remove SandBox",
517             std::to_string(rsNode_->GetId()).c_str());
518         sandBoxCount_ = 0;
519         rsNode_->SetSandBox(std::nullopt);
520     }
521 }
522 
SetFrameWithoutAnimation(const RectF & paintRect)523 void RosenRenderContext::SetFrameWithoutAnimation(const RectF& paintRect)
524 {
525     CHECK_NULL_VOID(rsNode_ && paintRect.IsValid());
526     RSNode::ExecuteWithoutAnimation([&]() { SyncGeometryFrame(paintRect); });
527 }
528 
SyncGeometryProperties(GeometryNode *,bool,uint8_t)529 void RosenRenderContext::SyncGeometryProperties(GeometryNode* /*geometryNode*/, bool /* isRound */, uint8_t /* flag */)
530 {
531     CHECK_NULL_VOID(rsNode_);
532     auto host = GetHost();
533     CHECK_NULL_VOID(host);
534     if (isNeedAnimate_) {
535         SyncGeometryProperties(paintRect_);
536     } else {
537         RSNode::ExecuteWithoutAnimation([&]() { SyncGeometryProperties(paintRect_); });
538     }
539     host->OnPixelRoundFinish(paintRect_.GetSize());
540 }
541 
SyncGeometryFrame(const RectF & paintRect)542 void RosenRenderContext::SyncGeometryFrame(const RectF& paintRect)
543 {
544     CHECK_NULL_VOID(rsNode_);
545     rsNode_->SetBounds(paintRect.GetX(), paintRect.GetY(), paintRect.Width(), paintRect.Height());
546     if (rsTextureExport_) {
547         rsTextureExport_->UpdateBufferInfo(paintRect.GetX(), paintRect.GetY(), paintRect.Width(), paintRect.Height());
548     }
549     if (handleChildBounds_) {
550         SetChildBounds(paintRect);
551     }
552     if (useContentRectForRSFrame_) {
553         SetContentRectToFrame(paintRect);
554     } else {
555         rsNode_->SetFrame(paintRect.GetX(), paintRect.GetY(), paintRect.Width(), paintRect.Height());
556     }
557     if (frameOffset_.has_value()) {
558         rsNode_->SetFrame(paintRect.GetX() + frameOffset_->GetX(), paintRect.GetY() + frameOffset_->GetY(),
559             paintRect.Width(), paintRect.Height());
560     }
561     auto host = GetHost();
562     CHECK_NULL_VOID(host);
563     host->OnSyncGeometryFrameFinish(paintRect);
564 }
565 
SetChildBounds(const RectF & paintRect) const566 void RosenRenderContext::SetChildBounds(const RectF& paintRect) const
567 {
568     CHECK_NULL_VOID(rsNode_);
569     auto childRsNodeId = rsNode_->GetChildIdByIndex(0);
570     if (childRsNodeId.has_value()) {
571         auto childRsNode = Rosen::RSNodeMap::Instance().GetNode(childRsNodeId.value());
572         CHECK_NULL_VOID(childRsNode);
573         childRsNode->SetBounds(0.0f, 0.0f, paintRect.Width(), paintRect.Height());
574     }
575 }
576 
SyncGeometryProperties(const RectF & paintRect)577 void RosenRenderContext::SyncGeometryProperties(const RectF& paintRect)
578 {
579     CHECK_NULL_VOID(rsNode_);
580     if (isDisappearing_ && !paintRect.IsValid()) {
581         return;
582     }
583     if (SystemProperties::GetSyncDebugTraceEnabled()) {
584         auto host = GetHost();
585         ACE_LAYOUT_SCOPED_TRACE("SyncGeometryProperties [%s][self:%d] set bounds %s",
586             host->GetTag().c_str(), host->GetId(), paintRect.ToString().c_str());
587     }
588     SyncGeometryFrame(paintRect);
589 
590     if (!isSynced_) {
591         isSynced_ = true;
592         auto borderRadius = GetBorderRadius();
593         if (borderRadius.has_value()) {
594             OnBorderRadiusUpdate(borderRadius.value());
595         }
596     }
597 
598     if (firstTransitionIn_) {
599         // need to perform transitionIn early so not influence the following SetPivot
600         NotifyTransitionInner(paintRect.GetSize(), true);
601         firstTransitionIn_ = false;
602     }
603 
604     SyncPartialRsProperties();
605     SyncAdditionalGeometryProperties(paintRect);
606 }
607 
SyncAdditionalGeometryProperties(const RectF & paintRect)608 void RosenRenderContext::SyncAdditionalGeometryProperties(const RectF& paintRect)
609 {
610     if (propPointLight_ && propPointLight_->HasLightPosition()) {
611         // if lightPosition unit is percent, it is related with frameSize
612         OnLightPositionUpdate(propPointLight_->GetLightPositionValue());
613     }
614 
615     if (bgLoadingCtx_ && bgImage_) {
616         PaintBackground();
617     }
618 
619     auto sourceFromImage = GetBorderSourceFromImage().value_or(false);
620     if (sourceFromImage && bdImageLoadingCtx_ && bdImage_) {
621         PaintBorderImage();
622     } else if (!sourceFromImage && GetBorderImageGradient()) {
623         PaintBorderImageGradient();
624     }
625 
626     if (propGradient_) {
627         PaintGradient(paintRect.GetSize());
628     }
629 
630     if (propClip_) {
631         PaintClip(paintRect.GetSize());
632     }
633 
634     if (HasProgressMask() && GetProgressMaskValue()) {
635         PaintProgressMask();
636     }
637 
638     if (propGraphics_) {
639         PaintGraphics();
640     }
641 
642     if (propOverlay_) {
643         PaintOverlayText();
644     }
645 
646     if (SystemProperties::GetDebugBoundaryEnabled()) {
647         PaintDebugBoundary(true);
648     }
649 
650     if (propParticleOptionArray_.has_value()) {
651         if (!measureTriggered_ || particleAnimationPlaying_) {
652             measureTriggered_ = true;
653             OnParticleOptionArrayUpdate(propParticleOptionArray_.value());
654         }
655     }
656 }
657 
PaintDebugBoundary(bool flag)658 void RosenRenderContext::PaintDebugBoundary(bool flag)
659 {
660     if (!flag && !debugBoundaryModifier_) {
661         return;
662     }
663     CHECK_NULL_VOID(NeedDebugBoundary());
664     CHECK_NULL_VOID(rsNode_);
665     auto host = GetHost();
666     CHECK_NULL_VOID(host);
667     auto geometryNode = host->GetGeometryNode();
668     auto paintTask = [contentSize = geometryNode->GetFrameSize(), frameSize = geometryNode->GetMarginFrameSize(),
669                          offset = geometryNode->GetMarginFrameOffset(), frameOffset = geometryNode->GetFrameOffset(),
670                          flag](RSCanvas& rsCanvas) mutable {
671         if (!flag) {
672             return;
673         }
674         DebugBoundaryPainter painter(contentSize, frameSize);
675         painter.SetFrameOffset(frameOffset);
676         painter.DrawDebugBoundaries(rsCanvas, offset);
677     };
678 
679     if (!debugBoundaryModifier_ && rsNode_->IsInstanceOf<Rosen::RSCanvasNode>()) {
680         debugBoundaryModifier_ = std::make_shared<DebugBoundaryModifier>();
681         debugBoundaryModifier_->SetPaintTask(std::move(paintTask));
682         auto rect = GetPaintRectWithoutTransform();
683         auto marginOffset = geometryNode->GetMarginFrameOffset();
684         std::shared_ptr<Rosen::RectF> drawRect =
685             std::make_shared<Rosen::RectF>(marginOffset.GetX() - rect.GetX(), marginOffset.GetY() - rect.GetY(),
686                 geometryNode->GetMarginFrameSize().Width(), geometryNode->GetMarginFrameSize().Height());
687         UpdateDrawRegion(DRAW_REGION_DEBUG_BOUNDARY_MODIFIER_INDEX, drawRect);
688         rsNode_->AddModifier(debugBoundaryModifier_);
689         // SetCustomData(AttachProperty to rs modifier) must be called after AddModifier.
690         debugBoundaryModifier_->SetCustomData(flag);
691     } else if (debugBoundaryModifier_) {
692         debugBoundaryModifier_->SetPaintTask(std::move(paintTask));
693         auto rect = GetPaintRectWithoutTransform();
694         auto marginOffset = geometryNode->GetMarginFrameOffset();
695         std::shared_ptr<Rosen::RectF> drawRect =
696             std::make_shared<Rosen::RectF>(marginOffset.GetX() - rect.GetX(), marginOffset.GetY() - rect.GetY(),
697                 geometryNode->GetMarginFrameSize().Width(), geometryNode->GetMarginFrameSize().Height());
698         UpdateDrawRegion(DRAW_REGION_DEBUG_BOUNDARY_MODIFIER_INDEX, drawRect);
699         debugBoundaryModifier_->SetCustomData(flag);
700     }
701 }
702 
OnBackgroundColorUpdate(const Color & value)703 void RosenRenderContext::OnBackgroundColorUpdate(const Color& value)
704 {
705     CHECK_NULL_VOID(rsNode_);
706     rsNode_->SetBackgroundColor(value.GetValue());
707     RequestNextFrame();
708 }
709 
OnForegroundColorUpdate(const Color & value)710 void RosenRenderContext::OnForegroundColorUpdate(const Color& value)
711 {
712     CHECK_NULL_VOID(rsNode_);
713     rsNode_->SetEnvForegroundColor(value.GetValue());
714     RequestNextFrame();
715 }
716 
OnForegroundEffectUpdate(float radius)717 void RosenRenderContext::OnForegroundEffectUpdate(float radius)
718 {
719     CHECK_NULL_VOID(rsNode_);
720     auto context = PipelineBase::GetCurrentContext();
721     CHECK_NULL_VOID(context);
722     CalcDimension value;
723     value.SetValue(static_cast<double>(radius));
724     float radiusPx = context->NormalizeToPx(value);
725 #ifndef USE_ROSEN_DRAWING
726     float foreRadius = SkiaDecorationPainter::ConvertRadiusToSigma(radiusPx);
727 #else
728     float foreRadius = DrawingDecorationPainter::ConvertRadiusToSigma(radiusPx);
729 #endif
730     rsNode_->SetForegroundEffectRadius(foreRadius);
731     RequestNextFrame();
732 }
733 
OnForegroundColorStrategyUpdate(const ForegroundColorStrategy & value)734 void RosenRenderContext::OnForegroundColorStrategyUpdate(const ForegroundColorStrategy& value)
735 {
736     CHECK_NULL_VOID(rsNode_);
737     Rosen::ForegroundColorStrategyType rsStrategy = Rosen::ForegroundColorStrategyType::INVALID;
738     switch (value) {
739         case ForegroundColorStrategy::INVERT:
740             rsStrategy = Rosen::ForegroundColorStrategyType::INVERT_BACKGROUNDCOLOR;
741             break;
742         default:
743             break;
744     }
745     rsNode_->SetEnvForegroundColorStrategy(rsStrategy);
746     RequestNextFrame();
747 }
748 
CreateBgImageDataReadyCallback()749 DataReadyNotifyTask RosenRenderContext::CreateBgImageDataReadyCallback()
750 {
751     auto task = [weak = WeakClaim(this)](const ImageSourceInfo& sourceInfo) {
752         auto rosenRenderContext = weak.Upgrade();
753         CHECK_NULL_VOID(rosenRenderContext);
754         auto imageSourceInfo = rosenRenderContext->GetBackgroundImage().value_or(ImageSourceInfo(""));
755         if (imageSourceInfo != sourceInfo) {
756             return;
757         }
758         rosenRenderContext->bgLoadingCtx_->MakeCanvasImage(SizeF(), true, ImageFit::NONE);
759     };
760     return task;
761 }
762 
CreateBgImageLoadSuccessCallback()763 LoadSuccessNotifyTask RosenRenderContext::CreateBgImageLoadSuccessCallback()
764 {
765     auto task = [weak = WeakClaim(this)](const ImageSourceInfo& sourceInfo) {
766         auto ctx = weak.Upgrade();
767         CHECK_NULL_VOID(ctx);
768         auto imageSourceInfo = ctx->GetBackgroundImage().value_or(ImageSourceInfo(""));
769         if (imageSourceInfo != sourceInfo) {
770             return;
771         }
772         ctx->bgImage_ = ctx->bgLoadingCtx_->MoveCanvasImage();
773         CHECK_NULL_VOID(ctx->bgImage_);
774         if (ctx->GetHost()->GetGeometryNode()->GetFrameSize().IsPositive()) {
775             ctx->PaintBackground();
776             ctx->RequestNextFrame();
777         }
778     };
779     return task;
780 }
781 
PaintBackground()782 void RosenRenderContext::PaintBackground()
783 {
784     CHECK_NULL_VOID(rsNode_);
785     if (InstanceOf<PixelMapImage>(bgImage_)) {
786         PaintPixmapBgImage();
787 #ifndef USE_ROSEN_DRAWING
788     } else if (InstanceOf<SkiaImage>(bgImage_)) {
789         PaintSkBgImage();
790 #else
791     } else if (InstanceOf<DrawingImage>(bgImage_)) {
792         PaintRSBgImage();
793 #endif
794     } else {
795         if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
796             rsNode_->SetBgImage(nullptr);
797         }
798         return;
799     }
800     auto srcSize = bgLoadingCtx_->GetImageSize();
801     SizeF renderSize = ImagePainter::CalculateBgImageSize(paintRect_.GetSize(), srcSize, GetBackgroundImageSize());
802     OffsetF positionOffset =
803         ImagePainter::CalculateBgImagePosition(paintRect_.GetSize(), renderSize, GetBackgroundImagePosition());
804     auto slice = GetBackgroundImageResizableSliceValue(ImageResizableSlice());
805     Rosen::Vector4f rect(slice.left.ConvertToPxWithSize(srcSize.Width()),
806         slice.top.ConvertToPxWithSize(srcSize.Height()),
807         srcSize.Width() - (slice.left + slice.right).ConvertToPxWithSize(srcSize.Width()),
808         srcSize.Height() - (slice.top + slice.bottom).ConvertToPxWithSize(srcSize.Height()));
809     rsNode_->SetBgImageWidth(renderSize.Width());
810     rsNode_->SetBgImageHeight(renderSize.Height());
811     rsNode_->SetBgImagePositionX(positionOffset.GetX());
812     rsNode_->SetBgImagePositionY(positionOffset.GetY());
813     rsNode_->SetBgImageInnerRect(rect);
814 }
815 
OnBackgroundImageUpdate(const ImageSourceInfo & src)816 void RosenRenderContext::OnBackgroundImageUpdate(const ImageSourceInfo& src)
817 {
818     CHECK_NULL_VOID(rsNode_);
819     if (src.GetSrc().empty() && src.GetPixmap() == nullptr) {
820         bgImage_ = nullptr;
821         bgLoadingCtx_ = nullptr;
822         auto frameNode = GetHost();
823         if (frameNode) {
824             frameNode->SetColorModeUpdateCallback(nullptr);
825         }
826         PaintBackground();
827         return;
828     }
829     if (!bgLoadingCtx_ || src != bgLoadingCtx_->GetSourceInfo()) {
830         auto frameNode = GetHost();
831         auto callback = [src, weak = WeakClaim(this)] {
832             auto renderContext = weak.Upgrade();
833             CHECK_NULL_VOID(renderContext);
834             renderContext->OnBackgroundImageUpdate(src);
835         };
836         frameNode->SetColorModeUpdateCallback(std::move(callback));
837     }
838     LoadNotifier bgLoadNotifier(CreateBgImageDataReadyCallback(), CreateBgImageLoadSuccessCallback(), nullptr);
839     bgLoadingCtx_ = AceType::MakeRefPtr<ImageLoadingContext>(src, std::move(bgLoadNotifier));
840     CHECK_NULL_VOID(bgLoadingCtx_);
841     bgLoadingCtx_->LoadImageData();
842 }
843 
OnBackgroundImageRepeatUpdate(const ImageRepeat &)844 void RosenRenderContext::OnBackgroundImageRepeatUpdate(const ImageRepeat& /*imageRepeat*/)
845 {
846     CHECK_NULL_VOID(rsNode_);
847     PaintBackground();
848 }
849 
OnBackgroundImageSizeUpdate(const BackgroundImageSize &)850 void RosenRenderContext::OnBackgroundImageSizeUpdate(const BackgroundImageSize& /*bgImgSize*/)
851 {
852     CHECK_NULL_VOID(rsNode_);
853     PaintBackground();
854 }
855 
OnBackgroundImagePositionUpdate(const BackgroundImagePosition &)856 void RosenRenderContext::OnBackgroundImagePositionUpdate(const BackgroundImagePosition& /*bgImgPosition*/)
857 {
858     CHECK_NULL_VOID(rsNode_);
859     PaintBackground();
860 }
861 
OnBackgroundImageResizableSliceUpdate(const ImageResizableSlice &)862 void RosenRenderContext::OnBackgroundImageResizableSliceUpdate(const ImageResizableSlice& /*ImageResizableSlice*/)
863 {
864     CHECK_NULL_VOID(rsNode_);
865     PaintBackground();
866 }
867 
HasValidBgImageResizable()868 bool RosenRenderContext::HasValidBgImageResizable()
869 {
870     CHECK_NULL_RETURN(bgLoadingCtx_, false);
871     auto srcSize = bgLoadingCtx_->GetImageSize();
872     auto slice = GetBackgroundImageResizableSliceValue(ImageResizableSlice());
873     auto left = slice.left.ConvertToPxWithSize(srcSize.Width());
874     auto right = slice.right.ConvertToPxWithSize(srcSize.Width());
875     auto top = slice.top.ConvertToPxWithSize(srcSize.Width());
876     auto bottom = slice.bottom.ConvertToPxWithSize(srcSize.Width());
877     return srcSize.Width() > left + right && srcSize.Height() > top + bottom && right > 0 && bottom > 0;
878 }
879 
SetBackBlurFilter()880 void RosenRenderContext::SetBackBlurFilter()
881 {
882     CHECK_NULL_VOID(rsNode_);
883     auto context = GetPipelineContext();
884     CHECK_NULL_VOID(context);
885     const auto& background = GetBackground();
886     CHECK_NULL_VOID(background);
887     const auto& blurStyleOption = background->propBlurStyleOption;
888     std::shared_ptr<Rosen::RSFilter> backFilter;
889     if (!blurStyleOption.has_value()) {
890         const auto& radius = background->propBlurRadius;
891         if (radius.has_value() && radius->IsValid()) {
892             float radiusPx = context->NormalizeToPx(radius.value());
893 #ifndef USE_ROSEN_DRAWING
894             float backblurRadius = SkiaDecorationPainter::ConvertRadiusToSigma(radiusPx);
895 #else
896             float backblurRadius = DrawingDecorationPainter::ConvertRadiusToSigma(radiusPx);
897 #endif
898             backFilter = Rosen::RSFilter::CreateBlurFilter(backblurRadius, backblurRadius);
899         }
900     } else {
901         backFilter = CreateRSMaterialFilter(blurStyleOption.value(), context);
902     }
903     rsNode_->SetBackgroundFilter(backFilter);
904 }
905 
SetFrontBlurFilter()906 void RosenRenderContext::SetFrontBlurFilter()
907 {
908     CHECK_NULL_VOID(rsNode_);
909     auto context = GetPipelineContext();
910     CHECK_NULL_VOID(context);
911     const auto& foreground = GetForeground();
912     CHECK_NULL_VOID(foreground);
913     const auto& blurStyleOption = foreground->propBlurStyleOption;
914     std::shared_ptr<Rosen::RSFilter> frontFilter;
915     if (!blurStyleOption.has_value()) {
916         const auto& radius = foreground->propBlurRadius;
917         if (radius.has_value() && radius->IsValid()) {
918             float radiusPx = context->NormalizeToPx(radius.value());
919 #ifndef USE_ROSEN_DRAWING
920             float backblurRadius = SkiaDecorationPainter::ConvertRadiusToSigma(radiusPx);
921 #else
922             float backblurRadius = DrawingDecorationPainter::ConvertRadiusToSigma(radiusPx);
923 #endif
924             frontFilter = Rosen::RSFilter::CreateBlurFilter(backblurRadius, backblurRadius);
925         }
926     } else {
927         frontFilter = CreateRSMaterialFilter(blurStyleOption.value(), context);
928     }
929 
930     rsNode_->SetFilter(frontFilter);
931 }
932 
UpdateBackBlurStyle(const std::optional<BlurStyleOption> & bgBlurStyle)933 void RosenRenderContext::UpdateBackBlurStyle(const std::optional<BlurStyleOption>& bgBlurStyle)
934 {
935     CHECK_NULL_VOID(rsNode_);
936     const auto& groupProperty = GetOrCreateBackground();
937     if (groupProperty->CheckBlurStyleOption(bgBlurStyle)) {
938         // Same with previous value.
939         // If colorMode is following system and has valid blurStyle, still needs updating
940         if (bgBlurStyle->colorMode != ThemeColorMode::SYSTEM) {
941             return;
942         }
943         if (bgBlurStyle->blurOption.grayscale.size() > 1) {
944             Rosen::Vector2f grayScale(bgBlurStyle->blurOption.grayscale[0], bgBlurStyle->blurOption.grayscale[1]);
945             rsNode_->SetGreyCoef(grayScale);
946         }
947     } else {
948         groupProperty->propBlurStyleOption = bgBlurStyle;
949     }
950     SetBackBlurFilter();
951 }
952 
UpdateBackgroundEffect(const std::optional<EffectOption> & effectOption)953 void RosenRenderContext::UpdateBackgroundEffect(const std::optional<EffectOption>& effectOption)
954 {
955     CHECK_NULL_VOID(rsNode_);
956     const auto& groupProperty = GetOrCreateBackground();
957     if (groupProperty->CheckEffectOption(effectOption)) {
958         return;
959     }
960     groupProperty->propEffectOption = effectOption;
961     if (!effectOption.has_value()) {
962         return;
963     }
964     auto context = PipelineBase::GetCurrentContext();
965     CHECK_NULL_VOID(context);
966     float radiusPx = context->NormalizeToPx(effectOption->radius);
967 #ifndef USE_ROSEN_DRAWING
968     float backblurRadius = SkiaDecorationPainter::ConvertRadiusToSigma(radiusPx);
969 #else
970     float backblurRadius = DrawingDecorationPainter::ConvertRadiusToSigma(radiusPx);
971 #endif
972     auto fastAverage = Rosen::BLUR_COLOR_MODE::DEFAULT;
973     if (effectOption->adaptiveColor == AdaptiveColor::AVERAGE) {
974         fastAverage = Rosen::BLUR_COLOR_MODE::FASTAVERAGE;
975     }
976     std::shared_ptr<Rosen::RSFilter> backFilter =
977         Rosen::RSFilter::CreateMaterialFilter(backblurRadius, static_cast<float>(effectOption->saturation),
978             static_cast<float>(effectOption->brightness), effectOption->color.GetValue(),
979             static_cast<Rosen::BLUR_COLOR_MODE>(fastAverage));
980     rsNode_->SetBackgroundFilter(backFilter);
981     if (effectOption->blurOption.grayscale.size() > 1) {
982         Rosen::Vector2f grayScale(effectOption->blurOption.grayscale[0], effectOption->blurOption.grayscale[1]);
983         rsNode_->SetGreyCoef(grayScale);
984     }
985 }
986 
UpdateFrontBlurStyle(const std::optional<BlurStyleOption> & fgBlurStyle)987 void RosenRenderContext::UpdateFrontBlurStyle(const std::optional<BlurStyleOption>& fgBlurStyle)
988 {
989     CHECK_NULL_VOID(rsNode_);
990     const auto& groupProperty = GetOrCreateForeground();
991     if (groupProperty->CheckBlurStyleOption(fgBlurStyle)) {
992         // Same with previous value.
993         // If colorMode is following system and has valid blurStyle, still needs updating
994         if (fgBlurStyle->colorMode != ThemeColorMode::SYSTEM) {
995             return;
996         }
997         if (fgBlurStyle->blurOption.grayscale.size() > 1) {
998             Rosen::Vector2f grayScale(fgBlurStyle->blurOption.grayscale[0], fgBlurStyle->blurOption.grayscale[1]);
999             rsNode_->SetGreyCoef(grayScale);
1000         }
1001     } else {
1002         groupProperty->propBlurStyleOption = fgBlurStyle;
1003     }
1004     SetFrontBlurFilter();
1005 }
1006 
ResetBackBlurStyle()1007 void RosenRenderContext::ResetBackBlurStyle()
1008 {
1009     const auto& groupProperty = GetOrCreateBackground();
1010     groupProperty->propBlurStyleOption.reset();
1011     SetBackBlurFilter();
1012 }
1013 
OnSphericalEffectUpdate(double radio)1014 void RosenRenderContext::OnSphericalEffectUpdate(double radio)
1015 {
1016     CHECK_NULL_VOID(rsNode_);
1017     rsNode_->SetSpherizeDegree(static_cast<float>(radio));
1018     RequestNextFrame();
1019 }
1020 
OnPixelStretchEffectUpdate(const PixStretchEffectOption & option)1021 void RosenRenderContext::OnPixelStretchEffectUpdate(const PixStretchEffectOption& option)
1022 {
1023     CHECK_NULL_VOID(rsNode_);
1024     Rosen::Vector4f pixStretchVector;
1025     if (option.IsPercentOption()) {
1026         pixStretchVector.SetValues(static_cast<float>(option.left.Value()), static_cast<float>(option.top.Value()),
1027             static_cast<float>(option.right.Value()), static_cast<float>(option.bottom.Value()));
1028         rsNode_->SetPixelStretchPercent(pixStretchVector);
1029         rsNode_->SetPixelStretch({ 0, 0, 0, 0 });
1030     } else {
1031         pixStretchVector.SetValues(static_cast<float>(option.left.ConvertToPx()),
1032             static_cast<float>(option.top.ConvertToPx()), static_cast<float>(option.right.ConvertToPx()),
1033             static_cast<float>(option.bottom.ConvertToPx()));
1034         rsNode_->SetPixelStretch(pixStretchVector);
1035         rsNode_->SetPixelStretchPercent({ 0, 0, 0, 0 });
1036     }
1037     RequestNextFrame();
1038 }
1039 
OnLightUpEffectUpdate(double radio)1040 void RosenRenderContext::OnLightUpEffectUpdate(double radio)
1041 {
1042     CHECK_NULL_VOID(rsNode_);
1043     rsNode_->SetLightUpEffectDegree(static_cast<float>(radio));
1044     RequestNextFrame();
1045 }
1046 
OnParticleOptionArrayUpdate(const std::list<ParticleOption> & optionList)1047 void RosenRenderContext::OnParticleOptionArrayUpdate(const std::list<ParticleOption>& optionList)
1048 {
1049     CHECK_NULL_VOID(rsNode_);
1050     RectF rect = GetPaintRectWithoutTransform();
1051     if (rect.IsEmpty()) {
1052         return;
1053     }
1054     if (NeedPreloadImage(optionList, rect)) {
1055         return;
1056     }
1057     auto pattern = GetHost()->GetPattern();
1058     auto particlePattern = AceType::DynamicCast<ParticlePattern>(pattern);
1059     if (particlePattern->HaveUnVisibleParent()) {
1060         return;
1061     }
1062     particleAnimationPlaying_ = true;
1063     std::vector<OHOS::Rosen::ParticleParams> particleParams;
1064     for (auto& item : optionList) {
1065         particleParams.emplace_back(ConvertParticleOptionToParams(item, rect));
1066     }
1067     auto finishCallback = [weak = WeakClaim(this)]() {
1068         auto renderContext = weak.Upgrade();
1069         CHECK_NULL_VOID(renderContext);
1070         renderContext->particleAnimationPlaying_ = false;
1071     };
1072     rsNode_->SetParticleParams(particleParams, finishCallback);
1073     RequestNextFrame();
1074 }
1075 
OnClickEffectLevelUpdate(const ClickEffectInfo & info)1076 void RosenRenderContext::OnClickEffectLevelUpdate(const ClickEffectInfo& info)
1077 {
1078     auto frameNode = GetHost();
1079     CHECK_NULL_VOID(frameNode);
1080     CHECK_NULL_VOID(rsNode_);
1081     if (HasClickEffectLevel()) {
1082         InitEventClickEffect();
1083     }
1084 }
1085 
UpdateVisualEffect(const OHOS::Rosen::VisualEffect * visualEffect)1086 void RosenRenderContext::UpdateVisualEffect(const OHOS::Rosen::VisualEffect* visualEffect)
1087 {
1088     CHECK_NULL_VOID(visualEffect);
1089     rsNode_->SetVisualEffect(visualEffect);
1090 }
1091 
UpdateBackgroundFilter(const OHOS::Rosen::Filter * backgroundFilter)1092 void RosenRenderContext::UpdateBackgroundFilter(const OHOS::Rosen::Filter* backgroundFilter)
1093 {
1094     CHECK_NULL_VOID(backgroundFilter);
1095     rsNode_->SetUIBackgroundFilter(backgroundFilter);
1096 }
1097 
UpdateForegroundFilter(const OHOS::Rosen::Filter * foregroundFilter)1098 void RosenRenderContext::UpdateForegroundFilter(const OHOS::Rosen::Filter* foregroundFilter)
1099 {
1100     CHECK_NULL_VOID(foregroundFilter);
1101     rsNode_->SetUIForegroundFilter(foregroundFilter);
1102 }
1103 
UpdateCompositingFilter(const OHOS::Rosen::Filter * compositingFilter)1104 void RosenRenderContext::UpdateCompositingFilter(const OHOS::Rosen::Filter* compositingFilter)
1105 {
1106     CHECK_NULL_VOID(compositingFilter);
1107     rsNode_->SetUICompositingFilter(compositingFilter);
1108 }
1109 
NeedPreloadImage(const std::list<ParticleOption> & optionList,RectF & rect)1110 bool RosenRenderContext::NeedPreloadImage(const std::list<ParticleOption>& optionList, RectF& rect)
1111 {
1112     bool flag = false;
1113     std::vector<OHOS::Rosen::ParticleParams> particleParams;
1114     for (auto& item : optionList) {
1115         auto emitterOption = item.GetEmitterOption();
1116         auto particle = emitterOption.GetParticle();
1117         auto particleType = particle.GetParticleType();
1118         auto particleConfig = particle.GetConfig();
1119         if (particleType == ParticleType::IMAGE) {
1120             auto imageParameter = particleConfig.GetImageParticleParameter();
1121             auto imageSize = imageParameter.GetSize();
1122             auto imageWidth = Dimension(ConvertDimensionToPx(imageSize.first, rect.Width()), DimensionUnit::PX);
1123             auto imageHeight = Dimension(ConvertDimensionToPx(imageSize.second, rect.Height()), DimensionUnit::PX);
1124             auto canvasImageIter = particleImageMap_.find(imageParameter.GetImageSource());
1125             bool imageHasData = true;
1126             if (canvasImageIter->second) {
1127                 imageHasData = canvasImageIter->second->HasData();
1128             }
1129             if (canvasImageIter == particleImageMap_.end() || !imageHasData) {
1130                 LoadParticleImage(imageParameter.GetImageSource(), imageWidth, imageHeight);
1131                 flag = true;
1132             }
1133         }
1134     }
1135     return flag;
1136 }
1137 
ConvertParticleOptionToParams(const ParticleOption & particleOption,const RectF & rect)1138 Rosen::ParticleParams RosenRenderContext::ConvertParticleOptionToParams(
1139     const ParticleOption& particleOption, const RectF& rect)
1140 {
1141     auto emitterOption = particleOption.GetEmitterOption();
1142     auto colorOptionOpt = particleOption.GetParticleColorOption();
1143     auto opacityOptionOpt = particleOption.GetParticleOpacityOption();
1144     auto scaleOptionOpt = particleOption.GetParticleScaleOption();
1145     auto velocityOptionOpt = particleOption.GetParticleVelocityOption();
1146     auto accelerationOpt = particleOption.GetParticleAccelerationOption();
1147     auto spinOptionOpt = particleOption.GetParticleSpinOption();
1148     auto rsEmitterConfig = ConvertParticleEmitterOption(emitterOption, rect);
1149     std::optional<OHOS::Rosen::ParticleColorParaType> rsColorOpt;
1150     std::optional<OHOS::Rosen::ParticleParaType<float>> rsSpinOpt;
1151     std::optional<OHOS::Rosen::ParticleVelocity> rsVelocityOpt;
1152     std::optional<OHOS::Rosen::ParticleParaType<float>> rsOpacityOpt;
1153     std::optional<OHOS::Rosen::ParticleParaType<float>> rsScaleOpt;
1154     std::optional<OHOS::Rosen::ParticleAcceleration> rsAccelerationOpt;
1155     if (colorOptionOpt.has_value()) {
1156         rsColorOpt = ConvertParticleColorOption(colorOptionOpt.value());
1157     } else {
1158         rsColorOpt = ConvertParticleDefaultColorOption(std::nullopt);
1159     }
1160     if (opacityOptionOpt.has_value()) {
1161         rsOpacityOpt = ConvertParticleFloatOption(opacityOptionOpt.value());
1162     } else {
1163         OHOS::Rosen::Range<float> rsInitRange(PARTICLE_DEFAULT_OPACITY, PARTICLE_DEFAULT_OPACITY);
1164         rsOpacityOpt = ConvertParticleDefaultFloatOption(rsInitRange);
1165     }
1166     if (scaleOptionOpt.has_value()) {
1167         rsScaleOpt = ConvertParticleFloatOption(scaleOptionOpt.value());
1168     } else {
1169         OHOS::Rosen::Range<float> rsInitRange(PARTICLE_DEFAULT_SCALE, PARTICLE_DEFAULT_SCALE);
1170         rsScaleOpt = ConvertParticleDefaultFloatOption(rsInitRange);
1171     }
1172     if (velocityOptionOpt.has_value()) {
1173         rsVelocityOpt = ConvertParticleVelocityOption(velocityOptionOpt.value());
1174     } else {
1175         rsVelocityOpt = ConvertParticleDefaultVelocityOption();
1176     }
1177     if (accelerationOpt.has_value()) {
1178         rsAccelerationOpt = ConvertParticleAccelerationOption(accelerationOpt.value());
1179     } else {
1180         rsAccelerationOpt = ConvertParticleDefaultAccelerationOption();
1181     }
1182     if (spinOptionOpt.has_value()) {
1183         rsSpinOpt = ConvertParticleFloatOption(spinOptionOpt.value());
1184     } else {
1185         OHOS::Rosen::Range<float> rsInitRange(PARTICLE_DEFAULT_SPIN, PARTICLE_DEFAULT_SPIN);
1186         rsSpinOpt = ConvertParticleDefaultFloatOption(rsInitRange);
1187     }
1188     return OHOS::Rosen::ParticleParams(rsEmitterConfig, rsVelocityOpt.value(), rsAccelerationOpt.value(),
1189         rsColorOpt.value(), rsOpacityOpt.value(), rsScaleOpt.value(), rsSpinOpt.value());
1190 }
1191 
ConvertParticleEmitterOption(const EmitterOption & emitterOption,const RectF & rect)1192 Rosen::EmitterConfig RosenRenderContext::ConvertParticleEmitterOption(
1193     const EmitterOption& emitterOption, const RectF& rect)
1194 {
1195     auto emitterRateOpt = emitterOption.GetEmitterRate();
1196     auto pointOpt = emitterOption.GetPosition();
1197     auto sizeOpt = emitterOption.GetSize();
1198     auto shapeOpt = emitterOption.GetShape();
1199     auto particle = emitterOption.GetParticle();
1200     auto particleType = particle.GetParticleType();
1201     auto particleConfig = particle.GetConfig();
1202     auto particleCount = particle.GetCount();
1203     auto lifeTimeOpt = particle.GetLifeTime();
1204     auto lifeTimeRangeOpt = particle.GetLifeTimeRange();
1205     std::optional<int64_t> lifeTimeMin = 0;
1206     std::optional<int64_t> lifeTimeMax = lifeTimeOpt.value() + lifeTimeRangeOpt.value();
1207     if (lifeTimeOpt.value() == -1) {
1208         // when lifeTime == -1 particle life cycle is infinite
1209         lifeTimeMin = -1;
1210         lifeTimeMax = -1;
1211     } else if (lifeTimeOpt.value() - lifeTimeRangeOpt.value() > 0) {
1212         lifeTimeMin = lifeTimeOpt.value() - lifeTimeRangeOpt.value();
1213     }
1214     auto rsPoint = pointOpt.has_value()
1215                        ? OHOS::Rosen::Vector2f(ConvertDimensionToPx(pointOpt.value().first, rect.Width()),
1216                            ConvertDimensionToPx(pointOpt.value().second, rect.Height()))
1217                        : OHOS::Rosen::Vector2f(0.0f, 0.0f);
1218     auto rsSize = sizeOpt.has_value() ? OHOS::Rosen::Vector2f(ConvertDimensionToPx(sizeOpt.value().first, rect.Width()),
1219         ConvertDimensionToPx(sizeOpt.value().second, rect.Height()))
1220                                       : OHOS::Rosen::Vector2f(rect.Width(), rect.Height());
1221     auto shapeInt = static_cast<int32_t>(shapeOpt.value_or(ParticleEmitterShape::RECTANGLE));
1222     auto lifeTimeRange = OHOS::Rosen::Range<int64_t>(
1223         lifeTimeMin.value_or(PARTICLE_DEFAULT_LIFETIME), lifeTimeMax.value_or(PARTICLE_DEFAULT_LIFETIME));
1224     if (particleType == ParticleType::IMAGE) {
1225         auto imageParameter = particleConfig.GetImageParticleParameter();
1226         auto imageSource = imageParameter.GetImageSource();
1227         auto imageSize = imageParameter.GetSize();
1228         auto imageWidth = Dimension(ConvertDimensionToPx(imageSize.first, rect.Width()), DimensionUnit::PX);
1229         auto imageHeight = Dimension(ConvertDimensionToPx(imageSize.second, rect.Height()), DimensionUnit::PX);
1230         auto rsImagePtr = std::make_shared<Rosen::RSImage>();
1231         if (particleImageMap_.find(imageSource) != particleImageMap_.end()) {
1232             SetRsParticleImage(rsImagePtr, imageSource);
1233         }
1234         rsImagePtr->SetImageFit(static_cast<int32_t>(imageParameter.GetImageFit().value_or(ImageFit::COVER)));
1235         OHOS::Rosen::Vector2f rsImageSize(imageWidth.ConvertToPx(), imageHeight.ConvertToPx());
1236         return OHOS::Rosen::EmitterConfig(emitterRateOpt.value_or(PARTICLE_DEFAULT_EMITTER_RATE),
1237             static_cast<OHOS::Rosen::ShapeType>(shapeInt), rsPoint, rsSize, particleCount,
1238             lifeTimeRange, OHOS::Rosen::ParticleType::IMAGES, 0.0f, rsImagePtr, rsImageSize);
1239     } else {
1240         auto pointParameter = particleConfig.GetPointParticleParameter();
1241         auto radius = pointParameter.GetRadius();
1242         return OHOS::Rosen::EmitterConfig(emitterRateOpt.value_or(PARTICLE_DEFAULT_EMITTER_RATE),
1243             static_cast<OHOS::Rosen::ShapeType>(shapeInt), rsPoint, rsSize, particleCount,
1244             lifeTimeRange, OHOS::Rosen::ParticleType::POINTS, radius,
1245             std::make_shared<OHOS::Rosen::RSImage>(), OHOS::Rosen::Vector2f());
1246     }
1247 }
1248 
SetRsParticleImage(std::shared_ptr<Rosen::RSImage> & rsImagePtr,std::string & imageSource)1249 void RosenRenderContext::SetRsParticleImage(std::shared_ptr<Rosen::RSImage>& rsImagePtr, std::string& imageSource)
1250 {
1251     auto it = particleImageMap_.find(imageSource);
1252     if (it == particleImageMap_.end()) {
1253         return;
1254     }
1255     auto image = it->second;
1256     CHECK_NULL_VOID(image);
1257 
1258     if (InstanceOf<PixelMapImage>(image)) {
1259         auto pixmap = image->GetPixelMap();
1260         CHECK_NULL_VOID(pixmap);
1261         auto pixMapPtr = pixmap->GetPixelMapSharedPtr();
1262         rsImagePtr->SetPixelMap(pixMapPtr);
1263         if (pixMapPtr) {
1264             rsImagePtr->SetSrcRect(Rosen::RectF(0, 0, pixMapPtr->GetWidth(), pixMapPtr->GetHeight()));
1265         }
1266 #ifndef USE_ROSEN_DRAWING
1267     } else if (InstanceOf<SkiaImage>(image)) {
1268         auto skiaImage = DynamicCast<SkiaImage>(image);
1269         CHECK_NULL_VOID(skiaImage);
1270         auto compressData = skiaImage->GetCompressData();
1271         if (compressData) {
1272             rsImagePtr->SetCompressData(
1273                 compressData, skiaImage->GetUniqueID(), skiaImage->GetCompressWidth(), skiaImage->GetCompressHeight());
1274             rsImagePtr->SetSrcRect(Rosen::RectF(0, 0, skiaImage->GetCompressWidth(), skiaImage->GetCompressHeight()));
1275         } else {
1276             rsImagePtr->SetImage(skiaImage->GetImage());
1277             if (skiaImage->GetImage()) {
1278                 rsImagePtr->SetSrcRect(
1279                     Rosen::RectF(0, 0, skiaImage->GetImage()->width(), skiaImage->GetImage()->height()));
1280             }
1281         }
1282         if (!HasValidBgImageResizable()) {
1283             rsImagePtr->SetImageRepeat(static_cast<int>(GetBackgroundImageRepeat().value_or(ImageRepeat::NO_REPEAT)));
1284         }
1285 #else
1286     } else if (InstanceOf<DrawingImage>(image)) {
1287         auto drawingImage = DynamicCast<DrawingImage>(image);
1288         CHECK_NULL_VOID(drawingImage);
1289         auto compressData = drawingImage->GetCompressData();
1290         if (compressData) {
1291             rsImagePtr->SetCompressData(compressData, drawingImage->GetUniqueID(), drawingImage->GetCompressWidth(),
1292                 drawingImage->GetCompressHeight());
1293             rsImagePtr->SetSrcRect(
1294                 Rosen::RectF(0, 0, drawingImage->GetCompressWidth(), drawingImage->GetCompressHeight()));
1295         } else {
1296             rsImagePtr->SetImage(drawingImage->GetImage());
1297             if (drawingImage->GetImage()) {
1298                 rsImagePtr->SetSrcRect(
1299                     Rosen::RectF(0, 0, drawingImage->GetImage()->GetWidth(), drawingImage->GetImage()->GetHeight()));
1300             }
1301         }
1302         if (!HasValidBgImageResizable()) {
1303             rsImagePtr->SetImageRepeat(static_cast<int>(GetBackgroundImageRepeat().value_or(ImageRepeat::NO_REPEAT)));
1304         }
1305 #endif
1306     }
1307 }
1308 
LoadParticleImage(const std::string & src,Dimension & width,Dimension & height)1309 void RosenRenderContext::LoadParticleImage(const std::string& src, Dimension& width, Dimension& height)
1310 {
1311     if (particleImageContextMap_.find(src) != particleImageContextMap_.end()) {
1312         return;
1313     }
1314     ImageSourceInfo imageSourceInfo(src, width, height);
1315     imageSourceInfo.SetNeedCache(false);
1316     auto preLoadCallback = [weak = WeakClaim(this), imageSrc = src](const ImageSourceInfo& sourceInfo) {
1317         auto renderContent = weak.Upgrade();
1318         CHECK_NULL_VOID(renderContent);
1319         auto& imageContext = renderContent->particleImageContextMap_[imageSrc];
1320         CHECK_NULL_VOID(imageContext);
1321         imageContext->MakeCanvasImage(SizeF(), true, ImageFit::NONE);
1322     };
1323     auto loadingSuccessCallback = [weak = WeakClaim(this), imageSrc = src](const ImageSourceInfo& sourceInfo) {
1324         auto renderContent = weak.Upgrade();
1325         CHECK_NULL_VOID(renderContent);
1326         auto& imageContext = renderContent->particleImageContextMap_[imageSrc];
1327         CHECK_NULL_VOID(imageContext);
1328         auto imagePtr = imageContext->MoveCanvasImage();
1329         renderContent->OnParticleImageLoaded(imageSrc, imagePtr);
1330     };
1331     auto loadingErrorCallback = [weak = WeakClaim(this), imageSrc = src](
1332                                     const ImageSourceInfo& sourceInfo, const std::string& errorMsg) {
1333         auto renderContent = weak.Upgrade();
1334         CHECK_NULL_VOID(renderContent);
1335         renderContent->OnParticleImageLoaded(imageSrc, nullptr);
1336     };
1337     LoadNotifier loadNotifier(preLoadCallback, loadingSuccessCallback, loadingErrorCallback);
1338     auto particleImageLoadingCtx = AceType::MakeRefPtr<ImageLoadingContext>(imageSourceInfo, std::move(loadNotifier));
1339     imageSourceInfo.SetSrc(src, Color(0x00000000));
1340     particleImageLoadingCtx->LoadImageData();
1341     particleImageContextMap_.try_emplace(src, particleImageLoadingCtx);
1342 }
1343 
OnParticleImageLoaded(const std::string & src,RefPtr<CanvasImage> canvasImage)1344 void RosenRenderContext::OnParticleImageLoaded(const std::string& src, RefPtr<CanvasImage> canvasImage)
1345 {
1346     particleImageMap_.try_emplace(src, canvasImage);
1347     if (particleImageContextMap_.find(src) != particleImageContextMap_.end()) {
1348         particleImageContextMap_.erase(src);
1349     }
1350     if (particleImageContextMap_.empty() && propParticleOptionArray_.has_value()) {
1351         OnParticleOptionArrayUpdate(propParticleOptionArray_.value());
1352     }
1353 }
1354 
ConvertDimensionToPx(Dimension & src,float size)1355 float RosenRenderContext::ConvertDimensionToPx(Dimension& src, float size)
1356 {
1357     if (src.Unit() == DimensionUnit::PERCENT) {
1358         return src.ConvertToPxWithSize(size);
1359     }
1360     return src.ConvertToPx();
1361 }
1362 
ConvertParticleVelocityOption(const VelocityProperty & velocity)1363 Rosen::ParticleVelocity RosenRenderContext::ConvertParticleVelocityOption(const VelocityProperty& velocity)
1364 {
1365     auto rsSpeedRange = OHOS::Rosen::Range<float>(velocity.GetSpeedRange().first, velocity.GetSpeedRange().second);
1366     auto rsAngleRange = OHOS::Rosen::Range<float>(velocity.GetAngleRange().first, velocity.GetAngleRange().second);
1367     return OHOS::Rosen::ParticleVelocity(rsSpeedRange, rsAngleRange);
1368 }
1369 
ConvertParticleDefaultVelocityOption()1370 Rosen::ParticleVelocity RosenRenderContext::ConvertParticleDefaultVelocityOption()
1371 {
1372     auto rsSpeedRange = OHOS::Rosen::Range<float>(PARTICLE_DEFAULT_SPEED, PARTICLE_DEFAULT_SPEED);
1373     auto rsAngleRange = OHOS::Rosen::Range<float>(PARTICLE_DEFAULT_ANGLE, PARTICLE_DEFAULT_ANGLE);
1374     return OHOS::Rosen::ParticleVelocity(rsSpeedRange, rsAngleRange);
1375 }
1376 
ConvertParticleAccelerationOption(const AccelerationProperty & acceleration)1377 Rosen::ParticleAcceleration RosenRenderContext::ConvertParticleAccelerationOption(
1378     const AccelerationProperty& acceleration)
1379 {
1380     auto speedOpt = acceleration.GetSpeed();
1381     auto angleOpt = acceleration.GetAngle();
1382     std::optional<OHOS::Rosen::ParticleParaType<float>> rsSpeedOpt;
1383     std::optional<OHOS::Rosen::ParticleParaType<float>> rsAngleOpt;
1384     OHOS::Rosen::Range<float> rsInitSpeedRange(PARTICLE_DEFAULT_SPEED, PARTICLE_DEFAULT_SPEED);
1385     if (speedOpt.has_value()) {
1386         rsSpeedOpt = ConvertParticleFloatOption(speedOpt.value());
1387     } else {
1388         rsSpeedOpt = ConvertParticleDefaultFloatOption(rsInitSpeedRange);
1389     }
1390     OHOS::Rosen::Range<float> rsInitAngleRange(PARTICLE_DEFAULT_ANGLE, PARTICLE_DEFAULT_ANGLE);
1391     if (angleOpt.has_value()) {
1392         rsAngleOpt = ConvertParticleFloatOption(angleOpt.value());
1393     } else {
1394         rsAngleOpt = ConvertParticleDefaultFloatOption(rsInitAngleRange);
1395     }
1396     return OHOS::Rosen::ParticleAcceleration(rsSpeedOpt.value(), rsAngleOpt.value());
1397 }
1398 
ConvertParticleDefaultAccelerationOption()1399 Rosen::ParticleAcceleration RosenRenderContext::ConvertParticleDefaultAccelerationOption()
1400 {
1401     OHOS::Rosen::Range<float> rsInitRange(PARTICLE_DEFAULT_SPEED, PARTICLE_DEFAULT_SPEED);
1402     return OHOS::Rosen::ParticleAcceleration(
1403         ConvertParticleDefaultFloatOption(rsInitRange), ConvertParticleDefaultFloatOption(rsInitRange));
1404 }
1405 
ConvertParticleColorOption(const ParticleColorPropertyOption & colorOption)1406 Rosen::ParticleColorParaType RosenRenderContext::ConvertParticleColorOption(
1407     const ParticleColorPropertyOption& colorOption)
1408 {
1409     auto initRange = colorOption.GetRange();
1410     auto colorDist = colorOption.GetDistribution();
1411     auto updaterOpt = colorOption.GetUpdater();
1412     OHOS::Rosen::Range<OHOS::Rosen::RSColor> rsInitRange(
1413         OHOS::Rosen::RSColor(initRange.first.GetRed(), initRange.first.GetGreen(), initRange.first.GetBlue(),
1414             initRange.first.GetAlpha()),
1415         OHOS::Rosen::RSColor(initRange.second.GetRed(), initRange.second.GetGreen(), initRange.second.GetBlue(),
1416             initRange.second.GetAlpha()));
1417     auto colorDistInt = static_cast<int32_t>(colorDist.value_or(DistributionType::UNIFORM));
1418     if (updaterOpt.has_value()) {
1419         auto updater = updaterOpt.value();
1420         auto updateType = updater.GetUpdateType();
1421         auto config = updater.GetConfig();
1422         if (updateType == UpdaterType::RANDOM) {
1423             auto randomConfig = config.GetRandomConfig();
1424             auto redRandom = randomConfig.GetRedRandom();
1425             auto greenRandom = randomConfig.GetGreenRandom();
1426             auto blueRandom = randomConfig.GetBlueRandom();
1427             auto alphaRandom = randomConfig.GetAlphaRandom();
1428             OHOS::Rosen::Range<float> rsRedRandom(redRandom.first, redRandom.second);
1429             OHOS::Rosen::Range<float> rsGreenRandom(greenRandom.first, greenRandom.second);
1430             OHOS::Rosen::Range<float> rsBlueRandom(blueRandom.first, blueRandom.second);
1431             OHOS::Rosen::Range<float> rsAlphaRandom(alphaRandom.first, alphaRandom.second);
1432             std::vector<OHOS::Rosen::Change<OHOS::Rosen::RSColor>> invalidCurve;
1433             return OHOS::Rosen::ParticleColorParaType(rsInitRange,
1434                 static_cast<OHOS::Rosen::DistributionType>(colorDistInt), OHOS::Rosen::ParticleUpdator::RANDOM,
1435                 rsRedRandom, rsGreenRandom, rsBlueRandom, rsAlphaRandom, invalidCurve);
1436         } else if (updateType == UpdaterType::CURVE) {
1437             auto& curveConfig = config.GetAnimationArray();
1438             std::vector<OHOS::Rosen::Change<OHOS::Rosen::RSColor>> valChangeOverLife;
1439             for (const auto& colorAnimationConfig : curveConfig) {
1440                 auto fromColor = colorAnimationConfig.GetFrom();
1441                 auto toColor = colorAnimationConfig.GetTo();
1442                 auto startMills = colorAnimationConfig.GetStartMills();
1443                 auto endMills = colorAnimationConfig.GetEndMills();
1444                 auto curve = colorAnimationConfig.GetCurve();
1445                 auto rsCurve = NativeCurveHelper::ToNativeCurve(curve);
1446                 valChangeOverLife.emplace_back(OHOS::Rosen::Change<OHOS::Rosen::RSColor>(
1447                     OHOS::Rosen::RSColor(
1448                         fromColor.GetRed(), fromColor.GetGreen(), fromColor.GetBlue(), fromColor.GetAlpha()),
1449                     OHOS::Rosen::RSColor(toColor.GetRed(), toColor.GetGreen(), toColor.GetBlue(), toColor.GetAlpha()),
1450                     startMills, endMills, rsCurve));
1451             }
1452             return OHOS::Rosen::ParticleColorParaType(rsInitRange,
1453                 static_cast<OHOS::Rosen::DistributionType>(colorDistInt), ParticleUpdator::CURVE,
1454                 OHOS::Rosen::Range<float>(), OHOS::Rosen::Range<float>(), OHOS::Rosen::Range<float>(),
1455                 OHOS::Rosen::Range<float>(), valChangeOverLife);
1456         }
1457     }
1458     return ConvertParticleDefaultColorOption(rsInitRange);
1459 }
1460 
ConvertParticleDefaultColorOption(std::optional<OHOS::Rosen::Range<OHOS::Rosen::RSColor>> rsInitRangeOpt)1461 Rosen::ParticleColorParaType RosenRenderContext::ConvertParticleDefaultColorOption(
1462     std::optional<OHOS::Rosen::Range<OHOS::Rosen::RSColor>> rsInitRangeOpt)
1463 {
1464     std::vector<OHOS::Rosen::Change<OHOS::Rosen::RSColor>> invalidCurve;
1465     if (rsInitRangeOpt.has_value()) {
1466         return OHOS::Rosen::ParticleColorParaType(rsInitRangeOpt.value(), OHOS::Rosen::DistributionType::UNIFORM,
1467             OHOS::Rosen::ParticleUpdator::NONE, OHOS::Rosen::Range<float>(), OHOS::Rosen::Range<float>(),
1468             OHOS::Rosen::Range<float>(), OHOS::Rosen::Range<float>(), invalidCurve);
1469     }
1470     return OHOS::Rosen::ParticleColorParaType(
1471         OHOS::Rosen::Range<OHOS::Rosen::RSColor>(
1472             OHOS::Rosen::RSColor(PARTICLE_DEFAULT_COLOR), OHOS::Rosen::RSColor(PARTICLE_DEFAULT_COLOR)),
1473         OHOS::Rosen::DistributionType::UNIFORM, OHOS::Rosen::ParticleUpdator::NONE, OHOS::Rosen::Range<float>(),
1474         OHOS::Rosen::Range<float>(), OHOS::Rosen::Range<float>(), OHOS::Rosen::Range<float>(), invalidCurve);
1475 }
1476 
ConvertParticleFloatOption(const ParticleFloatPropertyOption & floatOption)1477 Rosen::ParticleParaType<float> RosenRenderContext::ConvertParticleFloatOption(
1478     const ParticleFloatPropertyOption& floatOption)
1479 {
1480     auto initRange = floatOption.GetRange();
1481     OHOS::Rosen::Range<float> rsInitRange(initRange.first, initRange.second);
1482     auto updaterOpt = floatOption.GetUpdater();
1483     if (updaterOpt.has_value()) {
1484         auto updater = updaterOpt.value();
1485         auto updateType = updater.GetUpdaterType();
1486         auto& config = updater.GetConfig();
1487         if (updateType == UpdaterType::RANDOM) {
1488             auto& randomRangeConfig = config.GetRandomConfig();
1489             std::vector<OHOS::Rosen::Change<float>> invalidChangeInOverLifeArray;
1490             return OHOS::Rosen::ParticleParaType<float>(rsInitRange, OHOS::Rosen::ParticleUpdator::RANDOM,
1491                 OHOS::Rosen::Range<float>(randomRangeConfig.first, randomRangeConfig.second),
1492                 invalidChangeInOverLifeArray);
1493         } else if (updateType == UpdaterType::CURVE) {
1494             auto curveConfig = config.GetAnimations();
1495             std::vector<OHOS::Rosen::Change<float>> valChangeOverLife;
1496             for (auto& animationConfig : curveConfig) {
1497                 auto from = animationConfig.GetFrom();
1498                 auto to = animationConfig.GetTo();
1499                 auto startMills = animationConfig.GetStartMills();
1500                 auto endMills = animationConfig.GetEndMills();
1501                 auto rsCurve = NativeCurveHelper::ToNativeCurve(animationConfig.GetCurve());
1502                 valChangeOverLife.emplace_back(OHOS::Rosen::Change<float>(from, to, startMills, endMills, rsCurve));
1503             }
1504             OHOS::Rosen::Range<float> rsInvalidRange;
1505             return OHOS::Rosen::ParticleParaType<float>(
1506                 rsInitRange, OHOS::Rosen::ParticleUpdator::CURVE, rsInvalidRange, valChangeOverLife);
1507         }
1508     }
1509     return ConvertParticleDefaultFloatOption(rsInitRange);
1510 }
1511 
ConvertParticleDefaultFloatOption(OHOS::Rosen::Range<float> & rsInitRange)1512 Rosen::ParticleParaType<float> RosenRenderContext::ConvertParticleDefaultFloatOption(
1513     OHOS::Rosen::Range<float>& rsInitRange)
1514 {
1515     std::vector<OHOS::Rosen::Change<float>> invalidChangeInOverLifeArray;
1516     return OHOS::Rosen::ParticleParaType<float>(
1517         rsInitRange, OHOS::Rosen::ParticleUpdator::NONE, OHOS::Rosen::Range<float>(), invalidChangeInOverLifeArray);
1518 }
1519 
OnOpacityUpdate(double opacity)1520 void RosenRenderContext::OnOpacityUpdate(double opacity)
1521 {
1522     CHECK_NULL_VOID(rsNode_);
1523     if (AnimationUtils::IsImplicitAnimationOpen() && GetHost()) {
1524         auto preOpacity = rsNode_->GetStagingProperties().GetAlpha();
1525         if (!NearEqual(preOpacity, opacity)) {
1526             auto host = GetHost();
1527             ACE_SCOPED_TRACE("opacity from %f to %f, id:%d, tag:%s", rsNode_->GetStagingProperties().GetAlpha(),
1528                 opacity, host->GetId(), host->GetTag().c_str());
1529         }
1530     }
1531     rsNode_->SetAlpha(opacity);
1532     RequestNextFrame();
1533 }
1534 
OnDynamicRangeModeUpdate(DynamicRangeMode dynamicRangeMode)1535 void RosenRenderContext::OnDynamicRangeModeUpdate(DynamicRangeMode dynamicRangeMode)
1536 {
1537     auto rsCanvasDrawingNode = Rosen::RSNode::ReinterpretCast<Rosen::RSCanvasNode>(rsNode_);
1538     CHECK_NULL_VOID(rsCanvasDrawingNode);
1539     if (dynamicRangeMode < DynamicRangeMode::STANDARD && !isHdr_) {
1540         TAG_LOGD(AceLogTag::ACE_IMAGE, "Set HDRPresent True.");
1541         isHdr_ = true;
1542         rsCanvasDrawingNode->SetHDRPresent(true);
1543     } else if (isHdr_) {
1544         TAG_LOGD(AceLogTag::ACE_IMAGE, "Set HDRPresent False.");
1545         isHdr_ = false;
1546         rsCanvasDrawingNode->SetHDRPresent(false);
1547     }
1548 }
1549 
SetAlphaOffscreen(bool isOffScreen)1550 void RosenRenderContext::SetAlphaOffscreen(bool isOffScreen)
1551 {
1552     CHECK_NULL_VOID(rsNode_);
1553     rsNode_->SetAlphaOffscreen(isOffScreen);
1554 }
1555 
1556 class DrawDragThumbnailCallback : public SurfaceCaptureCallback {
1557 public:
OnSurfaceCapture(std::shared_ptr<Media::PixelMap> pixelMap)1558     void OnSurfaceCapture(std::shared_ptr<Media::PixelMap> pixelMap) override
1559     {
1560         if (pixelMap) {
1561 #ifdef PIXEL_MAP_SUPPORTED
1562             g_pixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
1563 #endif // PIXEL_MAP_SUPPORTED
1564         } else {
1565             g_pixelMap = nullptr;
1566             TAG_LOGE(AceLogTag::ACE_DRAG, "get thumbnail pixelMap failed!");
1567         }
1568 
1569         if (callback_ == nullptr) {
1570             std::unique_lock<std::mutex> lock(g_mutex);
1571             thumbnailGet.notify_all();
1572             return;
1573         }
1574         callback_(g_pixelMap);
1575     }
1576 
1577     std::function<void(const RefPtr<PixelMap>&)> callback_;
1578 };
1579 
GetThumbnailPixelMap(bool needScale)1580 RefPtr<PixelMap> RosenRenderContext::GetThumbnailPixelMap(bool needScale)
1581 {
1582     CHECK_NULL_RETURN(rsNode_, nullptr);
1583     std::shared_ptr<DrawDragThumbnailCallback> drawDragThumbnailCallback =
1584         std::make_shared<DrawDragThumbnailCallback>();
1585     CHECK_NULL_RETURN(drawDragThumbnailCallback, nullptr);
1586     drawDragThumbnailCallback->callback_ = nullptr;
1587     float scaleX = 1.0f;
1588     float scaleY = 1.0f;
1589     if (needScale) {
1590         UpdateThumbnailPixelMapScale(scaleX, scaleY);
1591     }
1592     auto ret =
1593         RSInterfaces::GetInstance().TakeSurfaceCaptureForUI(rsNode_, drawDragThumbnailCallback, scaleX, scaleY, true);
1594     if (!ret) {
1595         LOGE("TakeSurfaceCaptureForUI failed!");
1596         return nullptr;
1597     }
1598     std::unique_lock<std::mutex> lock(g_mutex);
1599     if (thumbnailGet.wait_for(lock, PIXELMAP_TIMEOUT_DURATION) == std::cv_status::timeout) {
1600         LOGE("get thumbnail pixelMap timeout!");
1601         return nullptr;
1602     }
1603     return g_pixelMap;
1604 }
1605 
CreateThumbnailPixelMapAsyncTask(bool needScale,std::function<void (const RefPtr<PixelMap>)> && callback)1606 bool RosenRenderContext::CreateThumbnailPixelMapAsyncTask(
1607     bool needScale, std::function<void(const RefPtr<PixelMap>)>&& callback)
1608 {
1609     CHECK_NULL_RETURN(rsNode_, false);
1610     std::shared_ptr<DrawDragThumbnailCallback> thumbnailCallback =
1611         std::make_shared<DrawDragThumbnailCallback>();
1612     CHECK_NULL_RETURN(thumbnailCallback, false);
1613     thumbnailCallback->callback_ = std::move(callback);
1614     float scaleX = 1.0f;
1615     float scaleY = 1.0f;
1616     if (needScale) {
1617         UpdateThumbnailPixelMapScale(scaleX, scaleY);
1618     }
1619     return RSInterfaces::GetInstance().TakeSurfaceCaptureForUI(rsNode_, thumbnailCallback, scaleX, scaleY, true);
1620 }
1621 
UpdateThumbnailPixelMapScale(float & scaleX,float & scaleY)1622 void RosenRenderContext::UpdateThumbnailPixelMapScale(float& scaleX, float& scaleY)
1623 {
1624     CHECK_NULL_VOID(rsNode_);
1625     auto scale = rsNode_->GetStagingProperties().GetScale();
1626     auto frameNode = GetHost();
1627     CHECK_NULL_VOID(frameNode);
1628     auto context = frameNode->GetRenderContext();
1629     CHECK_NULL_VOID(context);
1630     auto parent = frameNode->GetAncestorNodeOfFrame();
1631     while (parent) {
1632         auto parentRenderContext = parent->GetRenderContext();
1633         CHECK_NULL_VOID(parentRenderContext);
1634         auto parentScale = parentRenderContext->GetTransformScale();
1635         if (parentScale) {
1636             scale[0] *= parentScale.value().x;
1637             scale[1] *= parentScale.value().y;
1638         }
1639         parent = parent->GetAncestorNodeOfFrame();
1640     }
1641     scaleX = scale[0];
1642     scaleY = scale[1];
1643 }
1644 
1645 #ifndef USE_ROSEN_DRAWING
GetBitmap(SkBitmap & bitmap,std::shared_ptr<OHOS::Rosen::DrawCmdList> drawCmdList)1646 bool RosenRenderContext::GetBitmap(SkBitmap& bitmap, std::shared_ptr<OHOS::Rosen::DrawCmdList> drawCmdList)
1647 #else
1648 bool RosenRenderContext::GetBitmap(RSBitmap& bitmap, std::shared_ptr<RSDrawCmdList> drawCmdList)
1649 #endif
1650 {
1651     auto rsCanvasDrawingNode = Rosen::RSNode::ReinterpretCast<Rosen::RSCanvasDrawingNode>(rsNode_);
1652     if (!rsCanvasDrawingNode) {
1653         return false;
1654     }
1655     return rsCanvasDrawingNode->GetBitmap(bitmap, drawCmdList);
1656 }
1657 
1658 #ifndef USE_ROSEN_DRAWING
GetPixelMap(const std::shared_ptr<Media::PixelMap> & pixelMap,std::shared_ptr<OHOS::Rosen::DrawCmdList> drawCmdList,SkRect * rect)1659 bool RosenRenderContext::GetPixelMap(const std::shared_ptr<Media::PixelMap>& pixelMap,
1660     std::shared_ptr<OHOS::Rosen::DrawCmdList> drawCmdList, SkRect* rect)
1661 #else
1662 bool RosenRenderContext::GetPixelMap(const std::shared_ptr<Media::PixelMap>& pixelMap,
1663     std::shared_ptr<RSDrawCmdList> drawCmdList, Rosen::Drawing::Rect* rect)
1664 #endif
1665 {
1666     auto rsCanvasDrawingNode = Rosen::RSNode::ReinterpretCast<Rosen::RSCanvasDrawingNode>(rsNode_);
1667     if (!rsCanvasDrawingNode) {
1668         return false;
1669     }
1670     return rsCanvasDrawingNode->GetPixelmap(pixelMap, drawCmdList, rect);
1671 }
1672 
1673 template<typename ModifierName, typename T>
SetAnimatableProperty(std::shared_ptr<ModifierName> & modifier,const T & value)1674 void RosenRenderContext::SetAnimatableProperty(std::shared_ptr<ModifierName>& modifier, const T& value)
1675 {
1676     if (modifier) {
1677         auto property = std::static_pointer_cast<Rosen::RSAnimatableProperty<T>>(modifier->GetProperty());
1678         CHECK_NULL_VOID(property);
1679         property->Set(value);
1680     } else {
1681         auto property = std::make_shared<Rosen::RSAnimatableProperty<T>>(value);
1682         modifier = std::make_shared<ModifierName>(property);
1683         rsNode_->AddModifier(modifier);
1684     }
1685 }
1686 
OnTransformScaleUpdate(const VectorF & scale)1687 void RosenRenderContext::OnTransformScaleUpdate(const VectorF& scale)
1688 {
1689     CHECK_NULL_VOID(rsNode_);
1690     auto curScale = rsNode_->GetStagingProperties().GetScale();
1691     hasScales_ = !NearEqual(curScale, Vector2f(1.0f, 1.0f)) && !NearEqual(scale, VectorF(1.0f, 1.0f));
1692     if (AnimationUtils::IsImplicitAnimationOpen() && scaleXYUserModifier_ && GetHost()) {
1693         auto preScale =
1694             GetAnimatablePropertyStagingValue<Rosen::RSScaleModifier, Rosen::Vector2f>(scaleXYUserModifier_);
1695         if (!(NearEqual(preScale[0], scale.x) && NearEqual(preScale[1], scale.y))) {
1696             auto host = GetHost();
1697             ACE_SCOPED_TRACE("scale from (%f, %f) to (%f, %f), id:%d, tag:%s", preScale[0], preScale[1], scale.x,
1698                 scale.y, host->GetId(), host->GetTag().c_str());
1699         }
1700     }
1701     SetAnimatableProperty<Rosen::RSScaleModifier, Rosen::Vector2f>(scaleXYUserModifier_, { scale.x, scale.y });
1702     NotifyHostTransformUpdated();
1703     RequestNextFrame();
1704 }
1705 
MarshallTranslate(const TranslateOptions & translate)1706 Vector3F RosenRenderContext::MarshallTranslate(const TranslateOptions& translate)
1707 {
1708     float xValue = 0.0f;
1709     float yValue = 0.0f;
1710     if (translate.x.Unit() == DimensionUnit::PERCENT || translate.y.Unit() == DimensionUnit::PERCENT) {
1711         auto rect = GetPaintRectWithoutTransform();
1712         if (rect.IsEmpty()) {
1713             // size is not determined yet
1714             return Vector3F();
1715         }
1716         xValue = translate.x.ConvertToPxWithSize(rect.Width());
1717         yValue = translate.y.ConvertToPxWithSize(rect.Height());
1718     } else {
1719         xValue = translate.x.ConvertToPx();
1720         yValue = translate.y.ConvertToPx();
1721     }
1722     // translateZ doesn't support percentage
1723     float zValue = translate.z.ConvertToPx();
1724     return Vector3F(xValue, yValue, zValue);
1725 }
1726 
OnTransformTranslateUpdate(const TranslateOptions & translate)1727 void RosenRenderContext::OnTransformTranslateUpdate(const TranslateOptions& translate)
1728 {
1729     CHECK_NULL_VOID(rsNode_);
1730     auto translateVec = MarshallTranslate(translate);
1731     auto changed = true;
1732     Rosen::Vector2f preTranslate;
1733     if (translateXYUserModifier_) {
1734         preTranslate =
1735             GetAnimatablePropertyStagingValue<Rosen::RSTranslateModifier, Rosen::Vector2f>(translateXYUserModifier_);
1736         changed = !NearEqual(preTranslate[0], translateVec.x) || !NearEqual(preTranslate[1], translateVec.y);
1737     }
1738     if (AnimationUtils::IsImplicitAnimationOpen() && translateXYUserModifier_ && GetHost()) {
1739         if (!(NearEqual(preTranslate[0], translateVec.x) && NearEqual(preTranslate[1], translateVec.y))) {
1740             auto host = GetHost();
1741             ACE_SCOPED_TRACE("translate from (%f, %f) to (%f, %f), id:%d, tag:%s", preTranslate[0], preTranslate[1],
1742                 translateVec.x, translateVec.y, host->GetId(), host->GetTag().c_str());
1743         }
1744     }
1745     SetAnimatableProperty<Rosen::RSTranslateModifier, Rosen::Vector2f>(
1746         translateXYUserModifier_, { translateVec.x, translateVec.y });
1747     SetAnimatableProperty<Rosen::RSTranslateZModifier, float>(translateZUserModifier_, translateVec.z);
1748     ElementRegister::GetInstance()->ReSyncGeometryTransition(GetHost());
1749     NotifyHostTransformUpdated(changed);
1750     RequestNextFrame();
1751 }
1752 
OnTransformRotateUpdate(const Vector5F & rotate)1753 void RosenRenderContext::OnTransformRotateUpdate(const Vector5F& rotate)
1754 {
1755     CHECK_NULL_VOID(rsNode_);
1756     float norm = std::sqrt(std::pow(rotate.x, 2) + std::pow(rotate.y, 2) + std::pow(rotate.z, 2));
1757     if (NearZero(norm)) {
1758         norm = 1.0f;
1759     }
1760     // for rosen backend, the rotation angles in the x and y directions should be set to opposite angles
1761     rsNode_->SetRotation(-rotate.w * rotate.x / norm, -rotate.w * rotate.y / norm, rotate.w * rotate.z / norm);
1762     // set camera distance
1763     rsNode_->SetCameraDistance(rotate.v);
1764     NotifyHostTransformUpdated();
1765     RequestNextFrame();
1766 }
1767 
OnTransformCenterUpdate(const DimensionOffset & center)1768 void RosenRenderContext::OnTransformCenterUpdate(const DimensionOffset& center)
1769 {
1770     RectF rect = GetPaintRectWithoutTransform();
1771     if (!RectIsNull()) {
1772         float xPivot = ConvertDimensionToScaleBySize(center.GetX(), rect.Width());
1773         float yPivot = ConvertDimensionToScaleBySize(center.GetY(), rect.Height());
1774         float zPivot = 0.0f;
1775         auto& z = center.GetZ();
1776         if (z.has_value()) {
1777             zPivot = static_cast<float>(z.value().ConvertToVp());
1778         }
1779         SetPivot(xPivot, yPivot, zPivot);
1780         NotifyHostTransformUpdated();
1781     }
1782     RequestNextFrame();
1783 }
1784 
OnTransformMatrixUpdate(const Matrix4 & matrix)1785 void RosenRenderContext::OnTransformMatrixUpdate(const Matrix4& matrix)
1786 {
1787     CHECK_NULL_VOID(rsNode_);
1788     if (!transformMatrixModifier_.has_value()) {
1789         transformMatrixModifier_ = TransformMatrixModifier();
1790     }
1791     DecomposedTransform transform;
1792     if (!TransformUtil::DecomposeTransform(transform, matrix)) {
1793         // fallback to basic matrix decompose
1794         Rosen::Vector2f xyTranslateValue { static_cast<float>(matrix.Get(0, 3)), static_cast<float>(matrix.Get(1, 3)) };
1795         Rosen::Vector2f scaleValue { 0.0f, 0.0f };
1796         AddOrChangeTranslateModifier(rsNode_, transformMatrixModifier_->translateXY,
1797             transformMatrixModifier_->translateXYValue, xyTranslateValue);
1798         AddOrChangeScaleModifier(
1799             rsNode_, transformMatrixModifier_->scaleXY, transformMatrixModifier_->scaleXYValue, scaleValue);
1800     } else {
1801         Rosen::Vector2f xyPerspectiveValue { transform.perspective[0], transform.perspective[1] };
1802         Rosen::Vector2f xyTranslateValue { transform.translate[0], transform.translate[1] };
1803         Rosen::Quaternion quaternion { static_cast<float>(transform.quaternion.GetX()),
1804             static_cast<float>(transform.quaternion.GetY()), static_cast<float>(transform.quaternion.GetZ()),
1805             static_cast<float>(transform.quaternion.GetW()) };
1806         Rosen::Vector2f scaleValue { transform.scale[0], transform.scale[1] };
1807         Rosen::Vector2f skewValue { transform.skew[0], transform.skew[1] };
1808 
1809         AddOrChangePerspectiveModifier(rsNode_, transformMatrixModifier_->perspectiveXY,
1810             transformMatrixModifier_->perspectiveXYValue, xyPerspectiveValue);
1811         AddOrChangeTranslateModifier(rsNode_, transformMatrixModifier_->translateXY,
1812             transformMatrixModifier_->translateXYValue, xyTranslateValue);
1813         AddOrChangeScaleModifier(
1814             rsNode_, transformMatrixModifier_->scaleXY, transformMatrixModifier_->scaleXYValue, scaleValue);
1815         AddOrChangeSkewModifier(
1816             rsNode_, transformMatrixModifier_->skewXY, transformMatrixModifier_->skewXYValue, skewValue);
1817         AddOrChangeQuaternionModifier(
1818             rsNode_, transformMatrixModifier_->quaternion, transformMatrixModifier_->quaternionValue, quaternion);
1819     }
1820     NotifyHostTransformUpdated();
1821     RequestNextFrame();
1822 }
1823 
1824 RectF gRect;
1825 
Degree2Radian(int32_t degree)1826 double Degree2Radian(int32_t degree)
1827 {
1828     const float pi = 3.14159265;
1829     degree = degree % FULL_ROTATION;
1830     if (degree < 0) {
1831         degree += FULL_ROTATION;
1832     }
1833     return degree * pi / STRAIGHT_ANGLE;
1834 }
1835 
SetCorner(double & x,double & y,double width,double height,int32_t degree)1836 void SetCorner(double& x, double& y, double width, double height, int32_t degree)
1837 {
1838     if (degree == RIGHT_ANGLE) {
1839         x = 0;
1840         y = height;
1841     } else if (degree == STRAIGHT_ANGLE) {
1842         x = width;
1843         y = height;
1844     } else if (degree == REFLEX_ANGLE) {
1845         x = width;
1846         y = 0;
1847     }
1848 }
1849 
SkewRect(float sx,float sy,RectF & rect)1850 void SkewRect(float sx, float sy, RectF& rect)
1851 {
1852     auto left = rect.Left();
1853     auto right = rect.Right();
1854     auto top = rect.Top();
1855     auto bottom = rect.Bottom();
1856 
1857     auto leftAfterSkew = sx > 0? left + sx * top: left + sx * bottom;
1858     auto rightAfterSkew = sx > 0? right + sx * bottom: right + sx * top;
1859     auto topAfterSkew = sy > 0? top + sy * left: top + sy * right;
1860     auto bottomAfterSkew = sy > 0? bottom + sy * right: bottom + sy * left;
1861 
1862     rect.SetLeft(leftAfterSkew);
1863     rect.SetWidth(rightAfterSkew - leftAfterSkew);
1864     rect.SetTop(topAfterSkew);
1865     rect.SetHeight(bottomAfterSkew - topAfterSkew);
1866 }
1867 
PerspectiveRect(float px,float py,RectF & rect)1868 void PerspectiveRect(float px, float py, RectF& rect)
1869 {
1870     auto left = rect.Left();
1871     auto right = rect.Right();
1872     auto top = rect.Top();
1873     auto bottom = rect.Bottom();
1874 
1875     auto leftAfterSkew = Infinity<double>();
1876     auto rightAfterSkew = -Infinity<double>();
1877     auto topAfterSkew = Infinity<double>();
1878     auto bottomAfterSkew = -Infinity<double>();
1879 
1880     double xValues[] = { left, right };
1881     double yValues[] = { top, bottom };
1882 
1883     for (uint32_t i = 0; i < 2; i++) {
1884         for (uint32_t j = 0; j < 2; j++) {
1885             double perspectiveValue = px * xValues[i] + py * yValues[j] + 1;
1886             if (NearZero(perspectiveValue)) {
1887                 return;
1888             }
1889             leftAfterSkew = std::min(leftAfterSkew, xValues[i] / perspectiveValue);
1890             rightAfterSkew = std::max(rightAfterSkew, xValues[i] / perspectiveValue);
1891             topAfterSkew = std::min(topAfterSkew, yValues[i] / perspectiveValue);
1892             bottomAfterSkew = std::max(bottomAfterSkew, yValues[i] / perspectiveValue);
1893         }
1894     }
1895 
1896     rect.SetLeft(leftAfterSkew);
1897     rect.SetWidth(rightAfterSkew - leftAfterSkew);
1898     rect.SetTop(topAfterSkew);
1899     rect.SetHeight(bottomAfterSkew - topAfterSkew);
1900 }
1901 
SkewPoint(float sx,float sy,PointF & point)1902 void SkewPoint(float sx, float sy, PointF& point)
1903 {
1904     auto x = point.GetX();
1905     auto y = point.GetY();
1906 
1907     point.SetX(x + y * sx);
1908     point.SetY(y + x * sy);
1909 }
1910 
GetPaintRectWithTransform()1911 RectF RosenRenderContext::GetPaintRectWithTransform()
1912 {
1913     RectF rect;
1914 
1915     CHECK_NULL_RETURN(rsNode_, rect);
1916     rect = GetPaintRectWithoutTransform();
1917     auto translate = rsNode_->GetStagingProperties().GetTranslate();
1918     auto skew = rsNode_->GetStagingProperties().GetSkew();
1919     auto perspective = rsNode_->GetStagingProperties().GetPersp();
1920     auto scale = rsNode_->GetStagingProperties().GetScale();
1921     auto center = rsNode_->GetStagingProperties().GetPivot();
1922     auto degree = rsNode_->GetStagingProperties().GetRotation();
1923     // calculate new pos.
1924     auto centOffset = OffsetF(center[0] * rect.Width(), center[1] * rect.Height());
1925     auto centerPos = rect.GetOffset() + centOffset;
1926     auto newPos = centerPos - OffsetF(centOffset.GetX() * scale[0], centOffset.GetY() * scale[1]);
1927     newPos = newPos + OffsetF(translate[0], translate[1]);
1928     rect.SetOffset(newPos);
1929     // calculate new size.
1930     auto oldSize = rect.GetSize();
1931     auto newSize = SizeF(oldSize.Width() * scale[0], oldSize.Height() * scale[1]);
1932     rect.SetSize(newSize);
1933     // calculate skew
1934     SkewRect(skew[0], skew[1], rect);
1935     // calculate rotate
1936     degree = static_cast<int32_t>(degree) % FULL_ROTATION;
1937     auto radian = Degree2Radian(degree);
1938     if (degree != 0) {
1939         auto newRect = GetPaintRectWithoutTransform();
1940         double leftX = 0.0;
1941         double leftY = 0.0;
1942         degree = degree < 0 ? degree + FULL_ROTATION : degree;
1943         SetCorner(leftX, leftY, oldSize.Width(), oldSize.Height(), degree);
1944         double centerX = oldSize.Width() * center[0];
1945         double centerY = oldSize.Height() * center[1];
1946         auto tmp = leftX;
1947         leftX = (leftX - centerX) * cos(-1 * radian) + (leftY - centerY) * sin(-1 * radian);
1948         leftY = -1 * (tmp - centerX) * sin(-1 * radian) + (leftY - centerY) * cos(-1 * radian);
1949         leftX += newRect.GetOffset().GetX() + centerX;
1950         leftY += newRect.GetOffset().GetY() + centerY;
1951         auto offset = OffsetF(leftX + translate[0], leftY + translate[1]);
1952         rect.SetOffset(offset);
1953         if (degree == STRAIGHT_ANGLE) {
1954             newSize = SizeF(oldSize.Width() * scale[0], oldSize.Height() * scale[1]);
1955         } else {
1956             newSize = SizeF(oldSize.Height() * scale[1], oldSize.Width() * scale[0]);
1957         }
1958         rect.SetSize(newSize);
1959 
1960         // calculate perspective
1961         PerspectiveRect(perspective[0], perspective[1], rect);
1962     }
1963     gRect = rect;
1964     return rect;
1965 }
1966 
GetPaintRectWithTranslate()1967 std::pair<RectF, bool> RosenRenderContext::GetPaintRectWithTranslate()
1968 {
1969     RectF rect;
1970     bool error = hasScales_;
1971     CHECK_NULL_RETURN(rsNode_, std::make_pair(rect, error));
1972     if (rsNode_->GetStagingProperties().GetRotation()) {
1973         return std::make_pair(RectF(0, 0, -1, -1), error);
1974     }
1975     rect = GetPaintRectWithoutTransform();
1976     auto translate = rsNode_->GetStagingProperties().GetTranslate();
1977     rect.SetOffset(rect.GetOffset() + OffsetF(translate[0], translate[1]));
1978     return std::make_pair(rect, error);
1979 }
1980 
GetRevertMatrix()1981 Matrix4 RosenRenderContext::GetRevertMatrix()
1982 {
1983     CHECK_NULL_RETURN(rsNode_, {});
1984     auto center = rsNode_->GetStagingProperties().GetPivot();
1985     Matrix4 rotateMat;
1986     if (transformMatrixModifier_ &&
1987         !transformMatrixModifier_->quaternionValue->GetStagingValue().IsIdentity()) {
1988         auto quaternionValue = transformMatrixModifier_->quaternionValue->GetStagingValue();
1989         rotateMat = Matrix4::QuaternionToMatrix(quaternionValue[0], quaternionValue[1],
1990             quaternionValue[2], quaternionValue[3]);
1991     } else {
1992         int32_t degree = rsNode_->GetStagingProperties().GetRotation();
1993         if (rsNode_->GetType() == RSUINodeType::DISPLAY_NODE && degree != 0) {
1994             degree = 0;
1995             return Matrix4();
1996         }
1997         rotateMat = Matrix4::CreateRotate(degree, 0, 0, 1);
1998     }
1999 
2000     auto translate = rsNode_->GetStagingProperties().GetTranslate();
2001     auto skew = rsNode_->GetStagingProperties().GetSkew();
2002     auto scale = rsNode_->GetStagingProperties().GetScale();
2003     auto perspective = rsNode_->GetStagingProperties().GetPersp();
2004 
2005     RectF rect = GetPaintRectWithoutTransform();
2006     auto centOffset = OffsetF(center[0] * rect.Width(), center[1] * rect.Height());
2007     auto centerPos = rect.GetOffset() + centOffset;
2008 
2009     auto perspectiveMat = Matrix4::CreateTranslate(centerPos.GetX(), centerPos.GetY(), 0) *
2010                        Matrix4::CreateFactorPerspective(perspective[0], perspective[1]) *
2011                        Matrix4::CreateTranslate(-centerPos.GetX(), -centerPos.GetY(), 0);
2012     auto translateMat = Matrix4::CreateTranslate(translate[0], translate[1], 0);
2013     auto rotationMat = Matrix4::CreateTranslate(centerPos.GetX(), centerPos.GetY(), 0) *
2014                        rotateMat *
2015                        Matrix4::CreateTranslate(-centerPos.GetX(), -centerPos.GetY(), 0);
2016     auto skewMat = Matrix4::CreateTranslate(centerPos.GetX(), centerPos.GetY(), 0) *
2017                     Matrix4::CreateFactorSkew(skew[0], skew[1]) *
2018                     Matrix4::CreateTranslate(-centerPos.GetX(), -centerPos.GetY(), 0);
2019     auto scaleMat = Matrix4::CreateTranslate(centerPos.GetX(), centerPos.GetY(), 0) *
2020                     Matrix4::CreateScale(scale[0], scale[1], 1) *
2021                     Matrix4::CreateTranslate(-centerPos.GetX(), -centerPos.GetY(), 0);
2022 
2023     return Matrix4::Invert(perspectiveMat * translateMat * rotationMat * skewMat * scaleMat);
2024 }
2025 
GetMatrix()2026 Matrix4 RosenRenderContext::GetMatrix()
2027 {
2028     CHECK_NULL_RETURN(rsNode_, {});
2029     auto center = rsNode_->GetStagingProperties().GetPivot();
2030     int32_t degree = rsNode_->GetStagingProperties().GetRotation();
2031     if (rsNode_->GetType() == RSUINodeType::DISPLAY_NODE && degree != 0) {
2032         degree = 0;
2033         return Matrix4();
2034     }
2035 
2036     auto translate = rsNode_->GetStagingProperties().GetTranslate();
2037     auto skew = rsNode_->GetStagingProperties().GetSkew();
2038     auto scale = rsNode_->GetStagingProperties().GetScale();
2039 
2040     RectF rect = GetPaintRectWithoutTransform();
2041     auto centOffset = OffsetF(center[0] * rect.Width(), center[1] * rect.Height());
2042     auto centerPos = rect.GetOffset() + centOffset;
2043 
2044     auto translateMat = Matrix4::CreateTranslate(translate[0], translate[1], 0);
2045     auto rotationMat = Matrix4::CreateTranslate(centerPos.GetX(), centerPos.GetY(), 0) *
2046                        Matrix4::CreateRotate(degree, 0, 0, 1) *
2047                        Matrix4::CreateTranslate(-centerPos.GetX(), -centerPos.GetY(), 0);
2048     auto skewMat = Matrix4::CreateTranslate(centerPos.GetX(), centerPos.GetY(), 0) *
2049                     Matrix4::CreateFactorSkew(skew[0], skew[1]) *
2050                     Matrix4::CreateTranslate(-centerPos.GetX(), -centerPos.GetY(), 0);
2051     auto scaleMat = Matrix4::CreateTranslate(centerPos.GetX(), centerPos.GetY(), 0) *
2052                     Matrix4::CreateScale(scale[0], scale[1], 1) *
2053                     Matrix4::CreateTranslate(-centerPos.GetX(), -centerPos.GetY(), 0);
2054 
2055     return translateMat * rotationMat * skewMat * scaleMat;
2056 }
2057 
2058 // only for GetPositionToXXXWithTransform in FrameNode.
2059 // contains rotate and perspective matrix set by tranform.
GetMatrixWithTransformRotate()2060 Matrix4 RosenRenderContext::GetMatrixWithTransformRotate()
2061 {
2062     CHECK_NULL_RETURN(rsNode_, {});
2063     auto center = rsNode_->GetStagingProperties().GetPivot();
2064 
2065     Matrix4 rotateMat;
2066     if (transformMatrixModifier_ &&
2067         !transformMatrixModifier_->quaternionValue->GetStagingValue().IsIdentity()) {
2068         auto quaternionValue = transformMatrixModifier_->quaternionValue->GetStagingValue();
2069         rotateMat = Matrix4::QuaternionToMatrix(quaternionValue[0], quaternionValue[1],
2070             quaternionValue[2], quaternionValue[3]);
2071     } else {
2072         int32_t degree = rsNode_->GetStagingProperties().GetRotation();
2073         if (rsNode_->GetType() == RSUINodeType::DISPLAY_NODE && degree != 0) {
2074             degree = 0;
2075             return Matrix4();
2076         }
2077         rotateMat = Matrix4::CreateRotate(degree, 0, 0, 1);
2078     }
2079 
2080     auto translate = rsNode_->GetStagingProperties().GetTranslate();
2081     auto skew = rsNode_->GetStagingProperties().GetSkew();
2082     auto scale = rsNode_->GetStagingProperties().GetScale();
2083     auto perspective = rsNode_->GetStagingProperties().GetPersp();
2084 
2085     RectF rect = GetPaintRectWithoutTransform();
2086     auto centOffset = OffsetF(center[0] * rect.Width(), center[1] * rect.Height());
2087     auto centerPos = rect.GetOffset() + centOffset;
2088 
2089     auto perspectiveMat = Matrix4::CreateTranslate(centerPos.GetX(), centerPos.GetY(), 0) *
2090                        Matrix4::CreateFactorPerspective(perspective[0], perspective[1]) *
2091                        Matrix4::CreateTranslate(-centerPos.GetX(), -centerPos.GetY(), 0);
2092     auto translateMat = Matrix4::CreateTranslate(translate[0], translate[1], 0);
2093     auto rotationMat = Matrix4::CreateTranslate(centerPos.GetX(), centerPos.GetY(), 0) *
2094                        rotateMat *
2095                        Matrix4::CreateTranslate(-centerPos.GetX(), -centerPos.GetY(), 0);
2096     auto skewMat = Matrix4::CreateTranslate(centerPos.GetX(), centerPos.GetY(), 0) *
2097                     Matrix4::CreateFactorSkew(skew[0], skew[1]) *
2098                     Matrix4::CreateTranslate(-centerPos.GetX(), -centerPos.GetY(), 0);
2099     auto scaleMat = Matrix4::CreateTranslate(centerPos.GetX(), centerPos.GetY(), 0) *
2100                     Matrix4::CreateScale(scale[0], scale[1], 1) *
2101                     Matrix4::CreateTranslate(-centerPos.GetX(), -centerPos.GetY(), 0);
2102 
2103     return perspectiveMat * translateMat * rotationMat * skewMat * scaleMat;
2104 }
2105 
GetLocalTransformMatrix()2106 Matrix4 RosenRenderContext::GetLocalTransformMatrix()
2107 {
2108     auto invertMat = GetRevertMatrix();
2109     RectF rect = GetPaintRectWithoutTransform();
2110     auto transformMat = Matrix4::CreateTranslate(-rect.GetOffset().GetX(), -rect.GetOffset().GetY(), 0) * invertMat;
2111     return transformMat;
2112 }
2113 
GetPointWithRevert(PointF & point)2114 void RosenRenderContext::GetPointWithRevert(PointF& point)
2115 {
2116     auto invertMat = GetRevertMatrix();
2117     Point tmp(point.GetX(), point.GetY());
2118     auto invertPoint = invertMat * tmp;
2119     point.SetX(invertPoint.GetX());
2120     point.SetY(invertPoint.GetY());
2121 }
2122 
GetPointTransform(PointF & point)2123 void RosenRenderContext::GetPointTransform(PointF& point)
2124 {
2125     auto transformMat = GetMatrix();
2126     Point tmp(point.GetX(), point.GetY());
2127     auto transformPoint = transformMat * tmp;
2128     point.SetX(transformPoint.GetX());
2129     point.SetY(transformPoint.GetY());
2130 }
2131 
2132 // only for GetPositionToXXXWithTransform in FrameNode
GetPointTransformRotate(PointF & point)2133 void RosenRenderContext::GetPointTransformRotate(PointF& point)
2134 {
2135     auto transformMat = GetMatrixWithTransformRotate();
2136     Point tmp(point.GetX(), point.GetY());
2137     auto transformPoint = transformMat * tmp;
2138     point.SetX(transformPoint.GetX());
2139     point.SetY(transformPoint.GetY());
2140 }
2141 
GetPointWithTransform(PointF & point)2142 void RosenRenderContext::GetPointWithTransform(PointF& point)
2143 {
2144     CHECK_NULL_VOID(rsNode_);
2145     auto translate = rsNode_->GetStagingProperties().GetTranslate();
2146     auto skew = rsNode_->GetStagingProperties().GetSkew();
2147     auto perspective = rsNode_->GetStagingProperties().GetPersp();
2148     auto scale = rsNode_->GetStagingProperties().GetScale();
2149     point = PointF(point.GetX() / scale[0], point.GetY() / scale[1]);
2150     SkewPoint(skew[0], skew[1], point);
2151     RectF rect = GetPaintRectWithoutTransform();
2152     auto center = rsNode_->GetStagingProperties().GetPivot();
2153     int32_t degree = rsNode_->GetStagingProperties().GetRotation();
2154     if (rsNode_->GetType() == RSUINodeType::DISPLAY_NODE && degree != 0) {
2155         degree = 0;
2156     }
2157     degree = degree % FULL_ROTATION;
2158     auto radian = Degree2Radian(degree);
2159     if (degree != 0) {
2160         point = point + gRect.GetOffset();
2161         point = point - OffsetF(translate[0], translate[1]);
2162         auto centOffset = OffsetF(center[0] * gRect.Width(), center[1] * gRect.Height());
2163         auto centerPos = gRect.GetOffset() + centOffset - OffsetF(translate[0], translate[1]);
2164         auto centerX = centerPos.GetX();
2165         auto centerY = centerPos.GetY();
2166 
2167         double currentPointX = (point.GetX() - centerX) * cos(radian) + (point.GetY() - centerY) * sin(radian);
2168         double currentPointY = -1 * (point.GetX() - centerX) * sin(radian) + (point.GetY() - centerY) * cos(radian);
2169         currentPointX += centerX - rect.Left();
2170         currentPointY += centerY - rect.Top();
2171 
2172         double perspectiveValue = perspective[0] * currentPointX + perspective[1] * currentPointY + 1;
2173         if (NearZero(perspectiveValue)) {
2174             point.SetX(currentPointX);
2175             point.SetY(currentPointY);
2176             return;
2177         }
2178 
2179         point.SetX(currentPointX / perspectiveValue);
2180         point.SetY(currentPointY / perspectiveValue);
2181     }
2182 }
2183 
GetPaintRectWithoutTransform()2184 RectF RosenRenderContext::GetPaintRectWithoutTransform()
2185 {
2186     return paintRect_;
2187 }
2188 
UpdateTranslateInXY(const OffsetF & offset)2189 void RosenRenderContext::UpdateTranslateInXY(const OffsetF& offset)
2190 {
2191     CHECK_NULL_VOID(rsNode_);
2192     auto xValue = offset.GetX();
2193     auto yValue = offset.GetY();
2194     if (translateXY_) {
2195         auto propertyXY = std::static_pointer_cast<RSAnimatableProperty<Vector2f>>(translateXY_->GetProperty());
2196         if (propertyXY) {
2197             propertyXY->Set({ xValue, yValue });
2198         }
2199     } else {
2200         auto propertyXY = std::make_shared<RSAnimatableProperty<Vector2f>>(Vector2f(xValue, yValue));
2201         translateXY_ = std::make_shared<Rosen::RSTranslateModifier>(propertyXY);
2202         rsNode_->AddModifier(translateXY_);
2203     }
2204     ElementRegister::GetInstance()->ReSyncGeometryTransition(GetHost());
2205     NotifyHostTransformUpdated();
2206 }
2207 
GetShowingTranslateProperty()2208 OffsetF RosenRenderContext::GetShowingTranslateProperty()
2209 {
2210     OffsetF offset;
2211     CHECK_NULL_RETURN(translateXY_, offset);
2212     auto property = std::static_pointer_cast<RSAnimatableProperty<Vector2f>>(translateXY_->GetProperty());
2213     CHECK_NULL_RETURN(property, offset);
2214     auto result = property->GetShowingValueAndCancelAnimation();
2215     if (!result) {
2216         return offset;
2217     }
2218     auto translate = property->Get();
2219     offset.SetX(translate[0]);
2220     offset.SetY(translate[1]);
2221     return offset;
2222 }
2223 
CancelTranslateXYAnimation()2224 void RosenRenderContext::CancelTranslateXYAnimation()
2225 {
2226     CHECK_NULL_VOID(translateXY_);
2227     auto property = std::static_pointer_cast<RSAnimatableProperty<Vector2f>>(translateXY_->GetProperty());
2228     CHECK_NULL_VOID(property);
2229     property->RequestCancelAnimation();
2230 }
2231 
GetTranslateXYProperty()2232 OffsetF RosenRenderContext::GetTranslateXYProperty()
2233 {
2234     OffsetF offset;
2235     CHECK_NULL_RETURN(translateXY_, offset);
2236     auto property = std::static_pointer_cast<RSAnimatableProperty<Vector2f>>(translateXY_->GetProperty());
2237     CHECK_NULL_RETURN(property, offset);
2238     auto translate = property->Get();
2239     offset.SetX(translate[0]);
2240     offset.SetY(translate[1]);
2241     return offset;
2242 }
2243 
NotifyTransitionInner(const SizeF & frameSize,bool isTransitionIn)2244 void RosenRenderContext::NotifyTransitionInner(const SizeF& frameSize, bool isTransitionIn)
2245 {
2246     CHECK_NULL_VOID(rsNode_);
2247     if (propTransitionAppearing_ || propTransitionDisappearing_) {
2248         // old transition
2249         auto& transOptions = isTransitionIn ? propTransitionAppearing_ : propTransitionDisappearing_;
2250         auto effect = GetRSTransitionWithoutType(transOptions, frameSize);
2251         CHECK_NULL_VOID(effect);
2252         SetTransitionPivot(frameSize, isTransitionIn);
2253         // notice that we have been in animateTo, so do not need to use Animation closure to notify transition.
2254         rsNode_->NotifyTransition(effect, isTransitionIn);
2255         return;
2256     }
2257     // add default transition effect on the 'breaking point' of render tree, if no user-defined transition effect
2258     // and triggered in AnimateTo closure.
2259     // Note: this default transition effect will be removed after all transitions finished, implemented in
2260     // OnTransitionInFinish. and OnTransitionOutFinish.
2261     if (isBreakingPoint_ && !transitionEffect_ && AnimationUtils::IsImplicitAnimationOpen()) {
2262         hasDefaultTransition_ = true;
2263         transitionEffect_ = RosenTransitionEffect::CreateDefaultRosenTransitionEffect();
2264         RSNode::ExecuteWithoutAnimation([this, isTransitionIn]() {
2265             // transitionIn effects should be initialized as active if is transitionIn.
2266             transitionEffect_->Attach(Claim(this), isTransitionIn);
2267         });
2268     }
2269     NotifyTransition(isTransitionIn);
2270 }
2271 
OpacityAnimation(const AnimationOption & option,double begin,double end)2272 void RosenRenderContext::OpacityAnimation(const AnimationOption& option, double begin, double end)
2273 {
2274     CHECK_NULL_VOID(rsNode_);
2275     rsNode_->SetAlpha(begin);
2276     AnimationUtils::Animate(
2277         option,
2278         [rsNode = rsNode_, endAlpha = end]() {
2279             CHECK_NULL_VOID(rsNode);
2280             rsNode->SetAlpha(endAlpha);
2281         },
2282         option.GetOnFinishEvent());
2283 }
2284 
ScaleAnimation(const AnimationOption & option,double begin,double end)2285 void RosenRenderContext::ScaleAnimation(const AnimationOption& option, double begin, double end)
2286 {
2287     CHECK_NULL_VOID(rsNode_);
2288     SetScale(begin, begin);
2289     AnimationUtils::Animate(
2290         option, [this, end]() { SetScale(end, end); }, option.GetOnFinishEvent());
2291 }
2292 
SetBorderRadius(const BorderRadiusProperty & value)2293 void RosenRenderContext::SetBorderRadius(const BorderRadiusProperty& value)
2294 {
2295     CHECK_NULL_VOID(rsNode_);
2296     auto paintRect = AdjustPaintRect();
2297     if (isDisappearing_ && !paintRect.IsValid()) {
2298         return;
2299     }
2300     double width = paintRect.Width();
2301     Rosen::Vector4f cornerRadius;
2302     cornerRadius.SetValues(static_cast<float>(value.radiusTopLeft.value_or(Dimension()).ConvertToPxWithSize(width)),
2303         static_cast<float>(value.radiusTopRight.value_or(Dimension()).ConvertToPxWithSize(width)),
2304         static_cast<float>(value.radiusBottomRight.value_or(Dimension()).ConvertToPxWithSize(width)),
2305         static_cast<float>(value.radiusBottomLeft.value_or(Dimension()).ConvertToPxWithSize(width)));
2306     rsNode_->SetCornerRadius(cornerRadius);
2307     RequestNextFrame();
2308 }
2309 
OnBorderRadiusUpdate(const BorderRadiusProperty & value)2310 void RosenRenderContext::OnBorderRadiusUpdate(const BorderRadiusProperty& value)
2311 {
2312     if (densityChangedCallbackId_ == DEFAULT_CALLBACK_ID) {
2313         auto context = GetPipelineContext();
2314         CHECK_NULL_VOID(context);
2315         densityChangedCallbackId_ = context->RegisterDensityChangedCallback(
2316             [self = WeakClaim(this)](double density) {
2317             auto renderContext = self.Upgrade();
2318             CHECK_NULL_VOID(renderContext);
2319             auto borderRadius = renderContext->GetBorderRadius();
2320             if (borderRadius.has_value()) {
2321                 renderContext->SetBorderRadius(borderRadius.value());
2322             }
2323         });
2324     }
2325     CHECK_NULL_VOID(isSynced_);
2326     SetBorderRadius(value);
2327 }
2328 
OnBorderColorUpdate(const BorderColorProperty & value)2329 void RosenRenderContext::OnBorderColorUpdate(const BorderColorProperty& value)
2330 {
2331     SetBorderColor(value);
2332 }
2333 
SetBorderColor(const BorderColorProperty & value)2334 void RosenRenderContext::SetBorderColor(const BorderColorProperty& value)
2335 {
2336     CHECK_NULL_VOID(rsNode_);
2337     rsNode_->SetBorderColor(value.leftColor.value_or(Color::BLACK).GetValue(),
2338         value.topColor.value_or(Color::BLACK).GetValue(), value.rightColor.value_or(Color::BLACK).GetValue(),
2339         value.bottomColor.value_or(Color::BLACK).GetValue());
2340     RequestNextFrame();
2341 }
2342 
SetBorderWidth(const BorderWidthProperty & value)2343 void RosenRenderContext::SetBorderWidth(const BorderWidthProperty& value)
2344 {
2345     CHECK_NULL_VOID(rsNode_);
2346     Rosen::Vector4f cornerBorderWidth;
2347     cornerBorderWidth.SetValues(static_cast<float>((value.leftDimen.value()).ConvertToPx()),
2348         static_cast<float>((value.topDimen.value()).ConvertToPx()),
2349         static_cast<float>((value.rightDimen.value()).ConvertToPx()),
2350         static_cast<float>((value.bottomDimen.value()).ConvertToPx()));
2351     rsNode_->SetBorderWidth(cornerBorderWidth);
2352     borderWidth_ = cornerBorderWidth;
2353     RequestNextFrame();
2354 }
2355 
UpdateBorderWidthF(const BorderWidthPropertyF & value)2356 void RosenRenderContext::UpdateBorderWidthF(const BorderWidthPropertyF& value)
2357 {
2358     CHECK_NULL_VOID(rsNode_);
2359     Rosen::Vector4f cornerBorderWidth;
2360     cornerBorderWidth.SetValues(value.leftDimen.value_or(0), static_cast<float>(value.topDimen.value_or(0)),
2361         static_cast<float>(value.rightDimen.value_or(0)), static_cast<float>(value.bottomDimen.value_or(0)));
2362     rsNode_->SetBorderWidth(cornerBorderWidth);
2363     borderWidth_ = cornerBorderWidth;
2364     RequestNextFrame();
2365 }
2366 
OnBorderStyleUpdate(const BorderStyleProperty & value)2367 void RosenRenderContext::OnBorderStyleUpdate(const BorderStyleProperty& value)
2368 {
2369     SetBorderStyle(value);
2370 }
2371 
SetBorderStyle(const BorderStyleProperty & value)2372 void RosenRenderContext::SetBorderStyle(const BorderStyleProperty& value)
2373 {
2374     CHECK_NULL_VOID(rsNode_);
2375     rsNode_->SetBorderStyle(static_cast<uint32_t>(value.styleLeft.value_or(BorderStyle::SOLID)),
2376         static_cast<uint32_t>(value.styleTop.value_or(BorderStyle::SOLID)),
2377         static_cast<uint32_t>(value.styleRight.value_or(BorderStyle::SOLID)),
2378         static_cast<uint32_t>(value.styleBottom.value_or(BorderStyle::SOLID)));
2379     RequestNextFrame();
2380 }
2381 
OnDashGapUpdate(const BorderWidthProperty & value)2382 void RosenRenderContext::OnDashGapUpdate(const BorderWidthProperty& value)
2383 {
2384     SetDashGap(value);
2385 }
2386 
SetDashGap(const BorderWidthProperty & value)2387 void RosenRenderContext::SetDashGap(const BorderWidthProperty& value)
2388 {
2389     CHECK_NULL_VOID(rsNode_);
2390     Rosen::Vector4f cornerDashGap;
2391     cornerDashGap.SetValues(static_cast<float>((value.leftDimen.value_or(DASH_GEP_WIDTH)).ConvertToPx()),
2392         static_cast<float>((value.topDimen.value_or(DASH_GEP_WIDTH)).ConvertToPx()),
2393         static_cast<float>((value.rightDimen.value_or(DASH_GEP_WIDTH)).ConvertToPx()),
2394         static_cast<float>((value.bottomDimen.value_or(DASH_GEP_WIDTH)).ConvertToPx()));
2395     rsNode_->SetBorderDashGap(cornerDashGap);
2396     RequestNextFrame();
2397 }
2398 
OnDashWidthUpdate(const BorderWidthProperty & value)2399 void RosenRenderContext::OnDashWidthUpdate(const BorderWidthProperty& value)
2400 {
2401     SetDashWidth(value);
2402 }
2403 
SetDashWidth(const BorderWidthProperty & value)2404 void RosenRenderContext::SetDashWidth(const BorderWidthProperty& value)
2405 {
2406     CHECK_NULL_VOID(rsNode_);
2407     Rosen::Vector4f cornerDashWidth;
2408     cornerDashWidth.SetValues(static_cast<float>((value.leftDimen.value_or(DASH_GEP_WIDTH)).ConvertToPx()),
2409         static_cast<float>((value.topDimen.value_or(DASH_GEP_WIDTH)).ConvertToPx()),
2410         static_cast<float>((value.rightDimen.value_or(DASH_GEP_WIDTH)).ConvertToPx()),
2411         static_cast<float>((value.bottomDimen.value_or(DASH_GEP_WIDTH)).ConvertToPx()));
2412     rsNode_->SetBorderDashWidth(cornerDashWidth);
2413     RequestNextFrame();
2414 }
2415 
OnOuterBorderRadiusUpdate(const BorderRadiusProperty & value)2416 void RosenRenderContext::OnOuterBorderRadiusUpdate(const BorderRadiusProperty& value)
2417 {
2418     SetOuterBorderRadius(value);
2419 }
2420 
SetOuterBorderRadius(const BorderRadiusProperty & value)2421 void RosenRenderContext::SetOuterBorderRadius(const BorderRadiusProperty& value)
2422 {
2423     CHECK_NULL_VOID(rsNode_);
2424     auto paintRect = AdjustPaintRect();
2425     if (isDisappearing_ && !paintRect.IsValid()) {
2426         return;
2427     }
2428     double radiusX = paintRect.Width();
2429     Rosen::Vector4f cornerRadius;
2430     cornerRadius.SetValues(
2431         static_cast<float>(value.radiusTopLeft.value_or(Dimension(0.0)).ConvertToPxWithSize(radiusX)),
2432         static_cast<float>(value.radiusTopRight.value_or(Dimension(0.0)).ConvertToPxWithSize(radiusX)),
2433         static_cast<float>(value.radiusBottomRight.value_or(Dimension(0.0)).ConvertToPxWithSize(radiusX)),
2434         static_cast<float>(value.radiusBottomLeft.value_or(Dimension(0.0)).ConvertToPxWithSize(radiusX)));
2435     rsNode_->SetOuterBorderRadius(cornerRadius);
2436     RequestNextFrame();
2437 }
2438 
OnOuterBorderColorUpdate(const BorderColorProperty & value)2439 void RosenRenderContext::OnOuterBorderColorUpdate(const BorderColorProperty& value)
2440 {
2441     SetOuterBorderColor(value);
2442 }
2443 
SetOuterBorderColor(const BorderColorProperty & value)2444 void RosenRenderContext::SetOuterBorderColor(const BorderColorProperty& value)
2445 {
2446     CHECK_NULL_VOID(rsNode_);
2447     Rosen::Vector4<Rosen::RSColor> color(Rosen::RSColor::FromArgbInt(value.leftColor.value_or(Color::BLACK).GetValue()),
2448         Rosen::RSColor::FromArgbInt(value.topColor.value_or(Color::BLACK).GetValue()),
2449         Rosen::RSColor::FromArgbInt(value.rightColor.value_or(Color::BLACK).GetValue()),
2450         Rosen::RSColor::FromArgbInt(value.bottomColor.value_or(Color::BLACK).GetValue()));
2451     rsNode_->SetOuterBorderColor(color);
2452     RequestNextFrame();
2453 }
2454 
OnOuterBorderWidthUpdate(const BorderWidthProperty & value)2455 void RosenRenderContext::OnOuterBorderWidthUpdate(const BorderWidthProperty& value)
2456 {
2457     SetOuterBorderWidth(value);
2458 }
2459 
SetOuterBorderWidth(const BorderWidthProperty & value)2460 void RosenRenderContext::SetOuterBorderWidth(const BorderWidthProperty& value)
2461 {
2462     CHECK_NULL_VOID(rsNode_);
2463     Rosen::Vector4f cornerBorderWidth;
2464     cornerBorderWidth.SetValues(static_cast<float>((value.leftDimen.value_or(Dimension(0.0))).ConvertToPx()),
2465         static_cast<float>((value.topDimen.value_or(Dimension(0.0))).ConvertToPx()),
2466         static_cast<float>((value.rightDimen.value_or(Dimension(0.0))).ConvertToPx()),
2467         static_cast<float>((value.bottomDimen.value_or(Dimension(0.0))).ConvertToPx()));
2468     rsNode_->SetOuterBorderWidth(cornerBorderWidth);
2469     RequestNextFrame();
2470 }
2471 
OnOuterBorderStyleUpdate(const BorderStyleProperty & value)2472 void RosenRenderContext::OnOuterBorderStyleUpdate(const BorderStyleProperty& value)
2473 {
2474     SetOuterBorderStyle(value);
2475 }
2476 
SetOuterBorderStyle(const BorderStyleProperty & value)2477 void RosenRenderContext::SetOuterBorderStyle(const BorderStyleProperty& value)
2478 {
2479     CHECK_NULL_VOID(rsNode_);
2480     Rosen::Vector4<Rosen::BorderStyle> borderStyle(
2481         static_cast<Rosen::BorderStyle>(static_cast<uint32_t>(value.styleLeft.value_or(BorderStyle::SOLID))),
2482         static_cast<Rosen::BorderStyle>(static_cast<uint32_t>(value.styleTop.value_or(BorderStyle::SOLID))),
2483         static_cast<Rosen::BorderStyle>(static_cast<uint32_t>(value.styleRight.value_or(BorderStyle::SOLID))),
2484         static_cast<Rosen::BorderStyle>(static_cast<uint32_t>(value.styleBottom.value_or(BorderStyle::SOLID))));
2485     rsNode_->SetOuterBorderStyle(borderStyle);
2486     RequestNextFrame();
2487 }
2488 
OnAccessibilityFocusUpdate(bool isAccessibilityFocus,const int64_t accessibilityIdForVirtualNode)2489 void RosenRenderContext::OnAccessibilityFocusUpdate(
2490     bool isAccessibilityFocus, const int64_t accessibilityIdForVirtualNode)
2491 {
2492     auto uiNode = GetHost();
2493     CHECK_NULL_VOID(uiNode);
2494     UpdateAccessibilityFocus(isAccessibilityFocus);
2495     if (isAccessibilityFocus) {
2496         PaintAccessibilityFocus();
2497     } else {
2498         ClearAccessibilityFocus();
2499     }
2500 
2501     if (accessibilityIdForVirtualNode == ACCESSIBILITY_FOCUS_WITHOUT_EVENT) {
2502         return;
2503     }
2504 
2505     if (accessibilityIdForVirtualNode == INVALID_PARENT_ID) {
2506         uiNode->OnAccessibilityEvent(isAccessibilityFocus ? AccessibilityEventType::ACCESSIBILITY_FOCUSED
2507                                                           : AccessibilityEventType::ACCESSIBILITY_FOCUS_CLEARED);
2508     } else {
2509         uiNode->OnAccessibilityEventForVirtualNode(isAccessibilityFocus
2510                                                        ? AccessibilityEventType::ACCESSIBILITY_FOCUSED
2511                                                        : AccessibilityEventType::ACCESSIBILITY_FOCUS_CLEARED,
2512             accessibilityIdForVirtualNode);
2513     }
2514 }
2515 
OnAccessibilityFocusRectUpdate(RectT<int32_t> accessibilityFocusRect)2516 void RosenRenderContext::OnAccessibilityFocusRectUpdate(RectT<int32_t> accessibilityFocusRect)
2517 {
2518     auto isAccessibilityFocus = GetAccessibilityFocus().value_or(false);
2519     if (isAccessibilityFocus) {
2520         PaintAccessibilityFocus();
2521     }
2522 }
2523 
OnUseEffectUpdate(bool useEffect)2524 void RosenRenderContext::OnUseEffectUpdate(bool useEffect)
2525 {
2526     CHECK_NULL_VOID(rsNode_);
2527     rsNode_->SetUseEffect(useEffect);
2528 }
2529 
OnUseShadowBatchingUpdate(bool useShadowBatching)2530 void RosenRenderContext::OnUseShadowBatchingUpdate(bool useShadowBatching)
2531 {
2532     CHECK_NULL_VOID(rsNode_);
2533     rsNode_->SetUseShadowBatching(useShadowBatching);
2534 }
2535 
OnFreezeUpdate(bool isFreezed)2536 void RosenRenderContext::OnFreezeUpdate(bool isFreezed)
2537 {
2538     CHECK_NULL_VOID(rsNode_);
2539     rsNode_->SetFreeze(isFreezed);
2540 }
2541 
PaintAccessibilityFocus()2542 void RosenRenderContext::PaintAccessibilityFocus()
2543 {
2544     CHECK_NULL_VOID(rsNode_);
2545     Dimension focusPaddingVp = Dimension(0.0, DimensionUnit::VP);
2546     constexpr uint32_t ACCESSIBILITY_FOCUS_COLOR = 0xbf39b500;
2547     constexpr double ACCESSIBILITY_FOCUS_WIDTH = 4.0;
2548     constexpr float kAccessibilityMinSize = 1.0f;
2549     double lineWidth = ACCESSIBILITY_FOCUS_WIDTH * PipelineBase::GetCurrentDensity();
2550     Color paintColor(ACCESSIBILITY_FOCUS_COLOR);
2551     Dimension paintWidth(lineWidth, DimensionUnit::PX);
2552     const auto& bounds = rsNode_->GetStagingProperties().GetBounds();
2553     RoundRect frameRect;
2554     double noGreenBorderWidth = (bounds.w_ - (2 * lineWidth)) > 0 ? (bounds.w_ - (2 * lineWidth)) : 0;
2555     double noGreenBorderHeight = (bounds.z_ - (2 * lineWidth)) > 0 ? (bounds.z_ - (2 * lineWidth)) : 0;
2556     frameRect.SetRect(RectF(lineWidth, lineWidth, noGreenBorderHeight, noGreenBorderWidth));
2557     RectT<int32_t> localRect = GetAccessibilityFocusRect().value_or(RectT<int32_t>());
2558     if (localRect != RectT<int32_t>()) {
2559         RectF globalRect = frameRect.GetRect();
2560         auto localRectWidth = localRect.Width() - 2 * lineWidth;
2561         auto localRectHeight = localRect.Height() - 2 * lineWidth;
2562         if (NonPositive(localRectWidth)) {
2563             localRectWidth = kAccessibilityMinSize;
2564         }
2565         if (NonPositive(localRectHeight)) {
2566             localRectHeight = kAccessibilityMinSize;
2567         }
2568         globalRect.SetRect(globalRect.GetX() + localRect.GetX(), globalRect.GetY() + localRect.GetY(),
2569             localRectWidth, localRectHeight);
2570         globalRect = globalRect.Constrain(frameRect.GetRect());
2571         if (globalRect.IsEmpty()) {
2572             ClearAccessibilityFocus();
2573             return;
2574         }
2575         frameRect.SetRect(globalRect);
2576     }
2577     PaintFocusState(frameRect, focusPaddingVp, paintColor, paintWidth, true);
2578 }
2579 
UpdateAccessibilityRoundRect()2580 void RosenRenderContext::UpdateAccessibilityRoundRect()
2581 {
2582     CHECK_NULL_VOID(accessibilityFocusStateModifier_);
2583     const constexpr double accessibilityFocusWidth = 4.0;
2584     double lineWidth = accessibilityFocusWidth * PipelineBase::GetCurrentDensity();
2585     Dimension paintWidth(lineWidth, DimensionUnit::PX);
2586     Dimension focusPaddingVp = Dimension(0.0, DimensionUnit::VP);
2587 
2588     auto paintWidthPx = static_cast<float>(paintWidth.ConvertToPx());
2589     auto borderPaddingPx = static_cast<float>(focusPaddingVp.ConvertToPx());
2590 
2591     auto node = GetHost();
2592     CHECK_NULL_VOID(node);
2593     auto nodeWidth = node->GetGeometryNode()->GetFrameSize().Width();
2594     auto nodeHeight = node->GetGeometryNode()->GetFrameSize().Height();
2595 
2596     double noGreenBorderWidth = GreatOrEqual(nodeWidth - (2 * lineWidth), 0.0) ? (nodeWidth - (2 * lineWidth)) : 0;
2597     double noGreenBorderHeight = GreatOrEqual(nodeHeight - (2 * lineWidth), 0.0) ? (nodeHeight - (2 * lineWidth)) : 0;
2598 
2599     RoundRect frameRect;
2600     std::shared_ptr<FocusStateModifier> modifier;
2601     modifier = accessibilityFocusStateModifier_;
2602     frameRect.SetRect(RectF(lineWidth - borderPaddingPx - paintWidthPx / 2,
2603         lineWidth - borderPaddingPx - paintWidthPx / 2,
2604         noGreenBorderWidth + 2 * borderPaddingPx + paintWidthPx,
2605         noGreenBorderHeight + 2 * borderPaddingPx + paintWidthPx)); // 2: framenode to graphic specification
2606     modifier->SetRoundRect(frameRect, paintWidthPx);
2607 }
ClearAccessibilityFocus()2608 void RosenRenderContext::ClearAccessibilityFocus()
2609 {
2610     CHECK_NULL_VOID(rsNode_);
2611     CHECK_NULL_VOID(accessibilityFocusStateModifier_);
2612     rsNode_->RemoveModifier(accessibilityFocusStateModifier_);
2613     RequestNextFrame();
2614 }
2615 
BdImagePaintTask(RSCanvas & canvas)2616 void RosenRenderContext::BdImagePaintTask(RSCanvas& canvas)
2617 {
2618     CHECK_NULL_VOID(GetBorderImage());
2619     auto paintRect = GetPaintRectWithoutTransform();
2620     if (NearZero(paintRect.Width()) || NearZero(paintRect.Height())) {
2621         return;
2622     }
2623 
2624     auto host = GetHost();
2625     CHECK_NULL_VOID(host);
2626     auto layoutProps = host->GetLayoutProperty();
2627     CHECK_NULL_VOID(layoutProps);
2628     const auto& widthProp = layoutProps->GetBorderWidthProperty();
2629 
2630     auto pipeline = host->GetContextRefPtr();
2631     CHECK_NULL_VOID(pipeline);
2632     auto dipScale = pipeline->GetDipScale();
2633     auto lpxScale = pipeline->GetLogicScale();
2634 
2635     CHECK_NULL_VOID(bdImage_);
2636     std::shared_ptr<RSImage> image;
2637     if (InstanceOf<DrawingImage>(bdImage_)) {
2638         image = DynamicCast<DrawingImage>(bdImage_)->GetImage();
2639     } else if (InstanceOf<PixelMapImage>(bdImage_)) {
2640         auto pixmap = DynamicCast<PixelMapImage>(bdImage_)->GetPixelMap();
2641         CHECK_NULL_VOID(pixmap);
2642         image = DrawingImage::MakeRSImageFromPixmap(pixmap);
2643     } else {
2644         return;
2645     }
2646     CHECK_NULL_VOID(image);
2647     BorderImagePainter borderImagePainter(
2648         *GetBdImage(), widthProp, paintRect.GetSize(), *image, { dipScale, lpxScale });
2649     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_FOURTEEN)) {
2650         auto rect = borderImagePainter.GetDrawRect(OffsetF(0.0, 0.0));
2651         std::shared_ptr<Rosen::RectF> drawRect =
2652             std::make_shared<Rosen::RectF>(rect.GetX(), rect.GetY(), rect.Width(), rect.Height());
2653         UpdateDrawRegion(DRAW_REGION_FOREGROUND_MODIFIER_INDEX, drawRect);
2654     }
2655     borderImagePainter.PaintBorderImage(OffsetF(0.0, 0.0), canvas);
2656 }
2657 
PaintBorderImage()2658 void RosenRenderContext::PaintBorderImage()
2659 {
2660     CHECK_NULL_VOID(rsNode_);
2661 
2662     auto paintTask = [weak = WeakClaim(this)](RSCanvas& canvas) {
2663         auto ctx = weak.Upgrade();
2664         CHECK_NULL_VOID(ctx);
2665         ctx->BdImagePaintTask(canvas);
2666     };
2667 
2668     if (!borderImageModifier_) {
2669         borderImageModifier_ = std::make_shared<BorderImageModifier>();
2670         rsNode_->AddModifier(borderImageModifier_);
2671     }
2672     borderImageModifier_->SetPaintTask(std::move(paintTask));
2673     borderImageModifier_->Modify();
2674 }
2675 
CreateBorderImageDataReadyCallback()2676 DataReadyNotifyTask RosenRenderContext::CreateBorderImageDataReadyCallback()
2677 {
2678     return [weak = WeakClaim(this)](const ImageSourceInfo& sourceInfo) {
2679         auto rosenRenderContext = weak.Upgrade();
2680         CHECK_NULL_VOID(rosenRenderContext);
2681         auto imageSourceInfo = rosenRenderContext->GetBorderImageSource().value_or(ImageSourceInfo(""));
2682         if (imageSourceInfo != sourceInfo) {
2683             return;
2684         }
2685         rosenRenderContext->bdImageLoadingCtx_->MakeCanvasImage(SizeF(), true, ImageFit::NONE);
2686     };
2687 }
2688 
CreateBorderImageLoadSuccessCallback()2689 LoadSuccessNotifyTask RosenRenderContext::CreateBorderImageLoadSuccessCallback()
2690 {
2691     return [weak = WeakClaim(this)](const ImageSourceInfo& sourceInfo) {
2692         auto ctx = weak.Upgrade();
2693         CHECK_NULL_VOID(ctx);
2694         auto imageSourceInfo = ctx->GetBorderImageSource().value_or(ImageSourceInfo(""));
2695         if (imageSourceInfo != sourceInfo) {
2696             return;
2697         }
2698         ctx->bdImage_ = ctx->bdImageLoadingCtx_->MoveCanvasImage();
2699         CHECK_NULL_VOID(ctx->bdImage_);
2700         if (ctx->GetHost()->GetGeometryNode()->GetFrameSize().IsPositive()) {
2701             ctx->PaintBorderImage();
2702             ctx->RequestNextFrame();
2703         }
2704     };
2705 }
2706 
OnBackgroundAlignUpdate(const Alignment & align)2707 void RosenRenderContext::OnBackgroundAlignUpdate(const Alignment& align)
2708 {
2709     CHECK_NULL_VOID(rsNode_);
2710     if (!backgroundModifier_) {
2711         backgroundModifier_ = std::make_shared<BackgroundModifier>();
2712         rsNode_->AddModifier(backgroundModifier_);
2713     }
2714     backgroundModifier_->SetAlign(align);
2715     backgroundModifier_->Modify();
2716     RequestNextFrame();
2717 }
2718 
OnBackgroundPixelMapUpdate(const RefPtr<PixelMap> & pixelMap)2719 void RosenRenderContext::OnBackgroundPixelMapUpdate(const RefPtr<PixelMap>& pixelMap)
2720 {
2721     CHECK_NULL_VOID(rsNode_);
2722     if (!backgroundModifier_) {
2723         backgroundModifier_ = std::make_shared<BackgroundModifier>();
2724         rsNode_->AddModifier(backgroundModifier_);
2725     }
2726     auto node = GetHost();
2727     auto nodeWidth = node->GetGeometryNode()->GetFrameSize().Width();
2728     auto nodeHeight = node->GetGeometryNode()->GetFrameSize().Height();
2729     backgroundModifier_->SetInitialNodeSize(nodeWidth, nodeHeight);
2730     backgroundModifier_->SetPixelMap(pixelMap);
2731     backgroundModifier_->SetHostNode(node);
2732     backgroundModifier_->Modify();
2733     RequestNextFrame();
2734 }
2735 
CreateBackgroundPixelMap(const RefPtr<FrameNode> & customNode)2736 void RosenRenderContext::CreateBackgroundPixelMap(const RefPtr<FrameNode>& customNode)
2737 {
2738     NG::ComponentSnapshot::JsCallback callback = [weak = WeakPtr(GetHost()), containerId = Container::CurrentId()](
2739                                                      std::shared_ptr<Media::PixelMap> pixmap, int32_t errCode,
2740                                                      std::function<void()> finishCallback) {
2741         CHECK_NULL_VOID(pixmap);
2742         auto frameNode = weak.Upgrade();
2743         CHECK_NULL_VOID(frameNode);
2744         ContainerScope scope(containerId);
2745         std::shared_ptr<Media::PixelMap> pmap = std::move(pixmap);
2746         auto pixelmap = PixelMap::CreatePixelMap(&pmap);
2747         auto task = [pixelmap, containerId = containerId, frameNode]() {
2748             auto context = frameNode->GetRenderContext();
2749             if (context) {
2750                 context->UpdateBackgroundPixelMap(pixelmap);
2751                 context->RequestNextFrame();
2752             }
2753         };
2754         auto taskExecutor = Container::CurrentTaskExecutor();
2755         CHECK_NULL_VOID(taskExecutor);
2756         taskExecutor->PostTask(task, TaskExecutor::TaskType::UI, "ArkUICreateBackgroundPixelMap");
2757     };
2758     auto firstCallback = callback;
2759     SnapshotParam firstParam;
2760     firstParam.delay = 0;
2761     firstParam.checkImageStatus = true;
2762     firstParam.options.waitUntilRenderFinished = true;
2763     NG::ComponentSnapshot::Create(customNode, std::move(firstCallback), false, firstParam, true);
2764 
2765     SnapshotParam param;
2766     NG::ComponentSnapshot::Create(customNode, std::move(callback), false, param, false);
2767 }
2768 
OnBorderImageUpdate(const RefPtr<BorderImage> &)2769 void RosenRenderContext::OnBorderImageUpdate(const RefPtr<BorderImage>& /*borderImage*/)
2770 {
2771     CHECK_NULL_VOID(rsNode_);
2772     if (bdImageLoadingCtx_ && bdImage_) {
2773         PaintBorderImage();
2774         RequestNextFrame();
2775     }
2776 }
2777 
OnBorderImageSourceUpdate(const ImageSourceInfo & borderImageSourceInfo)2778 void RosenRenderContext::OnBorderImageSourceUpdate(const ImageSourceInfo& borderImageSourceInfo)
2779 {
2780     CHECK_NULL_VOID(rsNode_);
2781     if (!bdImageLoadingCtx_ || borderImageSourceInfo != bdImageLoadingCtx_->GetSourceInfo()) {
2782         LoadNotifier bgLoadNotifier(
2783             CreateBorderImageDataReadyCallback(), CreateBorderImageLoadSuccessCallback(), nullptr);
2784         bdImageLoadingCtx_ = AceType::MakeRefPtr<ImageLoadingContext>(borderImageSourceInfo, std::move(bgLoadNotifier));
2785         CHECK_NULL_VOID(bdImageLoadingCtx_);
2786         bdImageLoadingCtx_->LoadImageData();
2787     }
2788     RequestNextFrame();
2789 }
2790 
OnBorderImageGradientUpdate(const Gradient & gradient)2791 void RosenRenderContext::OnBorderImageGradientUpdate(const Gradient& gradient)
2792 {
2793     CHECK_NULL_VOID(rsNode_);
2794     if (!gradient.IsValid()) {
2795         return;
2796     }
2797     if (GetHost()->GetGeometryNode()->GetFrameSize().IsPositive()) {
2798         PaintBorderImageGradient();
2799     }
2800     RequestNextFrame();
2801 }
2802 
PaintBorderImageGradient()2803 void RosenRenderContext::PaintBorderImageGradient()
2804 {
2805     CHECK_NULL_VOID(rsNode_);
2806     CHECK_NULL_VOID(GetBorderImage());
2807     CHECK_NULL_VOID(GetBorderImageGradient());
2808     auto gradient = GetBorderImageGradient().value();
2809     if (!gradient.IsValid()) {
2810         return;
2811     }
2812     auto paintSize = GetPaintRectWithoutTransform().GetSize();
2813     if (NearZero(paintSize.Width()) || NearZero(paintSize.Height())) {
2814         return;
2815     }
2816     auto layoutProperty = GetHost()->GetLayoutProperty();
2817     CHECK_NULL_VOID(layoutProperty);
2818 
2819     auto borderImageProperty = *GetBdImage();
2820     auto&& borderWidthProperty = layoutProperty->GetBorderWidthProperty();
2821     auto paintTask = [weak = WeakClaim(this), paintSize, borderImageProperty, &borderWidthProperty, gradient](
2822                          RSCanvas& rsCanvas) mutable {
2823 #ifndef USE_ROSEN_DRAWING
2824         auto rsImage = SkiaDecorationPainter::CreateBorderImageGradient(gradient, paintSize);
2825 #else
2826         auto rsImage = DrawingDecorationPainter::CreateBorderImageGradient(gradient, paintSize);
2827 #endif
2828         auto pattern = weak.Upgrade();
2829         CHECK_NULL_VOID(pattern);
2830         auto host = pattern->GetHost();
2831         CHECK_NULL_VOID(host);
2832         auto pipeline = host->GetContext();
2833         CHECK_NULL_VOID(pipeline);
2834         BorderImagePainter borderImagePainter(borderImageProperty, borderWidthProperty, paintSize, rsImage,
2835             { pipeline->GetDipScale(), pipeline->GetLogicScale() });
2836         borderImagePainter.PaintBorderImage(OffsetF(0.0, 0.0), rsCanvas);
2837     };
2838 
2839     if (!borderImageModifier_) {
2840         borderImageModifier_ = std::make_shared<BorderImageModifier>();
2841         rsNode_->AddModifier(borderImageModifier_);
2842     }
2843     borderImageModifier_->SetPaintTask(std::move(paintTask));
2844     borderImageModifier_->Modify();
2845 }
2846 
OnModifyDone()2847 void RosenRenderContext::OnModifyDone()
2848 {
2849     auto frameNode = GetUnsafeHost();
2850     CHECK_NULL_VOID(frameNode);
2851     CHECK_NULL_VOID(rsNode_);
2852     if (HasClickEffectLevel()) {
2853         InitEventClickEffect();
2854     }
2855 }
2856 
GetPropertyOfPosition()2857 RectF RosenRenderContext::GetPropertyOfPosition()
2858 {
2859     return AdjustPaintRect();
2860 }
2861 
AdjustPaintRect()2862 RectF RosenRenderContext::AdjustPaintRect()
2863 {
2864     RectF rect;
2865     auto frameNode = GetHost();
2866     CHECK_NULL_RETURN(frameNode, rect);
2867     CHECK_NULL_RETURN(rsNode_, rect);
2868     const auto& geometryNode = frameNode->GetGeometryNode();
2869     rect = geometryNode->GetFrameRect();
2870     if (Container::LessThanAPIVersion(PlatformVersion::VERSION_TEN)) {
2871         if (!rect.GetSize().IsPositive()) {
2872             geometryNode->SetPixelGridRoundOffset(rect.GetOffset());
2873             return rect;
2874         }
2875     } else {
2876         if (!rect.GetSize().IsPositive() && !frameNode->IsLayoutComplete()) {
2877             geometryNode->SetPixelGridRoundOffset(rect.GetOffset());
2878             return rect;
2879         }
2880     }
2881     bool hasPosition = (HasPosition() || HasPositionEdges()) && IsUsingPosition(frameNode);
2882     bool hasOffset = HasOffset() || HasOffsetEdges();
2883     if (!HasAnchor() && !hasOffset && !hasPosition) {
2884         geometryNode->SetPixelGridRoundOffset(rect.GetOffset());
2885         return rect;
2886     }
2887     auto percentReference = GetPercentReference(frameNode);
2888     auto widthPercentReference = percentReference.Width();
2889     auto heightPercentReference = percentReference.Height();
2890     auto anchor = GetAnchorValue({});
2891     auto anchorWidthReference = rect.Width();
2892     auto anchorHeightReference = rect.Height();
2893     auto anchorX = ConvertToPx(anchor.GetX(), ScaleProperty::CreateScaleProperty(), anchorWidthReference);
2894     auto anchorY = ConvertToPx(anchor.GetY(), ScaleProperty::CreateScaleProperty(), anchorHeightReference);
2895     Dimension resultX;
2896     Dimension resultY;
2897     Dimension parentPaddingLeft;
2898     Dimension parentPaddingTop;
2899     GetPaddingOfFirstFrameNodeParent(parentPaddingLeft, parentPaddingTop);
2900     // Position properties take precedence over offset locations.
2901     if (HasPosition() && IsUsingPosition(frameNode)) {
2902         CombineMarginAndPosition(
2903             resultX, resultY, parentPaddingLeft, parentPaddingTop, widthPercentReference, heightPercentReference);
2904         rect.SetLeft(resultX.ConvertToPx() - anchorX.value_or(0));
2905         rect.SetTop(resultY.ConvertToPx() - anchorY.value_or(0));
2906         geometryNode->SetPixelGridRoundOffset(rect.GetOffset());
2907         return rect;
2908     }
2909     if (HasPositionEdges() && IsUsingPosition(frameNode)) {
2910         auto positionEdges = GetPositionEdgesValue(EdgesParam {});
2911         OffsetF rectOffset =
2912             GetRectOffsetWithPositionEdges(positionEdges, widthPercentReference, heightPercentReference);
2913         rect.SetLeft(rectOffset.GetX() - anchorX.value_or(0));
2914         rect.SetTop(rectOffset.GetY() - anchorY.value_or(0));
2915         geometryNode->SetPixelGridRoundOffset(rect.GetOffset());
2916         return rect;
2917     }
2918     if (HasOffset()) {
2919         auto offset = GetOffsetValue({});
2920         if (PipelineBase::GetCurrentContext() &&
2921             PipelineBase::GetCurrentContext()->GetMinPlatformVersion() < PLATFORM_VERSION_TEN) {
2922             offset += OffsetT<Dimension>(parentPaddingLeft, parentPaddingTop);
2923         }
2924         auto offsetX = ConvertToPx(offset.GetX(), ScaleProperty::CreateScaleProperty(), widthPercentReference);
2925         auto offsetY = ConvertToPx(offset.GetY(), ScaleProperty::CreateScaleProperty(), heightPercentReference);
2926         rect.SetLeft(rect.GetX() + offsetX.value_or(0) - anchorX.value_or(0));
2927         rect.SetTop(rect.GetY() + offsetY.value_or(0) - anchorY.value_or(0));
2928         geometryNode->SetPixelGridRoundOffset(rect.GetOffset());
2929         return rect;
2930     }
2931     if (HasOffsetEdges()) {
2932         auto offsetEdges = GetOffsetEdgesValue(EdgesParam {});
2933         OffsetF rectOffset = GetRectOffsetWithOffsetEdges(offsetEdges, widthPercentReference, heightPercentReference);
2934         rect.SetLeft(rect.GetX() + rectOffset.GetX() - anchorX.value_or(0));
2935         rect.SetTop(rect.GetY() + rectOffset.GetY() - anchorY.value_or(0));
2936         geometryNode->SetPixelGridRoundOffset(rect.GetOffset());
2937         return rect;
2938     }
2939     rect.SetLeft(rect.GetX() - anchorX.value_or(0));
2940     rect.SetTop(rect.GetY() - anchorY.value_or(0));
2941     geometryNode->SetPixelGridRoundOffset(rect.GetOffset());
2942     return rect;
2943 }
2944 
RoundValueToPixelGrid(float value)2945 float RosenRenderContext::RoundValueToPixelGrid(float value)
2946 {
2947     float fractials = fmod(value, 1.0f);
2948     if (fractials < 0.0f) {
2949         ++fractials;
2950     }
2951     if (NearEqual(fractials, 1.0f) || GreatOrEqual(fractials, 0.75f)) {
2952         return (value - fractials + 1.0f);
2953     } else if (NearEqual(fractials, 0.0f) || !GreatOrEqual(fractials, 0.25f)) {
2954         return (value - fractials);
2955     } else {
2956         return (value - fractials + 0.5f);
2957     }
2958 }
2959 
GetRectOffsetWithOffsetEdges(const EdgesParam & offsetEdges,float widthPercentReference,float heightPercentReference)2960 OffsetF RosenRenderContext::GetRectOffsetWithOffsetEdges(
2961     const EdgesParam& offsetEdges, float widthPercentReference, float heightPercentReference)
2962 {
2963     OffsetF rectOffset;
2964     if (offsetEdges.top.has_value()) {
2965         rectOffset.SetY(
2966             ConvertToPx(offsetEdges.top.value(), ScaleProperty::CreateScaleProperty(), heightPercentReference)
2967                 .value_or(0));
2968     }
2969     if (offsetEdges.left.has_value()) {
2970         rectOffset.SetX(
2971             ConvertToPx(offsetEdges.left.value(), ScaleProperty::CreateScaleProperty(), widthPercentReference)
2972                 .value_or(0));
2973     }
2974     if (!offsetEdges.top.has_value() && offsetEdges.bottom.has_value()) {
2975         rectOffset.SetY(
2976             -ConvertToPx(offsetEdges.bottom.value(), ScaleProperty::CreateScaleProperty(), heightPercentReference)
2977                  .value_or(0));
2978     }
2979     if (!offsetEdges.left.has_value() && offsetEdges.right.has_value()) {
2980         rectOffset.SetX(
2981             -ConvertToPx(offsetEdges.right.value(), ScaleProperty::CreateScaleProperty(), widthPercentReference)
2982                  .value_or(0));
2983     }
2984     return rectOffset;
2985 }
2986 
GetRectOffsetWithPositionEdges(const EdgesParam & positionEdges,float widthPercentReference,float heightPercentReference)2987 OffsetF RosenRenderContext::GetRectOffsetWithPositionEdges(
2988     const EdgesParam& positionEdges, float widthPercentReference, float heightPercentReference)
2989 {
2990     float rectTop = 0.0f;
2991     float rectLeft = 0.0f;
2992 
2993     auto frameNode = GetHost();
2994     CHECK_NULL_RETURN(frameNode, OffsetF {});
2995     auto layoutProperty = frameNode->GetLayoutProperty();
2996     CHECK_NULL_RETURN(layoutProperty, OffsetF {});
2997     auto& marginOri = layoutProperty->GetMarginProperty();
2998     std::unique_ptr<MarginProperty> margin(
2999         marginOri ? std::make_unique<MarginProperty>(*marginOri) : std::make_unique<MarginProperty>());
3000 
3001     auto parentNode = frameNode->GetAncestorNodeOfFrame();
3002     CHECK_NULL_RETURN(parentNode, OffsetF {});
3003     auto parentLayoutProperty = parentNode->GetLayoutProperty();
3004     CHECK_NULL_RETURN(parentLayoutProperty, OffsetF {});
3005     auto& parentPaddingOri = parentLayoutProperty->GetPaddingProperty();
3006     std::unique_ptr<PaddingProperty> parentPadding(
3007         parentPaddingOri ? std::make_unique<PaddingProperty>(*parentPaddingOri) : std::make_unique<PaddingProperty>());
3008 
3009     auto parenPercentRef = GetPercentReference(parentNode);
3010     float parentWidthRef = parenPercentRef.Width();
3011     float parentHeightRef = parenPercentRef.Height();
3012 
3013     SizeF selfSize = frameNode->GetGeometryNode()->GetFrameSize();
3014     float selfWidth = selfSize.Width();
3015     float selfHeight = selfSize.Height();
3016     SizeF parentSize = parentNode->GetGeometryNode()->GetFrameSize();
3017     float parentWidth = parentSize.Width();
3018     float parentHeight = parentSize.Height();
3019 
3020     if (positionEdges.top.has_value()) {
3021         rectTop = ConvertToPx(parentPadding->top.value_or(CalcLength(Dimension(0))).GetDimension(),
3022             ScaleProperty::CreateScaleProperty(), parentHeightRef)
3023                       .value_or(0) +
3024                   ConvertToPx(margin->top.value_or(CalcLength(Dimension(0))).GetDimension(),
3025                       ScaleProperty::CreateScaleProperty(), heightPercentReference)
3026                       .value_or(0) +
3027                   ConvertToPx(positionEdges.top.value(), ScaleProperty::CreateScaleProperty(), heightPercentReference)
3028                       .value_or(0);
3029     }
3030     if (positionEdges.left.has_value()) {
3031         rectLeft = ConvertToPx(parentPadding->left.value_or(CalcLength(Dimension(0))).GetDimension(),
3032             ScaleProperty::CreateScaleProperty(), parentWidthRef)
3033                        .value_or(0) +
3034                    ConvertToPx(margin->left.value_or(CalcLength(Dimension(0))).GetDimension(),
3035                        ScaleProperty::CreateScaleProperty(), widthPercentReference)
3036                        .value_or(0) +
3037                    ConvertToPx(positionEdges.left.value(), ScaleProperty::CreateScaleProperty(), widthPercentReference)
3038                        .value_or(0);
3039     }
3040     if (!positionEdges.top.has_value() && positionEdges.bottom.has_value()) {
3041         rectTop =
3042             parentHeight - selfHeight -
3043             ConvertToPx(parentPadding->bottom.value_or(CalcLength(Dimension(0))).GetDimension(),
3044                 ScaleProperty::CreateScaleProperty(), parentHeightRef)
3045                 .value_or(0) -
3046             ConvertToPx(margin->bottom.value_or(CalcLength(Dimension(0))).GetDimension(),
3047                 ScaleProperty::CreateScaleProperty(), heightPercentReference)
3048                 .value_or(0) -
3049             ConvertToPx(positionEdges.bottom.value(), ScaleProperty::CreateScaleProperty(), heightPercentReference)
3050                 .value_or(0);
3051     }
3052     if (!positionEdges.left.has_value() && positionEdges.right.has_value()) {
3053         rectLeft = parentWidth - selfWidth -
3054                    ConvertToPx(parentPadding->right.value_or(CalcLength(Dimension(0))).GetDimension(),
3055                        ScaleProperty::CreateScaleProperty(), parentWidthRef)
3056                        .value_or(0) -
3057                    ConvertToPx(margin->right.value_or(CalcLength(Dimension(0))).GetDimension(),
3058                        ScaleProperty::CreateScaleProperty(), widthPercentReference)
3059                        .value_or(0) -
3060                    ConvertToPx(positionEdges.right.value(), ScaleProperty::CreateScaleProperty(), widthPercentReference)
3061                        .value_or(0);
3062     }
3063     return OffsetF(rectLeft, rectTop);
3064 }
3065 
RoundValueToPixelGrid(float value,bool isRound,bool forceCeil,bool forceFloor)3066 float RosenRenderContext::RoundValueToPixelGrid(float value, bool isRound, bool forceCeil, bool forceFloor)
3067 {
3068     float fractials = fmod(value, 1.0f);
3069     if (fractials < 0.0f) {
3070         ++fractials;
3071     }
3072     if (forceCeil) {
3073         return (value - fractials + 1.0f);
3074     } else if (forceFloor) {
3075         return (value - fractials);
3076     } else if (isRound) {
3077         if (NearEqual(fractials, 1.0f) || GreatOrEqual(fractials, 0.75f)) {
3078             return (value - fractials + 1.0f);
3079         } else if (NearEqual(fractials, 0.0f) || !GreatOrEqual(fractials, 0.25f)) {
3080             return (value - fractials);
3081         } else {
3082             return (value - fractials + 0.5f);
3083         }
3084     }
3085     return value;
3086 }
3087 
OnePixelValueRounding(float value)3088 float RosenRenderContext::OnePixelValueRounding(float value)
3089 {
3090     float fractials = fmod(value, 1.0f);
3091     if (fractials < 0.0f) {
3092         ++fractials;
3093     }
3094     if (NearEqual(fractials, 1.0f) || GreatOrEqual(fractials, 0.5f)) {
3095         return (value - fractials + 1.0f);
3096     } else {
3097         return (value - fractials);
3098     }
3099 }
3100 
OnePixelValueRounding(float value,bool isRound,bool forceCeil,bool forceFloor)3101 float RosenRenderContext::OnePixelValueRounding(float value, bool isRound, bool forceCeil, bool forceFloor)
3102 {
3103     float fractials = fmod(value, 1.0f);
3104     if (fractials < 0.0f) {
3105         ++fractials;
3106     }
3107     if (forceCeil) {
3108         return (value - fractials + 1.0f);
3109     } else if (forceFloor) {
3110         return (value - fractials);
3111     } else if (isRound) {
3112         if (NearEqual(fractials, 1.0f) || GreatOrEqual(fractials, 0.5f)) {
3113             return (value - fractials + 1.0f);
3114         } else {
3115             return (value - fractials);
3116         }
3117     }
3118     return value;
3119 }
3120 
RoundToPixelGrid()3121 void RosenRenderContext::RoundToPixelGrid()
3122 {
3123     auto frameNode = GetHost();
3124     CHECK_NULL_VOID(frameNode);
3125     auto geometryNode = frameNode->GetGeometryNode();
3126     float relativeLeft = geometryNode->GetPixelGridRoundOffset().GetX();
3127     float relativeTop = geometryNode->GetPixelGridRoundOffset().GetY();
3128     float nodeWidth = geometryNode->GetFrameSize().Width();
3129     float nodeHeight = geometryNode->GetFrameSize().Height();
3130     float absoluteRight = relativeLeft + nodeWidth;
3131     float absoluteBottom = relativeTop + nodeHeight;
3132     // round node
3133     float nodeLeftI = RoundValueToPixelGrid(relativeLeft);
3134     float nodeTopI = RoundValueToPixelGrid(relativeTop);
3135     geometryNode->SetPixelGridRoundOffset(OffsetF(nodeLeftI, nodeTopI));
3136     float nodeWidthI = RoundValueToPixelGrid(absoluteRight) - nodeLeftI;
3137     float nodeHeightI = RoundValueToPixelGrid(absoluteBottom) - nodeTopI;
3138     geometryNode->SetPixelGridRoundSize(SizeF(nodeWidthI, nodeHeightI));
3139     if (borderWidth_ != Rosen::Vector4f(0.0f, 0.0f, 0.0f, 0.0f)) {
3140         // round inner
3141         float innerLeft = relativeLeft + borderWidth_[0];
3142         float innerRight = relativeLeft + nodeWidth - borderWidth_[2];
3143         float innerTop = relativeTop + borderWidth_[1];
3144         float innerBottom = relativeTop + nodeHeight - borderWidth_[3];
3145         float innerWidthI = RoundValueToPixelGrid(innerRight) - RoundValueToPixelGrid(innerLeft);
3146         float innerHeightI = RoundValueToPixelGrid(innerBottom) - RoundValueToPixelGrid(innerTop);
3147         // update border
3148         float borderLeftI = RoundValueToPixelGrid(borderWidth_[0]);
3149         float borderTopI = RoundValueToPixelGrid(borderWidth_[1]);
3150         float borderRightI = nodeWidthI - innerWidthI - borderLeftI;
3151         float borderBottomI = nodeHeightI - innerHeightI - borderTopI;
3152         BorderWidthPropertyF borderWidthPropertyF;
3153         borderWidthPropertyF.leftDimen = borderLeftI;
3154         borderWidthPropertyF.topDimen = borderTopI;
3155         borderWidthPropertyF.rightDimen = borderRightI;
3156         borderWidthPropertyF.bottomDimen = borderBottomI;
3157         UpdateBorderWidthF(borderWidthPropertyF);
3158     }
3159 }
3160 
RoundToPixelGrid(bool isRound,uint8_t flag)3161 void RosenRenderContext::RoundToPixelGrid(bool isRound, uint8_t flag)
3162 {
3163     CHECK_NULL_VOID(rsNode_);
3164     auto frameNode = GetHost();
3165     CHECK_NULL_VOID(frameNode);
3166     auto geometryNode = frameNode->GetGeometryNode();
3167     float relativeLeft = geometryNode->GetPixelGridRoundOffset().GetX();
3168     float relativeTop = geometryNode->GetPixelGridRoundOffset().GetY();
3169     float nodeWidth = geometryNode->GetFrameSize().Width();
3170     float nodeHeight = geometryNode->GetFrameSize().Height();
3171     float absoluteRight = relativeLeft + nodeWidth;
3172     float absoluteBottom = relativeTop + nodeHeight;
3173     bool ceilLeft = flag & static_cast<uint8_t>(PixelRoundPolicy::FORCE_CEIL_START);
3174     bool floorLeft = flag & static_cast<uint8_t>(PixelRoundPolicy::FORCE_FLOOR_START);
3175     bool ceilTop = flag & static_cast<uint8_t>(PixelRoundPolicy::FORCE_CEIL_TOP);
3176     bool floorTop = flag & static_cast<uint8_t>(PixelRoundPolicy::FORCE_FLOOR_TOP);
3177     bool ceilRight = flag & static_cast<uint8_t>(PixelRoundPolicy::FORCE_CEIL_END);
3178     bool floorRight = flag & static_cast<uint8_t>(PixelRoundPolicy::FORCE_FLOOR_END);
3179     bool ceilBottom = flag & static_cast<uint8_t>(PixelRoundPolicy::FORCE_CEIL_BOTTOM);
3180     bool floorBottom = flag & static_cast<uint8_t>(PixelRoundPolicy::FORCE_FLOOR_BOTTOM);
3181     // round node
3182     float nodeLeftI = RoundValueToPixelGrid(relativeLeft, isRound, ceilLeft, floorLeft);
3183     float nodeTopI = RoundValueToPixelGrid(relativeTop, isRound, ceilTop, floorTop);
3184     geometryNode->SetPixelGridRoundOffset(OffsetF(nodeLeftI, nodeTopI));
3185     float nodeWidthI = RoundValueToPixelGrid(absoluteRight, isRound, ceilRight, floorRight) - nodeLeftI;
3186     float nodeHeightI = RoundValueToPixelGrid(absoluteBottom, isRound, ceilBottom, floorBottom) - nodeTopI;
3187     geometryNode->SetPixelGridRoundSize(SizeF(nodeWidthI, nodeHeightI));
3188     if (borderWidth_ != Rosen::Vector4f(0.0f, 0.0f, 0.0f, 0.0f)) {
3189         // round inner
3190         float innerLeft = relativeLeft + borderWidth_[0];
3191         float innerRight = relativeLeft + nodeWidth - borderWidth_[2];
3192         float innerTop = relativeTop + borderWidth_[1];
3193         float innerBottom = relativeTop + nodeHeight - borderWidth_[3];
3194         float innerWidthI = RoundValueToPixelGrid(innerRight, isRound, ceilRight, floorRight) -
3195             RoundValueToPixelGrid(innerLeft, isRound, ceilLeft, floorLeft);
3196         float innerHeightI = RoundValueToPixelGrid(innerBottom, isRound, ceilBottom, floorBottom) -
3197             RoundValueToPixelGrid(innerTop, isRound, ceilTop, floorTop);
3198         // update border
3199         float borderLeftI = RoundValueToPixelGrid(borderWidth_[0], isRound, ceilLeft, floorLeft);
3200         float borderTopI = RoundValueToPixelGrid(borderWidth_[1], isRound, ceilTop, floorTop);
3201         float borderRightI = nodeWidthI - innerWidthI - borderLeftI;
3202         float borderBottomI = nodeHeightI - innerHeightI - borderTopI;
3203         BorderWidthPropertyF borderWidthPropertyF;
3204         borderWidthPropertyF.leftDimen = borderLeftI;
3205         borderWidthPropertyF.topDimen = borderTopI;
3206         borderWidthPropertyF.rightDimen = borderRightI;
3207         borderWidthPropertyF.bottomDimen = borderBottomI;
3208         UpdateBorderWidthF(borderWidthPropertyF);
3209     }
3210 }
3211 
OnePixelRounding()3212 void RosenRenderContext::OnePixelRounding()
3213 {
3214     auto frameNode = GetHost();
3215     CHECK_NULL_VOID(frameNode);
3216     auto geometryNode = frameNode->GetGeometryNode();
3217     float relativeLeft = geometryNode->GetPixelGridRoundOffset().GetX();
3218     float relativeTop = geometryNode->GetPixelGridRoundOffset().GetY();
3219     float nodeWidth = geometryNode->GetFrameSize().Width();
3220     float nodeHeight = geometryNode->GetFrameSize().Height();
3221     float roundToPixelErrorX = 0.0f;
3222     float roundToPixelErrorY = 0.0f;
3223     float absoluteRight = relativeLeft + nodeWidth;
3224     float absoluteBottom = relativeTop + nodeHeight;
3225 
3226     float nodeLeftI = OnePixelValueRounding(relativeLeft);
3227     float nodeTopI = OnePixelValueRounding(relativeTop);
3228     roundToPixelErrorX += nodeLeftI - relativeLeft;
3229     roundToPixelErrorY += nodeTopI - relativeTop;
3230     geometryNode->SetPixelGridRoundOffset(OffsetF(nodeLeftI, nodeTopI));
3231 
3232     float nodeWidthI = OnePixelValueRounding(absoluteRight) - nodeLeftI;
3233     float nodeWidthTemp = OnePixelValueRounding(nodeWidth);
3234     roundToPixelErrorX += nodeWidthI - nodeWidth;
3235     if (roundToPixelErrorX > 0.5f) {
3236         nodeWidthI -= 1.0f;
3237         roundToPixelErrorX -= 1.0f;
3238     }
3239     if (roundToPixelErrorX < -0.5f) {
3240         nodeWidthI += 1.0f;
3241         roundToPixelErrorX += 1.0f;
3242     }
3243     if (nodeWidthI < nodeWidthTemp) {
3244         roundToPixelErrorX += nodeWidthTemp - nodeWidthI;
3245         nodeWidthI = nodeWidthTemp;
3246     }
3247 
3248     float nodeHeightI = OnePixelValueRounding(absoluteBottom) - nodeTopI;
3249     float nodeHeightTemp = OnePixelValueRounding(nodeHeight);
3250     roundToPixelErrorY += nodeHeightI - nodeHeight;
3251     if (roundToPixelErrorY > 0.5f) {
3252         nodeHeightI -= 1.0f;
3253         roundToPixelErrorY -= 1.0f;
3254     }
3255     if (roundToPixelErrorY < -0.5f) {
3256         nodeHeightI += 1.0f;
3257         roundToPixelErrorY += 1.0f;
3258     }
3259     if (nodeHeightI < nodeHeightTemp) {
3260         roundToPixelErrorY += nodeHeightTemp - nodeHeightI;
3261         nodeHeightI = nodeHeightTemp;
3262     }
3263     geometryNode->SetPixelGridRoundSize(SizeF(nodeWidthI, nodeHeightI));
3264 }
3265 
OnePixelRounding(bool isRound,uint8_t flag)3266 void RosenRenderContext::OnePixelRounding(bool isRound, uint8_t flag)
3267 {
3268     auto frameNode = GetHost();
3269     CHECK_NULL_VOID(frameNode);
3270     auto geometryNode = frameNode->GetGeometryNode();
3271     float relativeLeft = geometryNode->GetPixelGridRoundOffset().GetX();
3272     float relativeTop = geometryNode->GetPixelGridRoundOffset().GetY();
3273     float nodeWidth = geometryNode->GetFrameSize().Width();
3274     float nodeHeight = geometryNode->GetFrameSize().Height();
3275     float roundToPixelErrorX = 0.0f;
3276     float roundToPixelErrorY = 0.0f;
3277     float absoluteRight = relativeLeft + nodeWidth;
3278     float absoluteBottom = relativeTop + nodeHeight;
3279     bool ceilLeft = flag & static_cast<uint8_t>(PixelRoundPolicy::FORCE_CEIL_START);
3280     bool floorLeft = flag & static_cast<uint8_t>(PixelRoundPolicy::FORCE_FLOOR_START);
3281     bool ceilTop = flag & static_cast<uint8_t>(PixelRoundPolicy::FORCE_CEIL_TOP);
3282     bool floorTop = flag & static_cast<uint8_t>(PixelRoundPolicy::FORCE_FLOOR_TOP);
3283     bool ceilRight = flag & static_cast<uint8_t>(PixelRoundPolicy::FORCE_CEIL_END);
3284     bool floorRight = flag & static_cast<uint8_t>(PixelRoundPolicy::FORCE_FLOOR_END);
3285     bool ceilBottom = flag & static_cast<uint8_t>(PixelRoundPolicy::FORCE_CEIL_BOTTOM);
3286     bool floorBottom = flag & static_cast<uint8_t>(PixelRoundPolicy::FORCE_FLOOR_BOTTOM);
3287 
3288     float nodeLeftI = OnePixelValueRounding(relativeLeft, isRound, ceilLeft, floorLeft);
3289     float nodeTopI = OnePixelValueRounding(relativeTop, isRound, ceilTop, floorTop);
3290     roundToPixelErrorX += nodeLeftI - relativeLeft;
3291     roundToPixelErrorY += nodeTopI - relativeTop;
3292     geometryNode->SetPixelGridRoundOffset(OffsetF(nodeLeftI, nodeTopI));
3293 
3294     float nodeWidthI = OnePixelValueRounding(absoluteRight, isRound, ceilRight, floorRight) - nodeLeftI;
3295     float nodeWidthTemp = OnePixelValueRounding(nodeWidth, isRound, ceilRight, floorRight);
3296     roundToPixelErrorX += nodeWidthI - nodeWidth;
3297     if (roundToPixelErrorX > 0.5f) {
3298         nodeWidthI -= 1.0f;
3299         roundToPixelErrorX -= 1.0f;
3300     }
3301     if (roundToPixelErrorX < -0.5f) {
3302         nodeWidthI += 1.0f;
3303         roundToPixelErrorX += 1.0f;
3304     }
3305     if (nodeWidthI < nodeWidthTemp) {
3306         roundToPixelErrorX += nodeWidthTemp - nodeWidthI;
3307         nodeWidthI = nodeWidthTemp;
3308     }
3309 
3310     float nodeHeightI = OnePixelValueRounding(absoluteBottom, isRound, ceilBottom, floorBottom) - nodeTopI;
3311     float nodeHeightTemp = OnePixelValueRounding(nodeHeight, isRound, ceilBottom, floorBottom);
3312     roundToPixelErrorY += nodeHeightI - nodeHeight;
3313     if (roundToPixelErrorY > 0.5f) {
3314         nodeHeightI -= 1.0f;
3315         roundToPixelErrorY -= 1.0f;
3316     }
3317     if (roundToPixelErrorY < -0.5f) {
3318         nodeHeightI += 1.0f;
3319         roundToPixelErrorY += 1.0f;
3320     }
3321     if (nodeHeightI < nodeHeightTemp) {
3322         roundToPixelErrorY += nodeHeightTemp - nodeHeightI;
3323         nodeHeightI = nodeHeightTemp;
3324     }
3325     geometryNode->SetPixelGridRoundSize(SizeF(nodeWidthI, nodeHeightI));
3326 }
3327 
3328 
CombineMarginAndPosition(Dimension & resultX,Dimension & resultY,const Dimension & parentPaddingLeft,const Dimension & parentPaddingTop,float widthPercentReference,float heightPercentReference)3329 void RosenRenderContext::CombineMarginAndPosition(Dimension& resultX, Dimension& resultY,
3330     const Dimension& parentPaddingLeft, const Dimension& parentPaddingTop, float widthPercentReference,
3331     float heightPercentReference)
3332 {
3333     Dimension selfMarginLeft;
3334     Dimension selfMarginTop;
3335     auto frameNode = GetHost();
3336     if (frameNode && frameNode->GetLayoutProperty() && frameNode->GetLayoutProperty()->GetMarginProperty()) {
3337         auto& margin = frameNode->GetLayoutProperty()->GetMarginProperty();
3338         if (margin->left.has_value()) {
3339             selfMarginLeft = margin->left.value().GetDimension();
3340         }
3341         if (margin->top.has_value()) {
3342             selfMarginTop = margin->top.value().GetDimension();
3343         }
3344     }
3345     // to distinguish cases ex. margin has percentage unit and padding has vp unit
3346     // final rect offset will be affected by parent padding, self margin and position property
3347     if (selfMarginLeft.Unit() != GetPositionValue({}).GetX().Unit() ||
3348         selfMarginLeft.Unit() != parentPaddingLeft.Unit() ||
3349         parentPaddingLeft.Unit() != GetPositionValue({}).GetX().Unit()) {
3350         resultX = Dimension(
3351             ConvertToPx(parentPaddingLeft, ScaleProperty::CreateScaleProperty(), widthPercentReference).value_or(0) +
3352                 ConvertToPx(selfMarginLeft, ScaleProperty::CreateScaleProperty(), widthPercentReference).value_or(0) +
3353                 ConvertToPx(GetPositionValue({}).GetX(), ScaleProperty::CreateScaleProperty(), widthPercentReference)
3354                     .value_or(0),
3355             DimensionUnit::PX);
3356     } else {
3357         resultX = selfMarginLeft + GetPositionValue({}).GetX() + parentPaddingLeft;
3358     }
3359     if (selfMarginTop.Unit() != GetPositionValue({}).GetY().Unit() || selfMarginTop.Unit() != parentPaddingTop.Unit() ||
3360         parentPaddingTop.Unit() != GetPositionValue({}).GetY().Unit()) {
3361         resultY = Dimension(
3362             ConvertToPx(parentPaddingTop, ScaleProperty::CreateScaleProperty(), heightPercentReference).value_or(0) +
3363                 ConvertToPx(selfMarginTop, ScaleProperty::CreateScaleProperty(), heightPercentReference).value_or(0) +
3364                 ConvertToPx(GetPositionValue({}).GetY(), ScaleProperty::CreateScaleProperty(), heightPercentReference)
3365                     .value_or(0),
3366             DimensionUnit::PX);
3367     } else {
3368         resultY = selfMarginTop + GetPositionValue({}).GetY() + parentPaddingTop;
3369     }
3370 }
3371 
IsUsingPosition(const RefPtr<FrameNode> & frameNode)3372 bool RosenRenderContext::IsUsingPosition(const RefPtr<FrameNode>& frameNode)
3373 {
3374     auto layoutProperty = frameNode->GetLayoutProperty();
3375     bool isUsingPosition = true;
3376     if (layoutProperty) {
3377         isUsingPosition = layoutProperty->IsUsingPosition();
3378     }
3379     return isUsingPosition;
3380 }
3381 
GetPaddingOfFirstFrameNodeParent(Dimension & parentPaddingLeft,Dimension & parentPaddingTop)3382 void RosenRenderContext::GetPaddingOfFirstFrameNodeParent(Dimension& parentPaddingLeft, Dimension& parentPaddingTop)
3383 {
3384     auto frameNode = GetHost();
3385     CHECK_NULL_VOID(frameNode);
3386     auto frameNodeParent = frameNode->GetAncestorNodeOfFrame();
3387     CHECK_NULL_VOID(frameNodeParent);
3388     auto layoutProperty = frameNodeParent->GetLayoutProperty();
3389     if (layoutProperty && layoutProperty->GetPaddingProperty()) {
3390         parentPaddingLeft =
3391             layoutProperty->GetPaddingProperty()->left.value_or(CalcLength(Dimension(0))).GetDimension();
3392         parentPaddingTop = layoutProperty->GetPaddingProperty()->top.value_or(CalcLength(Dimension(0))).GetDimension();
3393     }
3394 }
3395 
GetPercentReference(const RefPtr<FrameNode> & frameNode)3396 SizeF RosenRenderContext::GetPercentReference(const RefPtr<FrameNode>& frameNode)
3397 {
3398     SizeF percentReference = SizeF(PipelineContext::GetCurrentRootWidth(), PipelineContext::GetCurrentRootHeight());
3399     CHECK_NULL_RETURN(frameNode, percentReference);
3400     const auto& layoutConstraint = frameNode->GetGeometryNode()->GetParentLayoutConstraint();
3401     if (layoutConstraint.has_value()) {
3402         percentReference.SetWidth(layoutConstraint->percentReference.Width());
3403         percentReference.SetHeight(layoutConstraint->percentReference.Height());
3404     }
3405     return percentReference;
3406 }
3407 
SetPositionToRSNode()3408 void RosenRenderContext::SetPositionToRSNode()
3409 {
3410     auto frameNode = GetHost();
3411     CHECK_NULL_VOID(frameNode);
3412     CHECK_NULL_VOID(rsNode_);
3413     auto rect = AdjustPaintRect();
3414     if (!rect.GetSize().IsPositive()) {
3415         return;
3416     }
3417     paintRect_ = rect;
3418     if (frameNode->ParentExpansive() && !frameNode->SelfExpansive()) {
3419         // Dynamically modify position, need consider parent expand
3420         frameNode->AdjustNotExpandNode();
3421         rect = paintRect_;
3422     }
3423     if (AnimationUtils::IsImplicitAnimationOpen()) {
3424         auto preBounds = rsNode_->GetStagingProperties().GetBounds();
3425         if (!NearEqual(preBounds[0], rect.GetX()) || !NearEqual(preBounds[1], rect.GetY())) {
3426             ACE_SCOPED_TRACE("SetPosition, bounds from (%f, %f, %f, %f) to (%f, %f, %f, %f), id:%d, tag:%s",
3427                 preBounds[0], preBounds[1], preBounds[2], preBounds[3], rect.GetX(), rect.GetY(), rect.Width(),
3428                 rect.Height(), frameNode->GetId(), frameNode->GetTag().c_str());
3429         }
3430     }
3431     rsNode_->SetBounds(rect.GetX(), rect.GetY(), rect.Width(), rect.Height());
3432     if (useContentRectForRSFrame_) {
3433         SetContentRectToFrame(rect);
3434     } else {
3435         rsNode_->SetFrame(rect.GetX(), rect.GetY(), rect.Width(), rect.Height());
3436     }
3437     if (frameOffset_.has_value()) {
3438         rsNode_->SetFrame(rect.GetX() + frameOffset_->GetX(), rect.GetY() + frameOffset_->GetY(),
3439             rect.Width(), rect.Height());
3440     }
3441     ElementRegister::GetInstance()->ReSyncGeometryTransition(GetHost());
3442     RequestNextFrame();
3443 }
3444 
OnPositionUpdate(const OffsetT<Dimension> &)3445 void RosenRenderContext::OnPositionUpdate(const OffsetT<Dimension>& /*value*/)
3446 {
3447     SetPositionToRSNode();
3448 }
3449 
OnPositionEdgesUpdate(const EdgesParam &)3450 void RosenRenderContext::OnPositionEdgesUpdate(const EdgesParam& /*value*/)
3451 {
3452     SetPositionToRSNode();
3453 }
3454 
OnOffsetUpdate(const OffsetT<Dimension> &)3455 void RosenRenderContext::OnOffsetUpdate(const OffsetT<Dimension>& /*value*/)
3456 {
3457     SetPositionToRSNode();
3458 }
3459 
OnOffsetEdgesUpdate(const EdgesParam &)3460 void RosenRenderContext::OnOffsetEdgesUpdate(const EdgesParam& /*value*/)
3461 {
3462     SetPositionToRSNode();
3463 }
3464 
OnAnchorUpdate(const OffsetT<Dimension> &)3465 void RosenRenderContext::OnAnchorUpdate(const OffsetT<Dimension>& /*value*/)
3466 {
3467     SetPositionToRSNode();
3468 }
3469 
RecalculatePosition()3470 void RosenRenderContext::RecalculatePosition()
3471 {
3472     SetPositionToRSNode();
3473 }
3474 
OnZIndexUpdate(int32_t value)3475 void RosenRenderContext::OnZIndexUpdate(int32_t value)
3476 {
3477     CHECK_NULL_VOID(rsNode_);
3478     rsNode_->SetPositionZ(static_cast<float>(value));
3479     auto uiNode = GetHost();
3480     CHECK_NULL_VOID(uiNode);
3481     auto parent = uiNode->GetAncestorNodeOfFrame();
3482     CHECK_NULL_VOID(parent);
3483     parent->MarkNeedSyncRenderTree();
3484     parent->RebuildRenderContextTree();
3485 }
3486 
ResetBlendBgColor()3487 void RosenRenderContext::ResetBlendBgColor()
3488 {
3489     CHECK_NULL_VOID(rsNode_);
3490     blendColor_ = Color::TRANSPARENT;
3491     auto blendColor =
3492         GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(blendColor_).BlendColor(hoveredColor_);
3493     rsNode_->SetBackgroundColor(blendColor.GetValue());
3494     RequestNextFrame();
3495 }
3496 
BlendBgColor(const Color & color)3497 void RosenRenderContext::BlendBgColor(const Color& color)
3498 {
3499     CHECK_NULL_VOID(rsNode_);
3500     blendColor_ = color;
3501     auto blendColor =
3502         GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(blendColor_).BlendColor(hoveredColor_);
3503     rsNode_->SetBackgroundColor(blendColor.GetValue());
3504     RequestNextFrame();
3505 }
3506 
ResetBlendBorderColor()3507 void RosenRenderContext::ResetBlendBorderColor()
3508 {
3509     CHECK_NULL_VOID(rsNode_);
3510     auto leftColor = (Color::TRANSPARENT).GetValue();
3511     auto topColor = (Color::TRANSPARENT).GetValue();
3512     auto rightColor = (Color::TRANSPARENT).GetValue();
3513     auto bottomColor = (Color::TRANSPARENT).GetValue();
3514     if (GetBorderColor().has_value()) {
3515         leftColor = GetBorderColor()->leftColor.value_or(Color::TRANSPARENT).GetValue();
3516         topColor = GetBorderColor()->topColor.value_or(Color::TRANSPARENT).GetValue();
3517         rightColor = GetBorderColor()->rightColor.value_or(Color::TRANSPARENT).GetValue();
3518         bottomColor = GetBorderColor()->bottomColor.value_or(Color::TRANSPARENT).GetValue();
3519     }
3520     rsNode_->SetBorderColor(leftColor, topColor, rightColor, bottomColor);
3521     RequestNextFrame();
3522 }
3523 
BlendBorderColor(const Color & color)3524 void RosenRenderContext::BlendBorderColor(const Color& color)
3525 {
3526     CHECK_NULL_VOID(rsNode_);
3527     auto leftColor = color.GetValue();
3528     auto topColor = color.GetValue();
3529     auto rightColor = color.GetValue();
3530     auto bottomColor = color.GetValue();
3531     if (GetBorderColor().has_value()) {
3532         leftColor = (GetBorderColor()->leftColor.value_or(Color::TRANSPARENT).BlendColor(color)).GetValue();
3533         topColor = (GetBorderColor()->topColor.value_or(Color::TRANSPARENT).BlendColor(color)).GetValue();
3534         rightColor = (GetBorderColor()->rightColor.value_or(Color::TRANSPARENT).BlendColor(color)).GetValue();
3535         bottomColor = (GetBorderColor()->bottomColor.value_or(Color::TRANSPARENT).BlendColor(color)).GetValue();
3536     }
3537     rsNode_->SetBorderColor(leftColor, topColor, rightColor, bottomColor);
3538     RequestNextFrame();
3539 }
3540 
PaintFocusState(const RoundRect & paintRect,const Color & paintColor,const Dimension & paintWidth,bool isAccessibilityFocus)3541 void RosenRenderContext::PaintFocusState(
3542     const RoundRect& paintRect, const Color& paintColor, const Dimension& paintWidth, bool isAccessibilityFocus)
3543 {
3544     TAG_LOGD(AceLogTag::ACE_FOCUS,
3545         "PaintFocusState rect is (%{public}f, %{public}f, %{public}f, %{public}f). Color is %{public}s, PainWidth is "
3546         "%{public}s",
3547         paintRect.GetRect().Left(), paintRect.GetRect().Top(), paintRect.GetRect().Width(),
3548         paintRect.GetRect().Height(), paintColor.ColorToString().c_str(), paintWidth.ToString().c_str());
3549     CHECK_NULL_VOID(paintRect.GetRect().IsValid());
3550     CHECK_NULL_VOID(rsNode_);
3551     auto borderWidthPx = static_cast<float>(paintWidth.ConvertToPx());
3552     auto frameNode = GetHost();
3553     auto paintTask = [paintColor, borderWidthPx, weak = WeakClaim(AceType::RawPtr(frameNode))]
3554     (const RSRoundRect& rrect, RSCanvas& rsCanvas) mutable {
3555         RSPen pen;
3556         pen.SetAntiAlias(true);
3557         pen.SetColor(ToRSColor(paintColor));
3558         pen.SetWidth(borderWidthPx);
3559         rsCanvas.AttachPen(pen);
3560         auto delegatePtr = weak.Upgrade();
3561         CHECK_NULL_VOID(delegatePtr);
3562         if (!delegatePtr->GetCheckboxFlag()) {
3563             rsCanvas.DrawRoundRect(rrect);
3564         } else {
3565             auto paintProperty = delegatePtr->GetPaintProperty<CheckBoxPaintProperty>();
3566             CHECK_NULL_VOID(paintProperty);
3567             CheckBoxStyle checkboxStyle = CheckBoxStyle::CIRCULAR_STYLE;
3568             if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
3569                 checkboxStyle = CheckBoxStyle::CIRCULAR_STYLE;
3570             } else {
3571                 checkboxStyle = CheckBoxStyle::SQUARE_STYLE;
3572             }
3573             if (paintProperty->HasCheckBoxSelectedStyle()) {
3574                 checkboxStyle = paintProperty->GetCheckBoxSelectedStyleValue(CheckBoxStyle::CIRCULAR_STYLE);
3575             }
3576             RSScalar halfDenominator = 2.0f;
3577             RSScalar radius = 0.0f;
3578             RSRect rect = rrect.GetRect();
3579             RSScalar x = (rect.GetLeft() + rect.GetRight()) / halfDenominator;
3580             RSScalar y = (rect.GetTop() + rect.GetBottom()) / halfDenominator;
3581             RSPoint centerPt(x, y);
3582             if (rect.GetWidth() > rect.GetHeight()) {
3583                 radius = rect.GetHeight() / halfDenominator;
3584             } else {
3585                 radius = rect.GetWidth() / halfDenominator;
3586             }
3587             if (CheckBoxStyle::SQUARE_STYLE == checkboxStyle) {
3588                 rsCanvas.DrawRoundRect(rrect);
3589             } else {
3590                 rsCanvas.DrawCircle(centerPt, radius);
3591             }
3592         }
3593         rsCanvas.DetachPen();
3594     };
3595     std::shared_ptr<FocusStateModifier> modifier;
3596     if (isAccessibilityFocus) {
3597         if (!accessibilityFocusStateModifier_) {
3598             accessibilityFocusStateModifier_ = std::make_shared<FocusStateModifier>();
3599         }
3600         modifier = accessibilityFocusStateModifier_;
3601         modifier->SetRoundRect(paintRect, borderWidthPx);
3602         UpdateDrawRegion(DRAW_REGION_ACCESSIBILITY_FOCUS_MODIFIER_INDEX, modifier->GetOverlayRect());
3603     } else {
3604         if (!focusStateModifier_) {
3605             // TODO: Add property data
3606             focusStateModifier_ = std::make_shared<FocusStateModifier>();
3607         }
3608         modifier = focusStateModifier_;
3609         modifier->SetRoundRect(paintRect, borderWidthPx);
3610         UpdateDrawRegion(DRAW_REGION_FOCUS_MODIFIER_INDEX, modifier->GetOverlayRect());
3611     }
3612     modifier->SetPaintTask(std::move(paintTask));
3613     rsNode_->AddModifier(modifier);
3614     modifier->AttachAnimationRectProperty();
3615     RequestNextFrame();
3616 }
3617 
PaintFocusState(const RoundRect & paintRect,const Dimension & focusPaddingVp,const Color & paintColor,const Dimension & paintWidth,bool isAccessibilityFocus)3618 void RosenRenderContext::PaintFocusState(const RoundRect& paintRect, const Dimension& focusPaddingVp,
3619     const Color& paintColor, const Dimension& paintWidth, bool isAccessibilityFocus)
3620 {
3621     auto paintWidthPx = static_cast<float>(paintWidth.ConvertToPx());
3622     auto borderPaddingPx = static_cast<float>(focusPaddingVp.ConvertToPx());
3623     auto focusPaintRectLeft = paintRect.GetRect().Left() - borderPaddingPx - paintWidthPx / 2;
3624     auto focusPaintRectTop = paintRect.GetRect().Top() - borderPaddingPx - paintWidthPx / 2;
3625     auto focusPaintRectWidth = paintRect.GetRect().Width() + 2 * borderPaddingPx + paintWidthPx;
3626     auto focusPaintRectHeight = paintRect.GetRect().Height() + 2 * borderPaddingPx + paintWidthPx;
3627 
3628     EdgeF diffRadius = { borderPaddingPx + paintWidthPx / 2, borderPaddingPx + paintWidthPx / 2 };
3629     auto focusPaintCornerTopLeft = paintRect.GetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS) + diffRadius;
3630     auto focusPaintCornerTopRight = paintRect.GetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS) + diffRadius;
3631     auto focusPaintCornerBottomLeft = paintRect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS) + diffRadius;
3632     auto focusPaintCornerBottomRight = paintRect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS) + diffRadius;
3633 
3634     RoundRect focusPaintRect;
3635     focusPaintRect.SetRect(RectF(focusPaintRectLeft, focusPaintRectTop, focusPaintRectWidth, focusPaintRectHeight));
3636     focusPaintRect.SetCornerRadius(
3637         RoundRect::CornerPos::TOP_LEFT_POS, focusPaintCornerTopLeft.x, focusPaintCornerTopLeft.y);
3638     focusPaintRect.SetCornerRadius(
3639         RoundRect::CornerPos::TOP_RIGHT_POS, focusPaintCornerTopRight.x, focusPaintCornerTopRight.y);
3640     focusPaintRect.SetCornerRadius(
3641         RoundRect::CornerPos::BOTTOM_LEFT_POS, focusPaintCornerBottomLeft.x, focusPaintCornerBottomLeft.y);
3642     focusPaintRect.SetCornerRadius(
3643         RoundRect::CornerPos::BOTTOM_RIGHT_POS, focusPaintCornerBottomRight.x, focusPaintCornerBottomRight.y);
3644 
3645     PaintFocusState(focusPaintRect, paintColor, paintWidth, isAccessibilityFocus);
3646 }
3647 
PaintFocusState(const Dimension & focusPaddingVp,const Color & paintColor,const Dimension & paintWidth)3648 void RosenRenderContext::PaintFocusState(
3649     const Dimension& focusPaddingVp, const Color& paintColor, const Dimension& paintWidth)
3650 {
3651     CHECK_NULL_VOID(rsNode_);
3652     const auto& bounds = rsNode_->GetStagingProperties().GetBounds();
3653     const auto& radius = rsNode_->GetStagingProperties().GetCornerRadius();
3654 
3655     RoundRect frameRect;
3656     frameRect.SetRect(RectF(0, 0, bounds.z_, bounds.w_));
3657     frameRect.SetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS, radius.x_, radius.x_);
3658     frameRect.SetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS, radius.y_, radius.y_);
3659     frameRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS, radius.z_, radius.z_);
3660     frameRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS, radius.w_, radius.w_);
3661 
3662     PaintFocusState(frameRect, focusPaddingVp, paintColor, paintWidth);
3663 }
3664 
ClearFocusState()3665 void RosenRenderContext::ClearFocusState()
3666 {
3667     TAG_LOGD(AceLogTag::ACE_FOCUS, "Clear focus state.");
3668     CHECK_NULL_VOID(rsNode_);
3669     auto context = PipelineBase::GetCurrentContext();
3670     CHECK_NULL_VOID(context);
3671     CHECK_NULL_VOID(focusStateModifier_);
3672 
3673     UpdateDrawRegion(DRAW_REGION_FOCUS_MODIFIER_INDEX, focusStateModifier_->GetOverlayRect());
3674     rsNode_->RemoveModifier(focusStateModifier_);
3675     RequestNextFrame();
3676 }
3677 
FlushContentDrawFunction(CanvasDrawFunction && contentDraw)3678 void RosenRenderContext::FlushContentDrawFunction(CanvasDrawFunction&& contentDraw)
3679 {
3680     CHECK_NULL_VOID(rsNode_);
3681     CHECK_NULL_VOID(contentDraw);
3682     rsNode_->DrawOnNode(
3683 #ifndef USE_ROSEN_DRAWING
3684         Rosen::RSModifierType::CONTENT_STYLE, [contentDraw = std::move(contentDraw)](std::shared_ptr<SkCanvas> canvas) {
3685             RSCanvas rsCanvas(&canvas);
3686             contentDraw(rsCanvas);
3687 #else
3688         Rosen::RSModifierType::CONTENT_STYLE,
3689         [contentDraw = std::move(contentDraw)](std::shared_ptr<RSCanvas> canvas) {
3690             CHECK_NULL_VOID(canvas);
3691             contentDraw(*canvas);
3692 #endif
3693         });
3694 }
3695 
3696 void RosenRenderContext::FlushContentModifier(const RefPtr<Modifier>& modifier)
3697 {
3698     CHECK_NULL_VOID(rsNode_);
3699     CHECK_NULL_VOID(modifier);
3700     auto modifierAdapter = std::static_pointer_cast<ContentModifierAdapter>(ConvertContentModifier(modifier));
3701     auto contentModifier = AceType::DynamicCast<ContentModifier>(modifier);
3702     CHECK_NULL_VOID(contentModifier);
3703     auto rect = contentModifier->GetBoundsRect();
3704     if (rect.has_value()) {
3705         std::shared_ptr<Rosen::RectF> overlayRect =
3706             std::make_shared<Rosen::RectF>(rect->GetX(), rect->GetY(), rect->Width(), rect->Height());
3707         UpdateDrawRegion(DRAW_REGION_CONTENT_MODIFIER_INDEX, overlayRect);
3708     }
3709     rsNode_->SetIsCustomTextType(contentModifier->GetIsCustomFont());
3710     rsNode_->AddModifier(modifierAdapter);
3711     modifierAdapter->AttachProperties();
3712 }
3713 
3714 void RosenRenderContext::FlushForegroundDrawFunction(CanvasDrawFunction&& foregroundDraw)
3715 {
3716     CHECK_NULL_VOID(rsNode_);
3717     CHECK_NULL_VOID(foregroundDraw);
3718     rsNode_->DrawOnNode(Rosen::RSModifierType::FOREGROUND_STYLE,
3719 #ifndef USE_ROSEN_DRAWING
3720         [foregroundDraw = std::move(foregroundDraw)](std::shared_ptr<SkCanvas> canvas) {
3721             RSCanvas rsCanvas(&canvas);
3722             foregroundDraw(rsCanvas);
3723 #else
3724             [foregroundDraw = std::move(foregroundDraw)](std::shared_ptr<RSCanvas> canvas)
3725             {
3726                 CHECK_NULL_VOID(canvas);
3727                 foregroundDraw(*canvas);
3728 #endif
3729         });
3730 }
3731 
3732 void RosenRenderContext::FlushOverlayDrawFunction(CanvasDrawFunction&& overlayDraw)
3733 {
3734     CHECK_NULL_VOID(rsNode_);
3735     CHECK_NULL_VOID(overlayDraw);
3736     rsNode_->DrawOnNode(
3737 #ifndef USE_ROSEN_DRAWING
3738         Rosen::RSModifierType::OVERLAY_STYLE, [overlayDraw = std::move(overlayDraw)](std::shared_ptr<SkCanvas> canvas) {
3739             RSCanvas rsCanvas(&canvas);
3740             overlayDraw(rsCanvas);
3741 #else
3742         Rosen::RSModifierType::OVERLAY_STYLE,
3743         [overlayDraw = std::move(overlayDraw)](std::shared_ptr<RSCanvas> canvas) {
3744             CHECK_NULL_VOID(canvas);
3745             overlayDraw(*canvas);
3746 #endif
3747         });
3748 }
3749 
3750 void RosenRenderContext::FlushOverlayModifier(const RefPtr<Modifier>& modifier)
3751 {
3752     CHECK_NULL_VOID(rsNode_);
3753     CHECK_NULL_VOID(modifier);
3754     auto modifierAdapter = std::static_pointer_cast<OverlayModifierAdapter>(ConvertOverlayModifier(modifier));
3755     auto overlayModifier = AceType::DynamicCast<OverlayModifier>(modifier);
3756     CHECK_NULL_VOID(overlayModifier);
3757     auto rect = overlayModifier->GetBoundsRect();
3758     std::shared_ptr<Rosen::RectF> overlayRect =
3759         std::make_shared<Rosen::RectF>(rect.GetX(), rect.GetY(), rect.Width(), rect.Height());
3760     UpdateDrawRegion(DRAW_REGION_OVERLAY_MODIFIER_INDEX, overlayRect);
3761     rsNode_->AddModifier(modifierAdapter);
3762     modifierAdapter->AttachProperties();
3763 }
3764 
3765 void RosenRenderContext::FlushForegroundModifier(const RefPtr<Modifier>& modifier)
3766 {
3767     CHECK_NULL_VOID(rsNode_);
3768     CHECK_NULL_VOID(modifier);
3769     auto modifierAdapter = std::static_pointer_cast<ForegroundModifierAdapter>(ConvertForegroundModifier(modifier));
3770     auto foregroundModifier = AceType::DynamicCast<ForegroundModifier>(modifier);
3771     CHECK_NULL_VOID(foregroundModifier);
3772     auto rect = foregroundModifier->GetBoundsRect();
3773     std::shared_ptr<Rosen::RectF> foregroundRect =
3774         std::make_shared<Rosen::RectF>(rect.GetX(), rect.GetY(), rect.Width(), rect.Height());
3775     UpdateDrawRegion(DRAW_REGION_OVERLAY_MODIFIER_INDEX, foregroundRect);
3776     rsNode_->AddModifier(modifierAdapter);
3777     modifierAdapter->AttachProperties();
3778 }
3779 
3780 const std::shared_ptr<Rosen::RSNode>& RosenRenderContext::GetRSNode()
3781 {
3782     return rsNode_;
3783 }
3784 
3785 void RosenRenderContext::RebuildFrame(FrameNode* /*self*/, const std::list<RefPtr<FrameNode>>& children)
3786 {
3787     ReCreateRsNodeTree(children);
3788     RequestNextFrame();
3789 }
3790 
3791 std::vector<std::shared_ptr<Rosen::RSNode>> RosenRenderContext::GetChildrenRSNodes(
3792     const std::list<RefPtr<FrameNode>>& frameChildren, std::unordered_map<Rosen::NodeId, bool>& nodeIdMap)
3793 {
3794     std::vector<std::shared_ptr<Rosen::RSNode>> rsNodes;
3795     for (const auto& child : frameChildren) {
3796         if (!child) {
3797             continue;
3798         }
3799         auto rosenRenderContext = DynamicCast<RosenRenderContext>(child->renderContext_);
3800         if (!rosenRenderContext) {
3801             continue;
3802         }
3803         auto rsnode = rosenRenderContext->GetRSNode();
3804         if (!rsnode) {
3805             continue;
3806         }
3807         auto result = nodeIdMap.try_emplace(rsnode->GetId(), false);
3808         if (result.second) {
3809             rsNodes.emplace_back(rsnode);
3810         }
3811     }
3812     return rsNodes;
3813 }
3814 
3815 void RosenRenderContext::ReCreateRsNodeTree(const std::list<RefPtr<FrameNode>>& children)
3816 {
3817     CHECK_NULL_VOID(rsNode_);
3818     if (!isNeedRebuildRSTree_) {
3819         return;
3820     }
3821     // now rsNode's children, key is id of rsNode, value means whether the node exists in previous children of rsNode.
3822     std::unordered_map<Rosen::NodeId, bool> childNodeMap;
3823     auto nowRSNodes = GetChildrenRSNodes(children, childNodeMap);
3824     std::vector<Rosen::NodeId> childNodeIds;
3825     for (auto& child : nowRSNodes) {
3826         childNodeIds.emplace_back(child->GetId());
3827     }
3828     if (childNodeIds == rsNode_->GetChildren()) {
3829         return;
3830     }
3831     if (childNodeIds.empty()) {
3832         rsNode_->ClearChildren();
3833         return;
3834     }
3835 
3836     // save a copy of previous children because for loop will delete child
3837     auto preChildNodeIds = rsNode_->GetChildren();
3838     for (auto nodeId : preChildNodeIds) {
3839         auto iter = childNodeMap.find(nodeId);
3840         if (iter == childNodeMap.end()) {
3841             rsNode_->RemoveChildByNodeId(nodeId);
3842         } else {
3843             iter->second = true;
3844         }
3845     }
3846     for (size_t index = 0; index != childNodeIds.size(); ++index) {
3847         auto nodeId = rsNode_->GetChildIdByIndex(index);
3848         if (!(nodeId.has_value() && nodeId.value() == childNodeIds[index])) {
3849             auto iter = childNodeMap.find(childNodeIds[index]);
3850             if (iter == childNodeMap.end()) {
3851                 continue;
3852             }
3853             if (iter->second) {
3854                 rsNode_->MoveChild(nowRSNodes[index], index);
3855             } else {
3856                 rsNode_->AddChild(nowRSNodes[index], index);
3857             }
3858         }
3859     }
3860 }
3861 
3862 void RosenRenderContext::AddFrameChildren(FrameNode* /*self*/, const std::list<RefPtr<FrameNode>>& children)
3863 {
3864     CHECK_NULL_VOID(rsNode_);
3865     for (const auto& child : children) {
3866         if (!child) {
3867             continue;
3868         }
3869         auto rosenRenderContext = DynamicCast<RosenRenderContext>(child->renderContext_);
3870         if (!rosenRenderContext) {
3871             continue;
3872         }
3873         auto rsNode = rosenRenderContext->GetRSNode();
3874         if (rsNode) {
3875             rsNode_->AddChild(rsNode, -1);
3876         }
3877     }
3878 }
3879 
3880 void RosenRenderContext::RemoveFrameChildren(FrameNode* /*self*/, const std::list<RefPtr<FrameNode>>& children)
3881 {
3882     CHECK_NULL_VOID(rsNode_);
3883     for (const auto& child : children) {
3884         if (!child) {
3885             continue;
3886         }
3887         auto rosenRenderContext = DynamicCast<RosenRenderContext>(child->renderContext_);
3888         if (!rosenRenderContext) {
3889             continue;
3890         }
3891         auto rsNode = rosenRenderContext->GetRSNode();
3892         if (rsNode) {
3893             rsNode_->RemoveChild(rsNode);
3894         }
3895     }
3896 }
3897 
3898 void RosenRenderContext::MoveFrame(FrameNode* /*self*/, const RefPtr<FrameNode>& child, int32_t index)
3899 {
3900     CHECK_NULL_VOID(rsNode_);
3901     CHECK_NULL_VOID(child);
3902     auto rosenRenderContext = DynamicCast<RosenRenderContext>(child->renderContext_);
3903     CHECK_NULL_VOID(rosenRenderContext);
3904     auto rsNode = rosenRenderContext->GetRSNode();
3905     // no need to check nullptr since MoveChild will take care of it
3906     rsNode_->MoveChild(rsNode, index);
3907 }
3908 
3909 void RosenRenderContext::AnimateHoverEffectScale(bool isHovered)
3910 {
3911     if ((isHovered && isHoveredScale_) || (!isHovered && !isHoveredScale_)) {
3912         return;
3913     }
3914     CHECK_NULL_VOID(rsNode_);
3915     auto pipeline = PipelineBase::GetCurrentContext();
3916     CHECK_NULL_VOID(pipeline);
3917     auto appTheme = pipeline->GetTheme<AppTheme>();
3918     CHECK_NULL_VOID(appTheme);
3919 
3920     float hoverScaleFrom = isHovered ? appTheme->GetHoverScaleStart() : appTheme->GetHoverScaleEnd();
3921     float hoverColorTo = isHovered ? appTheme->GetHoverScaleEnd() : appTheme->GetHoverScaleStart();
3922     float scaleStart = hoverScaleFrom;
3923     float scaleEnd = hoverColorTo;
3924     int32_t themeDuration = appTheme->GetHoverDuration();
3925 
3926     SetScale(scaleStart, scaleStart);
3927     Rosen::RSAnimationTimingProtocol protocol;
3928     protocol.SetDuration(themeDuration);
3929     RSNode::Animate(protocol, Rosen::RSAnimationTimingCurve::CreateCubicCurve(0.2f, 0.0f, 0.2f, 1.0f),
3930         [this, scaleEnd]() {
3931             SetScale(scaleEnd, scaleEnd);
3932         });
3933     isHoveredScale_ = isHovered;
3934 }
3935 
3936 void RosenRenderContext::AnimateHoverEffectBoard(bool isHovered)
3937 {
3938     if ((isHovered && isHoveredBoard_) || (!isHovered && !isHoveredBoard_)) {
3939         return;
3940     }
3941     CHECK_NULL_VOID(rsNode_);
3942     auto pipeline = PipelineBase::GetCurrentContext();
3943     CHECK_NULL_VOID(pipeline);
3944     auto appTheme = pipeline->GetTheme<AppTheme>();
3945     CHECK_NULL_VOID(appTheme);
3946 
3947     Color hoverColorFrom = isHovered ? appTheme->GetHoverHighlightStart() : appTheme->GetHoverHighlightEnd();
3948     Color hoverColorTo = isHovered ? appTheme->GetHoverHighlightEnd() : appTheme->GetHoverHighlightStart();
3949     Color highlightStart =
3950         GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(blendColor_).BlendColor(hoverColorFrom);
3951     Color highlightEnd =
3952         GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(blendColor_).BlendColor(hoverColorTo);
3953     int32_t themeDuration = appTheme->GetHoverDuration();
3954 
3955     rsNode_->SetBackgroundColor(highlightStart.GetValue());
3956     Rosen::RSAnimationTimingProtocol protocol;
3957     protocol.SetDuration(themeDuration);
3958     RSNode::Animate(protocol, Rosen::RSAnimationTimingCurve::CreateCubicCurve(0.2f, 0.0f, 0.2f, 1.0f),
3959         [rsNode = rsNode_, highlightEnd]() {
3960             CHECK_NULL_VOID(rsNode);
3961             rsNode->SetBackgroundColor(highlightEnd.GetValue());
3962         });
3963     hoveredColor_ = hoverColorTo;
3964     isHoveredBoard_ = isHovered;
3965 }
3966 
3967 void RosenRenderContext::UpdateBackBlurRadius(const Dimension& radius)
3968 {
3969     const auto& groupProperty = GetOrCreateBackground();
3970     if (groupProperty->CheckBlurRadius(radius)) {
3971         // Same with previous value
3972         return;
3973     }
3974     groupProperty->propBlurRadius = radius;
3975     SetBackBlurFilter();
3976 }
3977 
3978 void RosenRenderContext::UpdateMotionBlur(const MotionBlurOption& motionBlurOption)
3979 {
3980     CHECK_NULL_VOID(rsNode_);
3981     const auto& groupProperty = GetOrCreateForeground();
3982     groupProperty->propMotionBlur = motionBlurOption;
3983     Rosen::Vector2f anchor(motionBlurOption.anchor.x, motionBlurOption.anchor.y);
3984     rsNode_->SetMotionBlurPara(motionBlurOption.radius, anchor);
3985 }
3986 
3987 void RosenRenderContext::UpdateBackBlur(const Dimension& radius, const BlurOption& blurOption)
3988 {
3989     CHECK_NULL_VOID(rsNode_);
3990     const auto& groupProperty = GetOrCreateBackground();
3991     if (groupProperty->CheckBlurRadius(radius)) {
3992         // Same with previous value
3993         return;
3994     }
3995     groupProperty->propBlurRadius = radius;
3996     SetBackBlurFilter();
3997     if (blurOption.grayscale.size() > 1) {
3998         Rosen::Vector2f grayScale(blurOption.grayscale[0], blurOption.grayscale[0]);
3999         rsNode_->SetGreyCoef(grayScale);
4000     }
4001 }
4002 
4003 void RosenRenderContext::UpdateFrontBlurRadius(const Dimension& radius)
4004 {
4005     const auto& groupProperty = GetOrCreateForeground();
4006     if (groupProperty->CheckBlurRadius(radius)) {
4007         // Same with previous value
4008         return;
4009     }
4010     groupProperty->propBlurRadius = radius;
4011     SetFrontBlurFilter();
4012 }
4013 
4014 void RosenRenderContext::UpdateFrontBlur(const Dimension& radius, const BlurOption& blurOption)
4015 {
4016     CHECK_NULL_VOID(rsNode_);
4017     const auto& groupProperty = GetOrCreateForeground();
4018     if (groupProperty->CheckBlurRadius(radius)) {
4019         // Same with previous value
4020         return;
4021     }
4022     groupProperty->propBlurRadius = radius;
4023     SetFrontBlurFilter();
4024     if (blurOption.grayscale.size() > 1) {
4025         Rosen::Vector2f grayScale(blurOption.grayscale[0], blurOption.grayscale[1]);
4026         rsNode_->SetGreyCoef(grayScale);
4027     }
4028 }
4029 
4030 Rosen::SHADOW_COLOR_STRATEGY RosenRenderContext::ToShadowColorStrategy(ShadowColorStrategy shadowColorStrategy)
4031 {
4032     if (shadowColorStrategy == ShadowColorStrategy::NONE) {
4033         return Rosen::SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE ;
4034     } else if (shadowColorStrategy == ShadowColorStrategy::AVERAGE) {
4035         return Rosen::SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_AVERAGE ;
4036     } else if (shadowColorStrategy == ShadowColorStrategy::PRIMARY) {
4037         return Rosen::SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_MAIN ;
4038     } else {
4039         return Rosen::SHADOW_COLOR_STRATEGY::COLOR_STRATEGY_NONE;
4040     }
4041 }
4042 
4043 void RosenRenderContext::OnBackShadowUpdate(const Shadow& shadow)
4044 {
4045     CHECK_NULL_VOID(rsNode_);
4046     if (!shadow.IsValid()) {
4047         if (shadow.GetHardwareAcceleration()) {
4048             rsNode_->SetShadowElevation(0.0);
4049         } else {
4050             rsNode_->SetShadowRadius(0.0);
4051         }
4052         RequestNextFrame();
4053         return;
4054     }
4055     rsNode_->SetShadowColor(shadow.GetColor().GetValue());
4056     rsNode_->SetShadowOffsetX(shadow.GetOffset().GetX());
4057     rsNode_->SetShadowOffsetY(shadow.GetOffset().GetY());
4058     rsNode_->SetShadowMask(shadow.GetShadowType() == ShadowType::BLUR);
4059     rsNode_->SetShadowIsFilled(shadow.GetIsFilled());
4060     rsNode_->SetShadowColorStrategy(ToShadowColorStrategy(shadow.GetShadowColorStrategy()));
4061     if (shadow.GetHardwareAcceleration()) {
4062         rsNode_->SetShadowElevation(shadow.GetElevation());
4063     } else {
4064 #ifndef USE_ROSEN_DRAWING
4065         rsNode_->SetShadowRadius(SkiaDecorationPainter::ConvertRadiusToSigma(shadow.GetBlurRadius()));
4066 #else
4067         rsNode_->SetShadowRadius(DrawingDecorationPainter::ConvertRadiusToSigma(shadow.GetBlurRadius()));
4068 #endif
4069     }
4070     RequestNextFrame();
4071 }
4072 
4073 void RosenRenderContext::OnBackBlendModeUpdate(BlendMode blendMode)
4074 {
4075     CHECK_NULL_VOID(rsNode_);
4076     if (blendMode == BlendMode::BACK_COMPAT_SOURCE_IN) {
4077         rsNode_->SetBackgroundShader(nullptr);
4078         rsNode_->SetColorBlendMode(Rosen::RSColorBlendMode::NONE);
4079     } else {
4080         auto rsBlendMode = static_cast<Rosen::RSColorBlendMode>(blendMode);
4081         rsNode_->SetColorBlendMode(rsBlendMode);
4082     }
4083     RequestNextFrame();
4084 }
4085 
4086 void RosenRenderContext::OnBackBlendApplyTypeUpdate(BlendApplyType blendApplyType)
4087 {
4088     CHECK_NULL_VOID(rsNode_);
4089     auto rsBlendApplyType = static_cast<Rosen::RSColorBlendApplyType>(blendApplyType);
4090     rsNode_->SetColorBlendApplyType(rsBlendApplyType);
4091     RequestNextFrame();
4092 }
4093 
4094 void RosenRenderContext::UpdateBrightnessBlender(const OHOS::Rosen::BrightnessBlender* brightnessBlender)
4095 {
4096     CHECK_NULL_VOID(rsNode_);
4097     CHECK_NULL_VOID(brightnessBlender);
4098     rsNode_->SetBlender(brightnessBlender);
4099     RequestNextFrame();
4100 }
4101 
4102 // called when frameNode size changes
4103 void RosenRenderContext::PaintGraphics()
4104 {
4105     CHECK_NULL_VOID(rsNode_);
4106     auto&& graphicProps = GetOrCreateGraphics();
4107 
4108     if (!graphics_) {
4109         graphics_ = std::make_unique<GraphicModifiers>();
4110     }
4111     if (graphicProps->HasFrontGrayScale()) {
4112         auto grayScale = graphicProps->GetFrontGrayScaleValue();
4113         OnFrontGrayScaleUpdate(grayScale);
4114     }
4115 
4116     if (graphicProps->HasFrontBrightness()) {
4117         auto brightness = graphicProps->GetFrontBrightnessValue();
4118         OnFrontBrightnessUpdate(brightness);
4119     }
4120 
4121     if (graphicProps->HasFrontContrast()) {
4122         auto contrast = graphicProps->GetFrontContrastValue();
4123         OnFrontContrastUpdate(contrast);
4124     }
4125 
4126     if (graphicProps->HasFrontSaturate()) {
4127         auto saturate = graphicProps->GetFrontSaturateValue();
4128         OnFrontSaturateUpdate(saturate);
4129     }
4130 
4131     if (graphicProps->HasFrontSepia()) {
4132         auto sepia = graphicProps->GetFrontSepiaValue();
4133         OnFrontSepiaUpdate(sepia);
4134     }
4135 
4136     if (graphicProps->HasFrontInvert()) {
4137         auto invert = graphicProps->GetFrontInvertValue();
4138         OnFrontInvertUpdate(invert);
4139     }
4140 
4141     if (graphicProps->HasFrontHueRotate()) {
4142         auto hueRotate = graphicProps->GetFrontHueRotateValue();
4143         OnFrontHueRotateUpdate(hueRotate);
4144     }
4145 
4146     if (graphicProps->HasFrontColorBlend()) {
4147         auto colorBlend = graphicProps->GetFrontColorBlendValue();
4148         OnFrontColorBlendUpdate(colorBlend);
4149     }
4150 }
4151 
4152 // helper function to check if frame react is valid
4153 bool RosenRenderContext::RectIsNull()
4154 {
4155     RectF rect = GetPaintRectWithoutTransform();
4156     return NearZero(rect.Width()) || NearZero(rect.Height());
4157 }
4158 
4159 template<typename T, typename D>
4160 void RosenRenderContext::SetGraphicModifier(std::shared_ptr<T>& modifier, D data)
4161 {
4162     CHECK_NULL_VOID(rsNode_);
4163     if (!modifier) {
4164         modifier = std::make_shared<T>();
4165         rsNode_->AddModifier(modifier);
4166     }
4167     modifier->SetCustomData(data);
4168 
4169     auto borderRadius = GetBorderRadius();
4170     if (borderRadius.has_value()) {
4171         Rosen::Vector4f rsRadius;
4172         ConvertRadius(*borderRadius, rsRadius);
4173         modifier->SetCornerRadius(rsRadius);
4174     }
4175 }
4176 
4177 void RosenRenderContext::AddModifier(const std::shared_ptr<Rosen::RSModifier>& modifier)
4178 {
4179     CHECK_NULL_VOID(modifier);
4180     CHECK_NULL_VOID(rsNode_);
4181     rsNode_->AddModifier(modifier);
4182 }
4183 
4184 void RosenRenderContext::RemoveModifier(const std::shared_ptr<Rosen::RSModifier>& modifier)
4185 {
4186     CHECK_NULL_VOID(modifier);
4187     CHECK_NULL_VOID(rsNode_);
4188     rsNode_->RemoveModifier(modifier);
4189 }
4190 
4191 // helper function to update one of the graphic effects
4192 template<typename T, typename D>
4193 void RosenRenderContext::UpdateGraphic(std::shared_ptr<T>& modifier, D data)
4194 {
4195     CHECK_NULL_VOID(!RectIsNull());
4196     SetGraphicModifier(modifier, data);
4197     RequestNextFrame();
4198 }
4199 
4200 void RosenRenderContext::OnFrontBrightnessUpdate(const Dimension& brightness)
4201 {
4202     CHECK_NULL_VOID(rsNode_);
4203     rsNode_->SetBrightness(brightness.Value());
4204     RequestNextFrame();
4205 }
4206 
4207 void RosenRenderContext::OnFrontGrayScaleUpdate(const Dimension& grayScale)
4208 {
4209     CHECK_NULL_VOID(rsNode_);
4210     rsNode_->SetGrayScale(grayScale.Value());
4211     RequestNextFrame();
4212 }
4213 
4214 void RosenRenderContext::OnFrontContrastUpdate(const Dimension& contrast)
4215 {
4216     CHECK_NULL_VOID(rsNode_);
4217     rsNode_->SetContrast(contrast.Value());
4218     RequestNextFrame();
4219 }
4220 
4221 void RosenRenderContext::OnFrontSaturateUpdate(const Dimension& saturate)
4222 {
4223     CHECK_NULL_VOID(rsNode_);
4224     rsNode_->SetSaturate(saturate.Value());
4225     RequestNextFrame();
4226 }
4227 
4228 void RosenRenderContext::OnFrontSepiaUpdate(const Dimension& sepia)
4229 {
4230     CHECK_NULL_VOID(rsNode_);
4231     rsNode_->SetSepia(sepia.Value());
4232     RequestNextFrame();
4233 }
4234 
4235 void RosenRenderContext::OnFrontInvertUpdate(const InvertVariant& invert)
4236 {
4237     CHECK_NULL_VOID(rsNode_);
4238     if (invert.index() == 0) {
4239         rsNode_->SetInvert(std::get<float>(invert));
4240     } else {
4241         InvertOption option = std::get<InvertOption>(invert);
4242         Rosen::Vector4f invertVector;
4243         invertVector.SetValues(option.low_, option.high_, option.threshold_, option.thresholdRange_);
4244         rsNode_->SetAiInvert(invertVector);
4245     }
4246     RequestNextFrame();
4247 }
4248 
4249 void RosenRenderContext::OnSystemBarEffectUpdate(bool systemBarEffect)
4250 {
4251     CHECK_NULL_VOID(rsNode_);
4252     rsNode_->SetSystemBarEffect();
4253     RequestNextFrame();
4254 }
4255 
4256 void RosenRenderContext::OnFrontHueRotateUpdate(float hueRotate)
4257 {
4258     CHECK_NULL_VOID(rsNode_);
4259     rsNode_->SetHueRotate(hueRotate);
4260     RequestNextFrame();
4261 }
4262 
4263 void RosenRenderContext::OnFrontColorBlendUpdate(const Color& colorBlend)
4264 {
4265     CHECK_NULL_VOID(rsNode_);
4266     rsNode_->SetColorBlend(colorBlend.GetValue());
4267     RequestNextFrame();
4268 }
4269 
4270 void RosenRenderContext::OnLinearGradientBlurUpdate(const NG::LinearGradientBlurPara& blurPara)
4271 {
4272     float blurRadius = 0.0f;
4273     if (blurPara.blurRadius_.IsValid()) {
4274         float radiusPx = blurPara.blurRadius_.ConvertToPx();
4275         blurRadius = radiusPx;
4276     }
4277 
4278     CHECK_NULL_VOID(rsNode_);
4279     std::shared_ptr<Rosen::RSLinearGradientBlurPara> rsLinearGradientBlurPara(
4280         std::make_shared<Rosen::RSLinearGradientBlurPara>(
4281             blurRadius, blurPara.fractionStops_, static_cast<Rosen::GradientDirection>(blurPara.direction_)));
4282 
4283     rsNode_->SetLinearGradientBlurPara(rsLinearGradientBlurPara);
4284     RequestNextFrame();
4285 }
4286 
4287 void RosenRenderContext::OnMagnifierUpdate(const MagnifierParams& magnifierParams)
4288 {
4289     CHECK_NULL_VOID(rsNode_);
4290     std::shared_ptr<Rosen::RSMagnifierParams> rsMagnifierParams(std::make_shared<Rosen::RSMagnifierParams>());
4291     rsMagnifierParams->factor_ = magnifierParams.factor_;
4292     rsMagnifierParams->width_ = magnifierParams.width_;
4293     rsMagnifierParams->height_ = magnifierParams.height_;
4294     rsMagnifierParams->borderWidth_ = magnifierParams.borderWidth_;
4295     rsMagnifierParams->cornerRadius_ = magnifierParams.cornerRadius_;
4296     rsMagnifierParams->offsetX_ = magnifierParams.offsetX_;
4297     rsMagnifierParams->offsetY_ = magnifierParams.offsetY_;
4298     rsMagnifierParams->shadowOffsetX_ = magnifierParams.shadowOffsetX_;
4299     rsMagnifierParams->shadowOffsetY_ = magnifierParams.shadowOffsetY_;
4300     rsMagnifierParams->shadowSize_ = magnifierParams.shadowSize_;
4301     rsMagnifierParams->shadowStrength_ = magnifierParams.shadowStrength_;
4302     rsMagnifierParams->gradientMaskColor1_ = magnifierParams.gradientMaskColor1_;
4303     rsMagnifierParams->gradientMaskColor2_ = magnifierParams.gradientMaskColor2_;
4304     rsMagnifierParams->outerContourColor1_ = magnifierParams.outerContourColor1_;
4305     rsMagnifierParams->outerContourColor2_ = magnifierParams.outerContourColor2_;
4306     rsNode_->SetMagnifierParams(rsMagnifierParams);
4307     RequestNextFrame();
4308 }
4309 void RosenRenderContext::OnDynamicDimDegreeUpdate(const float degree)
4310 {
4311     CHECK_NULL_VOID(rsNode_);
4312     rsNode_->SetDynamicDimDegree(degree);
4313     RequestNextFrame();
4314 }
4315 
4316 void RosenRenderContext::OnDynamicLightUpRateUpdate(const float rate)
4317 {
4318     CHECK_NULL_VOID(rsNode_);
4319     rsNode_->SetDynamicLightUpRate(rate);
4320     RequestNextFrame();
4321 }
4322 
4323 void RosenRenderContext::OnDynamicLightUpDegreeUpdate(const float degree)
4324 {
4325     CHECK_NULL_VOID(rsNode_);
4326     rsNode_->SetDynamicLightUpDegree(degree);
4327     RequestNextFrame();
4328 }
4329 
4330 void RosenRenderContext::OnBgDynamicBrightnessOptionUpdate(const std::optional<BrightnessOption>& brightnessOption)
4331 {
4332     if (!brightnessOption.has_value()) {
4333         return;
4334     }
4335     CHECK_NULL_VOID(rsNode_);
4336     rsNode_->SetBgBrightnessParams(
4337         {
4338             brightnessOption->rate,
4339             brightnessOption->lightUpDegree,
4340             brightnessOption->cubicCoeff,
4341             brightnessOption->quadCoeff,
4342             brightnessOption->saturation,
4343             { brightnessOption->posRGB[0], brightnessOption->posRGB[1], brightnessOption->posRGB[2] },
4344             { brightnessOption->negRGB[0], brightnessOption->negRGB[1], brightnessOption->negRGB[2] }
4345         }
4346     );
4347     rsNode_->SetBgBrightnessFract(brightnessOption->fraction);
4348     RequestNextFrame();
4349 }
4350 
4351 void RosenRenderContext::OnFgDynamicBrightnessOptionUpdate(const std::optional<BrightnessOption>& brightnessOption)
4352 {
4353     if (!brightnessOption.has_value()) {
4354         return;
4355     }
4356     CHECK_NULL_VOID(rsNode_);
4357     rsNode_->SetFgBrightnessParams(
4358         {
4359             brightnessOption->rate,
4360             brightnessOption->lightUpDegree,
4361             brightnessOption->cubicCoeff,
4362             brightnessOption->quadCoeff,
4363             brightnessOption->saturation,
4364             { brightnessOption->posRGB[0], brightnessOption->posRGB[1], brightnessOption->posRGB[2] },
4365             { brightnessOption->negRGB[0], brightnessOption->negRGB[1], brightnessOption->negRGB[2] }
4366         }
4367     );
4368     rsNode_->SetFgBrightnessFract(brightnessOption->fraction);
4369     RequestNextFrame();
4370 }
4371 
4372 void RosenRenderContext::UpdateTransition(const TransitionOptions& options)
4373 {
4374     CHECK_NULL_VOID(rsNode_);
4375     if (options.Type == TransitionType::ALL || options.Type == TransitionType::APPEARING) {
4376         if (!propTransitionAppearing_) {
4377             propTransitionAppearing_ = std::make_unique<TransitionOptions>(options);
4378         } else {
4379             *propTransitionAppearing_ = options;
4380         }
4381         propTransitionAppearing_->Type = TransitionType::APPEARING;
4382     }
4383     if (options.Type == TransitionType::ALL || options.Type == TransitionType::DISAPPEARING) {
4384         if (!propTransitionDisappearing_) {
4385             propTransitionDisappearing_ = std::make_unique<TransitionOptions>(options);
4386         } else {
4387             *propTransitionDisappearing_ = options;
4388         }
4389         propTransitionDisappearing_->Type = TransitionType::DISAPPEARING;
4390     }
4391     NotifyHostTransformUpdated();
4392 }
4393 
4394 void RosenRenderContext::CleanTransition()
4395 {
4396     propTransitionDisappearing_.reset();
4397     propTransitionDisappearing_.reset();
4398 }
4399 
4400 std::shared_ptr<Rosen::RSTransitionEffect> RosenRenderContext::GetRSTransitionWithoutType(
4401     const std::unique_ptr<TransitionOptions>& options, const SizeF& frameSize)
4402 {
4403     if (options == nullptr) {
4404         return nullptr;
4405     }
4406     std::shared_ptr<Rosen::RSTransitionEffect> effect = Rosen::RSTransitionEffect::Create();
4407     if (options->HasOpacity()) {
4408         effect = effect->Opacity(options->GetOpacityValue());
4409     }
4410     if (options->HasTranslate()) {
4411         const auto& translate = options->GetTranslateValue();
4412         effect = effect->Translate({ static_cast<float>(translate.x.ConvertToPxWithSize(frameSize.Width())),
4413             static_cast<float>(translate.y.ConvertToPxWithSize(frameSize.Height())),
4414             static_cast<float>(translate.z.ConvertToPx()) });
4415     }
4416     if (options->HasScale()) {
4417         const auto& scale = options->GetScaleValue();
4418         effect = effect->Scale({ scale.xScale, scale.yScale, scale.zScale });
4419     }
4420     if (options->HasRotate()) {
4421         const auto& rotate = options->GetRotateValue();
4422         effect = effect->Rotate({ rotate.xDirection, rotate.yDirection, rotate.zDirection, rotate.angle });
4423     }
4424     return effect;
4425 }
4426 
4427 void RosenRenderContext::SetBackgroundShader(const std::shared_ptr<Rosen::RSShader>& shader)
4428 {
4429     CHECK_NULL_VOID(rsNode_);
4430     // temporary code for back compat
4431     auto& graphicProps = GetOrCreateGraphics();
4432     if (graphicProps->GetBackBlendMode() == BlendMode::BACK_COMPAT_SOURCE_IN) {
4433         rsNode_->SetBackgroundShader(nullptr);
4434         return;
4435     }
4436     rsNode_->SetBackgroundShader(shader);
4437 }
4438 
4439 void RosenRenderContext::PaintGradient(const SizeF& frameSize)
4440 {
4441     CHECK_NULL_VOID(rsNode_);
4442     auto& gradientProperty = GetOrCreateGradient();
4443     Gradient gradient;
4444     if (gradientProperty->HasLastGradientType()) {
4445         switch (gradientProperty->GetLastGradientTypeValue()) {
4446             case GradientType::LINEAR:
4447                 gradient = gradientProperty->GetLinearGradientValue();
4448                 break;
4449             case GradientType::RADIAL:
4450                 gradient = gradientProperty->GetRadialGradientValue();
4451                 break;
4452             case GradientType::SWEEP:
4453                 gradient = gradientProperty->GetSweepGradientValue();
4454                 break;
4455             default:
4456                 return;
4457         }
4458     } else {
4459         if (gradientProperty->HasLinearGradient()) {
4460             gradient = gradientProperty->GetLinearGradientValue();
4461         }
4462         if (gradientProperty->HasRadialGradient()) {
4463             gradient = gradientProperty->GetRadialGradientValue();
4464         }
4465         if (gradientProperty->HasSweepGradient()) {
4466             gradient = gradientProperty->GetSweepGradientValue();
4467         }
4468     }
4469     if (!gradientStyleModifier_) {
4470         gradientStyleModifier_ = std::make_shared<GradientStyleModifier>(WeakClaim(this));
4471         rsNode_->AddModifier(gradientStyleModifier_);
4472     }
4473     gradientStyleModifier_->SetGradient(gradient);
4474     gradientStyleModifier_->SetSizeF(frameSize);
4475 }
4476 
4477 void RosenRenderContext::OnLinearGradientUpdate(const NG::Gradient& gradient)
4478 {
4479     RectF rect = GetPaintRectWithoutTransform();
4480     if (!RectIsNull()) {
4481         PaintGradient(rect.GetSize());
4482     }
4483     RequestNextFrame();
4484 }
4485 
4486 void RosenRenderContext::OnRadialGradientUpdate(const NG::Gradient& gradient)
4487 {
4488     RectF rect = GetPaintRectWithoutTransform();
4489     if (!RectIsNull()) {
4490         PaintGradient(rect.GetSize());
4491     }
4492     RequestNextFrame();
4493 }
4494 
4495 void RosenRenderContext::OnSweepGradientUpdate(const NG::Gradient& gradient)
4496 {
4497     RectF rect = GetPaintRectWithoutTransform();
4498     if (!RectIsNull()) {
4499         PaintGradient(rect.GetSize());
4500     }
4501     RequestNextFrame();
4502 }
4503 
4504 void RosenRenderContext::PaintClipShape(const std::unique_ptr<ClipProperty>& clip, const SizeF& frameSize)
4505 {
4506     CHECK_NULL_VOID(rsNode_);
4507     auto basicShape = clip->GetClipShapeValue();
4508 #ifndef USE_ROSEN_DRAWING
4509     auto skPath = SkiaDecorationPainter::SkiaCreateSkPath(basicShape, frameSize);
4510     auto shapePath = Rosen::RSPath::CreateRSPath(skPath);
4511     if (!clipBoundModifier_) {
4512         auto prop = std::make_shared<RSProperty<std::shared_ptr<Rosen::RSPath>>>(shapePath);
4513         clipBoundModifier_ = std::make_shared<Rosen::RSClipBoundsModifier>(prop);
4514         rsNode_->AddModifier(clipBoundModifier_);
4515     } else {
4516         auto property =
4517             std::static_pointer_cast<RSProperty<std::shared_ptr<Rosen::RSPath>>>(clipBoundModifier_->GetProperty());
4518         property->Set(shapePath);
4519     }
4520 #else
4521     auto rsPath = DrawingDecorationPainter::DrawingCreatePath(basicShape, frameSize);
4522     auto shapePath = Rosen::RSPath::CreateRSPath(rsPath);
4523     if (!clipBoundModifier_) {
4524         auto prop = std::make_shared<RSProperty<std::shared_ptr<Rosen::RSPath>>>(shapePath);
4525         clipBoundModifier_ = std::make_shared<Rosen::RSClipBoundsModifier>(prop);
4526         rsNode_->AddModifier(clipBoundModifier_);
4527     } else {
4528         auto property =
4529             std::static_pointer_cast<RSProperty<std::shared_ptr<Rosen::RSPath>>>(clipBoundModifier_->GetProperty());
4530         property->Set(shapePath);
4531     }
4532 #endif
4533 }
4534 
4535 void RosenRenderContext::PaintClipMask(const std::unique_ptr<ClipProperty>& clip, const SizeF& frameSize)
4536 {
4537     CHECK_NULL_VOID(rsNode_);
4538     auto basicShape = clip->GetClipMaskValue();
4539 #ifndef USE_ROSEN_DRAWING
4540     auto skPath = SkiaDecorationPainter::SkiaCreateSkPath(basicShape, frameSize);
4541     auto maskPath = Rosen::RSMask::CreatePathMask(skPath, SkiaDecorationPainter::CreateMaskSkPaint(basicShape));
4542     if (!clipMaskModifier_) {
4543         auto prop = std::make_shared<RSProperty<std::shared_ptr<Rosen::RSMask>>>(maskPath);
4544         clipMaskModifier_ = std::make_shared<Rosen::RSMaskModifier>(prop);
4545         rsNode_->AddModifier(clipMaskModifier_);
4546     } else {
4547         auto property =
4548             std::static_pointer_cast<RSProperty<std::shared_ptr<Rosen::RSMask>>>(clipMaskModifier_->GetProperty());
4549         property->Set(maskPath);
4550     }
4551 #else
4552     auto rsPath = DrawingDecorationPainter::DrawingCreatePath(basicShape, frameSize);
4553 
4554     RSColor rsStrokeColor;
4555     rsStrokeColor.SetColorQuad(basicShape->GetStrokeColor());
4556     RSPen pen;
4557     pen.SetColor(rsStrokeColor);
4558     pen.SetWidth(basicShape->GetStrokeWidth());
4559 
4560     auto maskPath =
4561         Rosen::RSMask::CreatePathMask(rsPath, pen, DrawingDecorationPainter::CreateMaskDrawingBrush(basicShape));
4562     if (!clipMaskModifier_) {
4563         auto prop = std::make_shared<RSProperty<std::shared_ptr<RSMask>>>(maskPath);
4564         clipMaskModifier_ = std::make_shared<Rosen::RSMaskModifier>(prop);
4565         rsNode_->AddModifier(clipMaskModifier_);
4566     } else {
4567         auto property = std::static_pointer_cast<RSProperty<std::shared_ptr<RSMask>>>(clipMaskModifier_->GetProperty());
4568         property->Set(maskPath);
4569     }
4570 #endif
4571 }
4572 
4573 void RosenRenderContext::PaintClip(const SizeF& frameSize)
4574 {
4575     CHECK_NULL_VOID(rsNode_);
4576     auto& clip = GetOrCreateClip();
4577     if (clip->HasClipShape()) {
4578         PaintClipShape(clip, frameSize);
4579     }
4580 
4581     if (clip->HasClipMask()) {
4582         PaintClipMask(clip, frameSize);
4583     }
4584 }
4585 
4586 void RosenRenderContext::PaintProgressMask()
4587 {
4588     CHECK_NULL_VOID(rsNode_);
4589     if (!moonProgressModifier_) {
4590         auto host = GetHost();
4591         CHECK_NULL_VOID(host);
4592         moonProgressModifier_ = AceType::MakeRefPtr<MoonProgressModifier>(host);
4593         auto modifierAdapter =
4594             std::static_pointer_cast<OverlayModifierAdapter>(ConvertOverlayModifier(moonProgressModifier_));
4595         rsNode_->AddModifier(modifierAdapter);
4596         modifierAdapter->AttachProperties();
4597     }
4598     auto progress = GetProgressMaskValue();
4599     moonProgressModifier_->SetMaskColor(LinearColor(progress->GetColor()));
4600     moonProgressModifier_->SetMaxValue(progress->GetMaxValue());
4601     if (progress->GetValue() > moonProgressModifier_->GetMaxValue()) {
4602         progress->SetValue(moonProgressModifier_->GetMaxValue());
4603     }
4604     moonProgressModifier_->SetValue(progress->GetValue());
4605     moonProgressModifier_->SetEnableBreathe(progress->GetEnableBreathe());
4606 }
4607 
4608 void RosenRenderContext::SetClipBoundsWithCommands(const std::string& commands)
4609 {
4610     CHECK_NULL_VOID(rsNode_);
4611 #ifndef USE_ROSEN_DRAWING
4612     SkPath skPath;
4613     SkParsePath::FromSVGString(commands.c_str(), &skPath);
4614     rsNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(skPath));
4615 #else
4616     RSRecordingPath rsPath;
4617     rsPath.BuildFromSVGString(commands);
4618     rsNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(rsPath));
4619 #endif
4620 }
4621 
4622 void RosenRenderContext::ClipWithRect(const RectF& rectF)
4623 {
4624     CHECK_NULL_VOID(rsNode_);
4625 #ifndef USE_ROSEN_DRAWING
4626     SkPath skPath;
4627     skPath.addRect(rectF.GetX(), rectF.GetY(), rectF.GetX() + rectF.Width(), rectF.GetY() + rectF.Height());
4628     rsNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(skPath));
4629 #else
4630     RSRecordingPath rsPath;
4631     rsPath.AddRect({ rectF.GetX(), rectF.GetY(), rectF.GetX() + rectF.Width(), rectF.GetY() + rectF.Height() });
4632     rsNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(rsPath));
4633 #endif
4634 }
4635 
4636 void RosenRenderContext::ClipWithRoundRect(const RoundRect& roundRect)
4637 {
4638     CHECK_NULL_VOID(rsNode_);
4639     RSRoundRect rsRoundRect;
4640 
4641     RSRect rsRect(roundRect.GetRect().Left(), roundRect.GetRect().Top(), roundRect.GetRect().Right(),
4642         roundRect.GetRect().Bottom());
4643     rsRoundRect.SetRect(rsRect);
4644 
4645     EdgeF edge = roundRect.GetCornerRadius(RoundRect::TOP_LEFT_POS);
4646     rsRoundRect.SetCornerRadius(RSRoundRect::TOP_LEFT_POS, edge.x, edge.y);
4647     edge = roundRect.GetCornerRadius(RoundRect::TOP_RIGHT_POS);
4648     rsRoundRect.SetCornerRadius(RSRoundRect::TOP_RIGHT_POS, edge.x, edge.y);
4649     edge = roundRect.GetCornerRadius(RoundRect::BOTTOM_LEFT_POS);
4650     rsRoundRect.SetCornerRadius(RSRoundRect::BOTTOM_LEFT_POS, edge.x, edge.y);
4651     edge = roundRect.GetCornerRadius(RoundRect::BOTTOM_RIGHT_POS);
4652     rsRoundRect.SetCornerRadius(RSRoundRect::BOTTOM_RIGHT_POS, edge.x, edge.y);
4653     RSRecordingPath rsPath;
4654     rsPath.AddRoundRect(rsRoundRect);
4655     rsNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(rsPath));
4656 }
4657 
4658 void RosenRenderContext::ClipWithOval(const RectF& rectF)
4659 {
4660     CHECK_NULL_VOID(rsNode_);
4661     RSRecordingPath rsPath;
4662     rsPath.AddOval({ rectF.GetX(), rectF.GetY(), rectF.GetX() + rectF.Width(), rectF.GetY() + rectF.Height() });
4663     rsNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(rsPath));
4664 }
4665 
4666 void RosenRenderContext::ClipWithCircle(const Circle& circle)
4667 {
4668     CHECK_NULL_VOID(rsNode_);
4669     RSRecordingPath rsPath;
4670     rsPath.AddCircle(circle.GetAxisX().Value(), circle.GetAxisY().Value(), circle.GetRadius().Value());
4671     rsNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(rsPath));
4672 }
4673 
4674 void RosenRenderContext::ClipWithRRect(const RectF& rectF, const RadiusF& radiusF)
4675 {
4676     CHECK_NULL_VOID(rsNode_);
4677     Rosen::Vector4f rect;
4678     Rosen::Vector4f radius;
4679     rect.SetValues(rectF.GetX(), rectF.GetY(), rectF.GetX() + rectF.Width(), rectF.GetY() + rectF.Height());
4680     radius.SetValues(radiusF.GetCorner(RoundRect::CornerPos::TOP_LEFT_POS).x,
4681         radiusF.GetCorner(RoundRect::CornerPos::TOP_RIGHT_POS).x,
4682         radiusF.GetCorner(RoundRect::CornerPos::BOTTOM_LEFT_POS).x,
4683         radiusF.GetCorner(RoundRect::CornerPos::BOTTOM_RIGHT_POS).x);
4684     rsNode_->SetClipRRect(rect, radius);
4685     RequestNextFrame();
4686 }
4687 
4688 void RosenRenderContext::RemoveClipWithRRect()
4689 {
4690     std::weak_ptr<Rosen::RSNode> weakRsNode = rsNode_;
4691     AnimationUtils::ExecuteWithoutAnimation([weakRsNode]() {
4692         auto rsNode = weakRsNode.lock();
4693         CHECK_NULL_VOID(rsNode);
4694         rsNode->SetClipRRect(nullptr);
4695     });
4696     RequestNextFrame();
4697 }
4698 
4699 void RosenRenderContext::OnClipShapeUpdate(const RefPtr<BasicShape>& basicShape)
4700 {
4701     CHECK_NULL_VOID(rsNode_);
4702     if (basicShape) {
4703         if (!RectIsNull()) {
4704             RectF rect = GetPaintRectWithoutTransform();
4705             PaintClipShape(GetOrCreateClip(), rect.GetSize());
4706         }
4707     } else if (clipBoundModifier_) {
4708         rsNode_->RemoveModifier(clipBoundModifier_);
4709         clipBoundModifier_ = nullptr;
4710     }
4711     RequestNextFrame();
4712 }
4713 
4714 void RosenRenderContext::OnClipEdgeUpdate(bool isClip)
4715 {
4716     CHECK_NULL_VOID(rsNode_);
4717     if (isClip) {
4718         rsNode_->SetClipToBounds(true);
4719     } else {
4720         // In the internal implementation, some nodes call SetClipToBounds(true), some call SetClipToFrame(true).
4721         // If the developer set clip to false, we should disable all internal clips
4722         // so that the child component can go beyond the parent component
4723         rsNode_->SetClipToBounds(false);
4724         rsNode_->SetClipToFrame(false);
4725     }
4726     RequestNextFrame();
4727 }
4728 
4729 void RosenRenderContext::OnClipMaskUpdate(const RefPtr<BasicShape>& basicShape)
4730 {
4731     CHECK_NULL_VOID(rsNode_);
4732     if (basicShape) {
4733         if (!RectIsNull()) {
4734             RectF rect = GetPaintRectWithoutTransform();
4735             PaintClipMask(GetOrCreateClip(), rect.GetSize());
4736         }
4737     } else if (clipMaskModifier_) {
4738         rsNode_->RemoveModifier(clipMaskModifier_);
4739         clipMaskModifier_ = nullptr;
4740     }
4741     RequestNextFrame();
4742 }
4743 
4744 void RosenRenderContext::OnProgressMaskUpdate(const RefPtr<ProgressMaskProperty>& progress)
4745 {
4746     CHECK_NULL_VOID(rsNode_);
4747     if (progress) {
4748         if (!RectIsNull()) {
4749             PaintProgressMask();
4750         }
4751         rsNode_->SetClipToBounds(true);
4752     } else if (moonProgressModifier_) {
4753         auto modifierAdapter =
4754             std::static_pointer_cast<OverlayModifierAdapter>(ConvertOverlayModifier(moonProgressModifier_));
4755         rsNode_->RemoveModifier(modifierAdapter);
4756         moonProgressModifier_ = nullptr;
4757     }
4758     RequestNextFrame();
4759 }
4760 
4761 RefPtr<PageTransitionEffect> RosenRenderContext::GetDefaultPageTransition(PageTransitionType type)
4762 {
4763     auto resultEffect = AceType::MakeRefPtr<PageTransitionEffect>(type, PageTransitionOption());
4764     resultEffect->SetScaleEffect(ScaleOptions(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct));
4765     TranslateOptions translate;
4766     auto rect = GetPaintRectWithoutTransform();
4767     auto initialBackgroundColor = DEFAULT_MASK_COLOR;
4768     auto backgroundColor = DEFAULT_MASK_COLOR;
4769     RectF pageTransitionRectF;
4770     RectF defaultPageTransitionRectF = RectF(0.0f, -GetStatusBarHeight(), rect.Width(),
4771         REMOVE_CLIP_SIZE);
4772     switch (type) {
4773         case PageTransitionType::ENTER_PUSH:
4774         case PageTransitionType::EXIT_POP:
4775             initialBackgroundColor = DEFAULT_MASK_COLOR;
4776             backgroundColor = DEFAULT_MASK_COLOR;
4777             if (AceApplicationInfo::GetInstance().IsRightToLeft()) {
4778                 pageTransitionRectF = RectF(0.0f, -GetStatusBarHeight(), rect.Width() * PARENT_PAGE_OFFSET,
4779                     REMOVE_CLIP_SIZE);
4780                 translate.x = Dimension(-rect.Width() * PARENT_PAGE_OFFSET);
4781                 break;
4782             }
4783             pageTransitionRectF = RectF(rect.Width() * HALF, -GetStatusBarHeight(), rect.Width() * HALF,
4784                 REMOVE_CLIP_SIZE);
4785             defaultPageTransitionRectF = RectF(0.0f, -GetStatusBarHeight(), REMOVE_CLIP_SIZE,
4786                 REMOVE_CLIP_SIZE);
4787             translate.x = Dimension(rect.Width() * HALF);
4788             break;
4789         case PageTransitionType::ENTER_POP:
4790             initialBackgroundColor = MASK_COLOR;
4791             backgroundColor = DEFAULT_MASK_COLOR;
4792             if (AceApplicationInfo::GetInstance().IsRightToLeft()) {
4793                 pageTransitionRectF = RectF(rect.Width() * HALF, -GetStatusBarHeight(), rect.Width() * HALF,
4794                     REMOVE_CLIP_SIZE);
4795                 translate.x = Dimension(rect.Width() * HALF);
4796                 break;
4797             }
4798             pageTransitionRectF = RectF(0.0f, -GetStatusBarHeight(), rect.Width() * PARENT_PAGE_OFFSET,
4799                 REMOVE_CLIP_SIZE);
4800             translate.x = Dimension(-rect.Width() * PARENT_PAGE_OFFSET);
4801             break;
4802         case PageTransitionType::EXIT_PUSH:
4803             initialBackgroundColor = DEFAULT_MASK_COLOR;
4804             backgroundColor = MASK_COLOR;
4805             if (AceApplicationInfo::GetInstance().IsRightToLeft()) {
4806                 pageTransitionRectF = RectF(rect.Width() * HALF, -GetStatusBarHeight(), rect.Width() * HALF,
4807                     REMOVE_CLIP_SIZE);
4808                 translate.x = Dimension(rect.Width() * HALF);
4809                 break;
4810             }
4811             pageTransitionRectF = RectF(0.0f, -GetStatusBarHeight(), rect.Width() * PARENT_PAGE_OFFSET,
4812                 REMOVE_CLIP_SIZE);
4813             translate.x = Dimension(-rect.Width() * PARENT_PAGE_OFFSET);
4814             break;
4815         default:
4816             break;
4817     }
4818     resultEffect->SetTranslateEffect(translate);
4819     resultEffect->SetOpacityEffect(1);
4820     resultEffect->SetPageTransitionRectF(pageTransitionRectF);
4821     resultEffect->SetDefaultPageTransitionRectF(defaultPageTransitionRectF);
4822     resultEffect->SetInitialBackgroundColor(initialBackgroundColor);
4823     resultEffect->SetBackgroundColor(backgroundColor);
4824     return resultEffect;
4825 }
4826 
4827 RefPtr<PageTransitionEffect> RosenRenderContext::GetPageTransitionEffect(const RefPtr<PageTransitionEffect>& transition)
4828 {
4829     auto resultEffect = AceType::MakeRefPtr<PageTransitionEffect>(
4830         transition->GetPageTransitionType(), transition->GetPageTransitionOption());
4831     resultEffect->SetScaleEffect(
4832         transition->GetScaleEffect().value_or(ScaleOptions(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct)));
4833     TranslateOptions translate;
4834     auto rect = GetPaintRectWithoutTransform();
4835     RectF defaultPageTransitionRectF = RectF(0.0f, -GetStatusBarHeight(), REMOVE_CLIP_SIZE,
4836         REMOVE_CLIP_SIZE);
4837     // slide and translate, only one can be effective
4838     if (transition->GetSlideEffect().has_value()) {
4839         SlideTransitionEffect(transition->GetSlideEffect().value(), rect, translate);
4840     } else if (transition->GetTranslateEffect().has_value()) {
4841         const auto& translateOptions = transition->GetTranslateEffect();
4842         translate.x = Dimension(translateOptions->x.ConvertToPxWithSize(rect.Width()));
4843         translate.y = Dimension(translateOptions->y.ConvertToPxWithSize(rect.Height()));
4844         translate.z = Dimension(translateOptions->z.ConvertToPx());
4845     }
4846     resultEffect->SetTranslateEffect(translate);
4847     resultEffect->SetOpacityEffect(transition->GetOpacityEffect().value_or(1));
4848     resultEffect->SetPageTransitionRectF(RectF(0.0f, -GetStatusBarHeight(), REMOVE_CLIP_SIZE, REMOVE_CLIP_SIZE));
4849     resultEffect->SetDefaultPageTransitionRectF(defaultPageTransitionRectF);
4850     resultEffect->SetInitialBackgroundColor(DEFAULT_MASK_COLOR);
4851     resultEffect->SetBackgroundColor(DEFAULT_MASK_COLOR);
4852     return resultEffect;
4853 }
4854 
4855 bool RosenRenderContext::TriggerPageTransition(PageTransitionType type, const std::function<void()>& onFinish)
4856 {
4857     bool transitionIn = true;
4858     if (type == PageTransitionType::ENTER_PUSH || type == PageTransitionType::ENTER_POP) {
4859         transitionIn = true;
4860     } else if (type == PageTransitionType::EXIT_PUSH || type == PageTransitionType::EXIT_POP) {
4861         transitionIn = false;
4862     } else {
4863         return false;
4864     }
4865     CHECK_NULL_RETURN(rsNode_, false);
4866     auto host = GetHost();
4867     CHECK_NULL_RETURN(host, false);
4868     auto pattern = host->GetPattern<PagePattern>();
4869     CHECK_NULL_RETURN(pattern, false);
4870     auto transition = pattern->FindPageTransitionEffect(type);
4871     RefPtr<PageTransitionEffect> effect;
4872     AnimationOption option;
4873     if (transition) {
4874         effect = GetPageTransitionEffect(transition);
4875         option.SetCurve(transition->GetCurve());
4876         option.SetDuration(transition->GetDuration());
4877         option.SetDelay(transition->GetDelay());
4878     } else {
4879         effect = GetDefaultPageTransition(type);
4880         const RefPtr<InterpolatingSpring> springCurve =
4881             AceType::MakeRefPtr<InterpolatingSpring>(0.0f, 1.0f, 342.0f, 37.0f);
4882         const float defaultAmplitudePx = 0.005f;
4883         springCurve->UpdateMinimumAmplitudeRatio(defaultAmplitudePx);
4884         option.SetCurve(springCurve);
4885         option.SetDuration(DEFAULT_ANIMATION_DURATION);
4886 #ifdef QUICK_PUSH_TRANSITION
4887         auto pipeline = PipelineBase::GetCurrentContext();
4888         if (pipeline) {
4889             const int32_t nanoToMilliSeconds = 1000000;
4890             const int32_t minTransitionDuration = DEFAULT_ANIMATION_DURATION / 2;
4891             const int32_t frameDelayTime = 32;
4892             int32_t startDelayTime =
4893                 static_cast<int32_t>(pipeline->GetTimeFromExternalTimer() - pipeline->GetLastTouchTime()) /
4894                 nanoToMilliSeconds;
4895             startDelayTime = std::max(0, startDelayTime);
4896             int32_t delayedDuration = DEFAULT_ANIMATION_DURATION > startDelayTime
4897                                       ? DEFAULT_ANIMATION_DURATION - startDelayTime
4898                                       : DEFAULT_ANIMATION_DURATION;
4899             delayedDuration = std::max(minTransitionDuration, delayedDuration - frameDelayTime);
4900             LOGI("Use quick push delayedDuration:%{public}d", delayedDuration);
4901             option.SetDuration(delayedDuration);
4902         }
4903 #endif
4904     }
4905     const auto& scaleOptions = effect->GetScaleEffect();
4906     const auto& translateOptions = effect->GetTranslateEffect();
4907     UpdateTransformCenter(DimensionOffset(scaleOptions->centerX, scaleOptions->centerY));
4908 
4909     if (transitionIn) {
4910         UpdateTransformScale(VectorF(scaleOptions->xScale, scaleOptions->yScale));
4911         UpdateTransformTranslate(translateOptions.value());
4912         UpdateOpacity(effect->GetOpacityEffect().value());
4913         ClipWithRRect(effect->GetPageTransitionRectF().value(), RadiusF(EdgeF(0.0f, 0.0f)));
4914         AnimationUtils::OpenImplicitAnimation(option, option.GetCurve(), onFinish);
4915         UpdateTransformScale(VectorF(1.0f, 1.0f));
4916         UpdateTransformTranslate({ 0.0f, 0.0f, 0.0f });
4917         UpdateOpacity(1.0);
4918         ClipWithRRect(effect->GetDefaultPageTransitionRectF().value(),
4919             RadiusF(EdgeF(0.0f, 0.0f)));
4920         AnimationUtils::CloseImplicitAnimation();
4921         MaskAnimation(effect->GetInitialBackgroundColor().value(), effect->GetBackgroundColor().value());
4922         return true;
4923     }
4924     UpdateTransformScale(VectorF(1.0f, 1.0f));
4925     UpdateTransformTranslate({ 0.0f, 0.0f, 0.0f });
4926     UpdateOpacity(1.0);
4927     ClipWithRRect(effect->GetDefaultPageTransitionRectF().value(),
4928         RadiusF(EdgeF(0.0f, 0.0f)));
4929     AnimationUtils::OpenImplicitAnimation(option, option.GetCurve(), onFinish);
4930     UpdateTransformScale(VectorF(scaleOptions->xScale, scaleOptions->yScale));
4931     UpdateTransformTranslate(translateOptions.value());
4932     UpdateOpacity(effect->GetOpacityEffect().value());
4933     ClipWithRRect(effect->GetPageTransitionRectF().value(), RadiusF(EdgeF(0.0f, 0.0f)));
4934     AnimationUtils::CloseImplicitAnimation();
4935     MaskAnimation(effect->GetInitialBackgroundColor().value(), effect->GetBackgroundColor().value());
4936     return true;
4937 }
4938 
4939 void RosenRenderContext::MaskAnimation(const Color& initialBackgroundColor, const Color& backgroundColor)
4940 {
4941     AnimationOption maskOption;
4942     maskOption.SetCurve(Curves::FRICTION);
4943     maskOption.SetDuration(MASK_DURATION);
4944     SetActualForegroundColor(initialBackgroundColor);
4945     AnimationUtils::OpenImplicitAnimation(maskOption, maskOption.GetCurve(), nullptr);
4946     SetActualForegroundColor(backgroundColor);
4947     AnimationUtils::CloseImplicitAnimation();
4948 }
4949 
4950 float RosenRenderContext::GetStatusBarHeight()
4951 {
4952     auto context = PipelineContext::GetCurrentContext();
4953     CHECK_NULL_RETURN(context, false);
4954     auto safeAreaInsets = context->GetSafeAreaWithoutProcess();
4955     auto statusBarHeight = safeAreaInsets.top_.Length();
4956     return static_cast<float>(statusBarHeight);
4957 }
4958 
4959 void RosenRenderContext::PaintOverlayText()
4960 {
4961     CHECK_NULL_VOID(rsNode_);
4962     auto& overlay = GetOrCreateOverlay();
4963     if (overlay->HasOverlayText()) {
4964         auto overlayText = overlay->GetOverlayTextValue();
4965         auto paintRect = GetPaintRectWithTransform();
4966         std::shared_ptr<Rosen::RectF> overlayRect;
4967         if (modifier_) {
4968             modifier_->SetCustomData(NG::OverlayTextData(overlayText));
4969             auto overlayOffset = modifier_->GetOverlayOffset();
4970             auto paragraphSize = modifier_->GetParagraphSize(paintRect.Width());
4971             overlayRect = std::make_shared<Rosen::RectF>(overlayOffset.GetX(), overlayOffset.GetY(),
4972                 std::max(paragraphSize.Width(), paintRect.Width()),
4973                 std::max(paragraphSize.Height(), paintRect.Height()));
4974             rsNode_->SetIsCustomTextType(modifier_->IsCustomFont());
4975             UpdateDrawRegion(DRAW_REGION_OVERLAY_TEXT_MODIFIER_INDEX, overlayRect);
4976         } else {
4977             modifier_ = std::make_shared<OverlayTextModifier>();
4978             rsNode_->AddModifier(modifier_);
4979             modifier_->SetCustomData(NG::OverlayTextData(overlayText));
4980             auto overlayOffset = modifier_->GetOverlayOffset();
4981             auto paragraphSize = modifier_->GetParagraphSize(paintRect.Width());
4982             overlayRect = std::make_shared<Rosen::RectF>(overlayOffset.GetX(), overlayOffset.GetY(),
4983                 std::max(paragraphSize.Width(), paintRect.Width()),
4984                 std::max(paragraphSize.Height(), paintRect.Height()));
4985             rsNode_->SetIsCustomTextType(modifier_->IsCustomFont());
4986             UpdateDrawRegion(DRAW_REGION_OVERLAY_TEXT_MODIFIER_INDEX, overlayRect);
4987         }
4988     }
4989 }
4990 
4991 void RosenRenderContext::OnOverlayTextUpdate(const OverlayOptions& overlay)
4992 {
4993     if (!RectIsNull()) {
4994         PaintOverlayText();
4995     }
4996     RequestNextFrame();
4997 }
4998 
4999 void RosenRenderContext::OnMotionPathUpdate(const MotionPathOption& motionPath)
5000 {
5001     CHECK_NULL_VOID(rsNode_);
5002     if (!motionPath.IsValid()) {
5003         rsNode_->SetMotionPathOption(nullptr);
5004         return;
5005     }
5006     auto motionOption = Rosen::RSMotionPathOption(motionPath.GetPath());
5007     motionOption.SetBeginFraction(motionPath.GetBegin());
5008     motionOption.SetEndFraction(motionPath.GetEnd());
5009     motionOption.SetRotationMode(
5010         motionPath.GetRotate() ? Rosen::RotationMode::ROTATE_AUTO : Rosen::RotationMode::ROTATE_NONE);
5011     motionOption.SetPathNeedAddOrigin(HasOffset());
5012     rsNode_->SetMotionPathOption(std::make_shared<Rosen::RSMotionPathOption>(motionOption));
5013     RequestNextFrame();
5014 }
5015 
5016 void RosenRenderContext::OnLightPositionUpdate(const TranslateOptions& translate)
5017 {
5018     CHECK_NULL_VOID(rsNode_);
5019     float xValue = 0.0f;
5020     float yValue = 0.0f;
5021     if (translate.x.Unit() == DimensionUnit::PERCENT || translate.y.Unit() == DimensionUnit::PERCENT) {
5022         auto rect = GetPaintRectWithoutTransform();
5023         if (rect.IsEmpty()) {
5024             // size is not determined yet
5025             return;
5026         }
5027         xValue = translate.x.ConvertToPxWithSize(rect.Width());
5028         yValue = translate.y.ConvertToPxWithSize(rect.Height());
5029     } else {
5030         xValue = translate.x.ConvertToPx();
5031         yValue = translate.y.ConvertToPx();
5032     }
5033     // translateZ doesn't support percentage
5034     float zValue = translate.z.ConvertToPx();
5035     rsNode_->SetLightPosition(xValue, yValue, zValue);
5036     RequestNextFrame();
5037 }
5038 
5039 void RosenRenderContext::OnLightIntensityUpdate(const float lightIntensity)
5040 {
5041     CHECK_NULL_VOID(rsNode_);
5042     rsNode_->SetLightIntensity(lightIntensity);
5043     RequestNextFrame();
5044 }
5045 
5046 void RosenRenderContext::OnLightColorUpdate(const Color& lightColor)
5047 {
5048     CHECK_NULL_VOID(rsNode_);
5049     rsNode_->SetLightColor(lightColor.GetValue());
5050     RequestNextFrame();
5051 }
5052 
5053 void RosenRenderContext::OnLightIlluminatedUpdate(const uint32_t lightIlluminated)
5054 {
5055     CHECK_NULL_VOID(rsNode_);
5056     rsNode_->SetIlluminatedType(lightIlluminated);
5057     RequestNextFrame();
5058 }
5059 
5060 void RosenRenderContext::OnIlluminatedBorderWidthUpdate(const Dimension& illuminatedBorderWidth)
5061 {
5062     CHECK_NULL_VOID(rsNode_);
5063     rsNode_->SetIlluminatedBorderWidth(static_cast<float>(illuminatedBorderWidth.ConvertToPx()));
5064     RequestNextFrame();
5065 }
5066 
5067 void RosenRenderContext::OnBloomUpdate(const float bloomIntensity)
5068 {
5069     CHECK_NULL_VOID(rsNode_);
5070     rsNode_->SetBloom(bloomIntensity);
5071     RequestNextFrame();
5072 }
5073 
5074 void RosenRenderContext::SetSharedTranslate(float xTranslate, float yTranslate)
5075 {
5076     if (!sharedTransitionModifier_) {
5077         sharedTransitionModifier_ = std::make_unique<SharedTransitionModifier>();
5078     }
5079     AddOrChangeTranslateModifier(rsNode_, sharedTransitionModifier_->translateXY,
5080         sharedTransitionModifier_->translateXYValue, { xTranslate, yTranslate });
5081     NotifyHostTransformUpdated();
5082 }
5083 
5084 void RosenRenderContext::ResetSharedTranslate()
5085 {
5086     CHECK_NULL_VOID(sharedTransitionModifier_);
5087     CHECK_NULL_VOID(sharedTransitionModifier_->translateXY);
5088     CHECK_NULL_VOID(rsNode_);
5089     rsNode_->RemoveModifier(sharedTransitionModifier_->translateXY);
5090     sharedTransitionModifier_->translateXYValue = nullptr;
5091     sharedTransitionModifier_->translateXY = nullptr;
5092     NotifyHostTransformUpdated();
5093 }
5094 
5095 void RosenRenderContext::ResetPageTransitionEffect()
5096 {
5097     UpdateTransformTranslate({ 0.0f, 0.0f, 0.0f });
5098     MaskAnimation(DEFAULT_MASK_COLOR, DEFAULT_MASK_COLOR);
5099 }
5100 
5101 void RosenRenderContext::AddChild(const RefPtr<RenderContext>& renderContext, int index)
5102 {
5103     CHECK_NULL_VOID(rsNode_);
5104     auto rosenRenderContext = AceType::DynamicCast<RosenRenderContext>(renderContext);
5105     CHECK_NULL_VOID(rosenRenderContext);
5106     auto child = rosenRenderContext->GetRSNode();
5107     rsNode_->AddChild(child, index);
5108 }
5109 
5110 void RosenRenderContext::RemoveChild(const RefPtr<RenderContext>& renderContext)
5111 {
5112     CHECK_NULL_VOID(rsNode_);
5113     auto rosenRenderContext = AceType::DynamicCast<RosenRenderContext>(renderContext);
5114     CHECK_NULL_VOID(rosenRenderContext);
5115     auto child = rosenRenderContext->GetRSNode();
5116     rsNode_->RemoveChild(child);
5117 }
5118 
5119 void RosenRenderContext::ClearChildren()
5120 {
5121     CHECK_NULL_VOID(rsNode_);
5122     rsNode_->ClearChildren();
5123 }
5124 
5125 void RosenRenderContext::SetBounds(float positionX, float positionY, float width, float height)
5126 {
5127     CHECK_NULL_VOID(rsNode_);
5128     paintRect_ = RectF(positionX, positionY, width, height);
5129     rsNode_->SetBounds(positionX, positionY, width, height);
5130 }
5131 
5132 void RosenRenderContext::SetUsingContentRectForRenderFrame(bool value, bool adjustRSFrameByContentRect)
5133 {
5134     useContentRectForRSFrame_ = value;
5135     adjustRSFrameByContentRect_ = adjustRSFrameByContentRect;
5136 }
5137 
5138 void RosenRenderContext::SetSecurityLayer(bool isSecure)
5139 {
5140     CHECK_NULL_VOID(rsNode_);
5141     auto rsSurfaceNode = rsNode_->ReinterpretCastTo<Rosen::RSSurfaceNode>();
5142     CHECK_NULL_VOID(rsSurfaceNode);
5143     rsSurfaceNode->SetSecurityLayer(isSecure);
5144 }
5145 
5146 void RosenRenderContext::SetFrameGravity(OHOS::Rosen::Gravity gravity)
5147 {
5148     CHECK_NULL_VOID(rsNode_);
5149     rsNode_->SetFrameGravity(gravity);
5150 }
5151 
5152 int32_t RosenRenderContext::CalcExpectedFrameRate(const std::string& scene, float speed)
5153 {
5154     if (rsNode_ == nullptr) {
5155         return 0;
5156     }
5157     return rsNode_->CalcExpectedFrameRate(scene, speed);
5158 }
5159 
5160 bool RosenRenderContext::DoTextureExport(uint64_t surfaceId)
5161 {
5162     CHECK_NULL_RETURN(rsNode_, false);
5163     rsNode_->RemoveFromTree();
5164     if (!rsTextureExport_) {
5165         rsTextureExport_ = std::make_shared<Rosen::RSTextureExport>(rsNode_, surfaceId);
5166     }
5167     auto rsSurfaceNode = rsNode_->ReinterpretCastTo<Rosen::RSSurfaceNode>();
5168     if (rsSurfaceNode) {
5169         rsSurfaceNode->SetTextureExport(true);
5170     }
5171     return rsTextureExport_->DoTextureExport();
5172 }
5173 
5174 bool RosenRenderContext::StopTextureExport()
5175 {
5176     CHECK_NULL_RETURN(rsNode_, false);
5177     CHECK_NULL_RETURN(rsTextureExport_, false);
5178     rsTextureExport_->StopTextureExport();
5179     auto rsSurfaceNode = rsNode_->ReinterpretCastTo<Rosen::RSSurfaceNode>();
5180     if (rsSurfaceNode) {
5181         rsSurfaceNode->SetTextureExport(false);
5182     }
5183     return true;
5184 }
5185 
5186 void RosenRenderContext::SetSurfaceRotation(bool isLock)
5187 {
5188     CHECK_NULL_VOID(rsNode_);
5189     auto rsSurfaceNode = rsNode_->ReinterpretCastTo<Rosen::RSSurfaceNode>();
5190     if (rsSurfaceNode) {
5191         rsSurfaceNode->SetForceHardwareAndFixRotation(isLock);
5192     }
5193 }
5194 
5195 void RosenRenderContext::SetRenderFit(RenderFit renderFit)
5196 {
5197     CHECK_NULL_VOID(rsNode_);
5198     auto rsSurfaceNode = rsNode_->ReinterpretCastTo<Rosen::RSSurfaceNode>();
5199     if (rsSurfaceNode) {
5200         rsSurfaceNode->SetFrameGravity(GetRosenGravity(renderFit));
5201     }
5202 }
5203 
5204 void RosenRenderContext::ClearDrawCommands()
5205 {
5206     StartRecording();
5207     StopRecordingIfNeeded();
5208 }
5209 
5210 void RosenRenderContext::SetRSNode(const std::shared_ptr<RSNode>& externalNode)
5211 {
5212     // Update rsNode_ to externalNode.
5213     if (externalNode == rsNode_) {
5214         return;
5215     }
5216     rsNode_ = externalNode;
5217     AddFrameNodeInfoToRsNode();
5218 
5219     ResetTransform();
5220     ResetTransformMatrix();
5221 
5222     // after update, tell parent to update RSNode hierarchy.
5223     auto uiNode = GetHost();
5224     CHECK_NULL_VOID(uiNode);
5225     auto parentUINode = uiNode->GetParent();
5226     CHECK_NULL_VOID(parentUINode);
5227     parentUINode->MarkNeedSyncRenderTree();
5228     parentUINode->RebuildRenderContextTree();
5229 }
5230 
5231 void RosenRenderContext::OnMouseSelectUpdate(bool isSelected, const Color& fillColor, const Color& strokeColor)
5232 {
5233     auto host = GetHost();
5234     CHECK_NULL_VOID(host);
5235 
5236     RectF rect = RectF();
5237     if (isSelected) {
5238         auto geometryNode = host->GetGeometryNode();
5239         CHECK_NULL_VOID(geometryNode);
5240         rect = geometryNode->GetFrameRect();
5241         rect.SetOffset(OffsetF());
5242     }
5243 
5244     UpdateMouseSelectWithRect(rect, fillColor, strokeColor);
5245 }
5246 
5247 void RosenRenderContext::UpdateMouseSelectWithRect(const RectF& rect, const Color& fillColor, const Color& strokeColor)
5248 {
5249     if (!rect.IsValid()) {
5250         return;
5251     }
5252     PaintMouseSelectRect(rect, fillColor, strokeColor);
5253     RequestNextFrame();
5254 }
5255 
5256 void RosenRenderContext::PaintMouseSelectRect(const RectF& rect, const Color& fillColor, const Color& strokeColor)
5257 {
5258     CHECK_NULL_VOID(rsNode_);
5259     if (mouseSelectModifier_) {
5260         mouseSelectModifier_->SetSelectRect(rect);
5261         return;
5262     }
5263 
5264     auto paintTask = [&fillColor, &strokeColor](const RectF& rect, RSCanvas& rsCanvas) mutable {
5265         RSBrush brush;
5266         brush.SetColor(ToRSColor(fillColor));
5267         rsCanvas.AttachBrush(brush);
5268         rsCanvas.DrawRect(ToRSRect(rect));
5269         rsCanvas.DetachBrush();
5270         RSPen pen;
5271         pen.SetColor(ToRSColor(strokeColor));
5272         rsCanvas.AttachPen(pen);
5273         rsCanvas.DrawRect(ToRSRect(rect));
5274         rsCanvas.DetachPen();
5275     };
5276 
5277     mouseSelectModifier_ = std::make_shared<MouseSelectModifier>();
5278     mouseSelectModifier_->SetPaintTask(std::move(paintTask));
5279     rsNode_->AddModifier(mouseSelectModifier_);
5280 }
5281 
5282 void RosenRenderContext::DumpInfo()
5283 {
5284     if (rsNode_) {
5285         DumpLog::GetInstance().AddDesc("------------start print rsNode");
5286         DumpLog::GetInstance().AddDesc(rsNode_->DumpNode(0));
5287         auto center = rsNode_->GetStagingProperties().GetPivot();
5288         if (!NearEqual(center[0], 0.5) || !NearEqual(center[1], 0.5)) {
5289             DumpLog::GetInstance().AddDesc(std::string("Center: x:")
5290                                                .append(std::to_string(center[0]))
5291                                                .append(" y:")
5292                                                .append(std::to_string(center[1])));
5293         }
5294         if (!NearZero(rsNode_->GetStagingProperties().GetPivotZ())) {
5295             DumpLog::GetInstance().AddDesc(
5296                 std::string("PivotZ:").append(std::to_string(rsNode_->GetStagingProperties().GetPivotZ())));
5297         }
5298         std::string res = "";
5299         if (!NearZero(rsNode_->GetStagingProperties().GetRotation())) {
5300             res.append(" Rotation:").append(std::to_string(rsNode_->GetStagingProperties().GetRotation()));
5301         }
5302         if (!NearZero(rsNode_->GetStagingProperties().GetRotationX())) {
5303             res.append(" RotationX:").append(std::to_string(rsNode_->GetStagingProperties().GetRotationX()));
5304         }
5305         if (!NearZero(rsNode_->GetStagingProperties().GetRotationY())) {
5306             res.append(" RotationY:").append(std::to_string(rsNode_->GetStagingProperties().GetRotationY()));
5307         }
5308         if (!res.empty()) {
5309             DumpLog::GetInstance().AddDesc(res);
5310             res.clear();
5311         }
5312         const auto& groupProperty = GetOrCreateBackground();
5313         if (groupProperty->propEffectOption.has_value()) {
5314             auto backgroundEffect = groupProperty->propEffectOption->ToJsonValue()->ToString();
5315             DumpLog::GetInstance().AddDesc(
5316                  std::string("backgroundEffect:").append(backgroundEffect));
5317         }
5318         if (!NearZero(rsNode_->GetStagingProperties().GetCameraDistance())) {
5319             DumpLog::GetInstance().AddDesc(
5320                 std::string("CameraDistance:")
5321                     .append(std::to_string(rsNode_->GetStagingProperties().GetCameraDistance())));
5322         }
5323         if (!NearZero(rsNode_->GetStagingProperties().GetTranslateZ())) {
5324             DumpLog::GetInstance().AddDesc(
5325                 std::string("TranslateZ:").append(std::to_string(rsNode_->GetStagingProperties().GetTranslateZ())));
5326         }
5327         if (!NearZero(rsNode_->GetStagingProperties().GetBgImageWidth())) {
5328             res.append(" BgImageWidth:").append(std::to_string(rsNode_->GetStagingProperties().GetBgImageWidth()));
5329         }
5330         if (!NearZero(rsNode_->GetStagingProperties().GetBgImageHeight())) {
5331             res.append(" BgImageHeight:").append(std::to_string(rsNode_->GetStagingProperties().GetBgImageHeight()));
5332         }
5333         if (!NearZero(rsNode_->GetStagingProperties().GetBgImagePositionX())) {
5334             res.append(" BgImagePositionX")
5335                 .append(std::to_string(rsNode_->GetStagingProperties().GetBgImagePositionX()));
5336         }
5337         if (!NearZero(rsNode_->GetStagingProperties().GetBgImagePositionY())) {
5338             res.append(" BgImagePositionY")
5339                 .append(std::to_string(rsNode_->GetStagingProperties().GetBgImagePositionY()));
5340         }
5341         if (!res.empty()) {
5342             DumpLog::GetInstance().AddDesc(res);
5343             res.clear();
5344         }
5345         if (!NearZero(rsNode_->GetStagingProperties().GetShadowOffsetX())) {
5346             res.append(" ShadowOffsetX:").append(std::to_string(rsNode_->GetStagingProperties().GetShadowOffsetX()));
5347         }
5348         if (!NearZero(rsNode_->GetStagingProperties().GetShadowOffsetY())) {
5349             res.append(" ShadowOffsetY:").append(std::to_string(rsNode_->GetStagingProperties().GetShadowOffsetY()));
5350         }
5351         if (!NearZero(rsNode_->GetStagingProperties().GetShadowAlpha())) {
5352             res.append(" ShadowAlpha:").append(std::to_string(rsNode_->GetStagingProperties().GetShadowAlpha()));
5353         }
5354         if (!NearZero(rsNode_->GetStagingProperties().GetShadowElevation())) {
5355             res.append(" ShadowElevation:")
5356                 .append(std::to_string(rsNode_->GetStagingProperties().GetShadowElevation()));
5357         }
5358         if (!NearZero(rsNode_->GetStagingProperties().GetShadowRadius())) {
5359             res.append(" ShadowRadius:").append(std::to_string(rsNode_->GetStagingProperties().GetShadowRadius()));
5360         }
5361         if (!res.empty()) {
5362             DumpLog::GetInstance().AddDesc(res);
5363             res.clear();
5364         }
5365         if (!NearZero(rsNode_->GetStagingProperties().GetSpherizeDegree())) {
5366             DumpLog::GetInstance().AddDesc(
5367                 std::string("SpherizeDegree:")
5368                     .append(std::to_string(rsNode_->GetStagingProperties().GetSpherizeDegree())));
5369         }
5370         if (!NearZero(rsNode_->GetStagingProperties().GetLightUpEffectDegree())) {
5371             DumpLog::GetInstance().AddDesc(
5372                 std::string("LightUpEffectDegree:")
5373                     .append(std::to_string(rsNode_->GetStagingProperties().GetLightUpEffectDegree())));
5374         }
5375         if (!NearEqual(rsNode_->GetStagingProperties().GetAlpha(), 1)) {
5376             DumpLog::GetInstance().AddDesc(
5377                 std::string("Alpha:").append(std::to_string(rsNode_->GetStagingProperties().GetAlpha())));
5378         }
5379         auto translate = rsNode_->GetStagingProperties().GetTranslate();
5380         if (!(NearZero(translate[0]) && NearZero(translate[1]))) {
5381             DumpLog::GetInstance().AddDesc(
5382                 std::string("translate(x,y): ")
5383                     .append(std::to_string(translate[0]).append(",").append(std::to_string(translate[1]))));
5384         }
5385         auto scale = rsNode_->GetStagingProperties().GetScale();
5386         if (!(NearEqual(scale[0], 1) && NearEqual(scale[1], 1))) {
5387             DumpLog::GetInstance().AddDesc(
5388                 std::string("scale(x,y): ")
5389                     .append(std::to_string(scale[0]).append(",").append(std::to_string(scale[1]))));
5390         }
5391         auto rect = GetPaintRectWithoutTransform();
5392         if (HasTransformTranslate()) {
5393             auto translateArk = GetTransformTranslate().value();
5394             auto arkTranslateX = translateArk.x.ConvertToPxWithSize(rect.Width());
5395             auto arkTranslateY = translateArk.y.ConvertToPxWithSize(rect.Height());
5396             if (!NearEqual(arkTranslateX, translate[0])) {
5397                 DumpLog::GetInstance().AddDesc(
5398                     std::string("TranlateX has difference,arkui:").append(std::to_string(arkTranslateX)));
5399             }
5400             if (!NearEqual(arkTranslateY, translate[1])) {
5401                 DumpLog::GetInstance().AddDesc(
5402                     std::string("TranlateY has difference,arkui:").append(std::to_string(arkTranslateY)));
5403             }
5404         }
5405         if (HasTransformScale()) {
5406             auto arkTransformScale = GetTransformScale().value();
5407             if (!NearEqual(arkTransformScale.x, scale[0])) {
5408                 DumpLog::GetInstance().AddDesc(
5409                     std::string("scaleX has difference,arkui:").append(std::to_string(arkTransformScale.x)));
5410             }
5411             if (!NearEqual(arkTransformScale.y, scale[1])) {
5412                 DumpLog::GetInstance().AddDesc(
5413                     std::string("scaleY has difference,arkui:").append(std::to_string(arkTransformScale.y)));
5414             }
5415         }
5416         if (HasOpacity()) {
5417             auto arkAlpha = GetOpacity();
5418             if (!NearEqual(arkAlpha.value(), rsNode_->GetStagingProperties().GetAlpha())) {
5419                 DumpLog::GetInstance().AddDesc(
5420                     std::string("Alpha has difference,arkui:").append(std::to_string(arkAlpha.value())));
5421             }
5422         }
5423         if (HasPosition()) {
5424             auto position = GetPosition();
5425             DumpLog::GetInstance().AddDesc(std::string("PositionX :")
5426                 .append(position->GetX().ToString().c_str())
5427                 .append(std::string(",PositionY :"))
5428                 .append(position->GetY().ToString().c_str()));
5429         }
5430         if (HasOffset()) {
5431             auto offset = GetOffset();
5432             DumpLog::GetInstance().AddDesc(std::string("OffsetX :")
5433                 .append(offset->GetX().ToString().c_str())
5434                 .append(std::string(",OffsetY :"))
5435                 .append(offset->GetY().ToString().c_str()));
5436         }
5437         if (HasPositionEdges()) {
5438             auto positionEdges = GetPositionEdges();
5439             DumpLog::GetInstance().AddDesc(std::string("positionEdges :").append(positionEdges->ToString().c_str()));
5440         }
5441         if (HasOffsetEdges()) {
5442             auto offsetEdges = GetOffsetEdges();
5443             DumpLog::GetInstance().AddDesc(std::string("offsetEdges :").append(offsetEdges->ToString().c_str()));
5444         }
5445         if (HasAnchor()) {
5446             auto anchor = GetAnchor();
5447             DumpLog::GetInstance().AddDesc(std::string("anchorX :")
5448                 .append(anchor->GetX().ToString().c_str())
5449                 .append(std::string(",anchorY :"))
5450                 .append(anchor->GetX().ToString().c_str()));
5451         }
5452     }
5453 }
5454 
5455 void RosenRenderContext::DumpAdvanceInfo()
5456 {
5457     if (GetBackgroundAlign().has_value()) {
5458         DumpLog::GetInstance().AddDesc("BackgroundAlign:" + GetBackgroundAlign().value().ToString());
5459     }
5460     if (GetBackgroundImage().has_value()) {
5461         DumpLog::GetInstance().AddDesc("BackgroundImage:" + GetBackgroundImage().value().ToString());
5462     }
5463     if (GetSphericalEffect().has_value()) {
5464         DumpLog::GetInstance().AddDesc("SphericalEffect:" + std::to_string(GetSphericalEffect().value()));
5465     }
5466     if (GetPixelStretchEffect().has_value()) {
5467         DumpLog::GetInstance().AddDesc("PixelStretchEffect:" + GetPixelStretchEffect().value().ToString());
5468     }
5469     if (GetLightUpEffect().has_value()) {
5470         DumpLog::GetInstance().AddDesc("LightUpEffect:" + std::to_string(GetLightUpEffect().value()));
5471     }
5472     if (GetBorderColor().has_value()) {
5473         DumpLog::GetInstance().AddDesc("BorderColor:" + GetBorderColor().value().ToString());
5474     }
5475     if (GetBorderWidth().has_value()) {
5476         DumpLog::GetInstance().AddDesc("BorderWidth:" + GetBorderWidth().value().ToString());
5477     }
5478     if (GetOuterBorderRadius().has_value()) {
5479         DumpLog::GetInstance().AddDesc("OuterBorderRadius:" + GetOuterBorderRadius().value().ToString());
5480     }
5481     if (GetOuterBorderColor().has_value()) {
5482         DumpLog::GetInstance().AddDesc("OuterBorderColor:" + GetOuterBorderColor().value().ToString());
5483     }
5484     if (GetOuterBorderWidth().has_value()) {
5485         DumpLog::GetInstance().AddDesc("OuterBorderWidth:" + GetOuterBorderWidth().value().ToString());
5486     }
5487     if (GetDynamicLightUpRate().has_value()) {
5488         DumpLog::GetInstance().AddDesc("DynamicLightUpRate:" + std::to_string(GetDynamicLightUpRate().value()));
5489     }
5490     if (GetDynamicLightUpDegree().has_value()) {
5491         DumpLog::GetInstance().AddDesc("DynamicLightUpDegree:" + std::to_string(GetDynamicLightUpDegree().value()));
5492     }
5493     if (GetBackBlendMode().has_value()) {
5494         DumpLog::GetInstance().AddDesc("BlendMode:" + std::to_string(static_cast<int>(GetBackBlendMode().value())));
5495     }
5496     if (GetLinearGradient().has_value()) {
5497         DumpLog::GetInstance().AddDesc("LinearGradient:" + GetLinearGradient().value().ToString());
5498     }
5499     if (GetSweepGradient().has_value()) {
5500         DumpLog::GetInstance().AddDesc("SweepGradient:" + GetSweepGradient().value().ToString());
5501     }
5502     if (GetRadialGradient().has_value()) {
5503         DumpLog::GetInstance().AddDesc("RadialGradient:" + GetRadialGradient().value().ToString());
5504     }
5505     if (GetFrontBrightness().has_value()) {
5506         DumpLog::GetInstance().AddDesc("FrontBrightness:" + GetFrontBrightness().value().ToString());
5507     }
5508     if (GetFrontGrayScale().has_value()) {
5509         DumpLog::GetInstance().AddDesc("FrontGrayScale:" + GetFrontGrayScale().value().ToString());
5510     }
5511     if (GetFrontContrast().has_value()) {
5512         DumpLog::GetInstance().AddDesc("FrontContrast:" + GetFrontContrast().value().ToString());
5513     }
5514     if (GetFrontSaturate().has_value()) {
5515         DumpLog::GetInstance().AddDesc("FrontSaturate:" + GetFrontSaturate().value().ToString());
5516     }
5517     if (GetFrontSepia().has_value()) {
5518         DumpLog::GetInstance().AddDesc("FrontSepia:" + GetFrontSepia().value().ToString());
5519     }
5520     if (GetFrontHueRotate().has_value()) {
5521         DumpLog::GetInstance().AddDesc("FrontHueRotate:" + std::to_string(GetFrontHueRotate().value()));
5522     }
5523     if (GetFrontColorBlend().has_value()) {
5524         DumpLog::GetInstance().AddDesc("FrontColorBlend:" + GetFrontColorBlend().value().ColorToString());
5525     }
5526     if (GetBorderImageSource().has_value()) {
5527         DumpLog::GetInstance().AddDesc("BorderImageSource:" + GetBorderImageSource().value().ToString());
5528     }
5529     if (GetBorderImageGradient().has_value()) {
5530         DumpLog::GetInstance().AddDesc("BorderImageGradient:" + GetBorderImageGradient().value().ToString());
5531     }
5532     if (GetForegroundColor().has_value()) {
5533         DumpLog::GetInstance().AddDesc("ForegroundColor:" + GetForegroundColor().value().ColorToString());
5534     }
5535     if (GetLightIntensity().has_value()) {
5536         DumpLog::GetInstance().AddDesc("LightIntensity:" + std::to_string(GetLightIntensity().value()));
5537     }
5538     if (GetLightIlluminated().has_value()) {
5539         DumpLog::GetInstance().AddDesc("LightIlluminated:" + std::to_string(GetLightIlluminated().value()));
5540     }
5541     if (GetIlluminatedBorderWidth().has_value()) {
5542         DumpLog::GetInstance().AddDesc("IlluminatedBorderWidth:" + GetIlluminatedBorderWidth().value().ToString());
5543     }
5544     if (GetBloom().has_value()) {
5545         DumpLog::GetInstance().AddDesc("Bloom:" + std::to_string(GetBloom().value()));
5546     }
5547 }
5548 
5549 void RosenRenderContext::MarkContentChanged(bool isChanged)
5550 {
5551     CHECK_NULL_VOID(rsNode_);
5552     rsNode_->MarkContentChanged(isChanged);
5553 }
5554 
5555 void RosenRenderContext::MarkDrivenRender(bool flag)
5556 {
5557     CHECK_NULL_VOID(rsNode_);
5558     rsNode_->MarkDrivenRender(flag);
5559 }
5560 
5561 void RosenRenderContext::MarkDrivenRenderItemIndex(int32_t index)
5562 {
5563     CHECK_NULL_VOID(rsNode_);
5564     rsNode_->MarkDrivenRenderItemIndex(index);
5565 }
5566 
5567 void RosenRenderContext::MarkDrivenRenderFramePaintState(bool flag)
5568 {
5569     CHECK_NULL_VOID(rsNode_);
5570     rsNode_->MarkDrivenRenderFramePaintState(flag);
5571 }
5572 
5573 void RosenRenderContext::UpdateChainedTransition(const RefPtr<NG::ChainedTransitionEffect>& effect)
5574 {
5575     if (transitionEffect_) {
5576         // use effect to update rosenTransitionEffect activeValue
5577         if (RosenTransitionEffect::UpdateRosenTransitionEffect(transitionEffect_, effect)) {
5578             return;
5579         }
5580         transitionEffect_->Detach(this);
5581     }
5582     transitionEffect_ = RosenTransitionEffect::ConvertToRosenTransitionEffect(effect);
5583     hasDefaultTransition_ = false;
5584     CHECK_NULL_VOID(transitionEffect_);
5585     auto frameNode = GetHost();
5586     CHECK_NULL_VOID(frameNode);
5587     bool isOnTheTree = frameNode->IsOnMainTree();
5588     // transition effects should be initialized without animation.
5589     RSNode::ExecuteWithoutAnimation([this, isOnTheTree, &frameNode]() {
5590         // transitionIn effects should be initialized as active if currently not on the tree.
5591         transitionEffect_->Attach(Claim(this), !isOnTheTree);
5592     });
5593 }
5594 
5595 void RosenRenderContext::NotifyTransition(bool isTransitionIn)
5596 {
5597     CHECK_NULL_VOID(transitionEffect_);
5598 
5599     auto frameNode = GetHost();
5600     CHECK_NULL_VOID(frameNode);
5601 
5602     RSNode::ExecuteWithoutAnimation([this, &frameNode, isTransitionIn]() {
5603         if (isTransitionIn && disappearingTransitionCount_ == 0 && appearingTransitionCount_ == 0) {
5604             // transitionIn, reset to state before attaching in case of node reappear
5605             transitionEffect_->Attach(Claim(this), true);
5606         }
5607         auto pipeline = PipelineBase::GetCurrentContext();
5608         CHECK_NULL_VOID(pipeline);
5609         SizeF rootSize(pipeline->GetRootWidth(), pipeline->GetRootHeight());
5610         auto parentOffset = frameNode->GetPaintRectOffset(true);
5611         auto rect = GetPaintRectWithoutTransform();
5612         // Do not consider the position after its own transform, as the transition modifier also affects the transform
5613         rect.SetOffset(parentOffset + rect.GetOffset());
5614 
5615         transitionEffect_->UpdateTransitionContext(Claim(this), rect, rootSize);
5616     });
5617 
5618     if (isTransitionIn) {
5619         // Isolate the animation callback function, to avoid changing the callback timing of current implicit animation.
5620         AnimationUtils::AnimateWithCurrentOptions(
5621             [this]() {
5622                 transitionEffect_->Appear();
5623                 ++appearingTransitionCount_;
5624             },
5625             [weakThis = WeakClaim(this)]() {
5626                 auto context = weakThis.Upgrade();
5627                 CHECK_NULL_VOID(context);
5628                 context->OnTransitionInFinish();
5629             },
5630             false);
5631     } else {
5632         if (!transitionEffect_->HasDisappearTransition()) {
5633             if (frameNode->GetTag() == V2::WINDOW_SCENE_ETS_TAG) {
5634                 auto frameParent = frameNode->GetAncestorNodeOfFrame();
5635                 CHECK_NULL_VOID(frameParent);
5636                 // for window surfaceNode, remove surfaceNode explicitly
5637                 frameParent->GetRenderContext()->RemoveChild(Claim(this));
5638             }
5639             if (transitionUserCallback_ && !disappearingTransitionCount_) {
5640                 PostTransitionUserOutCallback();
5641             }
5642             return;
5643         }
5644         // Re-use current implicit animation timing params, only replace the finish callback function.
5645         // The finish callback function will perform all the necessary cleanup work.
5646         // Important Note on timing:
5647         // 1. If any transition animations are created, the finish callback function will only be called when ALL
5648         //    animations have finished. This is accomplished by sharing the same shared_ptr<AnimationFinishCallback>
5649         //    among all animations.
5650         // 2. If no transition animations are created, the finish callback function will be called IMMEDIATELY. This
5651         //    is accomplished by setting the last param (timing sensitive) to false, which avoids creating an empty
5652         //    'timer' animation.
5653         AnimationUtils::AnimateWithCurrentOptions(
5654             [this]() {
5655                 transitionEffect_->Disappear();
5656                 // update transition out count
5657                 ++disappearingTransitionCount_;
5658             },
5659             [weakThis = WeakClaim(this), nodeId = frameNode->GetId(), id = Container::CurrentId()]() {
5660                 auto context = weakThis.Upgrade();
5661                 CHECK_NULL_VOID(context);
5662                 // update transition out count
5663                 context->OnTransitionOutFinish();
5664             },
5665             false);
5666     }
5667     auto host = GetHost();
5668     CHECK_NULL_VOID(host);
5669     host->OnNodeTransitionInfoUpdate();
5670 }
5671 
5672 void RosenRenderContext::RemoveDefaultTransition()
5673 {
5674     if (hasDefaultTransition_ && transitionEffect_ && disappearingTransitionCount_ == 0 &&
5675         appearingTransitionCount_ == 0) {
5676         transitionEffect_->Detach(this);
5677         transitionEffect_ = nullptr;
5678         hasDefaultTransition_ = false;
5679     }
5680 }
5681 
5682 void RosenRenderContext::OnTransitionInFinish()
5683 {
5684     --appearingTransitionCount_;
5685     // make sure we are the last transition out animation, if not, return.
5686     if (appearingTransitionCount_ > 0) {
5687         return;
5688     }
5689     if (appearingTransitionCount_ < 0) {
5690         appearingTransitionCount_ = 0;
5691     }
5692     // when all transition in/out animations are finished, we should remove the default transition effect.
5693     RemoveDefaultTransition();
5694     auto host = GetHost();
5695     CHECK_NULL_VOID(host);
5696     FireTransitionUserCallback(true);
5697     auto parent = host->GetParent();
5698     CHECK_NULL_VOID(parent);
5699     if (host->IsVisible()) {
5700         // trigger transition through visibility
5701         if (transitionInCallback_) {
5702             transitionInCallback_();
5703         }
5704     }
5705 }
5706 
5707 void RosenRenderContext::OnTransitionOutFinish()
5708 {
5709     // update transition out count
5710     --disappearingTransitionCount_;
5711     // make sure we are the last transition out animation, if not, return.
5712     if (disappearingTransitionCount_ > 0) {
5713         return;
5714     }
5715     if (disappearingTransitionCount_ < 0) {
5716         disappearingTransitionCount_ = 0;
5717     }
5718     // when all transition in/out animations are finished, we should remove the default transition effect.
5719     RemoveDefaultTransition();
5720     auto host = GetHost();
5721     CHECK_NULL_VOID(host);
5722     auto parent = host->GetParent();
5723     CHECK_NULL_VOID(parent);
5724     if (!host->IsVisible()) {
5725         // trigger transition through visibility
5726         if (host->IsOnMainTree()) {
5727             if (transitionOutCallback_) {
5728                 transitionOutCallback_();
5729             }
5730             parent->MarkNeedSyncRenderTree();
5731             parent->RebuildRenderContextTree();
5732             FireTransitionUserCallback(false);
5733             return;
5734         }
5735         parent->MarkNeedSyncRenderTree();
5736         parent->RebuildRenderContextTree();
5737     }
5738     RefPtr<UINode> breakPointChild = host;
5739     RefPtr<UINode> breakPointParent = breakPointChild->GetParent();
5740     UINode::GetBestBreakPoint(breakPointChild, breakPointParent);
5741     // if can not find the breakPoint, means the node is not disappearing (reappear? or the node of subtree), return.
5742     if (!breakPointParent) {
5743         FireTransitionUserCallback(false);
5744         return;
5745     }
5746     if (breakPointChild->RemoveImmediately()) {
5747         breakPointChild->OnRemoveFromParent(false);
5748         // remove breakPoint
5749         breakPointParent->RemoveDisappearingChild(breakPointChild);
5750         breakPointParent->MarkNeedSyncRenderTree();
5751         breakPointParent->RebuildRenderContextTree();
5752     }
5753     if (isModalRootNode_ && breakPointParent->GetChildren().empty()) {
5754         auto grandParent = breakPointParent->GetParent();
5755         CHECK_NULL_VOID(grandParent);
5756         grandParent->RemoveChild(breakPointParent);
5757         grandParent->RebuildRenderContextTree();
5758     }
5759     FireTransitionUserCallback(false);
5760 }
5761 
5762 void RosenRenderContext::FireTransitionUserCallback(bool isTransitionIn)
5763 {
5764     if (transitionUserCallback_) {
5765         auto callback = transitionUserCallback_;
5766         callback(isTransitionIn);
5767     }
5768 }
5769 
5770 void RosenRenderContext::PostTransitionUserOutCallback()
5771 {
5772     auto taskExecutor = Container::CurrentTaskExecutor();
5773     CHECK_NULL_VOID(taskExecutor);
5774     // post the callback to let it run on isolate environment
5775     taskExecutor->PostTask([callback = transitionUserCallback_]() {
5776         if (callback) {
5777             callback(false);
5778         }
5779     }, TaskExecutor::TaskType::UI, "ArkUITransitionOutFinishCallback", PriorityType::HIGH);
5780 }
5781 
5782 void RosenRenderContext::SetActualForegroundColor(const Color& value)
5783 {
5784     CHECK_NULL_VOID(rsNode_);
5785     rsNode_->SetForegroundColor(value.GetValue());
5786     RequestNextFrame();
5787 }
5788 
5789 void RosenRenderContext::AttachNodeAnimatableProperty(RefPtr<NodeAnimatablePropertyBase> property)
5790 {
5791     CHECK_NULL_VOID(rsNode_);
5792     CHECK_NULL_VOID(property);
5793     if (!property->GetModifyImpl()) {
5794         auto nodeModifierImpl = std::make_shared<RSNodeModifierImpl>();
5795         CHECK_NULL_VOID(nodeModifierImpl);
5796         property->SetModifyImpl(nodeModifierImpl);
5797         rsNode_->AddModifier(nodeModifierImpl);
5798         nodeModifierImpl->AddProperty(property->GetProperty());
5799     }
5800 }
5801 
5802 void RosenRenderContext::DetachNodeAnimatableProperty(const RefPtr<NodeAnimatablePropertyBase>& property)
5803 {
5804     CHECK_NULL_VOID(rsNode_);
5805     CHECK_NULL_VOID(property);
5806     std::shared_ptr<RSNodeModifierImpl> modifier =
5807         std::static_pointer_cast<RSNodeModifierImpl>(property->GetModifyImpl());
5808     RemoveModifier(modifier);
5809 }
5810 
5811 void RosenRenderContext::InitEventClickEffect()
5812 {
5813     if (touchListener_) {
5814         return;
5815     }
5816     auto host = GetHost();
5817     CHECK_NULL_VOID(host);
5818     auto gesture = host->GetOrCreateGestureEventHub();
5819     CHECK_NULL_VOID(gesture);
5820     auto touchCallback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
5821         auto renderContext = weak.Upgrade();
5822         CHECK_NULL_VOID(renderContext);
5823         renderContext->ClickEffectPlayAnimation(info.GetTouches().front().GetTouchType());
5824     };
5825     touchListener_ = MakeRefPtr<TouchEventImpl>(std::move(touchCallback));
5826     gesture->AddTouchEvent(touchListener_);
5827 }
5828 
5829 void RosenRenderContext::ClickEffectPlayAnimation(const TouchType& touchType)
5830 {
5831     if (touchType != TouchType::DOWN && touchType != TouchType::UP && touchType != TouchType::CANCEL) {
5832         return;
5833     }
5834     auto value = GetClickEffectLevelValue();
5835     auto level = value.level;
5836     auto scaleValue = value.scaleNumber;
5837     auto springCurve = UpdatePlayAnimationValue(level, scaleValue);
5838 
5839     AnimationOption option;
5840     option.SetCurve(springCurve);
5841     option.SetDuration(DEFAULT_OPTION_DURATION);
5842 
5843     if (touchType == TouchType::DOWN && level != ClickEffectLevel::UNDEFINED) {
5844         if (isTouchUpFinished_) {
5845             auto defaultScale = VectorF(1.0f, 1.0f);
5846             auto currentScale = GetTransformScaleValue(defaultScale);
5847             currentScale_ = currentScale;
5848             UpdateTransformScale(currentScale_);
5849 
5850             AnimationUtils::OpenImplicitAnimation(option, springCurve, nullptr);
5851             VectorF valueScale(scaleValue, scaleValue);
5852             UpdateTransformScale(valueScale);
5853             AnimationUtils::CloseImplicitAnimation();
5854         }
5855         isTouchUpFinished_ = false;
5856     }
5857 
5858     if ((touchType == TouchType::UP || touchType == TouchType::CANCEL) && level != ClickEffectLevel::UNDEFINED) {
5859         AnimationUtils::OpenImplicitAnimation(option, springCurve, nullptr);
5860         UpdateTransformScale(currentScale_);
5861         AnimationUtils::CloseImplicitAnimation();
5862         isTouchUpFinished_ = true;
5863     }
5864 }
5865 
5866 RefPtr<Curve> RosenRenderContext::UpdatePlayAnimationValue(const ClickEffectLevel& level, float& scaleValue)
5867 {
5868     float velocity = 0.0f;
5869     float mass = 0.0f;
5870     float stiffness = 0.0f;
5871     float damping = 0.0f;
5872     if (level == ClickEffectLevel::LIGHT) {
5873         velocity = ANIMATION_CURVE_VELOCITY_LIGHT_OR_MIDDLE;
5874         mass = ANIMATION_CURVE_MASS;
5875         stiffness = ANIMATION_CURVE_STIFFNESS_LIGHT;
5876         damping = ANIMATION_CURVE_DAMPING_LIGHT;
5877         if (GreatOrEqual(scaleValue, 0.0) && LessOrEqual(scaleValue, 1.0)) {
5878             scaleValue = sqrt(scaleValue);
5879         } else {
5880             scaleValue = sqrt(DEFAULT_SCALE_LIGHT);
5881         }
5882     } else if (level == ClickEffectLevel::MIDDLE) {
5883         velocity = ANIMATION_CURVE_VELOCITY_LIGHT_OR_MIDDLE;
5884         mass = ANIMATION_CURVE_MASS;
5885         stiffness = ANIMATION_CURVE_STIFFNESS_MIDDLE;
5886         damping = ANIMATION_CURVE_DAMPING_MIDDLE;
5887         if (GreatOrEqual(scaleValue, 0.0) && LessOrEqual(scaleValue, 1.0)) {
5888             scaleValue = sqrt(scaleValue);
5889         } else {
5890             scaleValue = sqrt(DEFAULT_SCALE_MIDDLE_OR_HEAVY);
5891         }
5892     } else if (level == ClickEffectLevel::HEAVY) {
5893         velocity = ANIMATION_CURVE_VELOCITY_HEAVY;
5894         mass = ANIMATION_CURVE_MASS;
5895         stiffness = ANIMATION_CURVE_STIFFNESS_HEAVY;
5896         damping = ANIMATION_CURVE_DAMPING_HEAVY;
5897         if (GreatOrEqual(scaleValue, 0.0) && LessOrEqual(scaleValue, 1.0)) {
5898             scaleValue = sqrt(scaleValue);
5899         } else {
5900             scaleValue = sqrt(DEFAULT_SCALE_MIDDLE_OR_HEAVY);
5901         }
5902     }
5903     return AceType::MakeRefPtr<InterpolatingSpring>(velocity, mass, stiffness, damping);
5904 }
5905 
5906 void RosenRenderContext::RegisterSharedTransition(const RefPtr<RenderContext>& other)
5907 {
5908     auto otherContext = AceType::DynamicCast<RosenRenderContext>(other);
5909     if (!otherContext) {
5910         return;
5911     }
5912     CHECK_NULL_VOID(rsNode_);
5913     RSNode::RegisterTransitionPair(rsNode_->GetId(), otherContext->rsNode_->GetId());
5914 }
5915 
5916 void RosenRenderContext::UnregisterSharedTransition(const RefPtr<RenderContext>& other)
5917 {
5918     auto otherContext = AceType::DynamicCast<RosenRenderContext>(other);
5919     if (!otherContext) {
5920         // the paired node is already destroyed, we don't need to unregister it, Rosen will handle it.
5921         return;
5922     }
5923     CHECK_NULL_VOID(rsNode_);
5924     RSNode::UnregisterTransitionPair(rsNode_->GetId(), otherContext->rsNode_->GetId());
5925 }
5926 
5927 inline void RosenRenderContext::ConvertRadius(const BorderRadiusProperty& value, Rosen::Vector4f& cornerRadius)
5928 {
5929     cornerRadius.SetValues(static_cast<float>(value.radiusTopLeft.value_or(Dimension()).ConvertToPx()),
5930         static_cast<float>(value.radiusTopRight.value_or(Dimension()).ConvertToPx()),
5931         static_cast<float>(value.radiusBottomRight.value_or(Dimension()).ConvertToPx()),
5932         static_cast<float>(value.radiusBottomLeft.value_or(Dimension()).ConvertToPx()));
5933 }
5934 
5935 #ifndef USE_ROSEN_DRAWING
5936 void RosenRenderContext::PaintSkBgImage()
5937 {
5938     auto image = DynamicCast<NG::SkiaImage>(bgImage_);
5939 #else
5940 void RosenRenderContext::PaintRSBgImage()
5941 {
5942     auto image = DynamicCast<NG::DrawingImage>(bgImage_);
5943 #endif
5944     CHECK_NULL_VOID(bgLoadingCtx_ && image);
5945     CHECK_NULL_VOID(rsNode_);
5946     auto rosenImage = std::make_shared<Rosen::RSImage>();
5947     auto compressData = image->GetCompressData();
5948     if (compressData) {
5949         rosenImage->SetCompressData(
5950             compressData, image->GetUniqueID(), image->GetCompressWidth(), image->GetCompressHeight());
5951     } else {
5952         rosenImage->SetImage(image->GetImage());
5953     }
5954     if (!HasValidBgImageResizable()) {
5955         rosenImage->SetImageRepeat(static_cast<int>(GetBackgroundImageRepeat().value_or(ImageRepeat::NO_REPEAT)));
5956     }
5957     rsNode_->SetBgImage(rosenImage);
5958 }
5959 
5960 void RosenRenderContext::PaintPixmapBgImage()
5961 {
5962     CHECK_NULL_VOID(rsNode_);
5963     auto image = DynamicCast<NG::PixelMapImage>(bgImage_);
5964     CHECK_NULL_VOID(bgLoadingCtx_ && image);
5965     auto pixmap = image->GetPixelMap();
5966     CHECK_NULL_VOID(pixmap);
5967 
5968     auto rosenImage = std::make_shared<Rosen::RSImage>();
5969     rosenImage->SetPixelMap(pixmap->GetPixelMapSharedPtr());
5970     if (!HasValidBgImageResizable()) {
5971         rosenImage->SetImageRepeat(static_cast<int>(GetBackgroundImageRepeat().value_or(ImageRepeat::NO_REPEAT)));
5972     }
5973     rsNode_->SetBgImage(rosenImage);
5974 }
5975 
5976 void RosenRenderContext::OnRenderGroupUpdate(bool isRenderGroup)
5977 {
5978     CHECK_NULL_VOID(rsNode_);
5979     rsNode_->MarkNodeGroup(isRenderGroup);
5980 }
5981 
5982 void RosenRenderContext::UpdateRenderGroup(bool isRenderGroup, bool isForced, bool includeProperty)
5983 {
5984     CHECK_NULL_VOID(rsNode_);
5985     rsNode_->MarkNodeGroup(isRenderGroup, isForced, includeProperty);
5986 }
5987 
5988 void RosenRenderContext::OnNodeNameUpdate(const std::string& id)
5989 {
5990     CHECK_NULL_VOID(rsNode_);
5991     rsNode_->SetNodeName(id);
5992 }
5993 
5994 void RosenRenderContext::OnSuggestedRenderGroupUpdate(bool isRenderGroup)
5995 {
5996     CHECK_NULL_VOID(rsNode_);
5997     rsNode_->MarkNodeGroup(isRenderGroup, false);
5998 }
5999 
6000 void RosenRenderContext::OnRenderFitUpdate(RenderFit renderFit)
6001 {
6002     CHECK_NULL_VOID(rsNode_);
6003     rsNode_->SetFrameGravity(GetRosenGravity(renderFit));
6004 }
6005 
6006 void RosenRenderContext::SetContentRectToFrame(RectF rect)
6007 {
6008     CHECK_NULL_VOID(rsNode_);
6009     auto host = GetHost();
6010     CHECK_NULL_VOID(host);
6011     if (adjustRSFrameByContentRect_) {
6012         auto geometryNode = host->GetGeometryNode();
6013         CHECK_NULL_VOID(geometryNode);
6014         auto contentRect = geometryNode->GetContentRect();
6015         rect.SetOffset(rect.GetOffset() + contentRect.GetOffset());
6016         rect.SetSize(contentRect.GetSize());
6017     } else {
6018         auto&& padding = host->GetGeometryNode()->GetPadding();
6019         // minus padding to get contentRect
6020         if (padding) {
6021             rect.SetOffset(rect.GetOffset() + OffsetF { padding->left.value_or(0), padding->top.value_or(0) });
6022             auto size = rect.GetSize();
6023             MinusPaddingToSize(*padding, size);
6024             rect.SetSize(size);
6025         }
6026     }
6027     rsNode_->SetFrame(rect.GetX(), rect.GetY(), rect.Width(), rect.Height());
6028 }
6029 
6030 void RosenRenderContext::MarkNewFrameAvailable(void* nativeWindow)
6031 {
6032     CHECK_NULL_VOID(rsNode_);
6033     auto rsSurfaceNode = rsNode_->ReinterpretCastTo<Rosen::RSSurfaceNode>();
6034     CHECK_NULL_VOID(rsSurfaceNode);
6035 #if defined(ANDROID_PLATFORM)
6036     rsSurfaceNode->MarkUiFrameAvailable(true);
6037 #endif
6038 #if defined(IOS_PLATFORM)
6039     RSSurfaceExtConfig config = {
6040         .type = RSSurfaceExtType::SURFACE_TEXTURE,
6041         .additionalData = nativeWindow,
6042     };
6043     rsSurfaceNode->SetSurfaceTexture(config);
6044 #endif
6045 }
6046 
6047 void RosenRenderContext::AddAttachCallBack(const std::function<void(int64_t, bool)>& attachCallback)
6048 {
6049     CHECK_NULL_VOID(rsNode_);
6050 #if defined(ANDROID_PLATFORM)
6051     auto rsSurfaceNode = rsNode_->ReinterpretCastTo<Rosen::RSSurfaceNode>();
6052     CHECK_NULL_VOID(rsSurfaceNode);
6053     rsSurfaceNode->SetSurfaceTextureAttachCallBack(attachCallback);
6054 #endif
6055 }
6056 
6057 void RosenRenderContext::AddUpdateCallBack(const std::function<void(std::vector<float>&)>& updateCallback)
6058 {
6059     CHECK_NULL_VOID(rsNode_);
6060 #if defined(ANDROID_PLATFORM)
6061     auto rsSurfaceNode = rsNode_->ReinterpretCastTo<Rosen::RSSurfaceNode>();
6062     CHECK_NULL_VOID(rsSurfaceNode);
6063     rsSurfaceNode->SetSurfaceTextureUpdateCallBack(updateCallback);
6064 #endif
6065 }
6066 
6067 bool RosenRenderContext::IsUniRenderEnabled()
6068 {
6069     return Rosen::RSSystemProperties::GetUniRenderEnabled();
6070 }
6071 
6072 void RosenRenderContext::SetRenderFrameOffset(const OffsetF& offset)
6073 {
6074     frameOffset_ = offset;
6075 }
6076 
6077 void RosenRenderContext::SetRotation(float rotationX, float rotationY, float rotationZ)
6078 {
6079     CHECK_NULL_VOID(rsNode_);
6080     rsNode_->SetRotation(rotationX, rotationY, rotationZ);
6081     NotifyHostTransformUpdated();
6082 }
6083 
6084 void RosenRenderContext::SetShadowColor(uint32_t color)
6085 {
6086     CHECK_NULL_VOID(rsNode_);
6087     rsNode_->SetShadowColor(color);
6088 }
6089 
6090 void RosenRenderContext::SetShadowOffset(float offsetX, float offsetY)
6091 {
6092     CHECK_NULL_VOID(rsNode_);
6093     rsNode_->SetShadowOffset(offsetX, offsetY);
6094 }
6095 
6096 void RosenRenderContext::SetShadowAlpha(float alpha)
6097 {
6098     CHECK_NULL_VOID(rsNode_);
6099     rsNode_->SetShadowAlpha(alpha);
6100 }
6101 
6102 void RosenRenderContext::SetShadowElevation(float elevation)
6103 {
6104     CHECK_NULL_VOID(rsNode_);
6105     rsNode_->SetShadowElevation(elevation);
6106 }
6107 
6108 void RosenRenderContext::SetShadowRadius(float radius)
6109 {
6110     CHECK_NULL_VOID(rsNode_);
6111     rsNode_->SetShadowRadius(radius);
6112 }
6113 
6114 void RosenRenderContext::SetScale(float scaleX, float scaleY)
6115 {
6116     CHECK_NULL_VOID(rsNode_);
6117     SetAnimatableProperty<Rosen::RSScaleModifier, Rosen::Vector2f>(scaleXYUserModifier_, { scaleX, scaleY });
6118     NotifyHostTransformUpdated();
6119 }
6120 
6121 void RosenRenderContext::SetBackgroundColor(uint32_t colorValue)
6122 {
6123     CHECK_NULL_VOID(rsNode_);
6124     rsNode_->SetBackgroundColor(colorValue);
6125 }
6126 
6127 void RosenRenderContext::SetRenderPivot(float pivotX, float pivotY)
6128 {
6129     CHECK_NULL_VOID(rsNode_);
6130     rsNode_->SetPivot(pivotX, pivotY);
6131     NotifyHostTransformUpdated();
6132 }
6133 
6134 void RosenRenderContext::SetFrame(float positionX, float positionY, float width, float height)
6135 {
6136     CHECK_NULL_VOID(rsNode_);
6137     rsNode_->SetFrame(positionX, positionY, width, height);
6138 }
6139 
6140 void RosenRenderContext::SetOpacity(float opacity)
6141 {
6142     CHECK_NULL_VOID(rsNode_);
6143     rsNode_->SetAlpha(opacity);
6144 }
6145 
6146 void RosenRenderContext::SetOpacityMultiplier(float opacity)
6147 {
6148     CHECK_NULL_VOID(rsNode_);
6149     SetAnimatableProperty<Rosen::RSAlphaModifier, float>(alphaModifier_, opacity);
6150 }
6151 
6152 void RosenRenderContext::SetTranslate(float translateX, float translateY, float translateZ)
6153 {
6154     CHECK_NULL_VOID(rsNode_);
6155     SetAnimatableProperty<Rosen::RSTranslateModifier, Rosen::Vector2f>(
6156         translateXYUserModifier_, { translateX, translateY });
6157     SetAnimatableProperty<Rosen::RSTranslateZModifier, float>(translateZUserModifier_, translateZ);
6158     NotifyHostTransformUpdated();
6159 }
6160 
6161 void RosenRenderContext::SetTransitionInCallback(std::function<void()>&& callback)
6162 {
6163     transitionInCallback_ = std::move(callback);
6164 }
6165 
6166 void RosenRenderContext::SetTransitionOutCallback(std::function<void()>&& callback)
6167 {
6168     transitionOutCallback_ = std::move(callback);
6169 }
6170 
6171 void RosenRenderContext::ResetSurface(int width, int height)
6172 {
6173     auto rsCanvasDrawingNode = Rosen::RSNode::ReinterpretCast<Rosen::RSCanvasDrawingNode>(rsNode_);
6174     CHECK_NULL_VOID(rsCanvasDrawingNode);
6175     rsCanvasDrawingNode->ResetSurface(width, height);
6176 }
6177 
6178 void RosenRenderContext::SetTransitionUserCallback(TransitionFinishCallback&& callback)
6179 {
6180     transitionUserCallback_ = std::move(callback);
6181 }
6182 
6183 void RosenRenderContext::SetRectMask(const RectF& rect, const ShapeMaskProperty& property)
6184 {
6185     CHECK_NULL_VOID(rsNode_);
6186     RSPath path;
6187     path.AddRect(rect.Left(), rect.Top(), rect.Right(), rect.Bottom());
6188 
6189     RSBrush brush = GetRsBrush(property.fillColor);
6190     RSPen pen = GetRsPen(property.strokeColor, property.strokeWidth);
6191 
6192     std::shared_ptr<RSMask> mask = RSMask::CreatePathMask(path, pen, brush);
6193     rsNode_->SetMask(mask);
6194 }
6195 
6196 void RosenRenderContext::SetCircleMask(const Circle& circle, const ShapeMaskProperty& property)
6197 {
6198     CHECK_NULL_VOID(rsNode_);
6199     RSPath path;
6200     path.AddCircle(circle.GetAxisX().Value(), circle.GetAxisY().Value(), circle.GetRadius().Value());
6201 
6202     RSBrush brush = GetRsBrush(property.fillColor);
6203     RSPen pen = GetRsPen(property.strokeColor, property.strokeWidth);
6204 
6205     std::shared_ptr<RSMask> mask = RSMask::CreatePathMask(path, pen, brush);
6206     rsNode_->SetMask(mask);
6207 }
6208 
6209 void RosenRenderContext::SetRoundRectMask(const RoundRect& roundRect, const ShapeMaskProperty& property)
6210 {
6211     CHECK_NULL_VOID(rsNode_);
6212     RSRoundRect rsRoundRect;
6213 
6214     RSRect rsRect(roundRect.GetRect().Left(), roundRect.GetRect().Top(), roundRect.GetRect().Right(),
6215         roundRect.GetRect().Bottom());
6216     rsRoundRect.SetRect(rsRect);
6217 
6218     EdgeF edge = roundRect.GetCornerRadius(RoundRect::TOP_LEFT_POS);
6219     rsRoundRect.SetCornerRadius(RSRoundRect::TOP_LEFT_POS, edge.x, edge.y);
6220     edge = roundRect.GetCornerRadius(RoundRect::TOP_RIGHT_POS);
6221     rsRoundRect.SetCornerRadius(RSRoundRect::TOP_RIGHT_POS, edge.x, edge.y);
6222     edge = roundRect.GetCornerRadius(RoundRect::BOTTOM_LEFT_POS);
6223     rsRoundRect.SetCornerRadius(RSRoundRect::BOTTOM_LEFT_POS, edge.x, edge.y);
6224     edge = roundRect.GetCornerRadius(RoundRect::BOTTOM_RIGHT_POS);
6225     rsRoundRect.SetCornerRadius(RSRoundRect::BOTTOM_RIGHT_POS, edge.x, edge.y);
6226 
6227     RSPath path;
6228     path.AddRoundRect(rsRoundRect);
6229 
6230     RSBrush brush = GetRsBrush(property.fillColor);
6231     RSPen pen = GetRsPen(property.strokeColor, property.strokeWidth);
6232 
6233     std::shared_ptr<RSMask> mask = Rosen::RSMask::CreatePathMask(path, pen, brush);
6234     rsNode_->SetMask(mask);
6235 }
6236 
6237 void RosenRenderContext::SetOvalMask(const RectF& rect, const ShapeMaskProperty& property)
6238 {
6239     CHECK_NULL_VOID(rsNode_);
6240     RSRect rsRect(rect.Left(), rect.Top(), rect.Right(), rect.Bottom());
6241     RSPath path;
6242     path.AddOval(rsRect);
6243 
6244     RSBrush brush = GetRsBrush(property.fillColor);
6245     RSPen pen = GetRsPen(property.strokeColor, property.strokeWidth);
6246 
6247     std::shared_ptr<RSMask> mask = RSMask::CreatePathMask(path, pen, brush);
6248     rsNode_->SetMask(mask);
6249 }
6250 
6251 void RosenRenderContext::SetCommandPathMask(
6252     const std::string& commands, const ShapeMaskProperty& property)
6253 {
6254     CHECK_NULL_VOID(rsNode_);
6255     RSPath path;
6256     path.BuildFromSVGString(commands);
6257 
6258     RSBrush brush = GetRsBrush(property.fillColor);
6259     RSPen pen = GetRsPen(property.strokeColor, property.strokeWidth);
6260 
6261     std::shared_ptr<RSMask> mask = RSMask::CreatePathMask(path, pen, brush);
6262     rsNode_->SetMask(mask);
6263 }
6264 
6265 void RosenRenderContext::SetMarkNodeGroup(bool isNodeGroup)
6266 {
6267     CHECK_NULL_VOID(rsNode_);
6268     rsNode_->MarkNodeGroup(isNodeGroup);
6269 }
6270 
6271 void RosenRenderContext::SavePaintRect(bool isRound, uint8_t flag)
6272 {
6273     auto host = GetHost();
6274     CHECK_NULL_VOID(host);
6275     const auto& geometryNode = host->GetGeometryNode();
6276     CHECK_NULL_VOID(geometryNode);
6277     AdjustPaintRect();
6278     if (!SystemProperties::GetPixelRoundEnabled()) {
6279         isRound = false;
6280     }
6281     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
6282         if (isRound && flag == 0) {
6283             OnePixelRounding(); // call OnePixelRounding without param to improve performance
6284         } else {
6285             OnePixelRounding(isRound, flag);
6286         }
6287     } else {
6288         if (isRound && flag == 0) {
6289             RoundToPixelGrid(); // call RoundToPixelGrid without param to improve performance
6290         } else {
6291             RoundToPixelGrid(isRound, flag);
6292         }
6293     }
6294     paintRect_ = RectF(geometryNode->GetPixelGridRoundOffset(), geometryNode->GetPixelGridRoundSize());
6295     if (SystemProperties::GetSyncDebugTraceEnabled()) {
6296         ACE_LAYOUT_SCOPED_TRACE("SavePaintRect[%s][self:%d] rs SavePaintRect %s",
6297             host->GetTag().c_str(), host->GetId(), paintRect_.ToString().c_str());
6298     }
6299 }
6300 
6301 void RosenRenderContext::UpdatePaintRect(const RectF& paintRect)
6302 {
6303     paintRect_ = paintRect;
6304 }
6305 
6306 void RosenRenderContext::SyncPartialRsProperties()
6307 {
6308     if (propTransform_ && propTransform_->HasTransformCenter()) {
6309         auto vec = propTransform_->GetTransformCenterValue();
6310         float xPivot = ConvertDimensionToScaleBySize(vec.GetX(), paintRect_.Width());
6311         float yPivot = ConvertDimensionToScaleBySize(vec.GetY(), paintRect_.Height());
6312         if (vec.GetZ().has_value()) {
6313             float zPivot = static_cast<float>(vec.GetZ().value().ConvertToVp());
6314             SetPivot(xPivot, yPivot, zPivot);
6315         } else {
6316             SetPivot(xPivot, yPivot);
6317         }
6318     }
6319 
6320     if (propTransform_ && propTransform_->HasTransformTranslate()) {
6321         // if translate unit is percent, it is related with frameSize
6322         OnTransformTranslateUpdate(propTransform_->GetTransformTranslateValue());
6323     }
6324 }
6325 
6326 void RosenRenderContext::UpdateDrawRegion(uint32_t index, const std::shared_ptr<Rosen::RectF>& rect)
6327 {
6328     if (drawRegionRects_[index] && rect && *drawRegionRects_[index] == *rect) {
6329         return;
6330     } else if (!drawRegionRects_[index] && !rect) {
6331         return;
6332     }
6333     // the drawRegion of this index has changed
6334     drawRegionRects_[index] = rect;
6335     std::shared_ptr<Rosen::RectF> result;
6336     for (size_t index = 0; index < DRAW_REGION_RECT_COUNT; ++index) {
6337         if (drawRegionRects_[index]) {
6338             if (result) {
6339                 *result = result->JoinRect(*drawRegionRects_[index]);
6340             } else {
6341                 result = std::make_shared<Rosen::RectF>(*drawRegionRects_[index]);
6342             }
6343         }
6344     }
6345     if (!result) {
6346         return;
6347     }
6348     rsNode_->SetDrawRegion(result);
6349 }
6350 
6351 void RosenRenderContext::SuggestOpIncNode(bool isOpincNode, bool isNeedCalculate)
6352 {
6353     CHECK_NULL_VOID(rsNode_);
6354     rsNode_->MarkSuggestOpincNode(isOpincNode, isNeedCalculate);
6355 }
6356 
6357 void RosenRenderContext::NotifyHostTransformUpdated(bool changed)
6358 {
6359     auto host = GetHost();
6360     CHECK_NULL_VOID(host);
6361     host->NotifyTransformInfoChanged();
6362     host->OnNodeTransformInfoUpdate(changed);
6363 }
6364 
6365 PipelineContext* RosenRenderContext::GetPipelineContext() const
6366 {
6367     auto host = GetHost();
6368     if (host) {
6369         return host->GetContextWithCheck();
6370     }
6371     return PipelineContext::GetCurrentContextPtrSafelyWithCheck();
6372 }
6373 
6374 void RosenRenderContext::DumpSimplifyInfo(std::unique_ptr<JsonValue>& json)
6375 {
6376     if (rsNode_) {
6377         DumpSimplifyStagingProperties(json);
6378         if (!NearZero(rsNode_->GetStagingProperties().GetPivotZ())) {
6379             json->Put("PivotZ", std::to_string(rsNode_->GetStagingProperties().GetPivotZ()).c_str());
6380         }
6381         if (!NearZero(rsNode_->GetStagingProperties().GetRotation())) {
6382             json->Put("Rotation", std::to_string(rsNode_->GetStagingProperties().GetRotation()).c_str());
6383         }
6384         if (!NearZero(rsNode_->GetStagingProperties().GetRotationX())) {
6385             json->Put("RotationX", std::to_string(rsNode_->GetStagingProperties().GetRotationX()).c_str());
6386         }
6387         if (!NearZero(rsNode_->GetStagingProperties().GetRotationY())) {
6388             json->Put("RotationY", std::to_string(rsNode_->GetStagingProperties().GetRotationY()).c_str());
6389         }
6390         if (!NearEqual(rsNode_->GetStagingProperties().GetAlpha(), 1)) {
6391             json->Put("Alpha", std::to_string(rsNode_->GetStagingProperties().GetAlpha()).c_str());
6392         }
6393         if (HasPosition()) {
6394             auto position = GetPosition();
6395             json->Put("Position",
6396                 position->GetX().ToString().append(",").append(position->GetY().ToString()).c_str());
6397         }
6398         if (HasOffset()) {
6399             auto offset = GetOffset();
6400             json->Put("Offset", offset->GetX().ToString().append(",").append(offset->GetY().ToString()).c_str());
6401         }
6402         if (HasPositionEdges()) {
6403             auto positionEdges = GetPositionEdges();
6404             json->Put("PositionEdges", positionEdges->ToString().c_str());
6405         }
6406         if (HasOffsetEdges()) {
6407             auto offsetEdges = GetOffsetEdges();
6408             json->Put("OffsetEdges", offsetEdges->ToString().c_str());
6409         }
6410         if (HasAnchor()) {
6411             auto anchor = GetAnchor();
6412             json->Put("Anchor", anchor->GetX().ToString().append(",").append(anchor->GetY().ToString()).c_str());
6413         }
6414     }
6415 }
6416 
6417 void RosenRenderContext::DumpSimplifyStagingProperties(std::unique_ptr<JsonValue>& json)
6418 {
6419     auto center = rsNode_->GetStagingProperties().GetPivot();
6420     if (!NearEqual(center[0], 0.5) || !NearEqual(center[1], 0.5)) {
6421         json->Put("Center", std::to_string(center[0]).append(",").append(std::to_string(center[1])).c_str());
6422     }
6423     auto translate = rsNode_->GetStagingProperties().GetTranslate();
6424     if (!(NearZero(translate[0]) && NearZero(translate[1]))) {
6425         json->Put("Translate",
6426             std::to_string(translate[0]).append(",").append(std::to_string(translate[1])).c_str());
6427     }
6428     auto scale = rsNode_->GetStagingProperties().GetScale();
6429     if (!(NearEqual(scale[0], 1) && NearEqual(scale[1], 1))) {
6430         json->Put("Scale", std::to_string(scale[0]).append(",").append(std::to_string(scale[1])).c_str());
6431     }
6432     if (HasTransformScale()) {
6433         auto arkTransformScale = GetTransformScale().value();
6434         if (!NearEqual(arkTransformScale.x, scale[0])) {
6435             json->Put("TransformScaleX", std::to_string(arkTransformScale.x).c_str());
6436         }
6437         if (!NearEqual(arkTransformScale.y, scale[1])) {
6438             json->Put("TransformScaleY", std::to_string(arkTransformScale.y).c_str());
6439         }
6440     }
6441     auto rect = GetPaintRectWithoutTransform();
6442     if (HasTransformTranslate()) {
6443         auto translateArk = GetTransformTranslate().value();
6444         auto arkTranslateX = translateArk.x.ConvertToPxWithSize(rect.Width());
6445         auto arkTranslateY = translateArk.y.ConvertToPxWithSize(rect.Height());
6446         if (!NearEqual(arkTranslateX, translate[0])) {
6447             json->Put("TransformTranslateX", std::to_string(arkTranslateX).c_str());
6448         }
6449         if (!NearEqual(arkTranslateY, translate[1])) {
6450             json->Put("TransformTranslateY", std::to_string(arkTranslateY).c_str());
6451         }
6452     }
6453     if (HasOpacity()) {
6454         auto arkAlpha = GetOpacity();
6455         if (!NearEqual(arkAlpha.value(), rsNode_->GetStagingProperties().GetAlpha())) {
6456             json->Put("TransformAlpha", std::to_string(arkAlpha.value()).c_str());
6457         }
6458     }
6459 }
6460 } // namespace OHOS::Ace::NG
6461