1 /*
2 * Copyright (c) 2022 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/render_context.h"
17
18 #include "base/utils/multi_thread.h"
19 #include "core/pipeline_ng/pipeline_context.h"
20
21 namespace OHOS::Ace::NG {
22 namespace {
RenderFitToString(RenderFit renderFit)23 std::string RenderFitToString(RenderFit renderFit)
24 {
25 static const std::string RenderFitStyles[] = { "RenderFit.CENTER", "RenderFit.TOP", "RenderFit.BOTTOM",
26 "RenderFit.LEFT", "RenderFit.RIGHT", "RenderFit.TOP_LEFT", "RenderFit.TOP_RIGHT", "RenderFit.BOTTOM_LEFT",
27 "RenderFit.BOTTOM_RIGHT", "RenderFit.RESIZE_FILL", "RenderFit.RESIZE_CONTAIN",
28 "RenderFit.RESIZE_CONTAIN_TOP_LEFT", "RenderFit.RESIZE_CONTAIN_BOTTOM_RIGHT", "RenderFit.RESIZE_COVER",
29 "RenderFit.RESIZE_COVER_TOP_LEFT", "RenderFit.RESIZE_COVER_BOTTOM_RIGHT" };
30 return RenderFitStyles[static_cast<int>(renderFit)];
31 }
32
UseEffectTypeToString(EffectType effectType)33 std::string UseEffectTypeToString(EffectType effectType)
34 {
35 static const std::string UseEffectTypeStyles[] = { "EffectType.DEFAULT", "EffectType.WINDOW_EFFECT" };
36 return UseEffectTypeStyles[static_cast<int>(effectType)];
37 }
38
39 } // namespace
40
SetRequestFrame(const std::function<void ()> & requestFrame)41 void RenderContext::SetRequestFrame(const std::function<void()>& requestFrame)
42 {
43 requestFrame_ = requestFrame;
44 }
45
RequestNextFrame() const46 void RenderContext::RequestNextFrame() const
47 {
48 auto node = GetHost();
49 // This function has a mirror function (XxxMultiThread) and needs to be modified synchronously.
50 FREE_NODE_CHECK(node, RequestNextFrame);
51 if (requestFrame_) {
52 requestFrame_();
53 CHECK_NULL_VOID(node);
54 auto eventHub = node->GetEventHub<NG::EventHub>();
55 if (node->GetInspectorId().has_value() || (eventHub && eventHub->HasNDKDrawCompletedCallback())) {
56 auto pipeline = AceType::DynamicCast<PipelineContext>(PipelineBase::GetCurrentContext());
57 CHECK_NULL_VOID(pipeline);
58 pipeline->SetNeedRenderNode(WeakPtr<FrameNode>(node));
59 }
60 if (node->IsObservedByDrawChildren()) {
61 auto pipeline = AceType::DynamicCast<PipelineContext>(PipelineBase::GetCurrentContext());
62 CHECK_NULL_VOID(pipeline);
63
64 auto frameNode = AceType::DynamicCast<FrameNode>(node->GetObserverParentForDrawChildren());
65 pipeline->SetNeedRenderForDrawChildrenNode(WeakPtr<FrameNode>(frameNode));
66 }
67 }
68 }
69
SetHostNode(const WeakPtr<FrameNode> & host)70 void RenderContext::SetHostNode(const WeakPtr<FrameNode>& host)
71 {
72 host_ = host;
73 }
74
GetHost() const75 RefPtr<FrameNode> RenderContext::GetHost() const
76 {
77 return host_.Upgrade();
78 }
79
SetSharedTransitionOptions(const std::shared_ptr<SharedTransitionOption> & option)80 void RenderContext::SetSharedTransitionOptions(const std::shared_ptr<SharedTransitionOption>& option)
81 {
82 sharedTransitionOption_ = option;
83 }
84
GetSharedTransitionOption() const85 const std::shared_ptr<SharedTransitionOption>& RenderContext::GetSharedTransitionOption() const
86 {
87 return sharedTransitionOption_;
88 }
89
SetShareId(const ShareId & shareId)90 void RenderContext::SetShareId(const ShareId& shareId)
91 {
92 shareId_ = shareId;
93 }
94
GetShareId() const95 const ShareId& RenderContext::GetShareId() const
96 {
97 return shareId_;
98 }
99
HasSharedTransition() const100 bool RenderContext::HasSharedTransition() const
101 {
102 return !shareId_.empty();
103 }
104
HasSharedTransitionOption() const105 bool RenderContext::HasSharedTransitionOption() const
106 {
107 return sharedTransitionOption_ != nullptr;
108 }
109
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const110 void RenderContext::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
111 {
112 ACE_PROPERTY_TO_JSON_VALUE(propBorder_, BorderProperty);
113 ACE_PROPERTY_TO_JSON_VALUE(propOuterBorder_, OuterBorderProperty);
114 ACE_PROPERTY_TO_JSON_VALUE(propPointLight_, PointLightProperty);
115 ACE_PROPERTY_TO_JSON_VALUE(propBdImage_, BorderImageProperty);
116 ACE_PROPERTY_TO_JSON_VALUE(propOverlay_, OverlayProperty);
117 ACE_PROPERTY_TO_JSON_VALUE(propPositionProperty_, RenderPositionProperty);
118 ACE_PROPERTY_TO_JSON_VALUE(propBackground_, BackgroundProperty);
119 ACE_PROPERTY_TO_JSON_VALUE(propForeground_, ForegroundProperty);
120 ACE_PROPERTY_TO_JSON_VALUE(propGraphics_, GraphicsProperty);
121 ACE_PROPERTY_TO_JSON_VALUE(propGradient_, GradientProperty);
122 ACE_PROPERTY_TO_JSON_VALUE(propTransform_, TransformProperty);
123 ACE_PROPERTY_TO_JSON_VALUE(propClip_, ClipProperty);
124 ACE_PROPERTY_TO_JSON_VALUE(GetBackBlurStyle(), BlurStyleOption);
125 ACE_PROPERTY_TO_JSON_VALUE(GetBackgroundEffect(), EffectOption);
126 if (filter.IsFastFilter()) {
127 ObscuredToJsonValue(json, filter);
128 return;
129 }
130 if (propTransformMatrix_.has_value()) {
131 auto jsonValue = JsonUtil::Create(true);
132 jsonValue->Put("type", "matrix");
133 auto matrixString = propTransformMatrix_->ToString();
134 while (matrixString.find("\n") != std::string::npos) {
135 auto num = matrixString.find("\n");
136 matrixString.replace(num, 1, "");
137 }
138 jsonValue->Put("matrix", matrixString.c_str());
139 json->PutExtAttr("transform", jsonValue, filter);
140 } else {
141 json->PutExtAttr("transform", JsonUtil::Create(true), filter);
142 }
143 json->PutExtAttr("backgroundColor",
144 propBackgroundColor_.value_or(Color::TRANSPARENT).ColorToString().c_str(), filter);
145 json->PutExtAttr("zIndex", propZIndex_.value_or(0), filter);
146 json->PutExtAttr("opacity", propOpacity_.value_or(1), filter);
147 if (propProgressMask_.has_value() && propProgressMask_.value()) {
148 json->PutExtAttr("total", propProgressMask_.value()->GetMaxValue(), filter);
149 json->PutExtAttr("updateProgress", propProgressMask_.value()->GetValue(), filter);
150 json->PutExtAttr("updateColor", propProgressMask_.value()->GetColor().ColorToString().c_str(), filter);
151 json->PutExtAttr("enableBreathe", propProgressMask_.value()->GetEnableBreathe(), filter);
152 }
153 json->PutExtAttr("lightUpEffect", propLightUpEffect_.value_or(0.0), filter);
154 json->PutExtAttr("sphericalEffect", propSphericalEffect_.value_or(0.0), filter);
155 auto pixStretchEffectOption = propPixelStretchEffect_.value_or(PixStretchEffectOption());
156 auto pixelJsonValue = JsonUtil::Create(true);
157 pixelJsonValue->Put("left", pixStretchEffectOption.left.ToString().c_str());
158 pixelJsonValue->Put("right", pixStretchEffectOption.right.ToString().c_str());
159 pixelJsonValue->Put("top", pixStretchEffectOption.top.ToString().c_str());
160 pixelJsonValue->Put("bottom", pixStretchEffectOption.bottom.ToString().c_str());
161 json->PutExtAttr("pixelStretchEffect", pixelJsonValue, filter);
162 json->PutExtAttr("foregroundColor",
163 propForegroundColor_.value_or(Color::FOREGROUND).ColorToString().c_str(), filter);
164 if (propClickEffectLevel_.has_value()) {
165 auto clickEffectJsonValue = JsonUtil::Create(true);
166 clickEffectJsonValue->Put("level", std::to_string((int)propClickEffectLevel_.value().level).c_str());
167 clickEffectJsonValue->Put("scale",
168 std::to_string((float)propClickEffectLevel_.value().scaleNumber).c_str());
169 json->PutExtAttr("clickEffect", clickEffectJsonValue, filter);
170 }
171 ObscuredToJsonValue(json, filter);
172 json->PutExtAttr("renderGroup", propRenderGroup_.value_or(false) ? "true" : "false", filter);
173 json->PutExtAttr("renderFit", RenderFitToString(propRenderFit_.value_or(RenderFit::TOP_LEFT)).c_str(), filter);
174 json->PutExtAttr("useShadowBatching", propUseShadowBatching_.value_or(false) ? "true" : "false", filter);
175 json->PutExtAttr("useEffect", propUseEffect_.value_or(false) ? "true" : "false", filter);
176 json->PutExtAttr("useEffectType",
177 UseEffectTypeToString(propUseEffectType_.value_or(EffectType::DEFAULT)).c_str(), filter);
178 }
179
ObscuredToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const180 void RenderContext::ObscuredToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
181 {
182 /* no fixed attr below, just return */
183 if (filter.IsFastFilter()) {
184 return;
185 }
186 auto jsonObscuredArray = JsonUtil::CreateArray(true);
187 std::vector<ObscuredReasons> obscuredReasons = propObscured_.value_or(std::vector<ObscuredReasons>());
188 for (size_t i = 0; i < obscuredReasons.size(); i++) {
189 auto index = std::to_string(i);
190 auto value = std::to_string(static_cast<int32_t>(obscuredReasons[i]));
191 jsonObscuredArray->Put(index.c_str(), value.c_str());
192 }
193 json->PutExtAttr("obscured", jsonObscuredArray, filter);
194 }
195
FromJson(const std::unique_ptr<JsonValue> & json)196 void RenderContext::FromJson(const std::unique_ptr<JsonValue>& json)
197 {
198 auto borderRadius = json->GetValue("borderRadius");
199 BorderRadiusProperty brp;
200 brp.radiusTopLeft = Dimension::FromString(borderRadius->GetString("topLeft"));
201 brp.radiusTopRight = Dimension::FromString(borderRadius->GetString("topRight"));
202 brp.radiusBottomLeft = Dimension::FromString(borderRadius->GetString("bottomLeft"));
203 brp.radiusBottomRight = Dimension::FromString(borderRadius->GetString("bottomRight"));
204 UpdateBorderRadius(brp);
205 UpdateBackgroundColor(Color::ColorFromString(json->GetString("backgroundColor")));
206 auto clip = json->GetString("clip");
207 if (clip == "true" || clip == "false") {
208 UpdateClipEdge(clip == "true" ? true : false);
209 } else {
210 LOGE("UITree |ERROR| invalid clip=%{public}s", clip.c_str());
211 }
212 }
213 } // namespace OHOS::Ace::NG
214