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 <algorithm>
19 #include <cstddef>
20 #include <cstdint>
21 #include <memory>
22
23 #include "common/rs_vector2.h"
24 #include "include/utils/SkParsePath.h"
25 #include "modifier/rs_property.h"
26 #include "render_service_base/include/property/rs_properties_def.h"
27 #include "render_service_client/core/modifier/rs_property_modifier.h"
28 #include "render_service_client/core/pipeline/rs_node_map.h"
29 #include "render_service_client/core/transaction/rs_interfaces.h"
30 #include "render_service_client/core/ui/rs_canvas_drawing_node.h"
31 #include "render_service_client/core/ui/rs_canvas_node.h"
32 #include "render_service_client/core/ui/rs_effect_node.h"
33 #include "render_service_client/core/ui/rs_root_node.h"
34 #include "render_service_client/core/ui/rs_surface_node.h"
35 #include "rosen_render_context.h"
36
37 #include "base/geometry/dimension.h"
38 #include "base/geometry/matrix4.h"
39 #include "base/geometry/ng/offset_t.h"
40 #include "base/geometry/ng/rect_t.h"
41 #include "base/log/dump_log.h"
42 #include "base/memory/ace_type.h"
43 #include "base/memory/referenced.h"
44 #include "base/utils/utils.h"
45 #include "core/animation/native_curve_helper.h"
46 #include "core/animation/page_transition_common.h"
47 #include "core/animation/spring_curve.h"
48 #include "core/common/container.h"
49 #include "core/common/rosen/rosen_convert_helper.h"
50 #include "core/components/common/properties/decoration.h"
51 #include "core/components/theme/app_theme.h"
52 #include "core/components_ng/base/frame_node.h"
53 #include "core/components_ng/base/geometry_node.h"
54 #include "core/components_ng/base/view_stack_processor.h"
55 #include "core/components_ng/event/event_hub.h"
56 #include "core/components_ng/pattern/stage/page_pattern.h"
57 #include "core/components_ng/pattern/stage/stage_pattern.h"
58 #include "core/components_ng/property/calc_length.h"
59 #include "core/components_ng/property/measure_utils.h"
60 #include "core/components_ng/render/adapter/background_modifier.h"
61 #include "core/components_ng/render/adapter/border_image_modifier.h"
62 #include "core/components_ng/render/adapter/component_snapshot.h"
63 #include "core/components_ng/render/adapter/debug_boundary_modifier.h"
64 #include "core/components_ng/render/adapter/focus_state_modifier.h"
65 #include "core/components_ng/render/adapter/gradient_style_modifier.h"
66 #include "core/components_ng/render/adapter/graphic_modifier.h"
67 #include "core/components_ng/render/adapter/moon_progress_modifier.h"
68 #include "core/components_ng/render/adapter/mouse_select_modifier.h"
69 #include "core/components_ng/render/adapter/overlay_modifier.h"
70 #include "core/components_ng/render/adapter/pixelmap_image.h"
71 #include "core/components_ng/render/adapter/rosen_modifier_adapter.h"
72 #include "core/components_ng/render/adapter/rosen_transition_effect.h"
73 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
74 #include "render_service_client/core/pipeline/rs_render_thread.h"
75 #endif
76 #ifndef USE_ROSEN_DRAWING
77 #include "core/components_ng/render/adapter/skia_decoration_painter.h"
78 #include "core/components_ng/render/adapter/skia_image.h"
79 #else
80 #include "core/components_ng/render/adapter/rosen/drawing_decoration_painter.h"
81 #include "core/components_ng/render/adapter/rosen/drawing_image.h"
82 #endif
83 #include "core/components_ng/render/animation_utils.h"
84 #include "core/components_ng/render/border_image_painter.h"
85 #include "core/components_ng/render/debug_boundary_painter.h"
86 #include "core/components_ng/render/drawing.h"
87 #include "core/components_ng/render/drawing_prop_convertor.h"
88 #include "core/components_ng/render/image_painter.h"
89 #include "core/pipeline_ng/pipeline_context.h"
90
91 namespace OHOS::Ace::NG {
92
93 using namespace OHOS::Rosen;
94 namespace {
95 RefPtr<PixelMap> g_pixelMap {};
96 std::mutex g_mutex;
97 std::condition_variable thumbnailGet;
98 constexpr std::chrono::duration<int, std::milli> PIXELMAP_TIMEOUT_DURATION(1000);
99 constexpr float ANIMATION_CURVE_VELOCITY_LIGHT_OR_MIDDLE = 10.0f;
100 constexpr float ANIMATION_CURVE_VELOCITY_HEAVY = 0.0f;
101 constexpr float ANIMATION_CURVE_MASS = 1.0f;
102 constexpr float ANIMATION_CURVE_STIFFNESS_LIGHT = 410.0f;
103 constexpr float ANIMATION_CURVE_STIFFNESS_MIDDLE = 350.0f;
104 constexpr float ANIMATION_CURVE_STIFFNESS_HEAVY = 240.0f;
105 constexpr float ANIMATION_CURVE_DAMPING_LIGHT = 38.0f;
106 constexpr float ANIMATION_CURVE_DAMPING_MIDDLE = 35.0f;
107 constexpr float ANIMATION_CURVE_DAMPING_HEAVY = 28.0f;
108 constexpr float DEFAULT_SCALE_LIGHT = 0.9f;
109 constexpr float DEFAULT_SCALE_MIDDLE_OR_HEAVY = 0.95f;
110 constexpr int32_t DEFAULT_OPTION_DURATION = 100;
111 constexpr int32_t PLATFORM_VERSION_TEN = 10;
112 constexpr int32_t PARTICLE_DEFAULT_COLOR = 0xFFFFFFFF;
113 constexpr float PARTICLE_DEFAULT_OPACITY = 1.0f;
114 constexpr float PARTICLE_DEFAULT_SCALE = 1.0f;
115 constexpr float PARTICLE_DEFAULT_SPEED = 0.0f;
116 constexpr float PARTICLE_DEFAULT_ANGLE = 0.0f;
117 constexpr float PARTICLE_DEFAULT_SPIN = 0.0f;
118 constexpr int64_t PARTICLE_DEFAULT_LIFETIME = 1000;
119 constexpr int32_t PARTICLE_DEFAULT_EMITTER_RATE = 5;
120
GetRosenGravity(RenderFit renderFit)121 Rosen::Gravity GetRosenGravity(RenderFit renderFit)
122 {
123 static const LinearEnumMapNode<RenderFit, Rosen::Gravity> gravityMap[] = {
124 { RenderFit::CENTER, Rosen::Gravity::CENTER },
125 { RenderFit::TOP, Rosen::Gravity::TOP },
126 { RenderFit::BOTTOM, Rosen::Gravity::BOTTOM },
127 { RenderFit::LEFT, Rosen::Gravity::LEFT },
128 { RenderFit::RIGHT, Rosen::Gravity::RIGHT },
129 { RenderFit::TOP_LEFT, Rosen::Gravity::TOP_LEFT },
130 { RenderFit::TOP_RIGHT, Rosen::Gravity::TOP_RIGHT },
131 { RenderFit::BOTTOM_LEFT, Rosen::Gravity::BOTTOM_LEFT },
132 { RenderFit::BOTTOM_RIGHT, Rosen::Gravity::BOTTOM_RIGHT },
133 { RenderFit::RESIZE_FILL, Rosen::Gravity::RESIZE },
134 { RenderFit::RESIZE_CONTAIN, Rosen::Gravity::RESIZE_ASPECT },
135 { RenderFit::RESIZE_CONTAIN_TOP_LEFT, Rosen::Gravity::RESIZE_ASPECT_TOP_LEFT },
136 { RenderFit::RESIZE_CONTAIN_BOTTOM_RIGHT, Rosen::Gravity::RESIZE_ASPECT_BOTTOM_RIGHT },
137 { RenderFit::RESIZE_COVER, Rosen::Gravity::RESIZE_ASPECT_FILL },
138 { RenderFit::RESIZE_COVER_TOP_LEFT, Rosen::Gravity::RESIZE_ASPECT_FILL_TOP_LEFT },
139 { RenderFit::RESIZE_COVER_BOTTOM_RIGHT, Rosen::Gravity::RESIZE_ASPECT_FILL_BOTTOM_RIGHT },
140 };
141 int64_t idx = BinarySearchFindIndex(gravityMap, ArraySize(gravityMap), renderFit);
142 return idx != -1 ? gravityMap[idx].value : Rosen::Gravity::DEFAULT;
143 }
144 } // namespace
145
ConvertDimensionToScaleBySize(const Dimension & dimension,float size)146 float RosenRenderContext::ConvertDimensionToScaleBySize(const Dimension& dimension, float size)
147 {
148 if (dimension.Unit() == DimensionUnit::PERCENT) {
149 return static_cast<float>(dimension.Value());
150 }
151 return size > 0.0f ? static_cast<float>(dimension.ConvertToPx() / size) : 0.5f;
152 }
153
~RosenRenderContext()154 RosenRenderContext::~RosenRenderContext()
155 {
156 StopRecordingIfNeeded();
157 if (transitionEffect_) {
158 transitionEffect_->Detach(this);
159 }
160 }
161
StartRecording()162 void RosenRenderContext::StartRecording()
163 {
164 CHECK_NULL_VOID(rsNode_);
165 auto rsCanvasNode = rsNode_->ReinterpretCastTo<Rosen::RSCanvasNode>();
166 CHECK_NULL_VOID_NOLOG(rsCanvasNode);
167 rsCanvasNode->BeginRecording(ceil(rsCanvasNode->GetPaintWidth()), ceil(rsCanvasNode->GetPaintHeight()));
168 }
169
StopRecordingIfNeeded()170 void RosenRenderContext::StopRecordingIfNeeded()
171 {
172 auto rsCanvasNode = Rosen::RSNode::ReinterpretCast<Rosen::RSCanvasNode>(rsNode_);
173 if (rsCanvasNode) {
174 rsCanvasNode->FinishRecording();
175 }
176 }
177
OnNodeAppear(bool recursive)178 void RosenRenderContext::OnNodeAppear(bool recursive)
179 {
180 isDisappearing_ = false;
181 auto host = GetHost();
182 CHECK_NULL_VOID(host);
183 // restore eventHub state when node appears.
184 host->GetEventHub<EventHub>()->RestoreEnabled();
185 if (recursive && !propTransitionAppearing_ && !transitionEffect_) {
186 // recursive and has no transition, no need to handle transition.
187 return;
188 }
189
190 isBreakingPoint_ = !recursive;
191 if (isSynced_) {
192 // has set size before, trigger transition directly.
193 auto rect = GetPaintRectWithoutTransform();
194 NotifyTransitionInner(rect.GetSize(), true);
195 return;
196 }
197 // pending transition in animation, will start on first layout
198 firstTransitionIn_ = true;
199 }
200
OnNodeDisappear(bool recursive)201 void RosenRenderContext::OnNodeDisappear(bool recursive)
202 {
203 isDisappearing_ = true;
204 bool noneOrDefaultTransition = !propTransitionDisappearing_ && (!transitionEffect_ || hasDefaultTransition_);
205 if (recursive && noneOrDefaultTransition) {
206 // recursive, and has no transition or has default transition, no need to trigger transition.
207 return;
208 }
209 CHECK_NULL_VOID(rsNode_);
210 auto host = GetHost();
211 if (!recursive && host && host->GetEventHub<EventHub>()) {
212 host->GetEventHub<EventHub>()->SetEnabledInternal(false);
213 }
214 auto rect = GetPaintRectWithoutTransform();
215 // only start default transition on the break point of render node tree.
216 isBreakingPoint_ = !recursive;
217 NotifyTransitionInner(rect.GetSize(), false);
218 }
219
SetPivot(float xPivot,float yPivot,float zPivot)220 void RosenRenderContext::SetPivot(float xPivot, float yPivot, float zPivot)
221 {
222 // change pivot without animation
223 CHECK_NULL_VOID(rsNode_);
224 if (pivotProperty_) {
225 pivotProperty_->Set({ xPivot, yPivot });
226 } else {
227 pivotProperty_ = std::make_shared<Rosen::RSProperty<Rosen::Vector2f>>(Rosen::Vector2f(xPivot, yPivot));
228 auto modifier = std::make_shared<Rosen::RSPivotModifier>(pivotProperty_);
229 rsNode_->AddModifier(modifier);
230 }
231 rsNode_->SetPivotZ(zPivot);
232 }
233
SetTransitionPivot(const SizeF & frameSize,bool transitionIn)234 void RosenRenderContext::SetTransitionPivot(const SizeF& frameSize, bool transitionIn)
235 {
236 auto& transitionEffect = transitionIn ? propTransitionAppearing_ : propTransitionDisappearing_;
237 CHECK_NULL_VOID_NOLOG(transitionEffect);
238 float xPivot = 0.0f;
239 float yPivot = 0.0f;
240 float zPivot = 0.0f;
241 if (transitionEffect->HasRotate()) {
242 xPivot = ConvertDimensionToScaleBySize(transitionEffect->GetRotateValue().centerX, frameSize.Width());
243 yPivot = ConvertDimensionToScaleBySize(transitionEffect->GetRotateValue().centerY, frameSize.Height());
244 zPivot = static_cast<float>(transitionEffect->GetRotateValue().centerZ.ConvertToVp());
245 } else if (transitionEffect->HasScale()) {
246 xPivot = ConvertDimensionToScaleBySize(transitionEffect->GetScaleValue().centerX, frameSize.Width());
247 yPivot = ConvertDimensionToScaleBySize(transitionEffect->GetScaleValue().centerY, frameSize.Height());
248 } else {
249 return;
250 }
251 SetPivot(xPivot, yPivot, zPivot);
252 }
253
SetSurfaceChangedCallBack(const std::function<void (float,float,float,float)> & callback)254 void RosenRenderContext::SetSurfaceChangedCallBack(
255 const std::function<void(float, float, float, float)>& callback)
256 {
257 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
258 if (rsNode_) {
259 RSRenderThread::Instance().AddSurfaceChangedCallBack(rsNode_->GetId(), callback);
260 }
261 #endif
262 }
263
RemoveSurfaceChangedCallBack()264 void RosenRenderContext::RemoveSurfaceChangedCallBack()
265 {
266 #if defined(ANDROID_PLATFORM) || defined(IOS_PLATFORM)
267 if (rsNode_) {
268 RSRenderThread::Instance().RemoveSurfaceChangedCallBack(rsNode_->GetId());
269 }
270 #endif
271 }
272
InitContext(bool isRoot,const std::optional<ContextParam> & param)273 void RosenRenderContext::InitContext(bool isRoot, const std::optional<ContextParam>& param)
274 {
275 // skip if node already created
276 CHECK_NULL_VOID_NOLOG(!rsNode_);
277 if (isRoot) {
278 rsNode_ = Rosen::RSRootNode::Create();
279 return;
280 } else if (!param.has_value()) {
281 rsNode_ = Rosen::RSCanvasNode::Create();
282 return;
283 }
284
285 // create proper RSNode base on input
286 switch (param->type) {
287 case ContextType::CANVAS:
288 rsNode_ = Rosen::RSCanvasNode::Create();
289 break;
290 case ContextType::ROOT:
291 rsNode_ = Rosen::RSRootNode::Create();
292 break;
293 case ContextType::SURFACE: {
294 Rosen::RSSurfaceNodeConfig surfaceNodeConfig = { .SurfaceNodeName = param->surfaceName.value_or("") };
295 rsNode_ = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, false);
296 break;
297 }
298 case ContextType::HARDWARE_SURFACE: {
299 Rosen::RSSurfaceNodeConfig surfaceNodeConfig = { .SurfaceNodeName = param->surfaceName.value_or("") };
300 auto surfaceNode = Rosen::RSSurfaceNode::Create(surfaceNodeConfig, false);
301 if (surfaceNode) {
302 surfaceNode->SetHardwareEnabled(true);
303 }
304 rsNode_ = surfaceNode;
305 break;
306 }
307 case ContextType::EFFECT:
308 rsNode_ = Rosen::RSEffectNode::Create();
309 break;
310 case ContextType::INCREMENTAL_CANVAS:
311 rsNode_ = Rosen::RSCanvasDrawingNode::Create();
312 break;
313 case ContextType::EXTERNAL:
314 break;
315 default:
316 LOGE("invalid context type");
317 break;
318 }
319 }
320
SetSandBox(const std::optional<OffsetF> & parentPosition)321 void RosenRenderContext::SetSandBox(const std::optional<OffsetF>& parentPosition)
322 {
323 CHECK_NULL_VOID(rsNode_);
324 if (parentPosition.has_value()) {
325 sandBoxCount_++;
326 Rosen::Vector2f value = { parentPosition.value().GetX(), parentPosition.value().GetY() };
327 rsNode_->SetSandBox(value);
328 } else {
329 sandBoxCount_--;
330 if (sandBoxCount_ > 0) {
331 return;
332 }
333 sandBoxCount_ = 0;
334 rsNode_->SetSandBox(std::nullopt);
335 }
336 }
337
SyncGeometryProperties(GeometryNode *)338 void RosenRenderContext::SyncGeometryProperties(GeometryNode* /*geometryNode*/)
339 {
340 CHECK_NULL_VOID(rsNode_);
341 auto paintRect = AdjustPaintRect();
342 SyncGeometryProperties(paintRect);
343 }
344
SyncGeometryProperties(const RectF & paintRect)345 void RosenRenderContext::SyncGeometryProperties(const RectF& paintRect)
346 {
347 CHECK_NULL_VOID(rsNode_);
348 if (isDisappearing_ && !paintRect.IsValid()) {
349 return;
350 }
351 rsNode_->SetBounds(paintRect.GetX(), paintRect.GetY(), paintRect.Width(), paintRect.Height());
352 if (useContentRectForRSFrame_) {
353 SetContentRectToFrame(paintRect);
354 } else {
355 rsNode_->SetFrame(paintRect.GetX(), paintRect.GetY(), paintRect.Width(), paintRect.Height());
356 }
357 if (!isSynced_) {
358 isSynced_ = true;
359 auto borderRadius = GetBorderRadius();
360 if (borderRadius.has_value()) {
361 OnBorderRadiusUpdate(borderRadius.value());
362 }
363 }
364
365 if (firstTransitionIn_) {
366 // need to perform transitionIn early so not influence the following SetPivot
367 NotifyTransitionInner(paintRect.GetSize(), true);
368 firstTransitionIn_ = false;
369 }
370
371 if (propTransform_ && propTransform_->HasTransformCenter()) {
372 auto vec = propTransform_->GetTransformCenterValue();
373 float xPivot = ConvertDimensionToScaleBySize(vec.GetX(), paintRect.Width());
374 float yPivot = ConvertDimensionToScaleBySize(vec.GetY(), paintRect.Height());
375 if (vec.GetZ().has_value()) {
376 float zPivot = static_cast<float>(vec.GetZ().value().ConvertToVp());
377 SetPivot(xPivot, yPivot, zPivot);
378 } else {
379 SetPivot(xPivot, yPivot);
380 }
381 }
382
383 if (propTransform_ && propTransform_->HasTransformTranslate()) {
384 // if translate unit is percent, it is related with frameSize
385 OnTransformTranslateUpdate(propTransform_->GetTransformTranslateValue());
386 }
387
388 if (bgLoadingCtx_ && bgImage_) {
389 PaintBackground();
390 }
391
392 if (bdImageLoadingCtx_ && bdImage_) {
393 PaintBorderImage();
394 }
395
396 if (GetBorderImageGradient()) {
397 PaintBorderImageGradient();
398 }
399
400 if (propGradient_) {
401 PaintGradient(paintRect.GetSize());
402 }
403
404 if (propClip_) {
405 PaintClip(paintRect.GetSize());
406 }
407
408 if (propGraphics_) {
409 PaintGraphics();
410 }
411
412 if (propOverlay_) {
413 PaintOverlayText();
414 }
415
416 if (NeedDebugBoundary() && SystemProperties::GetDebugBoundaryEnabled()) {
417 PaintDebugBoundary();
418 }
419
420 if (propParticleOptionArray_.has_value()) {
421 if (!measureTriggered_ || particleAnimationPlaying_) {
422 measureTriggered_ = true;
423 OnParticleOptionArrayUpdate(propParticleOptionArray_.value());
424 }
425 }
426 }
427
PaintDebugBoundary()428 void RosenRenderContext::PaintDebugBoundary()
429 {
430 CHECK_NULL_VOID(rsNode_);
431 auto host = GetHost();
432 CHECK_NULL_VOID(host);
433 auto geometryNode = host->GetGeometryNode();
434 auto paintTask = [contentSize = geometryNode->GetFrameSize(), frameSize = geometryNode->GetMarginFrameSize(),
435 offset = geometryNode->GetMarginFrameOffset(),
436 frameOffset = geometryNode->GetFrameOffset()](RSCanvas& rsCanvas) mutable {
437 DebugBoundaryPainter painter(contentSize, frameSize);
438 painter.SetFrameOffset(frameOffset);
439 painter.DrawDebugBoundaries(rsCanvas, offset);
440 };
441
442 if (!debugBoundaryModifier_ && rsNode_->IsInstanceOf<Rosen::RSCanvasNode>()) {
443 debugBoundaryModifier_ = std::make_shared<DebugBoundaryModifier>();
444 debugBoundaryModifier_->SetPaintTask(std::move(paintTask));
445 rsNode_->AddModifier(debugBoundaryModifier_);
446 }
447 if (debugBoundaryModifier_) {
448 debugBoundaryModifier_->SetCustomData(true);
449 }
450 }
451
OnBackgroundColorUpdate(const Color & value)452 void RosenRenderContext::OnBackgroundColorUpdate(const Color& value)
453 {
454 CHECK_NULL_VOID(rsNode_);
455 rsNode_->SetBackgroundColor(value.GetValue());
456 RequestNextFrame();
457 }
458
OnForegroundColorUpdate(const Color & value)459 void RosenRenderContext::OnForegroundColorUpdate(const Color& value)
460 {
461 CHECK_NULL_VOID(rsNode_);
462 rsNode_->SetEnvForegroundColor(value.GetValue());
463 RequestNextFrame();
464 }
465
OnForegroundColorStrategyUpdate(const ForegroundColorStrategy & value)466 void RosenRenderContext::OnForegroundColorStrategyUpdate(const ForegroundColorStrategy& value)
467 {
468 CHECK_NULL_VOID(rsNode_);
469 Rosen::ForegroundColorStrategyType rsStrategy = Rosen::ForegroundColorStrategyType::INVALID;
470 switch (value) {
471 case ForegroundColorStrategy::INVERT:
472 rsStrategy = Rosen::ForegroundColorStrategyType::INVERT_BACKGROUNDCOLOR;
473 break;
474 default:
475 break;
476 }
477 rsNode_->SetEnvForegroundColorStrategy(rsStrategy);
478 RequestNextFrame();
479 }
480
CreateBgImageDataReadyCallback()481 DataReadyNotifyTask RosenRenderContext::CreateBgImageDataReadyCallback()
482 {
483 auto task = [weak = WeakClaim(this)](const ImageSourceInfo& sourceInfo) {
484 auto rosenRenderContext = weak.Upgrade();
485 CHECK_NULL_VOID(rosenRenderContext);
486 auto imageSourceInfo = rosenRenderContext->GetBackgroundImage().value_or(ImageSourceInfo(""));
487 if (imageSourceInfo != sourceInfo) {
488 LOGW("sourceInfo does not match, ignore current callback. current: %{public}s vs callback's: %{public}s",
489 imageSourceInfo.ToString().c_str(), sourceInfo.ToString().c_str());
490 return;
491 }
492 LOGD("bgImage data ready %{public}s", sourceInfo.ToString().c_str());
493 rosenRenderContext->bgLoadingCtx_->MakeCanvasImage(SizeF(), true, ImageFit::NONE);
494 };
495 return task;
496 }
497
CreateBgImageLoadSuccessCallback()498 LoadSuccessNotifyTask RosenRenderContext::CreateBgImageLoadSuccessCallback()
499 {
500 auto task = [weak = WeakClaim(this)](const ImageSourceInfo& sourceInfo) {
501 auto ctx = weak.Upgrade();
502 CHECK_NULL_VOID(ctx);
503 auto imageSourceInfo = ctx->GetBackgroundImage().value_or(ImageSourceInfo(""));
504 if (imageSourceInfo != sourceInfo) {
505 LOGW("sourceInfo does not match, ignore current callback. current: %{public}s vs callback's: %{public}s",
506 imageSourceInfo.ToString().c_str(), sourceInfo.ToString().c_str());
507 return;
508 }
509 ctx->bgImage_ = ctx->bgLoadingCtx_->MoveCanvasImage();
510 CHECK_NULL_VOID(ctx->bgImage_);
511 LOGI("bgImage load success %{public}s", sourceInfo.ToString().c_str());
512 if (ctx->GetHost()->GetGeometryNode()->GetFrameSize().IsPositive()) {
513 ctx->PaintBackground();
514 ctx->RequestNextFrame();
515 }
516 };
517 return task;
518 }
519
PaintBackground()520 void RosenRenderContext::PaintBackground()
521 {
522 if (InstanceOf<PixelMapImage>(bgImage_)) {
523 PaintPixmapBgImage();
524 #ifndef USE_ROSEN_DRAWING
525 } else if (InstanceOf<SkiaImage>(bgImage_)) {
526 PaintSkBgImage();
527 #else
528 } else if (InstanceOf<DrawingImage>(bgImage_)) {
529 PaintRSBgImage();
530 #endif
531 } else {
532 return;
533 }
534
535 SizeF renderSize = ImagePainter::CalculateBgImageSize(
536 GetHost()->GetGeometryNode()->GetFrameSize(), bgLoadingCtx_->GetImageSize(), GetBackgroundImageSize());
537 OffsetF positionOffset = ImagePainter::CalculateBgImagePosition(
538 GetHost()->GetGeometryNode()->GetFrameSize(), renderSize, GetBackgroundImagePosition());
539 rsNode_->SetBgImageWidth(renderSize.Width());
540 rsNode_->SetBgImageHeight(renderSize.Height());
541 rsNode_->SetBgImagePositionX(positionOffset.GetX());
542 rsNode_->SetBgImagePositionY(positionOffset.GetY());
543 }
544
OnBackgroundImageUpdate(const ImageSourceInfo & src)545 void RosenRenderContext::OnBackgroundImageUpdate(const ImageSourceInfo& src)
546 {
547 CHECK_NULL_VOID(rsNode_);
548 if (src.GetSrc().empty()) {
549 return;
550 }
551 if (!bgLoadingCtx_ || src != bgLoadingCtx_->GetSourceInfo()) {
552 LoadNotifier bgLoadNotifier(CreateBgImageDataReadyCallback(), CreateBgImageLoadSuccessCallback(), nullptr);
553 bgLoadingCtx_ = AceType::MakeRefPtr<ImageLoadingContext>(src, std::move(bgLoadNotifier));
554 CHECK_NULL_VOID(bgLoadingCtx_);
555 bgLoadingCtx_->LoadImageData();
556 }
557 }
558
OnBackgroundImageRepeatUpdate(const ImageRepeat &)559 void RosenRenderContext::OnBackgroundImageRepeatUpdate(const ImageRepeat& /*imageRepeat*/)
560 {
561 CHECK_NULL_VOID(rsNode_);
562 PaintBackground();
563 }
564
OnBackgroundImageSizeUpdate(const BackgroundImageSize &)565 void RosenRenderContext::OnBackgroundImageSizeUpdate(const BackgroundImageSize& /*bgImgSize*/)
566 {
567 CHECK_NULL_VOID(rsNode_);
568 PaintBackground();
569 }
570
OnBackgroundImagePositionUpdate(const BackgroundImagePosition &)571 void RosenRenderContext::OnBackgroundImagePositionUpdate(const BackgroundImagePosition& /*bgImgPosition*/)
572 {
573 CHECK_NULL_VOID(rsNode_);
574 PaintBackground();
575 }
576
SetBackBlurFilter()577 void RosenRenderContext::SetBackBlurFilter()
578 {
579 auto context = PipelineBase::GetCurrentContext();
580 CHECK_NULL_VOID(context);
581 const auto& background = GetBackground();
582 CHECK_NULL_VOID(background);
583 const auto& blurStyle = background->propBlurStyleOption;
584 std::shared_ptr<Rosen::RSFilter> backFilter;
585 auto dipScale_ = context->GetDipScale();
586 if (!blurStyle.has_value()) {
587 const auto& radius = background->propBlurRadius;
588 if (radius.has_value() && radius->IsValid()) {
589 float radiusPx = context->NormalizeToPx(radius.value());
590 #ifndef USE_ROSEN_DRAWING
591 float backblurRadius = SkiaDecorationPainter::ConvertRadiusToSigma(radiusPx);
592 #else
593 float backblurRadius = DrawingDecorationPainter::ConvertRadiusToSigma(radiusPx);
594 #endif
595 backFilter = Rosen::RSFilter::CreateBlurFilter(backblurRadius, backblurRadius);
596 }
597 } else if (GetRosenBlurStyleValue(blurStyle.value()) == MATERIAL_BLUR_STYLE::NO_MATERIAL) {
598 backFilter = nullptr;
599 } else {
600 backFilter = Rosen::RSFilter::CreateMaterialFilter(static_cast<int>(GetRosenBlurStyleValue(blurStyle.value())),
601 static_cast<float>(dipScale_), static_cast<Rosen::BLUR_COLOR_MODE>(blurStyle->adaptiveColor),
602 static_cast<float>(blurStyle->scale));
603 }
604 rsNode_->SetBackgroundFilter(backFilter);
605 }
606
SetFrontBlurFilter()607 void RosenRenderContext::SetFrontBlurFilter()
608 {
609 auto context = PipelineBase::GetCurrentContext();
610 CHECK_NULL_VOID(context);
611 const auto& foreground = GetForeground();
612 CHECK_NULL_VOID(foreground);
613 const auto& blurStyle = foreground->propBlurStyleOption;
614 std::shared_ptr<Rosen::RSFilter> frontFilter;
615 auto dipScale_ = context->GetDipScale();
616 if (!blurStyle.has_value()) {
617 const auto& radius = foreground->propBlurRadius;
618 if (radius.has_value() && radius->IsValid()) {
619 float radiusPx = context->NormalizeToPx(radius.value());
620 #ifndef USE_ROSEN_DRAWING
621 float backblurRadius = SkiaDecorationPainter::ConvertRadiusToSigma(radiusPx);
622 #else
623 float backblurRadius = DrawingDecorationPainter::ConvertRadiusToSigma(radiusPx);
624 #endif
625 frontFilter = Rosen::RSFilter::CreateBlurFilter(backblurRadius, backblurRadius);
626 }
627 } else if (GetRosenBlurStyleValue(blurStyle.value()) == MATERIAL_BLUR_STYLE::NO_MATERIAL) {
628 frontFilter = nullptr;
629 } else {
630 frontFilter = Rosen::RSFilter::CreateMaterialFilter(static_cast<int>(GetRosenBlurStyleValue(blurStyle.value())),
631 static_cast<float>(dipScale_), static_cast<Rosen::BLUR_COLOR_MODE>(blurStyle->adaptiveColor),
632 static_cast<float>(blurStyle->scale));
633 }
634
635 rsNode_->SetFilter(frontFilter);
636 }
637
UpdateBackBlurStyle(const std::optional<BlurStyleOption> & bgBlurStyle)638 void RosenRenderContext::UpdateBackBlurStyle(const std::optional<BlurStyleOption>& bgBlurStyle)
639 {
640 const auto& groupProperty = GetOrCreateBackground();
641 if (groupProperty->CheckBlurStyleOption(bgBlurStyle)) {
642 // Same with previous value.
643 // If colorMode is following system and has valid blurStyle, still needs updating
644 if (bgBlurStyle->colorMode != ThemeColorMode::SYSTEM) {
645 return;
646 }
647 } else {
648 groupProperty->propBlurStyleOption = bgBlurStyle;
649 }
650 SetBackBlurFilter();
651 }
652
UpdateBackgroundEffect(const std::optional<EffectOption> & effectOption)653 void RosenRenderContext::UpdateBackgroundEffect(const std::optional<EffectOption>& effectOption)
654 {
655 const auto& groupProperty = GetOrCreateBackground();
656 if (groupProperty->CheckEffectOption(effectOption)) {
657 return;
658 }
659 groupProperty->propEffectOption = effectOption;
660 if (!effectOption.has_value()) {
661 return;
662 }
663 auto context = PipelineBase::GetCurrentContext();
664 CHECK_NULL_VOID(context);
665 float radiusPx = context->NormalizeToPx(effectOption->radius);
666 #ifndef USE_ROSEN_DRAWING
667 float backblurRadius = SkiaDecorationPainter::ConvertRadiusToSigma(radiusPx);
668 #else
669 float backblurRadius = DrawingDecorationPainter::ConvertRadiusToSigma(radiusPx);
670 #endif
671 std::shared_ptr<Rosen::RSFilter> backFilter = Rosen::RSFilter::CreateMaterialFilter(
672 backblurRadius, static_cast<float>(effectOption->saturation),
673 static_cast<float>(effectOption->brightness), effectOption->color.GetValue());
674 rsNode_->SetBackgroundFilter(backFilter);
675 }
676
UpdateFrontBlurStyle(const std::optional<BlurStyleOption> & fgBlurStyle)677 void RosenRenderContext::UpdateFrontBlurStyle(const std::optional<BlurStyleOption>& fgBlurStyle)
678 {
679 const auto& groupProperty = GetOrCreateForeground();
680 if (groupProperty->CheckBlurStyleOption(fgBlurStyle)) {
681 // Same with previous value.
682 // If colorMode is following system and has valid blurStyle, still needs updating
683 if (fgBlurStyle->colorMode != ThemeColorMode::SYSTEM) {
684 return;
685 }
686 } else {
687 groupProperty->propBlurStyleOption = fgBlurStyle;
688 }
689 SetFrontBlurFilter();
690 }
691
ResetBackBlurStyle()692 void RosenRenderContext::ResetBackBlurStyle()
693 {
694 const auto& groupProperty = GetOrCreateBackground();
695 groupProperty->propBlurStyleOption.reset();
696 SetBackBlurFilter();
697 }
698
OnSphericalEffectUpdate(double radio)699 void RosenRenderContext::OnSphericalEffectUpdate(double radio)
700 {
701 CHECK_NULL_VOID(rsNode_);
702 rsNode_->SetSpherizeDegree(static_cast<float>(radio));
703 RequestNextFrame();
704 }
705
OnPixelStretchEffectUpdate(const PixStretchEffectOption & option)706 void RosenRenderContext::OnPixelStretchEffectUpdate(const PixStretchEffectOption& option)
707 {
708 CHECK_NULL_VOID(rsNode_);
709 Rosen::Vector4f pixStretchVector;
710 if (option.IsPercentOption()) {
711 pixStretchVector.SetValues(static_cast<float>(option.left.Value()), static_cast<float>(option.top.Value()),
712 static_cast<float>(option.right.Value()), static_cast<float>(option.bottom.Value()));
713 rsNode_->SetPixelStretchPercent(pixStretchVector);
714 } else {
715 pixStretchVector.SetValues(static_cast<float>(option.left.ConvertToPx()),
716 static_cast<float>(option.top.ConvertToPx()), static_cast<float>(option.right.ConvertToPx()),
717 static_cast<float>(option.bottom.ConvertToPx()));
718 rsNode_->SetPixelStretch(pixStretchVector);
719 }
720 RequestNextFrame();
721 }
722
OnLightUpEffectUpdate(double radio)723 void RosenRenderContext::OnLightUpEffectUpdate(double radio)
724 {
725 CHECK_NULL_VOID(rsNode_);
726 rsNode_->SetLightUpEffectDegree(static_cast<float>(radio));
727 RequestNextFrame();
728 }
729
OnParticleOptionArrayUpdate(const std::list<ParticleOption> & optionList)730 void RosenRenderContext::OnParticleOptionArrayUpdate(const std::list<ParticleOption>& optionList)
731 {
732 CHECK_NULL_VOID(rsNode_);
733 RectF rect = GetPaintRectWithoutTransform();
734 if (rect.IsEmpty()) {
735 return;
736 }
737 if (NeedPreloadImage(optionList, rect)) {
738 return;
739 }
740 particleAnimationPlaying_ = true;
741 std::vector<OHOS::Rosen::ParticleParams> particleParams;
742 for (auto& item : optionList) {
743 particleParams.emplace_back(ConvertParticleOptionToParams(item, rect));
744 }
745 auto finishCallback = [weak = WeakClaim(this)]() {
746 auto renderContext = weak.Upgrade();
747 CHECK_NULL_VOID(renderContext);
748 renderContext->particleAnimationPlaying_ = false;
749 };
750 rsNode_->SetParticleParams(particleParams, finishCallback);
751 RequestNextFrame();
752 }
753
NeedPreloadImage(const std::list<ParticleOption> & optionList,RectF & rect)754 bool RosenRenderContext::NeedPreloadImage(const std::list<ParticleOption>& optionList, RectF& rect)
755 {
756 bool flag = false;
757 std::vector<OHOS::Rosen::ParticleParams> particleParams;
758 for (auto& item : optionList) {
759 auto emitterOption = item.GetEmitterOption();
760 auto particle = emitterOption.GetParticle();
761 auto particleType = particle.GetParticleType();
762 auto particleConfig = particle.GetConfig();
763 if (particleType == ParticleType::IMAGE) {
764 auto imageParameter = particleConfig.GetImageParticleParameter();
765 auto imageSize = imageParameter.GetSize();
766 auto imageWidth = Dimension(ConvertDimensionToPx(imageSize.first, rect.Width()), DimensionUnit::PX);
767 auto imageHeight = Dimension(ConvertDimensionToPx(imageSize.second, rect.Height()), DimensionUnit::PX);
768 if (particleImageMap_.find(imageParameter.GetImageSource()) == particleImageMap_.end()) {
769 LoadParticleImage(imageParameter.GetImageSource(), imageWidth, imageHeight);
770 flag = true;
771 }
772 }
773 }
774 return flag;
775 }
776
ConvertParticleOptionToParams(const ParticleOption & particleOption,const RectF & rect)777 Rosen::ParticleParams RosenRenderContext::ConvertParticleOptionToParams(
778 const ParticleOption& particleOption, const RectF& rect)
779 {
780 auto emitterOption = particleOption.GetEmitterOption();
781 auto colorOptionOpt = particleOption.GetParticleColorOption();
782 auto opacityOptionOpt = particleOption.GetParticleOpacityOption();
783 auto scaleOptionOpt = particleOption.GetParticleScaleOption();
784 auto velocityOptionOpt = particleOption.GetParticleVelocityOption();
785 auto accelerationOpt = particleOption.GetParticleAccelerationOption();
786 auto spinOptionOpt = particleOption.GetParticleSpinOption();
787 auto rsEmitterConfig = ConvertParticleEmitterOption(emitterOption, rect);
788 std::optional<OHOS::Rosen::ParticleColorParaType> rsColorOpt;
789 std::optional<OHOS::Rosen::ParticleParaType<float>> rsSpinOpt;
790 std::optional<OHOS::Rosen::ParticleVelocity> rsVelocityOpt;
791 std::optional<OHOS::Rosen::ParticleParaType<float>> rsOpacityOpt;
792 std::optional<OHOS::Rosen::ParticleParaType<float>> rsScaleOpt;
793 std::optional<OHOS::Rosen::ParticleAcceleration> rsAccelerationOpt;
794 if (colorOptionOpt.has_value()) {
795 rsColorOpt = ConvertParticleColorOption(colorOptionOpt.value());
796 } else {
797 rsColorOpt = ConvertParticleDefaultColorOption(std::nullopt);
798 }
799 if (opacityOptionOpt.has_value()) {
800 rsOpacityOpt = ConvertParticleFloatOption(opacityOptionOpt.value());
801 } else {
802 OHOS::Rosen::Range<float> rsInitRange(PARTICLE_DEFAULT_OPACITY, PARTICLE_DEFAULT_OPACITY);
803 rsOpacityOpt = ConvertParticleDefaultFloatOption(rsInitRange);
804 }
805 if (scaleOptionOpt.has_value()) {
806 rsScaleOpt = ConvertParticleFloatOption(scaleOptionOpt.value());
807 } else {
808 OHOS::Rosen::Range<float> rsInitRange(PARTICLE_DEFAULT_SCALE, PARTICLE_DEFAULT_SCALE);
809 rsScaleOpt = ConvertParticleDefaultFloatOption(rsInitRange);
810 }
811 if (velocityOptionOpt.has_value()) {
812 rsVelocityOpt = ConvertParticleVelocityOption(velocityOptionOpt.value());
813 } else {
814 rsVelocityOpt = ConvertParticleDefaultVelocityOption();
815 }
816 if (accelerationOpt.has_value()) {
817 rsAccelerationOpt = ConvertParticleAccelerationOption(accelerationOpt.value());
818 } else {
819 rsAccelerationOpt = ConvertParticleDefaultAccelerationOption();
820 }
821 if (spinOptionOpt.has_value()) {
822 rsSpinOpt = ConvertParticleFloatOption(spinOptionOpt.value());
823 } else {
824 OHOS::Rosen::Range<float> rsInitRange(PARTICLE_DEFAULT_SPIN, PARTICLE_DEFAULT_SPIN);
825 rsSpinOpt = ConvertParticleDefaultFloatOption(rsInitRange);
826 }
827 return OHOS::Rosen::ParticleParams(rsEmitterConfig, rsVelocityOpt.value(), rsAccelerationOpt.value(),
828 rsColorOpt.value(), rsOpacityOpt.value(), rsScaleOpt.value(), rsSpinOpt.value());
829 }
830
ConvertParticleEmitterOption(const EmitterOption & emitterOption,const RectF & rect)831 Rosen::EmitterConfig RosenRenderContext::ConvertParticleEmitterOption(
832 const EmitterOption& emitterOption, const RectF& rect)
833 {
834 auto emitterRateOpt = emitterOption.GetEmitterRate();
835 auto pointOpt = emitterOption.GetPosition();
836 auto sizeOpt = emitterOption.GetSize();
837 auto shapeOpt = emitterOption.GetShape();
838 auto particle = emitterOption.GetParticle();
839 auto particleType = particle.GetParticleType();
840 auto particleConfig = particle.GetConfig();
841 auto particleCount = particle.GetCount();
842 auto lifeTimeOpt = particle.GetLifeTime();
843 auto rsPoint = pointOpt.has_value()
844 ? OHOS::Rosen::Vector2f(ConvertDimensionToPx(pointOpt.value().first, rect.Width()),
845 ConvertDimensionToPx(pointOpt.value().second, rect.Height()))
846 : OHOS::Rosen::Vector2f(0.0f, 0.0f);
847 auto rsSize = sizeOpt.has_value() ? OHOS::Rosen::Vector2f(ConvertDimensionToPx(sizeOpt.value().first, rect.Width()),
848 ConvertDimensionToPx(sizeOpt.value().second, rect.Height()))
849 : OHOS::Rosen::Vector2f(rect.Width(), rect.Height());
850 auto shapeInt = static_cast<int32_t>(shapeOpt.value_or(ParticleEmitterShape::RECTANGLE));
851 if (particleType == ParticleType::IMAGE) {
852 auto imageParameter = particleConfig.GetImageParticleParameter();
853 auto imageSource = imageParameter.GetImageSource();
854 auto imageSize = imageParameter.GetSize();
855 auto imageWidth = Dimension(ConvertDimensionToPx(imageSize.first, rect.Width()), DimensionUnit::PX);
856 auto imageHeight = Dimension(ConvertDimensionToPx(imageSize.second, rect.Height()), DimensionUnit::PX);
857 auto rsImagePtr = std::make_shared<Rosen::RSImage>();
858 if (particleImageMap_.find(imageSource) != particleImageMap_.end()) {
859 SetRsParticleImage(rsImagePtr, imageSource);
860 }
861 rsImagePtr->SetImageFit(static_cast<int32_t>(imageParameter.GetImageFit().value_or(ImageFit::COVER)));
862 OHOS::Rosen::Vector2f rsImageSize(imageWidth.ConvertToPx(), imageHeight.ConvertToPx());
863 return OHOS::Rosen::EmitterConfig(emitterRateOpt.value_or(PARTICLE_DEFAULT_EMITTER_RATE),
864 static_cast<OHOS::Rosen::ShapeType>(shapeInt), rsPoint, rsSize, particleCount,
865 lifeTimeOpt.value_or(PARTICLE_DEFAULT_LIFETIME), OHOS::Rosen::ParticleType::IMAGES, 0.0f, rsImagePtr,
866 rsImageSize);
867 } else {
868 auto pointParameter = particleConfig.GetPointParticleParameter();
869 auto radius = pointParameter.GetRadius();
870 return OHOS::Rosen::EmitterConfig(emitterRateOpt.value_or(PARTICLE_DEFAULT_EMITTER_RATE),
871 static_cast<OHOS::Rosen::ShapeType>(shapeInt), rsPoint, rsSize, particleCount,
872 lifeTimeOpt.value_or(PARTICLE_DEFAULT_LIFETIME), OHOS::Rosen::ParticleType::POINTS, radius,
873 std::make_shared<OHOS::Rosen::RSImage>(), OHOS::Rosen::Vector2f());
874 }
875 }
876
SetRsParticleImage(std::shared_ptr<Rosen::RSImage> & rsImagePtr,std::string & imageSource)877 void RosenRenderContext::SetRsParticleImage(std::shared_ptr<Rosen::RSImage>& rsImagePtr, std::string& imageSource)
878 {
879 if (particleImageMap_.find(imageSource) == particleImageMap_.end()) {
880 return;
881 }
882 auto image = particleImageMap_[imageSource];
883 CHECK_NULL_VOID_NOLOG(image);
884
885 if (InstanceOf<PixelMapImage>(image)) {
886 auto pixmap = image->GetPixelMap();
887 CHECK_NULL_VOID_NOLOG(pixmap);
888 auto pixMapPtr = pixmap->GetPixelMapSharedPtr();
889 rsImagePtr->SetPixelMap(pixMapPtr);
890 if (pixMapPtr) {
891 rsImagePtr->SetSrcRect(Rosen::RectF(0, 0, pixMapPtr->GetWidth(), pixMapPtr->GetHeight()));
892 }
893 #ifndef USE_ROSEN_DRAWING
894 } else if (InstanceOf<SkiaImage>(image)) {
895 auto skiaImage = DynamicCast<SkiaImage>(image);
896 CHECK_NULL_VOID_NOLOG(skiaImage);
897 auto compressData = skiaImage->GetCompressData();
898 if (compressData) {
899 rsImagePtr->SetCompressData(
900 compressData, skiaImage->GetUniqueID(), skiaImage->GetCompressWidth(), skiaImage->GetCompressHeight());
901 rsImagePtr->SetSrcRect(Rosen::RectF(0, 0, skiaImage->GetCompressWidth(), skiaImage->GetCompressHeight()));
902 } else {
903 rsImagePtr->SetImage(skiaImage->GetImage());
904 if (skiaImage->GetImage()) {
905 rsImagePtr->SetSrcRect(
906 Rosen::RectF(0, 0, skiaImage->GetImage()->width(), skiaImage->GetImage()->height()));
907 }
908 }
909 rsImagePtr->SetImageRepeat(static_cast<int>(GetBackgroundImageRepeat().value_or(ImageRepeat::NO_REPEAT)));
910 #else
911 } else if (InstanceOf<DrawingImage>(image)) {
912 auto drawingImage = DynamicCast<DrawingImage>(image);
913 CHECK_NULL_VOID_NOLOG(drawingImage);
914 auto compressData = drawingImage->GetCompressData();
915 if (compressData) {
916 rsImagePtr->SetCompressData(compressData, drawingImage->GetUniqueID(), drawingImage->GetCompressWidth(),
917 drawingImage->GetCompressHeight());
918 rsImagePtr->SetSrcRect(
919 Rosen::RectF(0, 0, drawingImage->GetCompressWidth(), drawingImage->GetCompressHeight()));
920 } else {
921 rsImagePtr->SetImage(drawingImage->GetImage());
922 if (drawingImage->GetImage()) {
923 rsImagePtr->SetSrcRect(
924 Rosen::RectF(0, 0, drawingImage->GetImage()->width(), drawingImage->GetImage()->height()));
925 }
926 }
927 rsImagePtr->SetImageRepeat(static_cast<int>(GetBackgroundImageRepeat().value_or(ImageRepeat::NO_REPEAT)));
928 #endif
929 }
930 }
931
LoadParticleImage(const std::string & src,Dimension & width,Dimension & height)932 void RosenRenderContext::LoadParticleImage(const std::string& src, Dimension& width, Dimension& height)
933 {
934 if (particleImageContextMap_.find(src) != particleImageContextMap_.end()) {
935 return;
936 }
937 ImageSourceInfo imageSourceInfo(src, width, height);
938 imageSourceInfo.SetNeedCache(false);
939 auto preLoadCallback = [weak = WeakClaim(this), imageSrc = src](const ImageSourceInfo& sourceInfo) {
940 auto renderContent = weak.Upgrade();
941 CHECK_NULL_VOID(renderContent);
942 auto& imageContext = renderContent->particleImageContextMap_[imageSrc];
943 CHECK_NULL_VOID(imageContext);
944 imageContext->MakeCanvasImage(SizeF(), true, ImageFit::NONE);
945 };
946 auto loadingSuccessCallback = [weak = WeakClaim(this), imageSrc = src](const ImageSourceInfo& sourceInfo) {
947 auto renderContent = weak.Upgrade();
948 CHECK_NULL_VOID(renderContent);
949 auto& imageContext = renderContent->particleImageContextMap_[imageSrc];
950 CHECK_NULL_VOID(imageContext);
951 auto imagePtr = imageContext->MoveCanvasImage();
952 renderContent->OnParticleImageLoaded(imageSrc, imagePtr);
953 };
954 auto loadingErrorCallback = [weak = WeakClaim(this), imageSrc = src](const ImageSourceInfo& sourceInfo) {
955 auto renderContent = weak.Upgrade();
956 CHECK_NULL_VOID(renderContent);
957 renderContent->OnParticleImageLoaded(imageSrc, nullptr);
958 };
959 LoadNotifier loadNotifier(preLoadCallback, loadingSuccessCallback, loadingErrorCallback);
960 auto particleImageLoadingCtx = AceType::MakeRefPtr<ImageLoadingContext>(imageSourceInfo, std::move(loadNotifier));
961 imageSourceInfo.SetSrc(src, Color(0x00000000));
962 particleImageLoadingCtx->LoadImageData();
963 particleImageContextMap_.try_emplace(src, particleImageLoadingCtx);
964 }
965
OnParticleImageLoaded(const std::string & src,RefPtr<CanvasImage> canvasImage)966 void RosenRenderContext::OnParticleImageLoaded(const std::string& src, RefPtr<CanvasImage> canvasImage)
967 {
968 particleImageMap_.try_emplace(src, canvasImage);
969 if (particleImageContextMap_.find(src) != particleImageContextMap_.end()) {
970 particleImageContextMap_.erase(src);
971 }
972 if (particleImageContextMap_.empty() && propParticleOptionArray_.has_value()) {
973 OnParticleOptionArrayUpdate(propParticleOptionArray_.value());
974 }
975 }
976
ConvertDimensionToPx(Dimension & src,float size)977 float RosenRenderContext::ConvertDimensionToPx(Dimension& src, float size)
978 {
979 if (src.Unit() == DimensionUnit::PERCENT) {
980 return src.ConvertToPxWithSize(size);
981 }
982 return src.ConvertToPx();
983 }
984
ConvertParticleVelocityOption(const VelocityProperty & velocity)985 Rosen::ParticleVelocity RosenRenderContext::ConvertParticleVelocityOption(const VelocityProperty& velocity)
986 {
987 auto rsSpeedRange = OHOS::Rosen::Range<float>(velocity.GetSpeedRange().first, velocity.GetSpeedRange().second);
988 auto rsAngleRange = OHOS::Rosen::Range<float>(velocity.GetAngleRange().first, velocity.GetAngleRange().second);
989 return OHOS::Rosen::ParticleVelocity(rsSpeedRange, rsAngleRange);
990 }
991
ConvertParticleDefaultVelocityOption()992 Rosen::ParticleVelocity RosenRenderContext::ConvertParticleDefaultVelocityOption()
993 {
994 auto rsSpeedRange = OHOS::Rosen::Range<float>(PARTICLE_DEFAULT_SPEED, PARTICLE_DEFAULT_SPEED);
995 auto rsAngleRange = OHOS::Rosen::Range<float>(PARTICLE_DEFAULT_ANGLE, PARTICLE_DEFAULT_ANGLE);
996 return OHOS::Rosen::ParticleVelocity(rsSpeedRange, rsAngleRange);
997 }
998
ConvertParticleAccelerationOption(const AccelerationProperty & acceleration)999 Rosen::ParticleAcceleration RosenRenderContext::ConvertParticleAccelerationOption(
1000 const AccelerationProperty& acceleration)
1001 {
1002 auto speedOpt = acceleration.GetSpeed();
1003 auto angleOpt = acceleration.GetAngle();
1004 std::optional<OHOS::Rosen::ParticleParaType<float>> rsSpeedOpt;
1005 std::optional<OHOS::Rosen::ParticleParaType<float>> rsAngleOpt;
1006 OHOS::Rosen::Range<float> rsInitSpeedRange(PARTICLE_DEFAULT_SPEED, PARTICLE_DEFAULT_SPEED);
1007 if (speedOpt.has_value()) {
1008 rsSpeedOpt = ConvertParticleFloatOption(speedOpt.value());
1009 } else {
1010 rsSpeedOpt = ConvertParticleDefaultFloatOption(rsInitSpeedRange);
1011 }
1012 OHOS::Rosen::Range<float> rsInitAngleRange(PARTICLE_DEFAULT_ANGLE, PARTICLE_DEFAULT_ANGLE);
1013 if (angleOpt.has_value()) {
1014 rsAngleOpt = ConvertParticleFloatOption(angleOpt.value());
1015 } else {
1016 rsAngleOpt = ConvertParticleDefaultFloatOption(rsInitAngleRange);
1017 }
1018 return OHOS::Rosen::ParticleAcceleration(rsSpeedOpt.value(), rsAngleOpt.value());
1019 }
1020
ConvertParticleDefaultAccelerationOption()1021 Rosen::ParticleAcceleration RosenRenderContext::ConvertParticleDefaultAccelerationOption()
1022 {
1023 OHOS::Rosen::Range<float> rsInitRange(PARTICLE_DEFAULT_SPEED, PARTICLE_DEFAULT_SPEED);
1024 return OHOS::Rosen::ParticleAcceleration(
1025 ConvertParticleDefaultFloatOption(rsInitRange), ConvertParticleDefaultFloatOption(rsInitRange));
1026 }
1027
ConvertParticleColorOption(const ParticleColorPropertyOption & colorOption)1028 Rosen::ParticleColorParaType RosenRenderContext::ConvertParticleColorOption(
1029 const ParticleColorPropertyOption& colorOption)
1030 {
1031 auto initRange = colorOption.GetRange();
1032 auto updaterOpt = colorOption.GetUpdater();
1033 OHOS::Rosen::Range<OHOS::Rosen::RSColor> rsInitRange(
1034 OHOS::Rosen::RSColor(initRange.first.GetRed(), initRange.first.GetGreen(), initRange.first.GetBlue(),
1035 initRange.first.GetAlpha()),
1036 OHOS::Rosen::RSColor(initRange.second.GetRed(), initRange.second.GetGreen(), initRange.second.GetBlue(),
1037 initRange.second.GetAlpha()));
1038 if (updaterOpt.has_value()) {
1039 auto updater = updaterOpt.value();
1040 auto updateType = updater.GetUpdateType();
1041 auto config = updater.GetConfig();
1042 if (updateType == UpdaterType::RANDOM) {
1043 auto randomConfig = config.GetRandomConfig();
1044 auto redRandom = randomConfig.GetRedRandom();
1045 auto greenRandom = randomConfig.GetGreenRandom();
1046 auto blueRandom = randomConfig.GetBlueRandom();
1047 auto alphaRandom = randomConfig.GetAlphaRandom();
1048 OHOS::Rosen::Range<float> rsRedRandom(redRandom.first, redRandom.second);
1049 OHOS::Rosen::Range<float> rsGreenRandom(greenRandom.first, greenRandom.second);
1050 OHOS::Rosen::Range<float> rsBlueRandom(blueRandom.first, blueRandom.second);
1051 OHOS::Rosen::Range<float> rsAlphaRandom(alphaRandom.first, alphaRandom.second);
1052 std::vector<OHOS::Rosen::Change<OHOS::Rosen::RSColor>> invalidCurve;
1053 return OHOS::Rosen::ParticleColorParaType(rsInitRange, OHOS::Rosen::ParticleUpdator::RANDOM, rsRedRandom,
1054 rsGreenRandom, rsBlueRandom, rsAlphaRandom, invalidCurve);
1055 } else if (updateType == UpdaterType::CURVE) {
1056 auto& curveConfig = config.GetAnimationArray();
1057 std::vector<OHOS::Rosen::Change<OHOS::Rosen::RSColor>> valChangeOverLife;
1058 for (const auto& colorAnimationConfig : curveConfig) {
1059 auto fromColor = colorAnimationConfig.GetFrom();
1060 auto toColor = colorAnimationConfig.GetTo();
1061 auto startMills = colorAnimationConfig.GetStartMills();
1062 auto endMills = colorAnimationConfig.GetEndMills();
1063 auto curve = colorAnimationConfig.GetCurve();
1064 auto rsCurve = NativeCurveHelper::ToNativeCurve(curve);
1065 valChangeOverLife.emplace_back(OHOS::Rosen::Change<OHOS::Rosen::RSColor>(
1066 OHOS::Rosen::RSColor(
1067 fromColor.GetRed(), fromColor.GetGreen(), fromColor.GetBlue(), fromColor.GetAlpha()),
1068 OHOS::Rosen::RSColor(toColor.GetRed(), toColor.GetGreen(), toColor.GetBlue(), toColor.GetAlpha()),
1069 startMills, endMills, rsCurve));
1070 }
1071 return OHOS::Rosen::ParticleColorParaType(rsInitRange, ParticleUpdator::CURVE, OHOS::Rosen::Range<float>(),
1072 OHOS::Rosen::Range<float>(), OHOS::Rosen::Range<float>(), OHOS::Rosen::Range<float>(),
1073 valChangeOverLife);
1074 }
1075 }
1076 return ConvertParticleDefaultColorOption(rsInitRange);
1077 }
1078
ConvertParticleDefaultColorOption(std::optional<OHOS::Rosen::Range<OHOS::Rosen::RSColor>> rsInitRangeOpt)1079 Rosen::ParticleColorParaType RosenRenderContext::ConvertParticleDefaultColorOption(
1080 std::optional<OHOS::Rosen::Range<OHOS::Rosen::RSColor>> rsInitRangeOpt)
1081 {
1082 std::vector<OHOS::Rosen::Change<OHOS::Rosen::RSColor>> invalidCurve;
1083 if (rsInitRangeOpt.has_value()) {
1084 return OHOS::Rosen::ParticleColorParaType(rsInitRangeOpt.value(), OHOS::Rosen::ParticleUpdator::NONE,
1085 OHOS::Rosen::Range<float>(), OHOS::Rosen::Range<float>(), OHOS::Rosen::Range<float>(),
1086 OHOS::Rosen::Range<float>(), invalidCurve);
1087 }
1088 return OHOS::Rosen::ParticleColorParaType(
1089 OHOS::Rosen::Range<OHOS::Rosen::RSColor>(
1090 OHOS::Rosen::RSColor(PARTICLE_DEFAULT_COLOR), OHOS::Rosen::RSColor(PARTICLE_DEFAULT_COLOR)),
1091 OHOS::Rosen::ParticleUpdator::NONE, OHOS::Rosen::Range<float>(), OHOS::Rosen::Range<float>(),
1092 OHOS::Rosen::Range<float>(), OHOS::Rosen::Range<float>(), invalidCurve);
1093 }
1094
ConvertParticleFloatOption(const ParticleFloatPropertyOption & floatOption)1095 Rosen::ParticleParaType<float> RosenRenderContext::ConvertParticleFloatOption(
1096 const ParticleFloatPropertyOption& floatOption)
1097 {
1098 auto initRange = floatOption.GetRange();
1099 OHOS::Rosen::Range<float> rsInitRange(initRange.first, initRange.second);
1100 auto updaterOpt = floatOption.GetUpdater();
1101 if (updaterOpt.has_value()) {
1102 auto updater = updaterOpt.value();
1103 auto updateType = updater.GetUpdaterType();
1104 auto& config = updater.GetConfig();
1105 if (updateType == UpdaterType::RANDOM) {
1106 auto& randomRangeConfig = config.GetRandomConfig();
1107 std::vector<OHOS::Rosen::Change<float>> invalidChangeInOverLifeArray;
1108 return OHOS::Rosen::ParticleParaType<float>(rsInitRange, OHOS::Rosen::ParticleUpdator::RANDOM,
1109 OHOS::Rosen::Range<float>(randomRangeConfig.first, randomRangeConfig.second),
1110 invalidChangeInOverLifeArray);
1111 } else if (updateType == UpdaterType::CURVE) {
1112 auto curveConfig = config.GetAnimations();
1113 std::vector<OHOS::Rosen::Change<float>> valChangeOverLife;
1114 for (auto& animationConfig : curveConfig) {
1115 auto from = animationConfig.GetFrom();
1116 auto to = animationConfig.GetTo();
1117 auto startMills = animationConfig.GetStartMills();
1118 auto endMills = animationConfig.GetEndMills();
1119 auto rsCurve = NativeCurveHelper::ToNativeCurve(animationConfig.GetCurve());
1120 valChangeOverLife.emplace_back(OHOS::Rosen::Change<float>(from, to, startMills, endMills, rsCurve));
1121 }
1122 OHOS::Rosen::Range<float> rsInvalidRange;
1123 return OHOS::Rosen::ParticleParaType<float>(
1124 rsInitRange, OHOS::Rosen::ParticleUpdator::CURVE, rsInvalidRange, valChangeOverLife);
1125 }
1126 }
1127 return ConvertParticleDefaultFloatOption(rsInitRange);
1128 }
1129
ConvertParticleDefaultFloatOption(OHOS::Rosen::Range<float> & rsInitRange)1130 Rosen::ParticleParaType<float> RosenRenderContext::ConvertParticleDefaultFloatOption(
1131 OHOS::Rosen::Range<float>& rsInitRange)
1132 {
1133 std::vector<OHOS::Rosen::Change<float>> invalidChangeInOverLifeArray;
1134 return OHOS::Rosen::ParticleParaType<float>(
1135 rsInitRange, OHOS::Rosen::ParticleUpdator::NONE, OHOS::Rosen::Range<float>(), invalidChangeInOverLifeArray);
1136 }
1137
OnOpacityUpdate(double opacity)1138 void RosenRenderContext::OnOpacityUpdate(double opacity)
1139 {
1140 CHECK_NULL_VOID(rsNode_);
1141 rsNode_->SetAlpha(opacity);
1142 RequestNextFrame();
1143 }
1144
1145 class DrawDragThumbnailCallback : public SurfaceCaptureCallback {
1146 public:
OnSurfaceCapture(std::shared_ptr<Media::PixelMap> pixelMap)1147 void OnSurfaceCapture(std::shared_ptr<Media::PixelMap> pixelMap) override
1148 {
1149 if (pixelMap == nullptr) {
1150 LOGE("%{public}s: failed to get pixelmap, return nullptr", __func__);
1151 thumbnailGet.notify_all();
1152 return;
1153 }
1154 std::unique_lock<std::mutex> lock(g_mutex);
1155 #ifdef PIXEL_MAP_SUPPORTED
1156 g_pixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
1157 #endif // PIXEL_MAP_SUPPORTED
1158 thumbnailGet.notify_all();
1159 LOGI("Get pixelmap success");
1160 }
1161 };
1162
GetThumbnailPixelMap()1163 RefPtr<PixelMap> RosenRenderContext::GetThumbnailPixelMap()
1164 {
1165 if (rsNode_ == nullptr) {
1166 LOGE("rsNode is nullptr");
1167 return nullptr;
1168 }
1169 std::shared_ptr<DrawDragThumbnailCallback> drawDragThumbnailCallback =
1170 std::make_shared<DrawDragThumbnailCallback>();
1171 auto ret = RSInterfaces::GetInstance().TakeSurfaceCaptureForUI(rsNode_, drawDragThumbnailCallback, 1, 1);
1172 if (!ret) {
1173 LOGE("GetThumbnailPixelMap false, return nullptr");
1174 return nullptr;
1175 }
1176 std::unique_lock<std::mutex> lock(g_mutex);
1177 if (thumbnailGet.wait_for(lock, PIXELMAP_TIMEOUT_DURATION) == std::cv_status::timeout) {
1178 LOGW("Create GetThumbnailPixelMap false, wait lock timeout");
1179 return nullptr;
1180 }
1181 return g_pixelMap;
1182 }
1183
1184 #ifndef USE_ROSEN_DRAWING
GetBitmap(SkBitmap & bitmap,std::shared_ptr<OHOS::Rosen::DrawCmdList> drawCmdList)1185 bool RosenRenderContext::GetBitmap(SkBitmap& bitmap, std::shared_ptr<OHOS::Rosen::DrawCmdList> drawCmdList)
1186 #else
1187 bool RosenRenderContext::GetBitmap(RSBitmap& bitmap, std::shared_ptr<RSDrawCmdList> drawCmdList)
1188 #endif
1189 {
1190 auto rsCanvasDrawingNode = Rosen::RSNode::ReinterpretCast<Rosen::RSCanvasDrawingNode>(rsNode_);
1191 if (!rsCanvasDrawingNode) {
1192 return false;
1193 }
1194 return rsCanvasDrawingNode->GetBitmap(bitmap, drawCmdList);
1195 }
1196
1197 #ifndef USE_ROSEN_DRAWING
GetPixelMap(const std::shared_ptr<Media::PixelMap> & pixelMap,std::shared_ptr<OHOS::Rosen::DrawCmdList> drawCmdList,SkRect * rect)1198 bool RosenRenderContext::GetPixelMap(const std::shared_ptr<Media::PixelMap>& pixelMap,
1199 std::shared_ptr<OHOS::Rosen::DrawCmdList> drawCmdList, SkRect* rect)
1200 {
1201 auto rsCanvasDrawingNode = Rosen::RSNode::ReinterpretCast<Rosen::RSCanvasDrawingNode>(rsNode_);
1202 if (!rsCanvasDrawingNode) {
1203 return false;
1204 }
1205 return rsCanvasDrawingNode->GetPixelmap(pixelMap, drawCmdList, rect);
1206 }
1207 #endif
1208
OnTransformScaleUpdate(const VectorF & scale)1209 void RosenRenderContext::OnTransformScaleUpdate(const VectorF& scale)
1210 {
1211 CHECK_NULL_VOID(rsNode_);
1212 rsNode_->SetScale(scale.x, scale.y);
1213 RequestNextFrame();
1214 }
1215
OnTransformTranslateUpdate(const TranslateOptions & translate)1216 void RosenRenderContext::OnTransformTranslateUpdate(const TranslateOptions& translate)
1217 {
1218 CHECK_NULL_VOID(rsNode_);
1219 float xValue = 0.0f;
1220 float yValue = 0.0f;
1221 if (translate.x.Unit() == DimensionUnit::PERCENT || translate.y.Unit() == DimensionUnit::PERCENT) {
1222 auto rect = GetPaintRectWithoutTransform();
1223 if (rect.IsEmpty()) {
1224 // size is not determined yet
1225 return;
1226 }
1227 xValue = translate.x.ConvertToPxWithSize(rect.Width());
1228 yValue = translate.y.ConvertToPxWithSize(rect.Height());
1229 } else {
1230 xValue = translate.x.ConvertToPx();
1231 yValue = translate.y.ConvertToPx();
1232 }
1233 // translateZ doesn't support percentage
1234 float zValue = translate.z.ConvertToPx();
1235 rsNode_->SetTranslate(xValue, yValue, zValue);
1236 RequestNextFrame();
1237 }
1238
OnTransformRotateUpdate(const Vector5F & rotate)1239 void RosenRenderContext::OnTransformRotateUpdate(const Vector5F& rotate)
1240 {
1241 CHECK_NULL_VOID(rsNode_);
1242 float norm = std::sqrt(std::pow(rotate.x, 2) + std::pow(rotate.y, 2) + std::pow(rotate.z, 2));
1243 if (NearZero(norm)) {
1244 LOGW("rotate vector is near zero, please check");
1245 norm = 1.0f;
1246 }
1247 // for rosen backend, the rotation angles in the x and y directions should be set to opposite angles
1248 rsNode_->SetRotation(-rotate.w * rotate.x / norm, -rotate.w * rotate.y / norm, rotate.w * rotate.z / norm);
1249 // set camera distance
1250 rsNode_->SetCameraDistance(rotate.v);
1251 RequestNextFrame();
1252 }
1253
OnTransformCenterUpdate(const DimensionOffset & center)1254 void RosenRenderContext::OnTransformCenterUpdate(const DimensionOffset& center)
1255 {
1256 RectF rect = GetPaintRectWithoutTransform();
1257 if (!RectIsNull()) {
1258 float xPivot = ConvertDimensionToScaleBySize(center.GetX(), rect.Width());
1259 float yPivot = ConvertDimensionToScaleBySize(center.GetY(), rect.Height());
1260 float zPivot = 0.0f;
1261 auto& z = center.GetZ();
1262 if (z.has_value()) {
1263 zPivot = static_cast<float>(z.value().ConvertToVp());
1264 }
1265 SetPivot(xPivot, yPivot, zPivot);
1266 }
1267 RequestNextFrame();
1268 }
1269
OnTransformMatrixUpdate(const Matrix4 & matrix)1270 void RosenRenderContext::OnTransformMatrixUpdate(const Matrix4& matrix)
1271 {
1272 CHECK_NULL_VOID(rsNode_);
1273 if (!transformMatrixModifier_.has_value()) {
1274 transformMatrixModifier_ = TransformMatrixModifier();
1275 }
1276 DecomposedTransform transform;
1277 if (!TransformUtil::DecomposeTransform(transform, matrix)) {
1278 // fallback to basic matrix decompose
1279 Rosen::Vector2f xyTranslateValue { static_cast<float>(matrix.Get(0, 3)), static_cast<float>(matrix.Get(1, 3)) };
1280 Rosen::Vector2f scaleValue { 0.0f, 0.0f };
1281 AddOrChangeTranslateModifier(rsNode_, transformMatrixModifier_->translateXY,
1282 transformMatrixModifier_->translateXYValue, xyTranslateValue);
1283 AddOrChangeScaleModifier(
1284 rsNode_, transformMatrixModifier_->scaleXY, transformMatrixModifier_->scaleXYValue, scaleValue);
1285 } else {
1286 Rosen::Vector2f xyTranslateValue { transform.translate[0], transform.translate[1] };
1287 Rosen::Quaternion quaternion { static_cast<float>(transform.quaternion.GetX()),
1288 static_cast<float>(transform.quaternion.GetY()), static_cast<float>(transform.quaternion.GetZ()),
1289 static_cast<float>(transform.quaternion.GetW()) };
1290 Rosen::Vector2f scaleValue { transform.scale[0], transform.scale[1] };
1291 AddOrChangeTranslateModifier(rsNode_, transformMatrixModifier_->translateXY,
1292 transformMatrixModifier_->translateXYValue, xyTranslateValue);
1293 AddOrChangeScaleModifier(
1294 rsNode_, transformMatrixModifier_->scaleXY, transformMatrixModifier_->scaleXYValue, scaleValue);
1295 AddOrChangeQuaternionModifier(
1296 rsNode_, transformMatrixModifier_->quaternion, transformMatrixModifier_->quaternionValue, quaternion);
1297 }
1298 RequestNextFrame();
1299 }
1300
1301 RectF gRect;
1302
Degree2Radian(int32_t degree)1303 double Degree2Radian(int32_t degree)
1304 {
1305 const float pi = 3.14159265;
1306 degree = degree % 360;
1307 if (degree < 0) {
1308 degree += 360;
1309 }
1310 return degree * pi / 180;
1311 }
1312
SetCorner(double & x,double & y,double width,double height,int32_t degree)1313 void SetCorner(double& x, double& y, double width, double height, int32_t degree)
1314 {
1315 if (degree == 90) {
1316 x = 0;
1317 y = height;
1318 } else if (degree == 180) {
1319 x = width;
1320 y = height;
1321 } else if (degree == 270) {
1322 x = width;
1323 y = 0;
1324 }
1325 }
1326
GetPaintRectWithTransform()1327 RectF RosenRenderContext::GetPaintRectWithTransform()
1328 {
1329 RectF rect;
1330
1331 CHECK_NULL_RETURN(rsNode_, rect);
1332 rect = GetPaintRectWithoutTransform();
1333 auto translate = rsNode_->GetStagingProperties().GetTranslate();
1334 auto scale = rsNode_->GetStagingProperties().GetScale();
1335 auto center = rsNode_->GetStagingProperties().GetPivot();
1336 auto degree = rsNode_->GetStagingProperties().GetRotation();
1337 // calculate new pos.
1338 auto centOffset = OffsetF(center[0] * rect.Width(), center[1] * rect.Height());
1339 auto centerPos = rect.GetOffset() + centOffset;
1340 auto newPos = centerPos - OffsetF(centOffset.GetX() * scale[0], centOffset.GetY() * scale[1]);
1341 newPos = newPos + OffsetF(translate[0], translate[1]);
1342 rect.SetOffset(newPos);
1343 // calculate new size.
1344 auto oldSize = rect.GetSize();
1345 auto newSize = SizeF(oldSize.Width() * scale[0], oldSize.Height() * scale[1]);
1346 rect.SetSize(newSize);
1347 transInfo_ = { scale[0], scale[1], centerPos.GetX(), centerPos.GetY(), rect.GetX(), rect.GetY(), translate[0],
1348 translate[1], degree };
1349 // calculate rotate
1350 degree = static_cast<int32_t>(degree) % 360;
1351 auto radian = Degree2Radian(degree);
1352 if (degree != 0) {
1353 auto newRect = GetPaintRectWithoutTransform();
1354 double leftX = 0.0;
1355 double leftY = 0.0;
1356 degree = degree < 0 ? degree + 360 : degree;
1357 SetCorner(leftX, leftY, oldSize.Width(), oldSize.Height(), degree);
1358 double centerX = oldSize.Width() * center[0];
1359 double centerY = oldSize.Height() * center[1];
1360 auto tmp = leftX;
1361 leftX = (leftX - centerX) * cos(-1 * radian) + (leftY - centerY) * sin(-1 * radian);
1362 leftY = -1 * (tmp - centerX) * sin(-1 * radian) + (leftY - centerY) * cos(-1 * radian);
1363 auto leftXCalc = leftX + centerX;
1364 auto leftYCalc = leftY + centerY;
1365 leftX = newRect.GetOffset().GetX() + leftXCalc;
1366 leftY = newRect.GetOffset().GetY() + leftYCalc;
1367 auto offset = OffsetF(leftX + translate[0], leftY + translate[1]);
1368 rect.SetOffset(offset);
1369 if (degree == 180) {
1370 newSize = SizeF(oldSize.Width() * scale[0], oldSize.Height() * scale[1]);
1371 } else {
1372 newSize = SizeF(oldSize.Height() * scale[1], oldSize.Width() * scale[0]);
1373 }
1374 rect.SetSize(newSize);
1375 }
1376 gRect = rect;
1377 return rect;
1378 }
1379
GetTrans()1380 std::vector<double> RosenRenderContext::GetTrans()
1381 {
1382 return transInfo_;
1383 }
1384
GetPaintRectWithTranslate()1385 RectF RosenRenderContext::GetPaintRectWithTranslate()
1386 {
1387 RectF rect;
1388 CHECK_NULL_RETURN(rsNode_, rect);
1389 rect = GetPaintRectWithoutTransform();
1390 auto translate = rsNode_->GetStagingProperties().GetTranslate();
1391 rect.SetOffset(rect.GetOffset() + OffsetF(translate[0], translate[1]));
1392 return rect;
1393 }
1394
GetPointWithRevert(PointF & point)1395 void RosenRenderContext::GetPointWithRevert(PointF& point)
1396 {
1397 auto center = rsNode_->GetStagingProperties().GetPivot();
1398 int32_t degree = rsNode_->GetStagingProperties().GetRotation();
1399 auto translate = rsNode_->GetStagingProperties().GetTranslate();
1400 auto scale = rsNode_->GetStagingProperties().GetScale();
1401
1402 RectF rect = GetPaintRectWithoutTransform();
1403 auto centOffset = OffsetF(center[0] * rect.Width(), center[1] * rect.Height());
1404 auto centerPos = rect.GetOffset() + centOffset;
1405
1406 auto translateMat = Matrix4::CreateTranslate(translate[0], translate[1], 0);
1407 auto rotationMat = Matrix4::CreateTranslate(centerPos.GetX(), centerPos.GetY(), 0) *
1408 Matrix4::CreateRotate(degree, 0, 0, 1) *
1409 Matrix4::CreateTranslate(-centerPos.GetX(), -centerPos.GetY(), 0);
1410 auto scaleMat = Matrix4::CreateTranslate(centerPos.GetX(), centerPos.GetY(), 0) *
1411 Matrix4::CreateScale(scale[0], scale[1], 1) *
1412 Matrix4::CreateTranslate(-centerPos.GetX(), -centerPos.GetY(), 0);
1413
1414 auto invertMat = Matrix4::Invert(translateMat * rotationMat * scaleMat);
1415 Point tmp(point.GetX(), point.GetY());
1416 auto invertPoint = invertMat * tmp;
1417 point.SetX(invertPoint.GetX());
1418 point.SetY(invertPoint.GetY());
1419 }
1420
GetPointWithTransform(PointF & point)1421 void RosenRenderContext::GetPointWithTransform(PointF& point)
1422 {
1423 // TODO: add rotation and center support
1424 auto translate = rsNode_->GetStagingProperties().GetTranslate();
1425 auto scale = rsNode_->GetStagingProperties().GetScale();
1426 point = PointF(point.GetX() / scale[0], point.GetY() / scale[1]);
1427 RectF rect = GetPaintRectWithoutTransform();
1428 auto center = rsNode_->GetStagingProperties().GetPivot();
1429 int32_t degree = rsNode_->GetStagingProperties().GetRotation();
1430 degree = degree % 360;
1431 auto radian = Degree2Radian(degree);
1432 if (degree != 0) {
1433 point = point + gRect.GetOffset();
1434 point = point - OffsetF(translate[0], translate[1]);
1435 auto centOffset = OffsetF(center[0] * gRect.Width(), center[1] * gRect.Height());
1436 auto centerPos = gRect.GetOffset() + centOffset - OffsetF(translate[0], translate[1]);
1437 auto centerX = centerPos.GetX();
1438 auto centerY = centerPos.GetY();
1439
1440 double currentPointX = (point.GetX() - centerX) * cos(radian) + (point.GetY() - centerY) * sin(radian);
1441 double currentPointY = -1 * (point.GetX() - centerX) * sin(radian) + (point.GetY() - centerY) * cos(radian);
1442 currentPointX = currentPointX + centerX;
1443 currentPointY = currentPointY + centerY;
1444 point.SetX(currentPointX - rect.Left());
1445 point.SetY(currentPointY - rect.Top());
1446 }
1447 }
1448
1449
GetPaintRectWithoutTransform()1450 RectF RosenRenderContext::GetPaintRectWithoutTransform()
1451 {
1452 RectF rect;
1453 CHECK_NULL_RETURN(rsNode_, rect);
1454 auto paintRectVector = rsNode_->GetStagingProperties().GetBounds();
1455 rect.SetRect(paintRectVector[0], paintRectVector[1], paintRectVector[2], paintRectVector[3]);
1456 return rect;
1457 }
1458
UpdateTranslateInXY(const OffsetF & offset)1459 void RosenRenderContext::UpdateTranslateInXY(const OffsetF& offset)
1460 {
1461 CHECK_NULL_VOID(rsNode_);
1462 auto xValue = offset.GetX();
1463 auto yValue = offset.GetY();
1464 if (translateXY_) {
1465 auto propertyXY = std::static_pointer_cast<RSAnimatableProperty<Vector2f>>(translateXY_->GetProperty());
1466 if (propertyXY) {
1467 propertyXY->Set({ xValue, yValue });
1468 } else {
1469 LOGE("fail to get translateXY property");
1470 }
1471 } else {
1472 auto propertyXY = std::make_shared<RSAnimatableProperty<Vector2f>>(Vector2f(xValue, yValue));
1473 translateXY_ = std::make_shared<Rosen::RSTranslateModifier>(propertyXY);
1474 rsNode_->AddModifier(translateXY_);
1475 }
1476 }
1477
GetShowingTranslateProperty()1478 OffsetF RosenRenderContext::GetShowingTranslateProperty()
1479 {
1480 OffsetF offset;
1481 CHECK_NULL_RETURN(translateXY_, offset);
1482 auto property = std::static_pointer_cast<RSAnimatableProperty<Vector2f>>(translateXY_->GetProperty());
1483 CHECK_NULL_RETURN(property, offset);
1484 auto result = property->GetShowingValueAndCancelAnimation();
1485 if (!result) {
1486 LOGW("fail to stop current property animation");
1487 return offset;
1488 }
1489 auto translate = property->Get();
1490 offset.SetX(translate[0]);
1491 offset.SetY(translate[1]);
1492 return offset;
1493 }
1494
NotifyTransitionInner(const SizeF & frameSize,bool isTransitionIn)1495 void RosenRenderContext::NotifyTransitionInner(const SizeF& frameSize, bool isTransitionIn)
1496 {
1497 CHECK_NULL_VOID(rsNode_);
1498 if (propTransitionAppearing_ || propTransitionDisappearing_) {
1499 // old transition
1500 auto& transOptions = isTransitionIn ? propTransitionAppearing_ : propTransitionDisappearing_;
1501 auto effect = GetRSTransitionWithoutType(transOptions, frameSize);
1502 CHECK_NULL_VOID_NOLOG(effect);
1503 SetTransitionPivot(frameSize, isTransitionIn);
1504 // notice that we have been in animateTo, so do not need to use Animation closure to notify transition.
1505 rsNode_->NotifyTransition(effect, isTransitionIn);
1506 return;
1507 }
1508 // add default transition effect on the 'breaking point' of render tree, if no user-defined transition effect
1509 // and triggered in AnimateTo closure.
1510 // Note: this default transition effect will be removed after all transitions finished, implemented in
1511 // OnTransitionInFinish. and OnTransitionOutFinish.
1512 auto pipeline = PipelineBase::GetCurrentContext();
1513 CHECK_NULL_VOID(pipeline);
1514 if (isBreakingPoint_ && !transitionEffect_ &&
1515 (pipeline->GetSyncAnimationOption().IsValid() ||
1516 ViewStackProcessor::GetInstance()->GetImplicitAnimationOption().IsValid())) {
1517 hasDefaultTransition_ = true;
1518 transitionEffect_ = RosenTransitionEffect::CreateDefaultRosenTransitionEffect();
1519 RSNode::ExecuteWithoutAnimation([this, isTransitionIn]() {
1520 // transitionIn effects should be initialized as active if is transitionIn.
1521 transitionEffect_->Attach(Claim(this), isTransitionIn);
1522 });
1523 }
1524 NotifyTransition(isTransitionIn);
1525 }
1526
OpacityAnimation(const AnimationOption & option,double begin,double end)1527 void RosenRenderContext::OpacityAnimation(const AnimationOption& option, double begin, double end)
1528 {
1529 CHECK_NULL_VOID(rsNode_);
1530 rsNode_->SetAlpha(begin);
1531 AnimationUtils::Animate(
1532 option,
1533 [rsNode = rsNode_, endAlpha = end]() {
1534 CHECK_NULL_VOID_NOLOG(rsNode);
1535 rsNode->SetAlpha(endAlpha);
1536 },
1537 option.GetOnFinishEvent());
1538 }
1539
ScaleAnimation(const AnimationOption & option,double begin,double end)1540 void RosenRenderContext::ScaleAnimation(const AnimationOption& option, double begin, double end)
1541 {
1542 CHECK_NULL_VOID(rsNode_);
1543 rsNode_->SetScale(begin);
1544 AnimationUtils::Animate(
1545 option,
1546 [rsNode = rsNode_, endScale = end]() {
1547 CHECK_NULL_VOID_NOLOG(rsNode);
1548 rsNode->SetScale(endScale);
1549 },
1550 option.GetOnFinishEvent());
1551 }
1552
OnBorderRadiusUpdate(const BorderRadiusProperty & value)1553 void RosenRenderContext::OnBorderRadiusUpdate(const BorderRadiusProperty& value)
1554 {
1555 if (!isSynced_) {
1556 return;
1557 }
1558 CHECK_NULL_VOID(rsNode_);
1559 auto paintRect = AdjustPaintRect();
1560 if (isDisappearing_ && !paintRect.IsValid()) {
1561 return;
1562 }
1563 double radiusX = paintRect.Width();
1564 Rosen::Vector4f cornerRadius;
1565 // When the unit of radius is percent, the length and width of rect should be calculated at the same time,
1566 // but currently SetCornerRadius only supports Vector4f parameter passing.
1567 // Graphic should provide support .
1568 cornerRadius.SetValues(static_cast<float>(value.radiusTopLeft.value_or(Dimension()).ConvertToPxWithSize(radiusX)),
1569 static_cast<float>(value.radiusTopRight.value_or(Dimension()).ConvertToPxWithSize(radiusX)),
1570 static_cast<float>(value.radiusBottomRight.value_or(Dimension()).ConvertToPxWithSize(radiusX)),
1571 static_cast<float>(value.radiusBottomLeft.value_or(Dimension()).ConvertToPxWithSize(radiusX)));
1572 rsNode_->SetCornerRadius(cornerRadius);
1573 RequestNextFrame();
1574 }
1575
OnBorderColorUpdate(const BorderColorProperty & value)1576 void RosenRenderContext::OnBorderColorUpdate(const BorderColorProperty& value)
1577 {
1578 CHECK_NULL_VOID(rsNode_);
1579 rsNode_->SetBorderColor(value.leftColor.value_or(Color::BLACK).GetValue(),
1580 value.topColor.value_or(Color::BLACK).GetValue(), value.rightColor.value_or(Color::BLACK).GetValue(),
1581 value.bottomColor.value_or(Color::BLACK).GetValue());
1582 RequestNextFrame();
1583 }
1584
UpdateBorderWidthF(const BorderWidthPropertyF & value)1585 void RosenRenderContext::UpdateBorderWidthF(const BorderWidthPropertyF& value)
1586 {
1587 CHECK_NULL_VOID(rsNode_);
1588 Rosen::Vector4f cornerBorderWidth;
1589 cornerBorderWidth.SetValues(value.leftDimen.value_or(0), static_cast<float>(value.topDimen.value_or(0)),
1590 static_cast<float>(value.rightDimen.value_or(0)), static_cast<float>(value.bottomDimen.value_or(0)));
1591 rsNode_->SetBorderWidth(cornerBorderWidth);
1592 RequestNextFrame();
1593 }
1594
OnBorderStyleUpdate(const BorderStyleProperty & value)1595 void RosenRenderContext::OnBorderStyleUpdate(const BorderStyleProperty& value)
1596 {
1597 CHECK_NULL_VOID(rsNode_);
1598 rsNode_->SetBorderStyle(static_cast<uint32_t>(value.styleLeft.value_or(BorderStyle::SOLID)),
1599 static_cast<uint32_t>(value.styleTop.value_or(BorderStyle::SOLID)),
1600 static_cast<uint32_t>(value.styleRight.value_or(BorderStyle::SOLID)),
1601 static_cast<uint32_t>(value.styleBottom.value_or(BorderStyle::SOLID)));
1602 RequestNextFrame();
1603 }
1604
OnAccessibilityFocusUpdate(bool isAccessibilityFocus)1605 void RosenRenderContext::OnAccessibilityFocusUpdate(bool isAccessibilityFocus)
1606 {
1607 auto uiNode = GetHost();
1608 CHECK_NULL_VOID(uiNode);
1609 UpdateAccessibilityFocus(isAccessibilityFocus);
1610 if (isAccessibilityFocus) {
1611 PaintAccessibilityFocus();
1612 } else {
1613 ClearAccessibilityFocus();
1614 }
1615 uiNode->OnAccessibilityEvent(isAccessibilityFocus ? AccessibilityEventType::ACCESSIBILITY_FOCUSED
1616 : AccessibilityEventType::ACCESSIBILITY_FOCUS_CLEARED);
1617 }
1618
OnUseEffectUpdate(bool useEffect)1619 void RosenRenderContext::OnUseEffectUpdate(bool useEffect)
1620 {
1621 CHECK_NULL_VOID(rsNode_);
1622 rsNode_->SetUseEffect(useEffect);
1623 }
1624
OnFreezeUpdate(bool isFreezed)1625 void RosenRenderContext::OnFreezeUpdate(bool isFreezed)
1626 {
1627 CHECK_NULL_VOID(rsNode_);
1628 rsNode_->SetFreeze(isFreezed);
1629 }
1630
PaintAccessibilityFocus()1631 void RosenRenderContext::PaintAccessibilityFocus()
1632 {
1633 CHECK_NULL_VOID(rsNode_);
1634 Dimension focusPaddingVp = Dimension(0.0, DimensionUnit::VP);
1635 constexpr uint32_t ACCESSIBILITY_FOCUS_COLOR = 0xbf39b500;
1636 constexpr double ACCESSIBILITY_FOCUS_WIDTH = 4.0;
1637 Color paintColor(ACCESSIBILITY_FOCUS_COLOR);
1638 Dimension paintWidth(ACCESSIBILITY_FOCUS_WIDTH, DimensionUnit::PX);
1639 const auto& bounds = rsNode_->GetStagingProperties().GetBounds();
1640 RoundRect frameRect;
1641 frameRect.SetRect(RectF(0.0, 0.0, bounds.z_, bounds.w_));
1642 PaintFocusState(frameRect, focusPaddingVp, paintColor, paintWidth, true);
1643 }
1644
ClearAccessibilityFocus()1645 void RosenRenderContext::ClearAccessibilityFocus()
1646 {
1647 CHECK_NULL_VOID(rsNode_);
1648 auto context = PipelineBase::GetCurrentContext();
1649 CHECK_NULL_VOID(context);
1650 CHECK_NULL_VOID(accessibilityFocusStateModifier_);
1651 rsNode_->RemoveModifier(accessibilityFocusStateModifier_);
1652 RequestNextFrame();
1653 }
1654
BdImagePaintTask(RSCanvas & canvas)1655 void RosenRenderContext::BdImagePaintTask(RSCanvas& canvas)
1656 {
1657 CHECK_NULL_VOID(GetBorderImage());
1658 auto paintRect = GetPaintRectWithoutTransform();
1659 if (NearZero(paintRect.Width()) || NearZero(paintRect.Height())) {
1660 return;
1661 }
1662
1663 auto host = GetHost();
1664 CHECK_NULL_VOID(host);
1665 auto layoutProps = host->GetLayoutProperty();
1666 CHECK_NULL_VOID(layoutProps);
1667 const auto& widthProp = layoutProps->GetBorderWidthProperty();
1668
1669 auto pipeline = host->GetContext();
1670 CHECK_NULL_VOID(pipeline);
1671 auto dipScale = pipeline->GetDipScale();
1672
1673 CHECK_NULL_VOID(bdImage_);
1674 #ifndef USE_ROSEN_DRAWING
1675 sk_sp<SkImage> image;
1676 if (InstanceOf<SkiaImage>(bdImage_)) {
1677 image = DynamicCast<SkiaImage>(bdImage_)->GetImage();
1678 } else if (InstanceOf<PixelMapImage>(bdImage_)) {
1679 auto pixmap = DynamicCast<PixelMapImage>(bdImage_)->GetPixelMap();
1680 CHECK_NULL_VOID(pixmap);
1681 image = SkiaImage::MakeSkImageFromPixmap(pixmap);
1682 } else {
1683 return;
1684 }
1685 #else
1686 std::shared_ptr<RSImage> image;
1687 if (InstanceOf<DrawingImage>(bdImage_)) {
1688 image = DynamicCast<DrawingImage>(bdImage_)->GetImage();
1689 } else if (InstanceOf<PixelMapImage>(bdImage_)) {
1690 auto pixmap = DynamicCast<PixelMapImage>(bdImage_)->GetPixelMap();
1691 CHECK_NULL_VOID(pixmap);
1692 image = DrawingImage::MakeRSImageFromPixmap(pixmap);
1693 } else {
1694 return;
1695 }
1696 #endif
1697 CHECK_NULL_VOID(image);
1698 RSImage rsImage(&image);
1699 BorderImagePainter borderImagePainter(*GetBdImage(), widthProp, paintRect.GetSize(), rsImage, dipScale);
1700 borderImagePainter.PaintBorderImage(OffsetF(0.0, 0.0), canvas);
1701 }
1702
PaintBorderImage()1703 void RosenRenderContext::PaintBorderImage()
1704 {
1705 CHECK_NULL_VOID(rsNode_);
1706
1707 auto paintTask = [weak = WeakClaim(this)](RSCanvas& canvas) {
1708 auto ctx = weak.Upgrade();
1709 CHECK_NULL_VOID(ctx);
1710 ctx->BdImagePaintTask(canvas);
1711 };
1712
1713 if (!borderImageModifier_) {
1714 borderImageModifier_ = std::make_shared<BorderImageModifier>();
1715 rsNode_->AddModifier(borderImageModifier_);
1716 }
1717 borderImageModifier_->SetPaintTask(std::move(paintTask));
1718 borderImageModifier_->Modify();
1719 }
1720
CreateBorderImageDataReadyCallback()1721 DataReadyNotifyTask RosenRenderContext::CreateBorderImageDataReadyCallback()
1722 {
1723 return [weak = WeakClaim(this)](const ImageSourceInfo& sourceInfo) {
1724 auto rosenRenderContext = weak.Upgrade();
1725 CHECK_NULL_VOID(rosenRenderContext);
1726 auto imageSourceInfo = rosenRenderContext->GetBorderImageSource().value_or(ImageSourceInfo(""));
1727 if (imageSourceInfo != sourceInfo) {
1728 LOGW("sourceInfo does not match, ignore current callback. current: %{public}s vs callback's: %{public}s",
1729 imageSourceInfo.ToString().c_str(), sourceInfo.ToString().c_str());
1730 return;
1731 }
1732 LOGI("borderImage data ready %{public}s", sourceInfo.ToString().c_str());
1733 rosenRenderContext->bdImageLoadingCtx_->MakeCanvasImage(SizeF(), true, ImageFit::NONE);
1734 };
1735 }
1736
CreateBorderImageLoadSuccessCallback()1737 LoadSuccessNotifyTask RosenRenderContext::CreateBorderImageLoadSuccessCallback()
1738 {
1739 return [weak = WeakClaim(this)](const ImageSourceInfo& sourceInfo) {
1740 auto ctx = weak.Upgrade();
1741 CHECK_NULL_VOID(ctx);
1742 auto imageSourceInfo = ctx->GetBorderImageSource().value_or(ImageSourceInfo(""));
1743 if (imageSourceInfo != sourceInfo) {
1744 LOGW("sourceInfo does not match, ignore current callback. current: %{public}s vs callback's: %{public}s",
1745 imageSourceInfo.ToString().c_str(), sourceInfo.ToString().c_str());
1746 return;
1747 }
1748 ctx->bdImage_ = ctx->bdImageLoadingCtx_->MoveCanvasImage();
1749 CHECK_NULL_VOID(ctx->bdImage_);
1750 LOGI("borderImage load success %{public}s", sourceInfo.ToString().c_str());
1751 if (ctx->GetHost()->GetGeometryNode()->GetFrameSize().IsPositive()) {
1752 ctx->PaintBorderImage();
1753 ctx->RequestNextFrame();
1754 }
1755 };
1756 }
1757
OnBackgroundAlignUpdate(const Alignment & align)1758 void RosenRenderContext::OnBackgroundAlignUpdate(const Alignment& align)
1759 {
1760 CHECK_NULL_VOID(rsNode_);
1761 if (!backgroundModifier_) {
1762 backgroundModifier_ = std::make_shared<BackgroundModifier>();
1763 rsNode_->AddModifier(backgroundModifier_);
1764 }
1765 backgroundModifier_->SetAlign(align);
1766 backgroundModifier_->Modify();
1767 RequestNextFrame();
1768 }
1769
OnBackgroundPixelMapUpdate(const RefPtr<PixelMap> & pixelMap)1770 void RosenRenderContext::OnBackgroundPixelMapUpdate(const RefPtr<PixelMap>& pixelMap)
1771 {
1772 CHECK_NULL_VOID(rsNode_);
1773 if (!backgroundModifier_) {
1774 backgroundModifier_ = std::make_shared<BackgroundModifier>();
1775 rsNode_->AddModifier(backgroundModifier_);
1776 }
1777 auto node = GetHost();
1778 auto nodeWidth = node->GetGeometryNode()->GetFrameSize().Width();
1779 auto nodeHeight = node->GetGeometryNode()->GetFrameSize().Height();
1780 backgroundModifier_->SetInitialNodeSize(nodeWidth, nodeHeight);
1781 backgroundModifier_->SetPixelMap(pixelMap);
1782 backgroundModifier_->Modify();
1783 RequestNextFrame();
1784 }
1785
CreateBackgroundPixelMap(const RefPtr<FrameNode> & customNode)1786 void RosenRenderContext::CreateBackgroundPixelMap(const RefPtr<FrameNode>& customNode)
1787 {
1788 NG::ComponentSnapshot::JsCallback callback = [weak = WeakPtr(GetHost()),
1789 containerId = Container::CurrentId()](
1790 std::shared_ptr<Media::PixelMap> pixmap, int32_t errCode) {
1791 CHECK_NULL_VOID(pixmap);
1792 auto frameNode = weak.Upgrade();
1793 CHECK_NULL_VOID(frameNode);
1794 ContainerScope scope(containerId);
1795 std::shared_ptr<Media::PixelMap> pmap = std::move(pixmap);
1796 auto pixelmap = PixelMap::CreatePixelMap(&pmap);
1797 auto task = [pixelmap, containerId = containerId, frameNode]() {
1798 auto context = frameNode->GetRenderContext();
1799 if (context) {
1800 context->UpdateBackgroundPixelMap(pixelmap);
1801 context->RequestNextFrame();
1802 }
1803 };
1804 auto taskExecutor = Container::CurrentTaskExecutor();
1805 CHECK_NULL_VOID(taskExecutor);
1806 taskExecutor->PostTask(task, TaskExecutor::TaskType::UI);
1807 };
1808 NG::ComponentSnapshot::Create(customNode, std::move(callback));
1809 }
1810
OnBorderImageUpdate(const RefPtr<BorderImage> &)1811 void RosenRenderContext::OnBorderImageUpdate(const RefPtr<BorderImage>& /*borderImage*/)
1812 {
1813 CHECK_NULL_VOID(rsNode_);
1814 if (bdImageLoadingCtx_ && bdImage_) {
1815 PaintBorderImage();
1816 RequestNextFrame();
1817 }
1818 }
1819
OnBorderImageSourceUpdate(const ImageSourceInfo & borderImageSourceInfo)1820 void RosenRenderContext::OnBorderImageSourceUpdate(const ImageSourceInfo& borderImageSourceInfo)
1821 {
1822 CHECK_NULL_VOID(rsNode_);
1823 if (!bdImageLoadingCtx_ || borderImageSourceInfo != bdImageLoadingCtx_->GetSourceInfo()) {
1824 LoadNotifier bgLoadNotifier(
1825 CreateBorderImageDataReadyCallback(), CreateBorderImageLoadSuccessCallback(), nullptr);
1826 bdImageLoadingCtx_ = AceType::MakeRefPtr<ImageLoadingContext>(borderImageSourceInfo, std::move(bgLoadNotifier));
1827 CHECK_NULL_VOID(bdImageLoadingCtx_);
1828 bdImageLoadingCtx_->LoadImageData();
1829 }
1830 RequestNextFrame();
1831 }
1832
OnBorderImageGradientUpdate(const Gradient & gradient)1833 void RosenRenderContext::OnBorderImageGradientUpdate(const Gradient& gradient)
1834 {
1835 CHECK_NULL_VOID(rsNode_);
1836 if (!gradient.IsValid()) {
1837 LOGE("Gradient not valid");
1838 return;
1839 }
1840 if (GetHost()->GetGeometryNode()->GetFrameSize().IsPositive()) {
1841 PaintBorderImageGradient();
1842 }
1843 RequestNextFrame();
1844 }
1845
PaintBorderImageGradient()1846 void RosenRenderContext::PaintBorderImageGradient()
1847 {
1848 CHECK_NULL_VOID(rsNode_);
1849 CHECK_NULL_VOID(GetBorderImage());
1850 CHECK_NULL_VOID(GetBorderImageGradient());
1851 auto gradient = GetBorderImageGradient().value();
1852 if (!gradient.IsValid()) {
1853 LOGE("Gradient not valid");
1854 return;
1855 }
1856 auto paintSize = GetPaintRectWithoutTransform().GetSize();
1857 if (NearZero(paintSize.Width()) || NearZero(paintSize.Height())) {
1858 return;
1859 }
1860 auto layoutProperty = GetHost()->GetLayoutProperty();
1861 CHECK_NULL_VOID(layoutProperty);
1862
1863 auto borderImageProperty = *GetBdImage();
1864 auto&& borderWidthProperty = layoutProperty->GetBorderWidthProperty();
1865 auto paintTask = [paintSize, borderImageProperty, &borderWidthProperty, gradient](RSCanvas& rsCanvas) mutable {
1866 #ifndef USE_ROSEN_DRAWING
1867 auto rsImage = SkiaDecorationPainter::CreateBorderImageGradient(gradient, paintSize);
1868 #else
1869 auto rsImage = DrawingDecorationPainter::CreateBorderImageGradient(gradient, paintSize);
1870 #endif
1871 BorderImagePainter borderImagePainter(borderImageProperty, borderWidthProperty, paintSize, rsImage,
1872 PipelineBase::GetCurrentContext()->GetDipScale());
1873 borderImagePainter.PaintBorderImage(OffsetF(0.0, 0.0), rsCanvas);
1874 };
1875
1876 if (!borderImageModifier_) {
1877 borderImageModifier_ = std::make_shared<BorderImageModifier>();
1878 rsNode_->AddModifier(borderImageModifier_);
1879 }
1880 borderImageModifier_->SetPaintTask(std::move(paintTask));
1881 borderImageModifier_->Modify();
1882 }
1883
OnModifyDone()1884 void RosenRenderContext::OnModifyDone()
1885 {
1886 auto frameNode = GetHost();
1887 CHECK_NULL_VOID(frameNode);
1888 CHECK_NULL_VOID(rsNode_);
1889 if (HasClickEffectLevel()) {
1890 InitEventClickEffect();
1891 }
1892 }
1893
GetPropertyOfPosition()1894 RectF RosenRenderContext::GetPropertyOfPosition()
1895 {
1896 return AdjustPaintRect();
1897 }
1898
AdjustPaintRect()1899 RectF RosenRenderContext::AdjustPaintRect()
1900 {
1901 RectF rect;
1902 auto frameNode = GetHost();
1903 CHECK_NULL_RETURN(frameNode, rect);
1904 CHECK_NULL_RETURN(rsNode_, rect);
1905 const auto& geometryNode = frameNode->GetGeometryNode();
1906 rect = geometryNode->GetFrameRect();
1907 if (!rect.GetSize().IsPositive()) {
1908 LOGD("paint size is zero");
1909 return rect;
1910 }
1911 const auto& layoutConstraint = frameNode->GetGeometryNode()->GetParentLayoutConstraint();
1912 auto widthPercentReference = layoutConstraint.has_value() ? layoutConstraint->percentReference.Width()
1913 : PipelineContext::GetCurrentRootWidth();
1914 auto heightPercentReference = layoutConstraint.has_value() ? layoutConstraint->percentReference.Height()
1915 : PipelineContext::GetCurrentRootHeight();
1916 auto anchor = GetAnchorValue({});
1917 auto anchorWidthReference = rect.Width();
1918 auto anchorHeightReference = rect.Height();
1919 auto anchorX = ConvertToPx(anchor.GetX(), ScaleProperty::CreateScaleProperty(), anchorWidthReference);
1920 auto anchorY = ConvertToPx(anchor.GetY(), ScaleProperty::CreateScaleProperty(), anchorHeightReference);
1921 Dimension resultX;
1922 Dimension resultY;
1923 Dimension parentPaddingLeft;
1924 Dimension parentPaddingTop;
1925 GetPaddingOfFirstFrameNodeParent(parentPaddingLeft, parentPaddingTop);
1926 // Position properties take precedence over offset locations.
1927 if (HasPosition() && IsUsingPosition(frameNode)) {
1928 CombineMarginAndPosition(
1929 resultX, resultY, parentPaddingLeft, parentPaddingTop, widthPercentReference, heightPercentReference);
1930 rect.SetLeft(resultX.ConvertToPx() - anchorX.value_or(0));
1931 rect.SetTop(resultY.ConvertToPx() - anchorY.value_or(0));
1932 return rect;
1933 }
1934 if (HasOffset()) {
1935 auto offset = GetOffsetValue({});
1936 if (PipelineBase::GetCurrentContext() &&
1937 PipelineBase::GetCurrentContext()->GetMinPlatformVersion() < PLATFORM_VERSION_TEN) {
1938 offset += OffsetT<Dimension>(parentPaddingLeft, parentPaddingTop);
1939 }
1940 auto offsetX = ConvertToPx(offset.GetX(), ScaleProperty::CreateScaleProperty(), widthPercentReference);
1941 auto offsetY = ConvertToPx(offset.GetY(), ScaleProperty::CreateScaleProperty(), heightPercentReference);
1942 rect.SetLeft(rect.GetX() + offsetX.value_or(0) - anchorX.value_or(0));
1943 rect.SetTop(rect.GetY() + offsetY.value_or(0) - anchorY.value_or(0));
1944 return rect;
1945 }
1946 rect.SetLeft(rect.GetX() - anchorX.value_or(0));
1947 rect.SetTop(rect.GetY() - anchorY.value_or(0));
1948 return rect;
1949 }
1950
CombineMarginAndPosition(Dimension & resultX,Dimension & resultY,const Dimension & parentPaddingLeft,const Dimension & parentPaddingTop,float widthPercentReference,float heightPercentReference)1951 void RosenRenderContext::CombineMarginAndPosition(Dimension& resultX, Dimension& resultY,
1952 const Dimension& parentPaddingLeft, const Dimension& parentPaddingTop, float widthPercentReference,
1953 float heightPercentReference)
1954 {
1955 Dimension selfMarginLeft;
1956 Dimension selfMarginTop;
1957 auto frameNode = GetHost();
1958 if (frameNode && frameNode->GetLayoutProperty() && frameNode->GetLayoutProperty()->GetMarginProperty()) {
1959 auto& margin = frameNode->GetLayoutProperty()->GetMarginProperty();
1960 if (margin->left.has_value()) {
1961 selfMarginLeft = margin->left.value().GetDimension();
1962 }
1963 if (margin->top.has_value()) {
1964 selfMarginTop = margin->top.value().GetDimension();
1965 }
1966 }
1967 // to distinguish cases ex. margin has percentage unit and padding has vp unit
1968 // final rect offset will be affected by parent padding, self margin and position property
1969 if (selfMarginLeft.Unit() != GetPositionValue({}).GetX().Unit() ||
1970 selfMarginLeft.Unit() != parentPaddingLeft.Unit() ||
1971 parentPaddingLeft.Unit() != GetPositionValue({}).GetX().Unit()) {
1972 resultX = Dimension(
1973 ConvertToPx(parentPaddingLeft, ScaleProperty::CreateScaleProperty(), widthPercentReference).value_or(0) +
1974 ConvertToPx(selfMarginLeft, ScaleProperty::CreateScaleProperty(), widthPercentReference).value_or(0) +
1975 ConvertToPx(GetPositionValue({}).GetX(), ScaleProperty::CreateScaleProperty(), widthPercentReference)
1976 .value_or(0),
1977 DimensionUnit::PX);
1978 } else {
1979 resultX = selfMarginLeft + GetPositionValue({}).GetX() + parentPaddingLeft;
1980 }
1981 if (selfMarginTop.Unit() != GetPositionValue({}).GetY().Unit() || selfMarginTop.Unit() != parentPaddingTop.Unit() ||
1982 parentPaddingTop.Unit() != GetPositionValue({}).GetY().Unit()) {
1983 resultY = Dimension(
1984 ConvertToPx(parentPaddingTop, ScaleProperty::CreateScaleProperty(), heightPercentReference).value_or(0) +
1985 ConvertToPx(selfMarginTop, ScaleProperty::CreateScaleProperty(), heightPercentReference).value_or(0) +
1986 ConvertToPx(GetPositionValue({}).GetY(), ScaleProperty::CreateScaleProperty(), heightPercentReference)
1987 .value_or(0),
1988 DimensionUnit::PX);
1989 } else {
1990 resultY = selfMarginTop + GetPositionValue({}).GetY() + parentPaddingTop;
1991 }
1992 }
1993
IsUsingPosition(const RefPtr<FrameNode> & frameNode)1994 bool RosenRenderContext::IsUsingPosition(const RefPtr<FrameNode>& frameNode)
1995 {
1996 auto layoutProperty = frameNode->GetLayoutProperty();
1997 bool isUsingPosition = true;
1998 if (layoutProperty) {
1999 isUsingPosition = layoutProperty->IsUsingPosition();
2000 }
2001 return isUsingPosition;
2002 }
2003
GetPaddingOfFirstFrameNodeParent(Dimension & parentPaddingLeft,Dimension & parentPaddingTop)2004 void RosenRenderContext::GetPaddingOfFirstFrameNodeParent(Dimension& parentPaddingLeft, Dimension& parentPaddingTop)
2005 {
2006 auto frameNode = GetHost();
2007 CHECK_NULL_VOID(frameNode);
2008 auto frameNodeParent = frameNode->GetAncestorNodeOfFrame();
2009 CHECK_NULL_VOID_NOLOG(frameNodeParent);
2010 auto layoutProperty = frameNodeParent->GetLayoutProperty();
2011 if (layoutProperty && layoutProperty->GetPaddingProperty()) {
2012 parentPaddingLeft =
2013 layoutProperty->GetPaddingProperty()->left.value_or(CalcLength(Dimension(0))).GetDimension();
2014 parentPaddingTop = layoutProperty->GetPaddingProperty()->top.value_or(CalcLength(Dimension(0))).GetDimension();
2015 }
2016 }
SetPositionToRSNode()2017 void RosenRenderContext::SetPositionToRSNode()
2018 {
2019 auto frameNode = GetHost();
2020 CHECK_NULL_VOID(frameNode);
2021 CHECK_NULL_VOID(rsNode_);
2022 const auto& size = frameNode->GetGeometryNode()->GetFrameSize();
2023 if (!size.IsPositive()) {
2024 LOGD("first modify, make change in SyncGeometryProperties");
2025 return;
2026 }
2027 auto rect = AdjustPaintRect();
2028 if (!rect.GetSize().IsPositive()) {
2029 return;
2030 }
2031 rsNode_->SetBounds(rect.GetX(), rect.GetY(), rect.Width(), rect.Height());
2032 if (useContentRectForRSFrame_) {
2033 SetContentRectToFrame(rect);
2034 } else {
2035 rsNode_->SetFrame(rect.GetX(), rect.GetY(), rect.Width(), rect.Height());
2036 }
2037 }
2038
OnPositionUpdate(const OffsetT<Dimension> &)2039 void RosenRenderContext::OnPositionUpdate(const OffsetT<Dimension>& /*value*/)
2040 {
2041 SetPositionToRSNode();
2042 }
2043
OnOffsetUpdate(const OffsetT<Dimension> &)2044 void RosenRenderContext::OnOffsetUpdate(const OffsetT<Dimension>& /*value*/)
2045 {
2046 SetPositionToRSNode();
2047 }
2048
OnAnchorUpdate(const OffsetT<Dimension> &)2049 void RosenRenderContext::OnAnchorUpdate(const OffsetT<Dimension>& /*value*/)
2050 {
2051 SetPositionToRSNode();
2052 }
2053
OnZIndexUpdate(int32_t value)2054 void RosenRenderContext::OnZIndexUpdate(int32_t value)
2055 {
2056 CHECK_NULL_VOID(rsNode_);
2057 rsNode_->SetPositionZ(static_cast<float>(value));
2058 }
2059
ResetBlendBgColor()2060 void RosenRenderContext::ResetBlendBgColor()
2061 {
2062 CHECK_NULL_VOID(rsNode_);
2063 blendColor_ = Color::TRANSPARENT;
2064 auto blendColor =
2065 GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(blendColor_).BlendColor(hoveredColor_);
2066 rsNode_->SetBackgroundColor(blendColor.GetValue());
2067 RequestNextFrame();
2068 }
2069
BlendBgColor(const Color & color)2070 void RosenRenderContext::BlendBgColor(const Color& color)
2071 {
2072 CHECK_NULL_VOID(rsNode_);
2073 blendColor_ = color;
2074 auto blendColor =
2075 GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(blendColor_).BlendColor(hoveredColor_);
2076 rsNode_->SetBackgroundColor(blendColor.GetValue());
2077 RequestNextFrame();
2078 }
2079
ResetBlendBorderColor()2080 void RosenRenderContext::ResetBlendBorderColor()
2081 {
2082 CHECK_NULL_VOID(rsNode_);
2083 auto leftColor = (Color::TRANSPARENT).GetValue();
2084 auto topColor = (Color::TRANSPARENT).GetValue();
2085 auto rightColor = (Color::TRANSPARENT).GetValue();
2086 auto bottomColor = (Color::TRANSPARENT).GetValue();
2087 if (GetBorderColor().has_value()) {
2088 leftColor = GetBorderColor()->leftColor.value_or(Color::TRANSPARENT).GetValue();
2089 topColor = GetBorderColor()->topColor.value_or(Color::TRANSPARENT).GetValue();
2090 rightColor = GetBorderColor()->rightColor.value_or(Color::TRANSPARENT).GetValue();
2091 bottomColor = GetBorderColor()->bottomColor.value_or(Color::TRANSPARENT).GetValue();
2092 }
2093 rsNode_->SetBorderColor(leftColor, topColor, rightColor, bottomColor);
2094 RequestNextFrame();
2095 }
2096
BlendBorderColor(const Color & color)2097 void RosenRenderContext::BlendBorderColor(const Color& color)
2098 {
2099 CHECK_NULL_VOID(rsNode_);
2100 auto leftColor = color.GetValue();
2101 auto topColor = color.GetValue();
2102 auto rightColor = color.GetValue();
2103 auto bottomColor = color.GetValue();
2104 if (GetBorderColor().has_value()) {
2105 leftColor = (GetBorderColor()->leftColor.value_or(Color::TRANSPARENT).BlendColor(color)).GetValue();
2106 topColor = (GetBorderColor()->topColor.value_or(Color::TRANSPARENT).BlendColor(color)).GetValue();
2107 rightColor = (GetBorderColor()->rightColor.value_or(Color::TRANSPARENT).BlendColor(color)).GetValue();
2108 bottomColor = (GetBorderColor()->bottomColor.value_or(Color::TRANSPARENT).BlendColor(color)).GetValue();
2109 }
2110 rsNode_->SetBorderColor(leftColor, topColor, rightColor, bottomColor);
2111 RequestNextFrame();
2112 }
2113
PaintFocusState(const RoundRect & paintRect,const Color & paintColor,const Dimension & paintWidth,bool isAccessibilityFocus)2114 void RosenRenderContext::PaintFocusState(
2115 const RoundRect& paintRect, const Color& paintColor, const Dimension& paintWidth, bool isAccessibilityFocus)
2116 {
2117 LOGD("PaintFocusState rect is (%{public}f, %{public}f, %{public}f, %{public}f). Color is %{public}s, PainWidth is "
2118 "%{public}s",
2119 paintRect.GetRect().Left(), paintRect.GetRect().Top(), paintRect.GetRect().Width(),
2120 paintRect.GetRect().Height(), paintColor.ColorToString().c_str(), paintWidth.ToString().c_str());
2121 CHECK_NULL_VOID_NOLOG(paintRect.GetRect().IsValid());
2122 CHECK_NULL_VOID(rsNode_);
2123
2124 auto borderWidthPx = static_cast<float>(paintWidth.ConvertToPx());
2125
2126 auto paintTask = [paintColor, borderWidthPx](const RSRoundRect& rrect, RSCanvas& rsCanvas) mutable {
2127 RSPen pen;
2128 pen.SetAntiAlias(true);
2129 pen.SetColor(ToRSColor(paintColor));
2130 pen.SetWidth(borderWidthPx);
2131 rsCanvas.AttachPen(pen);
2132 rsCanvas.DrawRoundRect(rrect);
2133 };
2134 std::shared_ptr<Rosen::RectF> overlayRect = std::make_shared<Rosen::RectF>(
2135 paintRect.GetRect().Left() - borderWidthPx / 2, paintRect.GetRect().Top() - borderWidthPx / 2,
2136 paintRect.GetRect().Width() + borderWidthPx, paintRect.GetRect().Height() + borderWidthPx);
2137 if (isAccessibilityFocus) {
2138 if (!accessibilityFocusStateModifier_) {
2139 accessibilityFocusStateModifier_ = std::make_shared<FocusStateModifier>();
2140 }
2141 accessibilityFocusStateModifier_->SetRoundRect(paintRect, borderWidthPx);
2142 accessibilityFocusStateModifier_->SetPaintTask(std::move(paintTask));
2143 rsNode_->SetDrawRegion(overlayRect);
2144 rsNode_->AddModifier(accessibilityFocusStateModifier_);
2145 } else {
2146 if (!focusStateModifier_) {
2147 // TODO: Add property data
2148 focusStateModifier_ = std::make_shared<FocusStateModifier>();
2149 }
2150 focusStateModifier_->SetRoundRect(paintRect, borderWidthPx);
2151 focusStateModifier_->SetPaintTask(std::move(paintTask));
2152 rsNode_->SetDrawRegion(overlayRect);
2153 rsNode_->AddModifier(focusStateModifier_);
2154 }
2155 RequestNextFrame();
2156 }
2157
PaintFocusState(const RoundRect & paintRect,const Dimension & focusPaddingVp,const Color & paintColor,const Dimension & paintWidth,bool isAccessibilityFocus)2158 void RosenRenderContext::PaintFocusState(const RoundRect& paintRect, const Dimension& focusPaddingVp,
2159 const Color& paintColor, const Dimension& paintWidth, bool isAccessibilityFocus)
2160 {
2161 LOGD("PaintFocusState rect is (%{public}f, %{public}f, %{public}f, %{public}f). focusPadding is %{public}s, Color "
2162 "is %{public}s, PainWidth is %{public}s",
2163 paintRect.GetRect().Left(), paintRect.GetRect().Top(), paintRect.GetRect().Width(),
2164 paintRect.GetRect().Height(), focusPaddingVp.ToString().c_str(), paintColor.ColorToString().c_str(),
2165 paintWidth.ToString().c_str());
2166
2167 auto paintWidthPx = static_cast<float>(paintWidth.ConvertToPx());
2168 auto borderPaddingPx = static_cast<float>(focusPaddingVp.ConvertToPx());
2169 auto focusPaintRectLeft = paintRect.GetRect().Left() - borderPaddingPx - paintWidthPx / 2;
2170 auto focusPaintRectTop = paintRect.GetRect().Top() - borderPaddingPx - paintWidthPx / 2;
2171 auto focusPaintRectWidth = paintRect.GetRect().Width() + 2 * borderPaddingPx + paintWidthPx;
2172 auto focusPaintRectHeight = paintRect.GetRect().Height() + 2 * borderPaddingPx + paintWidthPx;
2173
2174 EdgeF diffRadius = { borderPaddingPx + paintWidthPx / 2, borderPaddingPx + paintWidthPx / 2 };
2175 auto focusPaintCornerTopLeft = paintRect.GetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS) + diffRadius;
2176 auto focusPaintCornerTopRight = paintRect.GetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS) + diffRadius;
2177 auto focusPaintCornerBottomLeft = paintRect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS) + diffRadius;
2178 auto focusPaintCornerBottomRight = paintRect.GetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS) + diffRadius;
2179
2180 RoundRect focusPaintRect;
2181 focusPaintRect.SetRect(RectF(focusPaintRectLeft, focusPaintRectTop, focusPaintRectWidth, focusPaintRectHeight));
2182 focusPaintRect.SetCornerRadius(
2183 RoundRect::CornerPos::TOP_LEFT_POS, focusPaintCornerTopLeft.x, focusPaintCornerTopLeft.y);
2184 focusPaintRect.SetCornerRadius(
2185 RoundRect::CornerPos::TOP_RIGHT_POS, focusPaintCornerTopRight.x, focusPaintCornerTopRight.y);
2186 focusPaintRect.SetCornerRadius(
2187 RoundRect::CornerPos::BOTTOM_LEFT_POS, focusPaintCornerBottomLeft.x, focusPaintCornerBottomLeft.y);
2188 focusPaintRect.SetCornerRadius(
2189 RoundRect::CornerPos::BOTTOM_RIGHT_POS, focusPaintCornerBottomRight.x, focusPaintCornerBottomRight.y);
2190
2191 PaintFocusState(focusPaintRect, paintColor, paintWidth, isAccessibilityFocus);
2192 }
2193
PaintFocusState(const Dimension & focusPaddingVp,const Color & paintColor,const Dimension & paintWidth)2194 void RosenRenderContext::PaintFocusState(
2195 const Dimension& focusPaddingVp, const Color& paintColor, const Dimension& paintWidth)
2196 {
2197 const auto& bounds = rsNode_->GetStagingProperties().GetBounds();
2198 const auto& radius = rsNode_->GetStagingProperties().GetCornerRadius();
2199
2200 RoundRect frameRect;
2201 frameRect.SetRect(RectF(0, 0, bounds.z_, bounds.w_));
2202 frameRect.SetCornerRadius(RoundRect::CornerPos::TOP_LEFT_POS, radius.x_, radius.x_);
2203 frameRect.SetCornerRadius(RoundRect::CornerPos::TOP_RIGHT_POS, radius.y_, radius.y_);
2204 frameRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_LEFT_POS, radius.z_, radius.z_);
2205 frameRect.SetCornerRadius(RoundRect::CornerPos::BOTTOM_RIGHT_POS, radius.w_, radius.w_);
2206
2207 PaintFocusState(frameRect, focusPaddingVp, paintColor, paintWidth);
2208 }
2209
ClearFocusState()2210 void RosenRenderContext::ClearFocusState()
2211 {
2212 LOGD("ClearFocusState in.");
2213 CHECK_NULL_VOID(rsNode_);
2214 auto context = PipelineBase::GetCurrentContext();
2215 CHECK_NULL_VOID(context);
2216 CHECK_NULL_VOID_NOLOG(focusStateModifier_);
2217 rsNode_->RemoveModifier(focusStateModifier_);
2218 RequestNextFrame();
2219 }
2220
FlushContentDrawFunction(CanvasDrawFunction && contentDraw)2221 void RosenRenderContext::FlushContentDrawFunction(CanvasDrawFunction&& contentDraw)
2222 {
2223 CHECK_NULL_VOID(rsNode_);
2224 CHECK_NULL_VOID(contentDraw);
2225 rsNode_->DrawOnNode(
2226 #ifndef USE_ROSEN_DRAWING
2227 Rosen::RSModifierType::CONTENT_STYLE, [contentDraw = std::move(contentDraw)](std::shared_ptr<SkCanvas> canvas) {
2228 RSCanvas rsCanvas(&canvas);
2229 contentDraw(rsCanvas);
2230 #else
2231 Rosen::RSModifierType::CONTENT_STYLE,
2232 [contentDraw = std::move(contentDraw)](std::shared_ptr<RSCanvas> canvas) {
2233 CHECK_NULL_VOID(canvas);
2234 contentDraw(*canvas);
2235 #endif
2236 });
2237 }
2238
2239 void RosenRenderContext::FlushContentModifier(const RefPtr<Modifier>& modifier)
2240 {
2241 CHECK_NULL_VOID(rsNode_);
2242 CHECK_NULL_VOID(modifier);
2243 auto modifierAdapter = std::static_pointer_cast<ContentModifierAdapter>(ConvertContentModifier(modifier));
2244 auto contentModifier = AceType::DynamicCast<ContentModifier>(modifier);
2245 CHECK_NULL_VOID(contentModifier);
2246 auto rect = contentModifier->GetBoundsRect();
2247 if (rect.has_value()) {
2248 std::shared_ptr<Rosen::RectF> overlayRect =
2249 std::make_shared<Rosen::RectF>(rect->GetX(), rect->GetY(), rect->Width(), rect->Height());
2250 rsNode_->SetDrawRegion(overlayRect);
2251 }
2252 rsNode_->SetIsCustomTextType(contentModifier->GetIsCustomFont());
2253 rsNode_->AddModifier(modifierAdapter);
2254 modifierAdapter->AttachProperties();
2255 }
2256
2257 void RosenRenderContext::FlushForegroundDrawFunction(CanvasDrawFunction&& foregroundDraw)
2258 {
2259 CHECK_NULL_VOID(rsNode_);
2260 CHECK_NULL_VOID(foregroundDraw);
2261 rsNode_->DrawOnNode(Rosen::RSModifierType::FOREGROUND_STYLE,
2262 #ifndef USE_ROSEN_DRAWING
2263 [foregroundDraw = std::move(foregroundDraw)](std::shared_ptr<SkCanvas> canvas) {
2264 RSCanvas rsCanvas(&canvas);
2265 foregroundDraw(rsCanvas);
2266 #else
2267 [foregroundDraw = std::move(foregroundDraw)](std::shared_ptr<RSCanvas> canvas) {
2268 CHECK_NULL_VOID(canvas);
2269 foregroundDraw(*canvas);
2270 #endif
2271 });
2272 }
2273
2274 void RosenRenderContext::FlushOverlayDrawFunction(CanvasDrawFunction&& overlayDraw)
2275 {
2276 CHECK_NULL_VOID(rsNode_);
2277 CHECK_NULL_VOID(overlayDraw);
2278 rsNode_->DrawOnNode(
2279 #ifndef USE_ROSEN_DRAWING
2280 Rosen::RSModifierType::OVERLAY_STYLE, [overlayDraw = std::move(overlayDraw)](std::shared_ptr<SkCanvas> canvas) {
2281 RSCanvas rsCanvas(&canvas);
2282 overlayDraw(rsCanvas);
2283 #else
2284 Rosen::RSModifierType::OVERLAY_STYLE,
2285 [overlayDraw = std::move(overlayDraw)](std::shared_ptr<RSCanvas> canvas) {
2286 CHECK_NULL_VOID(canvas);
2287 overlayDraw(*canvas);
2288 #endif
2289 });
2290 }
2291
2292 void RosenRenderContext::FlushOverlayModifier(const RefPtr<Modifier>& modifier)
2293 {
2294 CHECK_NULL_VOID(rsNode_);
2295 CHECK_NULL_VOID(modifier);
2296 auto modifierAdapter = std::static_pointer_cast<OverlayModifierAdapter>(ConvertOverlayModifier(modifier));
2297 auto overlayModifier = AceType::DynamicCast<OverlayModifier>(modifier);
2298 CHECK_NULL_VOID(overlayModifier);
2299 auto rect = overlayModifier->GetBoundsRect();
2300 std::shared_ptr<Rosen::RectF> overlayRect =
2301 std::make_shared<Rosen::RectF>(rect.GetX(), rect.GetY(), rect.Width(), rect.Height());
2302 rsNode_->SetDrawRegion(overlayRect);
2303 rsNode_->AddModifier(modifierAdapter);
2304 modifierAdapter->AttachProperties();
2305 }
2306
2307 const std::shared_ptr<Rosen::RSNode>& RosenRenderContext::GetRSNode()
2308 {
2309 return rsNode_;
2310 }
2311
2312 void RosenRenderContext::RebuildFrame(FrameNode* /*self*/, const std::list<RefPtr<FrameNode>>& children)
2313 {
2314 ReCreateRsNodeTree(children);
2315 RequestNextFrame();
2316 }
2317
2318 std::list<std::shared_ptr<Rosen::RSNode>> RosenRenderContext::GetChildrenRSNodes(
2319 const std::list<RefPtr<FrameNode>>& frameChildren)
2320 {
2321 std::list<std::shared_ptr<Rosen::RSNode>> rsNodes;
2322 for (const auto& child : frameChildren) {
2323 if (!child) {
2324 continue;
2325 }
2326 auto rosenRenderContext = DynamicCast<RosenRenderContext>(child->renderContext_);
2327 if (!rosenRenderContext) {
2328 continue;
2329 }
2330 auto rsnode = rosenRenderContext->GetRSNode();
2331 if (rsnode) {
2332 rsNodes.emplace_back(rsnode);
2333 }
2334 }
2335 return rsNodes;
2336 }
2337
2338 void RosenRenderContext::ReCreateRsNodeTree(const std::list<RefPtr<FrameNode>>& children)
2339 {
2340 CHECK_NULL_VOID(rsNode_);
2341 auto nowRSNodes = GetChildrenRSNodes(children);
2342 std::vector<OHOS::Rosen::NodeId> childNodeIds;
2343 for (auto& child : nowRSNodes) {
2344 childNodeIds.emplace_back(child->GetId());
2345 }
2346 if (childNodeIds == rsNode_->GetChildren()) {
2347 return;
2348 }
2349 rsNode_->ClearChildren();
2350 for (const auto& rsnode : nowRSNodes) {
2351 rsNode_->AddChild(rsnode, -1);
2352 }
2353 }
2354
2355 void RosenRenderContext::AddFrameChildren(FrameNode* /*self*/, const std::list<RefPtr<FrameNode>>& children)
2356 {
2357 CHECK_NULL_VOID(rsNode_);
2358 for (const auto& child : children) {
2359 if (!child) {
2360 continue;
2361 }
2362 auto rosenRenderContext = DynamicCast<RosenRenderContext>(child->renderContext_);
2363 if (!rosenRenderContext) {
2364 continue;
2365 }
2366 auto rsNode = rosenRenderContext->GetRSNode();
2367 if (rsNode) {
2368 rsNode_->AddChild(rsNode, -1);
2369 }
2370 }
2371 }
2372
2373 void RosenRenderContext::RemoveFrameChildren(FrameNode* /*self*/, const std::list<RefPtr<FrameNode>>& children)
2374 {
2375 CHECK_NULL_VOID(rsNode_);
2376 for (const auto& child : children) {
2377 if (!child) {
2378 continue;
2379 }
2380 auto rosenRenderContext = DynamicCast<RosenRenderContext>(child->renderContext_);
2381 if (!rosenRenderContext) {
2382 continue;
2383 }
2384 auto rsNode = rosenRenderContext->GetRSNode();
2385 if (rsNode) {
2386 rsNode_->RemoveChild(rsNode);
2387 }
2388 }
2389 }
2390
2391 void RosenRenderContext::MoveFrame(FrameNode* /*self*/, const RefPtr<FrameNode>& child, int32_t index)
2392 {
2393 CHECK_NULL_VOID(rsNode_);
2394 CHECK_NULL_VOID(child);
2395 auto rosenRenderContext = DynamicCast<RosenRenderContext>(child->renderContext_);
2396 CHECK_NULL_VOID(rosenRenderContext);
2397 auto rsNode = rosenRenderContext->GetRSNode();
2398 // no need to check nullptr since MoveChild will take care of it
2399 rsNode_->MoveChild(rsNode, index);
2400 }
2401
2402 void RosenRenderContext::AnimateHoverEffectScale(bool isHovered)
2403 {
2404 LOGD("HoverEffect.Scale: isHovered = %{public}d", isHovered);
2405 if ((isHovered && isHoveredScale_) || (!isHovered && !isHoveredScale_)) {
2406 return;
2407 }
2408 CHECK_NULL_VOID(rsNode_);
2409 auto pipeline = PipelineBase::GetCurrentContext();
2410 CHECK_NULL_VOID(pipeline);
2411 auto appTheme = pipeline->GetTheme<AppTheme>();
2412 CHECK_NULL_VOID(appTheme);
2413
2414 float hoverScaleFrom = isHovered ? appTheme->GetHoverScaleStart() : appTheme->GetHoverScaleEnd();
2415 float hoverColorTo = isHovered ? appTheme->GetHoverScaleEnd() : appTheme->GetHoverScaleStart();
2416 float scaleStart = hoverScaleFrom;
2417 float scaleEnd = hoverColorTo;
2418 int32_t themeDuration = appTheme->GetHoverDuration();
2419
2420 LOGD("HoverEffect.Scale: scale from %{public}f to %{public}f", scaleStart, scaleEnd);
2421 rsNode_->SetScale(scaleStart);
2422 Rosen::RSAnimationTimingProtocol protocol;
2423 protocol.SetDuration(themeDuration);
2424 RSNode::Animate(protocol, Rosen::RSAnimationTimingCurve::CreateCubicCurve(0.2f, 0.0f, 0.2f, 1.0f),
2425 [rsNode = rsNode_, scaleEnd]() {
2426 if (rsNode) {
2427 rsNode->SetScale(scaleEnd);
2428 }
2429 });
2430 isHoveredScale_ = isHovered;
2431 }
2432
2433 void RosenRenderContext::AnimateHoverEffectBoard(bool isHovered)
2434 {
2435 LOGD("HoverEffect.Highlight: isHovered = %{public}d", isHovered);
2436 if ((isHovered && isHoveredBoard_) || (!isHovered && !isHoveredBoard_)) {
2437 return;
2438 }
2439 CHECK_NULL_VOID(rsNode_);
2440 auto pipeline = PipelineBase::GetCurrentContext();
2441 CHECK_NULL_VOID(pipeline);
2442 auto appTheme = pipeline->GetTheme<AppTheme>();
2443 CHECK_NULL_VOID(appTheme);
2444
2445 Color hoverColorFrom = isHovered ? appTheme->GetHoverHighlightStart() : appTheme->GetHoverHighlightEnd();
2446 Color hoverColorTo = isHovered ? appTheme->GetHoverHighlightEnd() : appTheme->GetHoverHighlightStart();
2447 Color highlightStart =
2448 GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(blendColor_).BlendColor(hoverColorFrom);
2449 Color highlightEnd =
2450 GetBackgroundColor().value_or(Color::TRANSPARENT).BlendColor(blendColor_).BlendColor(hoverColorTo);
2451 int32_t themeDuration = appTheme->GetHoverDuration();
2452
2453 LOGD("HoverEffect.Highlight: background color from %{public}x to %{public}x", highlightStart.GetValue(),
2454 highlightEnd.GetValue());
2455 rsNode_->SetBackgroundColor(highlightStart.GetValue());
2456 Rosen::RSAnimationTimingProtocol protocol;
2457 protocol.SetDuration(themeDuration);
2458 RSNode::Animate(protocol, Rosen::RSAnimationTimingCurve::CreateCubicCurve(0.2f, 0.0f, 0.2f, 1.0f),
2459 [rsNode = rsNode_, highlightEnd]() {
2460 CHECK_NULL_VOID_NOLOG(rsNode);
2461 rsNode->SetBackgroundColor(highlightEnd.GetValue());
2462 });
2463 hoveredColor_ = hoverColorTo;
2464 isHoveredBoard_ = isHovered;
2465 }
2466
2467 void RosenRenderContext::UpdateBackBlurRadius(const Dimension& radius)
2468 {
2469 const auto& groupProperty = GetOrCreateBackground();
2470 if (groupProperty->CheckBlurRadius(radius)) {
2471 // Same with previous value
2472 return;
2473 }
2474 groupProperty->propBlurRadius = radius;
2475 SetBackBlurFilter();
2476 }
2477
2478 void RosenRenderContext::UpdateFrontBlurRadius(const Dimension& radius)
2479 {
2480 const auto& groupProperty = GetOrCreateForeground();
2481 if (groupProperty->CheckBlurRadius(radius)) {
2482 // Same with previous value
2483 return;
2484 }
2485 groupProperty->propBlurRadius = radius;
2486 SetFrontBlurFilter();
2487 }
2488
2489 void RosenRenderContext::OnBackShadowUpdate(const Shadow& shadow)
2490 {
2491 CHECK_NULL_VOID(rsNode_);
2492 if (!shadow.IsValid()) {
2493 if (shadow.GetHardwareAcceleration()) {
2494 rsNode_->SetShadowElevation(0.0);
2495 } else {
2496 rsNode_->SetShadowRadius(0.0);
2497 }
2498 RequestNextFrame();
2499 return;
2500 }
2501 rsNode_->SetShadowColor(shadow.GetColor().GetValue());
2502 rsNode_->SetShadowOffsetX(shadow.GetOffset().GetX());
2503 rsNode_->SetShadowOffsetY(shadow.GetOffset().GetY());
2504 rsNode_->SetShadowMask(shadow.GetShadowType() == ShadowType::BLUR);
2505 if (shadow.GetHardwareAcceleration()) {
2506 rsNode_->SetShadowElevation(shadow.GetElevation());
2507 } else {
2508 #ifndef USE_ROSEN_DRAWING
2509 rsNode_->SetShadowRadius(SkiaDecorationPainter::ConvertRadiusToSigma(shadow.GetBlurRadius()));
2510 #else
2511 rsNode_->SetShadowRadius(DrawingDecorationPainter::ConvertRadiusToSigma(shadow.GetBlurRadius()));
2512 #endif
2513 }
2514 RequestNextFrame();
2515 }
2516
2517 // called when frameNode size changes
2518 void RosenRenderContext::PaintGraphics()
2519 {
2520 CHECK_NULL_VOID(rsNode_);
2521 auto&& graphicProps = GetOrCreateGraphics();
2522
2523 if (!graphics_) {
2524 graphics_ = std::make_unique<GraphicModifiers>();
2525 }
2526 if (graphicProps->HasFrontGrayScale()) {
2527 auto grayScale = graphicProps->GetFrontGrayScaleValue();
2528 OnFrontGrayScaleUpdate(grayScale);
2529 }
2530
2531 if (graphicProps->HasFrontBrightness()) {
2532 auto brightness = graphicProps->GetFrontBrightnessValue();
2533 OnFrontBrightnessUpdate(brightness);
2534 }
2535
2536 if (graphicProps->HasFrontContrast()) {
2537 auto contrast = graphicProps->GetFrontContrastValue();
2538 OnFrontContrastUpdate(contrast);
2539 }
2540
2541 if (graphicProps->HasFrontSaturate()) {
2542 auto saturate = graphicProps->GetFrontSaturateValue();
2543 OnFrontSaturateUpdate(saturate);
2544 }
2545
2546 if (graphicProps->HasFrontSepia()) {
2547 auto sepia = graphicProps->GetFrontSepiaValue();
2548 OnFrontSepiaUpdate(sepia);
2549 }
2550
2551 if (graphicProps->HasFrontInvert()) {
2552 auto invert = graphicProps->GetFrontInvertValue();
2553 OnFrontInvertUpdate(invert);
2554 }
2555
2556 if (graphicProps->HasFrontHueRotate()) {
2557 auto hueRotate = graphicProps->GetFrontHueRotateValue();
2558 OnFrontHueRotateUpdate(hueRotate);
2559 }
2560
2561 if (graphicProps->HasFrontColorBlend()) {
2562 auto colorBlend = graphicProps->GetFrontColorBlendValue();
2563 OnFrontColorBlendUpdate(colorBlend);
2564 }
2565 }
2566
2567 // helper function to check if frame react is valid
2568 bool RosenRenderContext::RectIsNull()
2569 {
2570 RectF rect = GetPaintRectWithoutTransform();
2571 return NearZero(rect.Width()) || NearZero(rect.Height());
2572 }
2573
2574 template<typename T, typename D>
2575 void RosenRenderContext::SetGraphicModifier(std::shared_ptr<T>& modifier, D data)
2576 {
2577 if (!modifier) {
2578 LOGD("create new modifier");
2579 modifier = std::make_shared<T>();
2580 rsNode_->AddModifier(modifier);
2581 }
2582 modifier->SetCustomData(data);
2583
2584 auto borderRadius = GetBorderRadius();
2585 if (borderRadius.has_value()) {
2586 Rosen::Vector4f rsRadius;
2587 ConvertRadius(*borderRadius, rsRadius);
2588 modifier->SetCornerRadius(rsRadius);
2589 }
2590 }
2591
2592 void RosenRenderContext::AddModifier(const std::shared_ptr<Rosen::RSModifier>& modifier)
2593 {
2594 CHECK_NULL_VOID(modifier);
2595 rsNode_->AddModifier(modifier);
2596 }
2597
2598 void RosenRenderContext::RemoveModifier(const std::shared_ptr<Rosen::RSModifier>& modifier)
2599 {
2600 CHECK_NULL_VOID(modifier);
2601 rsNode_->RemoveModifier(modifier);
2602 }
2603
2604 // helper function to update one of the graphic effects
2605 template<typename T, typename D>
2606 void RosenRenderContext::UpdateGraphic(std::shared_ptr<T>& modifier, D data)
2607 {
2608 CHECK_NULL_VOID_NOLOG(!RectIsNull());
2609 LOGD("updating graphic effect");
2610 SetGraphicModifier(modifier, data);
2611 RequestNextFrame();
2612 }
2613
2614 void RosenRenderContext::OnFrontBrightnessUpdate(const Dimension& brightness)
2615 {
2616 CHECK_NULL_VOID(rsNode_);
2617 rsNode_->SetBrightness(brightness.Value());
2618 RequestNextFrame();
2619 }
2620
2621 void RosenRenderContext::OnFrontGrayScaleUpdate(const Dimension& grayScale)
2622 {
2623 CHECK_NULL_VOID(rsNode_);
2624 rsNode_->SetGrayScale(grayScale.Value());
2625 RequestNextFrame();
2626 }
2627
2628 void RosenRenderContext::OnFrontContrastUpdate(const Dimension& contrast)
2629 {
2630 CHECK_NULL_VOID(rsNode_);
2631 rsNode_->SetContrast(contrast.Value());
2632 RequestNextFrame();
2633 }
2634
2635 void RosenRenderContext::OnFrontSaturateUpdate(const Dimension& saturate)
2636 {
2637 CHECK_NULL_VOID(rsNode_);
2638 rsNode_->SetSaturate(saturate.Value());
2639 RequestNextFrame();
2640 }
2641
2642 void RosenRenderContext::OnFrontSepiaUpdate(const Dimension& sepia)
2643 {
2644 CHECK_NULL_VOID(rsNode_);
2645 rsNode_->SetSepia(sepia.Value());
2646 RequestNextFrame();
2647 }
2648
2649 void RosenRenderContext::OnFrontInvertUpdate(const Dimension& invert)
2650 {
2651 CHECK_NULL_VOID(rsNode_);
2652 rsNode_->SetInvert(invert.Value());
2653 RequestNextFrame();
2654 }
2655
2656 void RosenRenderContext::OnFrontHueRotateUpdate(float hueRotate)
2657 {
2658 CHECK_NULL_VOID(rsNode_);
2659 rsNode_->SetHueRotate(hueRotate);
2660 RequestNextFrame();
2661 }
2662
2663 void RosenRenderContext::OnFrontColorBlendUpdate(const Color& colorBlend)
2664 {
2665 CHECK_NULL_VOID(rsNode_);
2666 rsNode_->SetColorBlend(colorBlend.GetValue());
2667 RequestNextFrame();
2668 }
2669
2670 void RosenRenderContext::OnLinearGradientBlurUpdate(const NG::LinearGradientBlurPara& blurPara)
2671 {
2672 float blurRadius = 0.0f;
2673 if (blurPara.blurRadius_.IsValid()) {
2674 float radiusPx = blurPara.blurRadius_.ConvertToPx();
2675 blurRadius = radiusPx;
2676 }
2677
2678 CHECK_NULL_VOID(rsNode_);
2679 std::shared_ptr<Rosen::RSLinearGradientBlurPara> rsLinearGradientBlurPara(
2680 std::make_shared<Rosen::RSLinearGradientBlurPara>(
2681 blurRadius, blurPara.fractionStops_, static_cast<Rosen::GradientDirection>(blurPara.direction_)));
2682
2683 rsNode_->SetLinearGradientBlurPara(rsLinearGradientBlurPara);
2684 RequestNextFrame();
2685 }
2686
2687 void RosenRenderContext::OnDynamicLightUpRateUpdate(const float rate)
2688 {
2689 CHECK_NULL_VOID(rsNode_);
2690 rsNode_->SetDynamicLightUpRate(rate);
2691 RequestNextFrame();
2692 }
2693
2694 void RosenRenderContext::OnDynamicLightUpDegreeUpdate(const float degree)
2695 {
2696 CHECK_NULL_VOID(rsNode_);
2697 rsNode_->SetDynamicLightUpDegree(degree);
2698 RequestNextFrame();
2699 }
2700
2701 void RosenRenderContext::UpdateTransition(const TransitionOptions& options)
2702 {
2703 CHECK_NULL_VOID(rsNode_);
2704 if (options.Type == TransitionType::ALL || options.Type == TransitionType::APPEARING) {
2705 if (!propTransitionAppearing_) {
2706 propTransitionAppearing_ = std::make_unique<TransitionOptions>(options);
2707 } else {
2708 *propTransitionAppearing_ = options;
2709 }
2710 propTransitionAppearing_->Type = TransitionType::APPEARING;
2711 }
2712 if (options.Type == TransitionType::ALL || options.Type == TransitionType::DISAPPEARING) {
2713 if (!propTransitionDisappearing_) {
2714 propTransitionDisappearing_ = std::make_unique<TransitionOptions>(options);
2715 } else {
2716 *propTransitionDisappearing_ = options;
2717 }
2718 propTransitionDisappearing_->Type = TransitionType::DISAPPEARING;
2719 }
2720 }
2721
2722 std::shared_ptr<Rosen::RSTransitionEffect> RosenRenderContext::GetRSTransitionWithoutType(
2723 const std::unique_ptr<TransitionOptions>& options, const SizeF& frameSize)
2724 {
2725 if (options == nullptr) {
2726 return nullptr;
2727 }
2728 std::shared_ptr<Rosen::RSTransitionEffect> effect = Rosen::RSTransitionEffect::Create();
2729 if (options->HasOpacity()) {
2730 effect = effect->Opacity(options->GetOpacityValue());
2731 }
2732 if (options->HasTranslate()) {
2733 const auto& translate = options->GetTranslateValue();
2734 effect = effect->Translate({ static_cast<float>(translate.x.ConvertToPxWithSize(frameSize.Width())),
2735 static_cast<float>(translate.y.ConvertToPxWithSize(frameSize.Height())),
2736 static_cast<float>(translate.z.ConvertToPx()) });
2737 }
2738 if (options->HasScale()) {
2739 const auto& scale = options->GetScaleValue();
2740 effect = effect->Scale({ scale.xScale, scale.yScale, scale.zScale });
2741 }
2742 if (options->HasRotate()) {
2743 const auto& rotate = options->GetRotateValue();
2744 effect = effect->Rotate({ rotate.xDirection, rotate.yDirection, rotate.zDirection, rotate.angle });
2745 }
2746 return effect;
2747 }
2748
2749 void RosenRenderContext::PaintGradient(const SizeF& frameSize)
2750 {
2751 CHECK_NULL_VOID(rsNode_);
2752 auto& gradientProperty = GetOrCreateGradient();
2753 Gradient gradient;
2754 if (gradientProperty->HasLinearGradient()) {
2755 gradient = gradientProperty->GetLinearGradientValue();
2756 }
2757 if (gradientProperty->HasRadialGradient()) {
2758 gradient = gradientProperty->GetRadialGradientValue();
2759 }
2760 if (gradientProperty->HasSweepGradient()) {
2761 gradient = gradientProperty->GetSweepGradientValue();
2762 }
2763 auto shader = SkiaDecorationPainter::CreateGradientShader(gradient, frameSize);
2764 rsNode_->SetBackgroundShader(RSShader::CreateRSShader(shader));
2765 }
2766
2767 void RosenRenderContext::OnLinearGradientUpdate(const NG::Gradient& gradient)
2768 {
2769 RectF rect = GetPaintRectWithoutTransform();
2770 if (!RectIsNull()) {
2771 PaintGradient(rect.GetSize());
2772 }
2773 RequestNextFrame();
2774 }
2775
2776 void RosenRenderContext::OnRadialGradientUpdate(const NG::Gradient& gradient)
2777 {
2778 RectF rect = GetPaintRectWithoutTransform();
2779 if (!RectIsNull()) {
2780 PaintGradient(rect.GetSize());
2781 }
2782 RequestNextFrame();
2783 }
2784
2785 void RosenRenderContext::OnSweepGradientUpdate(const NG::Gradient& gradient)
2786 {
2787 RectF rect = GetPaintRectWithoutTransform();
2788 if (!RectIsNull()) {
2789 PaintGradient(rect.GetSize());
2790 }
2791 RequestNextFrame();
2792 }
2793
2794 void RosenRenderContext::PaintClipShape(const std::unique_ptr<ClipProperty>& clip, const SizeF& frameSize)
2795 {
2796 auto basicShape = clip->GetClipShapeValue();
2797 #ifndef USE_ROSEN_DRAWING
2798 auto skPath = SkiaDecorationPainter::SkiaCreateSkPath(basicShape, frameSize);
2799 auto shapePath = Rosen::RSPath::CreateRSPath(skPath);
2800 if (!clipBoundModifier_) {
2801 auto prop = std::make_shared<RSProperty<std::shared_ptr<Rosen::RSPath>>>(shapePath);
2802 clipBoundModifier_ = std::make_shared<Rosen::RSClipBoundsModifier>(prop);
2803 rsNode_->AddModifier(clipBoundModifier_);
2804 } else {
2805 auto property = std::static_pointer_cast<RSProperty<std::shared_ptr<Rosen::RSPath>>>(
2806 clipBoundModifier_->GetProperty());
2807 property->Set(shapePath);
2808 }
2809 #else
2810 auto rsPath = DrawingDecorationPainter::DrawingCreatePath(basicShape, frameSize);
2811 auto shapePath = Rosen::RSPath::CreateRSPath(rsPath);
2812 if (!clipBoundModifier_) {
2813 auto prop = std::make_shared<RSProperty<RSPath>>(shapePath);
2814 clipBoundModifier_ = std::make_shared<Rosen::RSClipBoundsModifier>(prop);
2815 rsNode_->AddModifier(clipBoundModifier_);
2816 } else {
2817 auto property = std::static_pointer_cast<RSProperty<std::shared_ptr<RSPath>>>(
2818 clipBoundModifier_->GetProperty());
2819 property->Set(shapePath);
2820 }
2821 #endif
2822 }
2823
2824 void RosenRenderContext::PaintClipMask(const std::unique_ptr<ClipProperty>& clip, const SizeF& frameSize)
2825 {
2826 if (moonProgressModifier_) {
2827 auto modifierAdapter =
2828 std::static_pointer_cast<OverlayModifierAdapter>(ConvertOverlayModifier(moonProgressModifier_));
2829 rsNode_->RemoveModifier(modifierAdapter);
2830 moonProgressModifier_ = nullptr;
2831 }
2832 auto basicShape = clip->GetClipMaskValue();
2833 #ifndef USE_ROSEN_DRAWING
2834 auto skPath = SkiaDecorationPainter::SkiaCreateSkPath(basicShape, frameSize);
2835 auto maskPath = Rosen::RSMask::CreatePathMask(skPath, SkiaDecorationPainter::CreateMaskSkPaint(basicShape));
2836 if (!clipMaskModifier_) {
2837 auto prop = std::make_shared<RSProperty<std::shared_ptr<Rosen::RSMask>>>(maskPath);
2838 clipMaskModifier_ = std::make_shared<Rosen::RSMaskModifier>(prop);
2839 rsNode_->AddModifier(clipMaskModifier_);
2840 } else {
2841 auto property = std::static_pointer_cast<RSProperty<std::shared_ptr<Rosen::RSMask>>>(
2842 clipMaskModifier_->GetProperty());
2843 property->Set(maskPath);
2844 }
2845 #else
2846 auto rsPath = DrawingDecorationPainter::DrawingCreatePath(basicShape, frameSize);
2847 auto maskPath = Rosen::RSMask::CreatePathMask(
2848 rsPath, DrawingDecorationPainter::CreateMaskDrawingBrush(basicShape));
2849 if (!clipMaskModifier_) {
2850 auto prop = std::make_shared<RSProperty<RSMask>>(maskPath);
2851 clipMaskModifier_ = std::make_shared<Rosen::RSMaskModifier>(prop);
2852 rsNode_->AddModifier(clipMaskModifier_);
2853 } else {
2854 auto property = std::static_pointer_cast<RSProperty<std::shared_ptr<RSMask>>>(
2855 clipMaskModifier_->GetProperty());
2856 property->Set(maskPath);
2857 }
2858 #endif
2859 }
2860
2861
2862 void RosenRenderContext::PaintClip(const SizeF& frameSize)
2863 {
2864 CHECK_NULL_VOID(rsNode_);
2865 auto& clip = GetOrCreateClip();
2866 if (clip->HasClipShape()) {
2867 PaintClipShape(clip, frameSize);
2868 }
2869
2870 if (clip->HasClipMask()) {
2871 PaintClipMask(clip, frameSize);
2872 }
2873 }
2874
2875 void RosenRenderContext::PaintProgressMask()
2876 {
2877 if (clipMaskModifier_) {
2878 rsNode_->RemoveModifier(clipMaskModifier_);
2879 clipMaskModifier_ = nullptr;
2880 }
2881 if (!moonProgressModifier_) {
2882 moonProgressModifier_ = AceType::MakeRefPtr<MoonProgressModifier>();
2883 auto modifierAdapter =
2884 std::static_pointer_cast<OverlayModifierAdapter>(ConvertOverlayModifier(moonProgressModifier_));
2885 rsNode_->AddModifier(modifierAdapter);
2886 modifierAdapter->AttachProperties();
2887 }
2888 auto progress = GetProgressMaskValue();
2889 moonProgressModifier_->SetMaskColor(LinearColor(progress->GetColor()));
2890 moonProgressModifier_->SetMaxValue(progress->GetMaxValue());
2891 if (progress->GetValue() > moonProgressModifier_->GetMaxValue()) {
2892 progress->SetValue(moonProgressModifier_->GetMaxValue());
2893 }
2894 moonProgressModifier_->SetValue(progress->GetValue());
2895 }
2896
2897 void RosenRenderContext::SetClipBoundsWithCommands(const std::string& commands)
2898 {
2899 CHECK_NULL_VOID(rsNode_);
2900 #ifndef USE_ROSEN_DRAWING
2901 SkPath skPath;
2902 SkParsePath::FromSVGString(commands.c_str(), &skPath);
2903 rsNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(skPath));
2904 #else
2905 RSRecordingPath rsPath;
2906 rsPath.BuildFromSVGString(commands);
2907 rsNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(rsPath));
2908 #endif
2909 }
2910
2911 void RosenRenderContext::ClipWithRect(const RectF& rectF)
2912 {
2913 CHECK_NULL_VOID(rsNode_);
2914 #ifndef USE_ROSEN_DRAWING
2915 SkPath skPath;
2916 skPath.addRect(rectF.GetX(), rectF.GetY(), rectF.GetX() + rectF.Width(), rectF.GetY() + rectF.Height());
2917 rsNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(skPath));
2918 #else
2919 RSRecordingPath rsPath;
2920 rsPath.AddRect({ rectF.GetX(), rectF.GetY(), rectF.GetX() + rectF.Width(), rectF.GetY() + rectF.Height() });
2921 rsNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(rsPath));
2922 #endif
2923 }
2924
2925 void RosenRenderContext::ClipWithRRect(const RectF& rectF, const RadiusF& radiusF)
2926 {
2927 CHECK_NULL_VOID(rsNode_);
2928 Rosen::Vector4f rect;
2929 Rosen::Vector4f radius;
2930 rect.SetValues(rectF.GetX(), rectF.GetY(), rectF.GetX() + rectF.Width(), rectF.GetY() + rectF.Height());
2931 radius.SetValues(radiusF.GetCorner(RoundRect::CornerPos::TOP_LEFT_POS).x,
2932 radiusF.GetCorner(RoundRect::CornerPos::TOP_RIGHT_POS).x,
2933 radiusF.GetCorner(RoundRect::CornerPos::BOTTOM_LEFT_POS).x,
2934 radiusF.GetCorner(RoundRect::CornerPos::BOTTOM_RIGHT_POS).x);
2935 rsNode_->SetClipRRect(rect, radius);
2936 RequestNextFrame();
2937 }
2938
2939 void RosenRenderContext::OnClipShapeUpdate(const RefPtr<BasicShape>& /*basicShape*/)
2940 {
2941 RectF rect = GetPaintRectWithoutTransform();
2942 if (!RectIsNull()) {
2943 PaintClip(SizeF(rect.Width(), rect.Height()));
2944 }
2945 RequestNextFrame();
2946 }
2947
2948 void RosenRenderContext::OnClipEdgeUpdate(bool isClip)
2949 {
2950 CHECK_NULL_VOID(rsNode_);
2951 if (isClip) {
2952 rsNode_->SetClipToBounds(true);
2953 } else {
2954 // In the internal implementation, some nodes call SetClipToBounds(true), some call SetClipToFrame(true).
2955 // If the developer set clip to false, we should disable all internal clips
2956 // so that the child component can go beyond the parent component
2957 rsNode_->SetClipToBounds(false);
2958 rsNode_->SetClipToFrame(false);
2959 }
2960 RequestNextFrame();
2961 }
2962
2963 void RosenRenderContext::OnClipMaskUpdate(const RefPtr<BasicShape>& /*basicShape*/)
2964 {
2965 RectF rect = GetPaintRectWithoutTransform();
2966 if (!RectIsNull()) {
2967 PaintClip(SizeF(rect.Width(), rect.Height()));
2968 }
2969 RequestNextFrame();
2970 }
2971
2972 void RosenRenderContext::OnProgressMaskUpdate(const RefPtr<ProgressMaskProperty>& /* progress */)
2973 {
2974 PaintProgressMask();
2975 CHECK_NULL_VOID(rsNode_);
2976 rsNode_->SetClipToBounds(true);
2977 RequestNextFrame();
2978 }
2979
2980 RefPtr<PageTransitionEffect> RosenRenderContext::GetDefaultPageTransition(PageTransitionType type)
2981 {
2982 auto resultEffect = AceType::MakeRefPtr<PageTransitionEffect>(type, PageTransitionOption());
2983 resultEffect->SetScaleEffect(ScaleOptions(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct));
2984 TranslateOptions translate;
2985 auto rect = GetPaintRectWithoutTransform();
2986 switch (type) {
2987 case PageTransitionType::ENTER_PUSH:
2988 case PageTransitionType::EXIT_POP:
2989 translate.x = Dimension(rect.Width());
2990 break;
2991 case PageTransitionType::ENTER_POP:
2992 case PageTransitionType::EXIT_PUSH:
2993 translate.x = Dimension(-rect.Width());
2994 break;
2995 default:
2996 LOGI("unexpected transition type");
2997 break;
2998 }
2999 resultEffect->SetTranslateEffect(translate);
3000 resultEffect->SetOpacityEffect(1);
3001 return resultEffect;
3002 }
3003
3004 RefPtr<PageTransitionEffect> RosenRenderContext::GetPageTransitionEffect(const RefPtr<PageTransitionEffect>& transition)
3005 {
3006 auto resultEffect = AceType::MakeRefPtr<PageTransitionEffect>(
3007 transition->GetPageTransitionType(), transition->GetPageTransitionOption());
3008 resultEffect->SetScaleEffect(
3009 transition->GetScaleEffect().value_or(ScaleOptions(1.0f, 1.0f, 1.0f, 0.5_pct, 0.5_pct)));
3010 TranslateOptions translate;
3011 // slide and translate, only one can be effective
3012 if (transition->GetSlideEffect().has_value()) {
3013 auto rect = GetPaintRectWithoutTransform();
3014 switch (transition->GetSlideEffect().value()) {
3015 case SlideEffect::LEFT:
3016 translate.x = Dimension(-rect.Width());
3017 break;
3018 case SlideEffect::RIGHT:
3019 translate.x = Dimension(rect.Width());
3020 break;
3021 case SlideEffect::BOTTOM:
3022 translate.y = Dimension(rect.Height());
3023 break;
3024 case SlideEffect::TOP:
3025 translate.y = Dimension(-rect.Height());
3026 break;
3027 default:
3028 LOGW("unexpected slide effect");
3029 break;
3030 }
3031 } else if (transition->GetTranslateEffect().has_value()) {
3032 auto rect = GetPaintRectWithoutTransform();
3033 const auto& translateOptions = transition->GetTranslateEffect();
3034 translate.x = Dimension(translateOptions->x.ConvertToPxWithSize(rect.Width()));
3035 translate.y = Dimension(translateOptions->y.ConvertToPxWithSize(rect.Height()));
3036 translate.z = Dimension(translateOptions->z.ConvertToPx());
3037 }
3038 resultEffect->SetTranslateEffect(translate);
3039 resultEffect->SetOpacityEffect(transition->GetOpacityEffect().value_or(1));
3040 return resultEffect;
3041 }
3042
3043 bool RosenRenderContext::TriggerPageTransition(PageTransitionType type, const std::function<void()>& onFinish)
3044 {
3045 bool transitionIn = true;
3046 if (type == PageTransitionType::ENTER_PUSH || type == PageTransitionType::ENTER_POP) {
3047 transitionIn = true;
3048 } else if (type == PageTransitionType::EXIT_PUSH || type == PageTransitionType::EXIT_POP) {
3049 transitionIn = false;
3050 } else {
3051 LOGW("unexpected transition type");
3052 return false;
3053 }
3054 CHECK_NULL_RETURN(rsNode_, false);
3055 auto host = GetHost();
3056 CHECK_NULL_RETURN(host, false);
3057 auto pattern = host->GetPattern<PagePattern>();
3058 CHECK_NULL_RETURN(pattern, false);
3059 auto transition = pattern->FindPageTransitionEffect(type);
3060 RefPtr<PageTransitionEffect> effect;
3061 AnimationOption option;
3062 if (transition) {
3063 effect = GetPageTransitionEffect(transition);
3064 option.SetCurve(transition->GetCurve());
3065 option.SetDuration(transition->GetDuration());
3066 option.SetDelay(transition->GetDelay());
3067 } else {
3068 effect = GetDefaultPageTransition(type);
3069 const int32_t pageTransitionDuration = 300;
3070 option.SetCurve(Curves::LINEAR);
3071 option.SetDuration(pageTransitionDuration);
3072 #ifdef QUICK_PUSH_TRANSITION
3073 auto pipeline = PipelineBase::GetCurrentContext();
3074 if (pipeline) {
3075 const int32_t nanoToMilliSeconds = 1000000;
3076 const int32_t minTransitionDuration = pageTransitionDuration / 2;
3077 const int32_t frameDelayTime = 32;
3078 int32_t startDelayTime =
3079 static_cast<int32_t>(pipeline->GetTimeFromExternalTimer() - pipeline->GetLastTouchTime()) /
3080 nanoToMilliSeconds;
3081 startDelayTime = std::max(0, startDelayTime);
3082 int32_t delayedDuration = pageTransitionDuration > startDelayTime ? pageTransitionDuration - startDelayTime
3083 : pageTransitionDuration;
3084 delayedDuration = std::max(minTransitionDuration, delayedDuration - frameDelayTime);
3085 LOGI("Use quick push delayedDuration:%{public}d", delayedDuration);
3086 option.SetDuration(delayedDuration);
3087 }
3088 #endif
3089 }
3090 const auto& scaleOptions = effect->GetScaleEffect();
3091 const auto& translateOptions = effect->GetTranslateEffect();
3092 UpdateTransformCenter(DimensionOffset(scaleOptions->centerX, scaleOptions->centerY));
3093
3094 if (transitionIn) {
3095 UpdateTransformScale(VectorF(scaleOptions->xScale, scaleOptions->yScale));
3096 UpdateTransformTranslate(translateOptions.value());
3097 UpdateOpacity(effect->GetOpacityEffect().value());
3098 AnimationUtils::OpenImplicitAnimation(option, option.GetCurve(), onFinish);
3099 UpdateTransformScale(VectorF(1.0f, 1.0f));
3100 UpdateTransformTranslate({ 0.0f, 0.0f, 0.0f });
3101 UpdateOpacity(1.0);
3102 AnimationUtils::CloseImplicitAnimation();
3103 return true;
3104 }
3105 UpdateTransformScale(VectorF(1.0f, 1.0f));
3106 UpdateTransformTranslate({ 0.0f, 0.0f, 0.0f });
3107 UpdateOpacity(1.0);
3108 AnimationUtils::OpenImplicitAnimation(option, option.GetCurve(), onFinish);
3109 UpdateTransformScale(VectorF(scaleOptions->xScale, scaleOptions->yScale));
3110 UpdateTransformTranslate(translateOptions.value());
3111 UpdateOpacity(effect->GetOpacityEffect().value());
3112 AnimationUtils::CloseImplicitAnimation();
3113 return true;
3114 }
3115
3116 void RosenRenderContext::PaintOverlayText()
3117 {
3118 CHECK_NULL_VOID(rsNode_);
3119 auto& overlay = GetOrCreateOverlay();
3120 if (overlay->HasOverlayText()) {
3121 auto overlayText = overlay->GetOverlayTextValue();
3122 auto paintRect = GetPaintRectWithTransform();
3123 std::shared_ptr<Rosen::RectF> overlayRect;
3124 if (modifier_) {
3125 modifier_->SetCustomData(NG::OverlayTextData(overlayText));
3126 auto overlayOffset = modifier_->GetOverlayOffset();
3127 overlayRect = std::make_shared<Rosen::RectF>(paintRect.GetX(), paintRect.GetY(),
3128 paintRect.Width() + overlayOffset.GetX(), paintRect.Height() + overlayOffset.GetY());
3129 rsNode_->SetDrawRegion(overlayRect);
3130 } else {
3131 modifier_ = std::make_shared<OverlayTextModifier>();
3132 rsNode_->AddModifier(modifier_);
3133 modifier_->SetCustomData(NG::OverlayTextData(overlayText));
3134 auto overlayOffset = modifier_->GetOverlayOffset();
3135 overlayRect = std::make_shared<Rosen::RectF>(paintRect.GetX(), paintRect.GetY(),
3136 paintRect.Width() + overlayOffset.GetX(), paintRect.Height() + overlayOffset.GetY());
3137 rsNode_->SetDrawRegion(overlayRect);
3138 }
3139 }
3140 }
3141
3142 void RosenRenderContext::OnOverlayTextUpdate(const OverlayOptions& overlay)
3143 {
3144 if (!RectIsNull()) {
3145 PaintOverlayText();
3146 }
3147 RequestNextFrame();
3148 }
3149
3150 void RosenRenderContext::OnMotionPathUpdate(const MotionPathOption& motionPath)
3151 {
3152 CHECK_NULL_VOID(rsNode_);
3153 if (!motionPath.IsValid()) {
3154 rsNode_->SetMotionPathOption(nullptr);
3155 return;
3156 }
3157 auto motionOption = Rosen::RSMotionPathOption(motionPath.GetPath());
3158 motionOption.SetBeginFraction(motionPath.GetBegin());
3159 motionOption.SetEndFraction(motionPath.GetEnd());
3160 motionOption.SetRotationMode(
3161 motionPath.GetRotate() ? Rosen::RotationMode::ROTATE_AUTO : Rosen::RotationMode::ROTATE_NONE);
3162 motionOption.SetPathNeedAddOrigin(HasOffset());
3163 rsNode_->SetMotionPathOption(std::make_shared<Rosen::RSMotionPathOption>(motionOption));
3164 RequestNextFrame();
3165 }
3166
3167 void RosenRenderContext::SetSharedTranslate(float xTranslate, float yTranslate)
3168 {
3169 if (!sharedTransitionModifier_) {
3170 sharedTransitionModifier_ = std::make_unique<SharedTransitionModifier>();
3171 }
3172 AddOrChangeTranslateModifier(rsNode_, sharedTransitionModifier_->translateXY,
3173 sharedTransitionModifier_->translateXYValue, { xTranslate, yTranslate });
3174 }
3175
3176 void RosenRenderContext::ResetSharedTranslate()
3177 {
3178 CHECK_NULL_VOID_NOLOG(sharedTransitionModifier_);
3179 CHECK_NULL_VOID_NOLOG(sharedTransitionModifier_->translateXY);
3180 CHECK_NULL_VOID_NOLOG(rsNode_);
3181 rsNode_->RemoveModifier(sharedTransitionModifier_->translateXY);
3182 sharedTransitionModifier_->translateXYValue = nullptr;
3183 sharedTransitionModifier_->translateXY = nullptr;
3184 }
3185
3186 void RosenRenderContext::ResetPageTransitionEffect()
3187 {
3188 UpdateTransformScale(VectorF(1.0f, 1.0f));
3189 UpdateTransformTranslate({ 0.0f, 0.0f, 0.0f });
3190 UpdateOpacity(1.0);
3191 }
3192
3193 void RosenRenderContext::AddChild(const RefPtr<RenderContext>& renderContext, int index)
3194 {
3195 CHECK_NULL_VOID(rsNode_);
3196 auto rosenRenderContext = AceType::DynamicCast<RosenRenderContext>(renderContext);
3197 CHECK_NULL_VOID(rosenRenderContext);
3198 auto child = rosenRenderContext->GetRSNode();
3199 rsNode_->AddChild(child, index);
3200 }
3201
3202 void RosenRenderContext::RemoveChild(const RefPtr<RenderContext>& renderContext)
3203 {
3204 CHECK_NULL_VOID(rsNode_);
3205 auto rosenRenderContext = AceType::DynamicCast<RosenRenderContext>(renderContext);
3206 CHECK_NULL_VOID(rosenRenderContext);
3207 auto child = rosenRenderContext->GetRSNode();
3208 rsNode_->RemoveChild(child);
3209 }
3210
3211 void RosenRenderContext::ClearChildren()
3212 {
3213 CHECK_NULL_VOID(rsNode_);
3214 rsNode_->ClearChildren();
3215 }
3216
3217 void RosenRenderContext::SetBounds(float positionX, float positionY, float width, float height)
3218 {
3219 CHECK_NULL_VOID(rsNode_);
3220 rsNode_->SetBounds(positionX, positionY, width, height);
3221 }
3222
3223 void RosenRenderContext::SetUsingContentRectForRenderFrame(bool value)
3224 {
3225 useContentRectForRSFrame_ = value;
3226 }
3227
3228 void RosenRenderContext::SetFrameGravity(OHOS::Rosen::Gravity gravity)
3229 {
3230 CHECK_NULL_VOID(rsNode_);
3231 rsNode_->SetFrameGravity(gravity);
3232 }
3233
3234 void RosenRenderContext::ClearDrawCommands()
3235 {
3236 StartRecording();
3237 StopRecordingIfNeeded();
3238 }
3239
3240 void RosenRenderContext::SetRSNode(const std::shared_ptr<RSNode>& externalNode)
3241 {
3242 // Update rsNode_ to externalNode.
3243 if (externalNode == rsNode_) {
3244 return;
3245 }
3246 rsNode_ = externalNode;
3247
3248 // TODO: need move property to new rs node.
3249 ResetTransform();
3250 ResetTransformMatrix();
3251
3252 // after update, tell parent to update RSNode hierarchy.
3253 auto uiNode = GetHost();
3254 CHECK_NULL_VOID(uiNode);
3255 auto parentUINode = uiNode->GetParent();
3256 CHECK_NULL_VOID(parentUINode);
3257 parentUINode->MarkNeedSyncRenderTree();
3258 parentUINode->RebuildRenderContextTree();
3259 }
3260
3261 void RosenRenderContext::OnMouseSelectUpdate(bool isSelected, const Color& fillColor, const Color& strokeColor)
3262 {
3263 auto host = GetHost();
3264 CHECK_NULL_VOID(host);
3265
3266 RectF rect = RectF();
3267 if (isSelected) {
3268 auto geometryNode = host->GetGeometryNode();
3269 CHECK_NULL_VOID(geometryNode);
3270 rect = geometryNode->GetFrameRect();
3271 rect.SetOffset(OffsetF());
3272 }
3273
3274 UpdateMouseSelectWithRect(rect, fillColor, strokeColor);
3275 }
3276
3277 void RosenRenderContext::UpdateMouseSelectWithRect(const RectF& rect, const Color& fillColor, const Color& strokeColor)
3278 {
3279 if (!rect.IsValid()) {
3280 LOGE("UpdateMouseSelectWithRect: selected rect not valid");
3281 return;
3282 }
3283 PaintMouseSelectRect(rect, fillColor, strokeColor);
3284 RequestNextFrame();
3285 }
3286
3287 void RosenRenderContext::PaintMouseSelectRect(const RectF& rect, const Color& fillColor, const Color& strokeColor)
3288 {
3289 if (mouseSelectModifier_) {
3290 mouseSelectModifier_->SetSelectRect(rect);
3291 return;
3292 }
3293
3294 auto paintTask = [&fillColor, &strokeColor](const RectF& rect, RSCanvas& rsCanvas) mutable {
3295 RSBrush brush;
3296 brush.SetColor(ToRSColor(fillColor));
3297 rsCanvas.AttachBrush(brush);
3298 rsCanvas.DrawRect(ToRSRect(rect));
3299 rsCanvas.DetachBrush();
3300 RSPen pen;
3301 pen.SetColor(ToRSColor(strokeColor));
3302 rsCanvas.AttachPen(pen);
3303 rsCanvas.DrawRect(ToRSRect(rect));
3304 };
3305
3306 mouseSelectModifier_ = std::make_shared<MouseSelectModifier>();
3307 mouseSelectModifier_->SetPaintTask(std::move(paintTask));
3308 rsNode_->AddModifier(mouseSelectModifier_);
3309 }
3310
3311 void RosenRenderContext::DumpInfo() const
3312 {
3313 if (rsNode_) {
3314 DumpLog::GetInstance().AddDesc(rsNode_->DumpNode(0));
3315 }
3316 }
3317
3318 void RosenRenderContext::MarkContentChanged(bool isChanged)
3319 {
3320 CHECK_NULL_VOID(rsNode_);
3321 rsNode_->MarkContentChanged(isChanged);
3322 }
3323
3324 void RosenRenderContext::MarkDrivenRender(bool flag)
3325 {
3326 CHECK_NULL_VOID(rsNode_);
3327 rsNode_->MarkDrivenRender(flag);
3328 }
3329
3330 void RosenRenderContext::MarkDrivenRenderItemIndex(int32_t index)
3331 {
3332 CHECK_NULL_VOID(rsNode_);
3333 rsNode_->MarkDrivenRenderItemIndex(index);
3334 }
3335
3336 void RosenRenderContext::MarkDrivenRenderFramePaintState(bool flag)
3337 {
3338 CHECK_NULL_VOID(rsNode_);
3339 rsNode_->MarkDrivenRenderFramePaintState(flag);
3340 }
3341
3342 void RosenRenderContext::UpdateChainedTransition(const RefPtr<NG::ChainedTransitionEffect>& effect)
3343 {
3344 if (transitionEffect_) {
3345 // use effect to update rosenTransitionEffect activeValue
3346 if (RosenTransitionEffect::UpdateRosenTransitionEffect(transitionEffect_, effect)) {
3347 return;
3348 }
3349 LOGD("transition effect struct changed");
3350 transitionEffect_->Detach(this);
3351 }
3352 transitionEffect_ = RosenTransitionEffect::ConvertToRosenTransitionEffect(effect);
3353 hasDefaultTransition_ = false;
3354 CHECK_NULL_VOID(transitionEffect_);
3355 auto frameNode = GetHost();
3356 CHECK_NULL_VOID(frameNode);
3357 bool isOnTheTree = frameNode->IsOnMainTree();
3358 // transition effects should be initialized without animation.
3359 RSNode::ExecuteWithoutAnimation([this, isOnTheTree, &frameNode]() {
3360 // transitionIn effects should be initialized as active if currently not on the tree.
3361 transitionEffect_->Attach(Claim(this), !isOnTheTree);
3362 });
3363 }
3364
3365 void RosenRenderContext::NotifyTransition(bool isTransitionIn)
3366 {
3367 CHECK_NULL_VOID_NOLOG(transitionEffect_);
3368
3369 auto frameNode = GetHost();
3370 CHECK_NULL_VOID(frameNode);
3371 LOGD("RosenTransitionEffect::NotifyTransition transition BEGIN, node %{public}d, isTransitionIn: %{public}d",
3372 frameNode->GetId(), isTransitionIn);
3373
3374 RSNode::ExecuteWithoutAnimation([this, &frameNode, isTransitionIn]() {
3375 if (isTransitionIn && disappearingTransitionCount_ == 0) {
3376 // transitionIn, reset to state before attaching in case of node reappear
3377 transitionEffect_->Attach(Claim(this), true);
3378 }
3379 auto pipeline = PipelineBase::GetCurrentContext();
3380 CHECK_NULL_VOID(pipeline);
3381 SizeF rootSize(pipeline->GetRootWidth(), pipeline->GetRootHeight());
3382 auto parentOffset = frameNode->GetPaintRectOffset(true);
3383 auto rect = GetPaintRectWithoutTransform();
3384 // Do not consider the position after its own transform, as the transition modifier also affects the transform
3385 rect.SetOffset(parentOffset + rect.GetOffset());
3386
3387 transitionEffect_->UpdateTransitionContext(Claim(this), rect, rootSize);
3388 });
3389
3390 if (isTransitionIn) {
3391 // Isolate the animation callback function, to avoid changing the callback timing of current implicit animation.
3392 AnimationUtils::AnimateWithCurrentOptions(
3393 [this]() {
3394 transitionEffect_->Appear();
3395 ++appearingTransitionCount_;
3396 },
3397 [weakThis = WeakClaim(this), nodeId = frameNode->GetId(), id = Container::CurrentId()]() {
3398 auto context = weakThis.Upgrade();
3399 CHECK_NULL_VOID(context);
3400 ContainerScope scope(id);
3401 LOGD("RosenTransitionEffect::NotifyTransition transition END, node %{public}d, isTransitionIn: IN",
3402 nodeId);
3403 context->OnTransitionInFinish();
3404 },
3405 false);
3406 } else {
3407 // Re-use current implicit animation timing params, only replace the finish callback function.
3408 // The finish callback function will perform all the necessary cleanup work.
3409 // Important Note on timing:
3410 // 1. If any transition animations are created, the finish callback function will only be called when ALL
3411 // animations have finished. This is accomplished by sharing the same shared_ptr<AnimationFinishCallback>
3412 // among all animations.
3413 // 2. If no transition animations are created, the finish callback function will be called IMMEDIATELY. This
3414 // is accomplished by setting the last param (timing sensitive) to false, which avoids creating an empty
3415 // 'timer' animation.
3416 AnimationUtils::AnimateWithCurrentOptions(
3417 [this]() {
3418 transitionEffect_->Disappear();
3419 // update transition out count
3420 ++disappearingTransitionCount_;
3421 },
3422 [weakThis = WeakClaim(this), nodeId = frameNode->GetId(), id = Container::CurrentId()]() {
3423 auto context = weakThis.Upgrade();
3424 CHECK_NULL_VOID(context);
3425 ContainerScope scope(id);
3426 auto pipeline = PipelineBase::GetCurrentContext();
3427 CHECK_NULL_VOID(pipeline);
3428 auto taskExecutor = pipeline->GetTaskExecutor();
3429 CHECK_NULL_VOID(taskExecutor);
3430 taskExecutor->PostTask(
3431 [id, nodeId, context]() {
3432 ContainerScope scope(id);
3433 LOGD("RosenTransitionEffect::NotifyTransition transition END, node %{public}d, "
3434 "isTransitionIn: OUT",
3435 nodeId);
3436 // update transition out count
3437 context->OnTransitionOutFinish();
3438 },
3439 TaskExecutor::TaskType::UI);
3440 },
3441 false);
3442 }
3443 }
3444
3445 void RosenRenderContext::RemoveDefaultTransition()
3446 {
3447 if (hasDefaultTransition_ && transitionEffect_ && disappearingTransitionCount_ == 0 &&
3448 appearingTransitionCount_ == 0) {
3449 transitionEffect_->Detach(this);
3450 transitionEffect_ = nullptr;
3451 hasDefaultTransition_ = false;
3452 }
3453 }
3454
3455 void RosenRenderContext::OnTransitionInFinish()
3456 {
3457 --appearingTransitionCount_;
3458 // make sure we are the last transition out animation, if not, return.
3459 if (appearingTransitionCount_ > 0) {
3460 LOGD("RosenTransitionEffect: appearingTransitionCount_ is %{public}d, not the last transition out animation",
3461 appearingTransitionCount_);
3462 return;
3463 }
3464 if (appearingTransitionCount_ < 0) {
3465 LOGW("RosenTransitionEffect: appearingTransitionCount_ should not be less than 0");
3466 appearingTransitionCount_ = 0;
3467 }
3468 // when all transition in/out animations are finished, we should remove the default transition effect.
3469 RemoveDefaultTransition();
3470 }
3471
3472 void RosenRenderContext::OnTransitionOutFinish()
3473 {
3474 // update transition out count
3475 --disappearingTransitionCount_;
3476 // make sure we are the last transition out animation, if not, return.
3477 if (disappearingTransitionCount_ > 0) {
3478 LOGD("RosenTransitionEffect: disappearingTransitionCount_ is %{public}d, not the last transition out animation",
3479 disappearingTransitionCount_);
3480 return;
3481 }
3482 if (disappearingTransitionCount_ < 0) {
3483 LOGW("RosenTransitionEffect: disappearingTransitionCount_ should not be less than 0");
3484 disappearingTransitionCount_ = 0;
3485 }
3486 // when all transition in/out animations are finished, we should remove the default transition effect.
3487 RemoveDefaultTransition();
3488 auto host = GetHost();
3489 CHECK_NULL_VOID(host);
3490 auto parent = host->GetParent();
3491 CHECK_NULL_VOID(parent);
3492 if (!host->IsVisible()) {
3493 // trigger transition through visibility
3494 parent->MarkNeedSyncRenderTree();
3495 parent->RebuildRenderContextTree();
3496 return;
3497 }
3498 RefPtr<UINode> breakPointChild = host;
3499 RefPtr<UINode> breakPointParent = breakPointChild->GetParent();
3500 while (breakPointParent && !breakPointChild->IsDisappearing()) {
3501 // recursively looking up the node tree, until we reach the breaking point (IsDisappearing() == true).
3502 // Because when trigger transition, only the breakPoint will be marked as disappearing and
3503 // moved to disappearingChildren.
3504 breakPointChild = breakPointParent;
3505 breakPointParent = breakPointParent->GetParent();
3506 }
3507 // if can not find the breakPoint, means the node is not disappearing (reappear?), return.
3508 if (!breakPointParent) {
3509 LOGI("RosenTransitionEffect: node is not disappearing, skip, id: %{public}d", host->GetId());
3510 return;
3511 }
3512 if (breakPointChild->RemoveImmediately()) {
3513 LOGD("RosenTransitionEffect: transition out finish, node %{public}d, break point %{public}d, break point tag: "
3514 "%{public}s",
3515 host->GetId(), breakPointChild->GetId(), breakPointChild->GetTag().c_str());
3516 breakPointChild->OnRemoveFromParent(false);
3517 // remove breakPoint
3518 breakPointParent->RemoveDisappearingChild(breakPointChild);
3519 breakPointParent->MarkNeedSyncRenderTree();
3520 breakPointParent->RebuildRenderContextTree();
3521 } else {
3522 LOGD("RosenTransitionEffect: transition out finish, node %{public}d, node tag: %{public}s", host->GetId(),
3523 host->GetTag().c_str());
3524 // When host's transition is done, RemoveImmediately must return true, so this branch means
3525 // host is different from breakPointChild. It will be removed when breakPoint is removed.
3526 }
3527 if (isModalRootNode_ && breakPointParent->GetChildren().empty()) {
3528 auto grandParent = breakPointParent->GetParent();
3529 CHECK_NULL_VOID(grandParent);
3530 grandParent->RemoveChild(breakPointParent);
3531 grandParent->RebuildRenderContextTree();
3532 }
3533 }
3534
3535 void RosenRenderContext::SetActualForegroundColor(const Color& value)
3536 {
3537 CHECK_NULL_VOID(rsNode_);
3538 rsNode_->SetForegroundColor(value.GetValue());
3539 RequestNextFrame();
3540 }
3541
3542 void RosenRenderContext::AttachNodeAnimatableProperty(RefPtr<NodeAnimatablePropertyBase> property)
3543 {
3544 CHECK_NULL_VOID(rsNode_);
3545 CHECK_NULL_VOID(property);
3546 if (!property->GetModifyImpl()) {
3547 auto nodeModifierImpl = std::make_shared<RSNodeModifierImpl>();
3548 CHECK_NULL_VOID(nodeModifierImpl);
3549 property->SetModifyImpl(nodeModifierImpl);
3550 rsNode_->AddModifier(nodeModifierImpl);
3551 nodeModifierImpl->AddProperty(property->GetProperty());
3552 }
3553 }
3554
3555 void RosenRenderContext::InitEventClickEffect()
3556 {
3557 if (touchListener_) {
3558 return;
3559 }
3560 auto host = GetHost();
3561 CHECK_NULL_VOID(host);
3562 auto gesture = host->GetOrCreateGestureEventHub();
3563 CHECK_NULL_VOID(gesture);
3564 auto touchCallback = [weak = WeakClaim(this)](const TouchEventInfo& info) {
3565 auto renderContext = weak.Upgrade();
3566 CHECK_NULL_VOID(renderContext);
3567 renderContext->ClickEffectPlayAnimation(info.GetTouches().front().GetTouchType());
3568 };
3569 touchListener_ = MakeRefPtr<TouchEventImpl>(std::move(touchCallback));
3570 gesture->AddTouchEvent(touchListener_);
3571 }
3572
3573 void RosenRenderContext::ClickEffectPlayAnimation(const TouchType& touchType)
3574 {
3575 if (touchType != TouchType::DOWN && touchType != TouchType::UP && touchType != TouchType::CANCEL) {
3576 return;
3577 }
3578 auto value = GetClickEffectLevelValue();
3579 auto level = value.level;
3580 auto scaleValue = value.scaleNumber;
3581 auto springCurve = UpdatePlayAnimationValue(level, scaleValue);
3582
3583 AnimationOption option;
3584 option.SetCurve(springCurve);
3585 option.SetDuration(DEFAULT_OPTION_DURATION);
3586
3587 if (touchType == TouchType::DOWN && level != ClickEffectLevel::UNDEFINED) {
3588 if (isTouchUpFinished_) {
3589 auto defaultScale = VectorF(1.0f, 1.0f);
3590 auto currentScale = GetTransformScaleValue(defaultScale);
3591 currentScale_ = currentScale;
3592 UpdateTransformScale(currentScale_);
3593
3594 AnimationUtils::OpenImplicitAnimation(option, springCurve, nullptr);
3595 VectorF valueScale(scaleValue, scaleValue);
3596 UpdateTransformScale(valueScale);
3597 AnimationUtils::CloseImplicitAnimation();
3598 }
3599 isTouchUpFinished_ = false;
3600 }
3601
3602 if ((touchType == TouchType::UP || touchType == TouchType::CANCEL) && level != ClickEffectLevel::UNDEFINED) {
3603 AnimationUtils::OpenImplicitAnimation(option, springCurve, nullptr);
3604 UpdateTransformScale(currentScale_);
3605 AnimationUtils::CloseImplicitAnimation();
3606 isTouchUpFinished_ = true;
3607 }
3608 }
3609
3610 RefPtr<Curve> RosenRenderContext::UpdatePlayAnimationValue(const ClickEffectLevel& level, float& scaleValue)
3611 {
3612 float velocity = 0.0f;
3613 float mass = 0.0f;
3614 float stiffness = 0.0f;
3615 float damping = 0.0f;
3616 if (level == ClickEffectLevel::LIGHT) {
3617 velocity = ANIMATION_CURVE_VELOCITY_LIGHT_OR_MIDDLE;
3618 mass = ANIMATION_CURVE_MASS;
3619 stiffness = ANIMATION_CURVE_STIFFNESS_LIGHT;
3620 damping = ANIMATION_CURVE_DAMPING_LIGHT;
3621 if (GreatOrEqual(scaleValue, 0.0) && LessOrEqual(scaleValue, 1.0)) {
3622 scaleValue = sqrt(scaleValue);
3623 } else {
3624 scaleValue = sqrt(DEFAULT_SCALE_LIGHT);
3625 }
3626 } else if (level == ClickEffectLevel::MIDDLE) {
3627 velocity = ANIMATION_CURVE_VELOCITY_LIGHT_OR_MIDDLE;
3628 mass = ANIMATION_CURVE_MASS;
3629 stiffness = ANIMATION_CURVE_STIFFNESS_MIDDLE;
3630 damping = ANIMATION_CURVE_DAMPING_MIDDLE;
3631 if (GreatOrEqual(scaleValue, 0.0) && LessOrEqual(scaleValue, 1.0)) {
3632 scaleValue = sqrt(scaleValue);
3633 } else {
3634 scaleValue = sqrt(DEFAULT_SCALE_MIDDLE_OR_HEAVY);
3635 }
3636 } else if (level == ClickEffectLevel::HEAVY) {
3637 velocity = ANIMATION_CURVE_VELOCITY_HEAVY;
3638 mass = ANIMATION_CURVE_MASS;
3639 stiffness = ANIMATION_CURVE_STIFFNESS_HEAVY;
3640 damping = ANIMATION_CURVE_DAMPING_HEAVY;
3641 if (GreatOrEqual(scaleValue, 0.0) && LessOrEqual(scaleValue, 1.0)) {
3642 scaleValue = sqrt(scaleValue);
3643 } else {
3644 scaleValue = sqrt(DEFAULT_SCALE_MIDDLE_OR_HEAVY);
3645 }
3646 }
3647 return AceType::MakeRefPtr<InterpolatingSpring>(velocity, mass, stiffness, damping);
3648 }
3649
3650 void RosenRenderContext::RegisterSharedTransition(const RefPtr<RenderContext>& other)
3651 {
3652 auto otherContext = AceType::DynamicCast<RosenRenderContext>(other);
3653 if (!otherContext) {
3654 LOGE("RosenRenderContext::RegisterSharedTransition: other is not RosenRenderContext");
3655 return;
3656 }
3657 RSNode::RegisterTransitionPair(rsNode_->GetId(), otherContext->rsNode_->GetId());
3658 }
3659
3660 void RosenRenderContext::UnregisterSharedTransition(const RefPtr<RenderContext>& other)
3661 {
3662 auto otherContext = AceType::DynamicCast<RosenRenderContext>(other);
3663 if (!otherContext) {
3664 // the paired node is already destroyed, we don't need to unregister it, Rosen will handle it.
3665 return;
3666 }
3667 RSNode::UnregisterTransitionPair(rsNode_->GetId(), otherContext->rsNode_->GetId());
3668 }
3669
3670 inline void RosenRenderContext::ConvertRadius(const BorderRadiusProperty& value, Rosen::Vector4f& cornerRadius)
3671 {
3672 cornerRadius.SetValues(static_cast<float>(value.radiusTopLeft.value_or(Dimension()).ConvertToPx()),
3673 static_cast<float>(value.radiusTopRight.value_or(Dimension()).ConvertToPx()),
3674 static_cast<float>(value.radiusBottomRight.value_or(Dimension()).ConvertToPx()),
3675 static_cast<float>(value.radiusBottomLeft.value_or(Dimension()).ConvertToPx()));
3676 }
3677
3678 #ifndef USE_ROSEN_DRAWING
3679 void RosenRenderContext::PaintSkBgImage()
3680 {
3681 auto image = DynamicCast<NG::SkiaImage>(bgImage_);
3682 #else
3683 void RosenRenderContext::PaintRSBgImage()
3684 {
3685 auto image = DynamicCast<NG::DrawingImage>(bgImage_);
3686 #endif
3687 CHECK_NULL_VOID(bgLoadingCtx_ && image);
3688
3689 auto rosenImage = std::make_shared<Rosen::RSImage>();
3690 auto compressData = image->GetCompressData();
3691 if (compressData) {
3692 rosenImage->SetCompressData(
3693 compressData, image->GetUniqueID(), image->GetCompressWidth(), image->GetCompressHeight());
3694 } else {
3695 rosenImage->SetImage(image->GetImage());
3696 }
3697 rosenImage->SetImageRepeat(static_cast<int>(GetBackgroundImageRepeat().value_or(ImageRepeat::NO_REPEAT)));
3698 rsNode_->SetBgImage(rosenImage);
3699 }
3700
3701 void RosenRenderContext::PaintPixmapBgImage()
3702 {
3703 auto image = DynamicCast<NG::PixelMapImage>(bgImage_);
3704 CHECK_NULL_VOID(bgLoadingCtx_ && image);
3705 auto pixmap = image->GetPixelMap();
3706 CHECK_NULL_VOID(pixmap);
3707
3708 auto rosenImage = std::make_shared<Rosen::RSImage>();
3709 rosenImage->SetPixelMap(pixmap->GetPixelMapSharedPtr());
3710 rosenImage->SetImageRepeat(static_cast<int>(GetBackgroundImageRepeat().value_or(ImageRepeat::NO_REPEAT)));
3711 rsNode_->SetBgImage(rosenImage);
3712 }
3713
3714 void RosenRenderContext::OnRenderGroupUpdate(bool isRenderGroup)
3715 {
3716 CHECK_NULL_VOID(rsNode_);
3717 rsNode_->MarkNodeGroup(isRenderGroup);
3718 }
3719
3720 void RosenRenderContext::OnRenderFitUpdate(RenderFit renderFit)
3721 {
3722 CHECK_NULL_VOID(rsNode_);
3723 rsNode_->SetFrameGravity(GetRosenGravity(renderFit));
3724 }
3725
3726 void RosenRenderContext::SetContentRectToFrame(RectF rect)
3727 {
3728 auto host = GetHost();
3729 CHECK_NULL_VOID(host);
3730 auto&& padding = host->GetGeometryNode()->GetPadding();
3731 // minus padding to get contentRect
3732 if (padding) {
3733 rect.SetOffset(rect.GetOffset() + OffsetF { padding->left.value_or(0), padding->top.value_or(0) });
3734 auto size = rect.GetSize();
3735 MinusPaddingToSize(*padding, size);
3736 rect.SetSize(size);
3737 }
3738 rsNode_->SetFrame(rect.GetX(), rect.GetY(), rect.Width(), rect.Height());
3739 }
3740
3741 } // namespace OHOS::Ace::NG
3742