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