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