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