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