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