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_property.h"
17
18 #include "core/pipeline_ng/pipeline_context.h"
19
20 namespace OHOS::Ace::NG {
21 namespace {
ImageRepeatToString(ImageRepeat type)22 std::string ImageRepeatToString(ImageRepeat type)
23 {
24 static const LinearEnumMapNode<ImageRepeat, std::string> toStringMap[] = {
25 { ImageRepeat::NO_REPEAT, "ImageRepeat.NoRepeat" },
26 { ImageRepeat::REPEAT_X, "ImageRepeat.X" },
27 { ImageRepeat::REPEAT_Y, "ImageRepeat.Y" },
28 { ImageRepeat::REPEAT, "ImageRepeat.XY" },
29 };
30 auto idx = BinarySearchFindIndex(toStringMap, ArraySize(toStringMap), type);
31 if (idx >= 0) {
32 return toStringMap[idx].value;
33 }
34 return "ImageRepeat.NoRepeat";
35 }
36
BasicShapeTypeToString(BasicShapeType type)37 std::string BasicShapeTypeToString(BasicShapeType type)
38 {
39 static const LinearEnumMapNode<BasicShapeType, std::string> toStringMap[] = {
40 { BasicShapeType::NONE, "None" },
41 { BasicShapeType::INSET, "Inset" },
42 { BasicShapeType::CIRCLE, "Circle" },
43 { BasicShapeType::ELLIPSE, "Ellipse" },
44 { BasicShapeType::POLYGON, "Polygon" },
45 { BasicShapeType::PATH, "Path" },
46 { BasicShapeType::RECT, "Rect" },
47 };
48 auto idx = BinarySearchFindIndex(toStringMap, ArraySize(toStringMap), type);
49 if (idx >= 0) {
50 return toStringMap[idx].value;
51 }
52 return "";
53 }
54
LinearGradientBlurDirection(GradientDirection direction)55 std::string LinearGradientBlurDirection(GradientDirection direction)
56 {
57 static const LinearEnumMapNode<GradientDirection, std::string> toStringMap[] = {
58 { GradientDirection::LEFT, "LEFT" },
59 { GradientDirection::TOP, "LEFT" },
60 { GradientDirection::RIGHT, "RIGHT" },
61 { GradientDirection::BOTTOM, "BOTTOM" },
62 { GradientDirection::LEFT_TOP, "LEFT_TOP" },
63 { GradientDirection::LEFT_BOTTOM, "LEFT_BOTTOM" },
64 { GradientDirection::RIGHT_TOP, "RIGHT_TOP" },
65 { GradientDirection::RIGHT_BOTTOM, "RIGHT_BOTTOM" },
66 { GradientDirection::NONE, "NONE" },
67 { GradientDirection::START_TO_END, "START_TO_END" },
68 { GradientDirection::END_TO_START, "END_TO_START" },
69 };
70 auto idx = BinarySearchFindIndex(toStringMap, ArraySize(toStringMap), direction);
71 if (idx >= 0) {
72 return toStringMap[idx].value;
73 }
74 return "";
75 }
76 } // namespace
77
78 #define ACE_OFFSET_API_NINE_TO_JSON(name) \
79 auto json##name = JsonUtil::Create(true); \
80 if (prop##name.has_value()) { \
81 json##name->Put("x", prop##name->GetX().ToString().c_str()); \
82 json##name->Put("y", prop##name->GetY().ToString().c_str()); \
83 } else { \
84 json##name->Put("x", "0.0px"); \
85 json##name->Put("y", "0.0px"); \
86 }
87
88 #define ACE_OFFSET_API_TEN_TO_JSON(name) \
89 auto json##name = JsonUtil::Create(true); \
90 if (prop##name.has_value()) { \
91 json##name->Put("x", prop##name->GetX().ToString().c_str()); \
92 json##name->Put("y", prop##name->GetY().ToString().c_str()); \
93 } else { \
94 json##name->Put("x", ""); \
95 json##name->Put("y", ""); \
96 }
97
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const98 void RenderPositionProperty::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
99 {
100 /* no fixed attr below, just return */
101 if (filter.IsFastFilter()) {
102 return;
103 }
104 ACE_OFFSET_API_TEN_TO_JSON(Position);
105 json->PutExtAttr("position", jsonPosition, filter);
106
107 auto context = PipelineContext::GetCurrentContext();
108 // add version protection, null as default start from API 10 or higher
109 if (context && context->GetMinPlatformVersion() > static_cast<int32_t>(PlatformVersion::VERSION_NINE)) {
110 ACE_OFFSET_API_TEN_TO_JSON(Offset);
111 json->PutExtAttr("offset", jsonOffset, filter);
112
113 ACE_OFFSET_API_TEN_TO_JSON(Anchor);
114 json->PutExtAttr("markAnchor", jsonAnchor, filter);
115 } else {
116 ACE_OFFSET_API_NINE_TO_JSON(Offset);
117 json->PutExtAttr("offset", jsonOffset, filter);
118
119 ACE_OFFSET_API_NINE_TO_JSON(Anchor);
120 json->PutExtAttr("markAnchor", jsonAnchor, filter);
121 }
122 }
123
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const124 void GraphicsProperty::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
125 {
126 /* no fixed attr below, just return */
127 if (filter.IsFastFilter()) {
128 return;
129 }
130 json->PutExtAttr("grayscale", propFrontGrayScale.has_value() ? propFrontGrayScale->Value() : 0.0, filter);
131 json->PutExtAttr("brightness", propFrontBrightness.has_value() ? propFrontBrightness->Value() : 1.0, filter);
132 json->PutExtAttr("saturate", propFrontSaturate.has_value() ? propFrontSaturate->Value() : 1.0, filter);
133 json->PutExtAttr("contrast", propFrontContrast.has_value() ? propFrontContrast->Value() : 1.0, filter);
134 json->PutExtAttr("sepia", propFrontSepia.has_value() ? propFrontSepia->Value() : 0.0, filter);
135 json->PutExtAttr("hueRotate", propFrontHueRotate.has_value() ? propFrontHueRotate.value() : 0.0, filter);
136 json->PutExtAttr("colorBlend",
137 propFrontColorBlend.has_value() ? propFrontColorBlend->ColorToString().c_str() : "", filter);
138 json->PutExtAttr("blendMode",
139 propBackBlendMode.has_value() ? static_cast<uint16_t>(propBackBlendMode.value()) : 0, filter);
140 json->PutExtAttr("dynamicDimming", propDynamicDimDegree.has_value() ?
141 static_cast<float_t>(propDynamicDimDegree.value()) : 1.0f, filter);
142 auto jsonBgBrightness = JsonUtil::Create(true);
143 jsonBgBrightness->Put(
144 "dynamicLightUpRate", propDynamicLightUpRate.has_value() ? propDynamicLightUpRate.value() : 0.0);
145 jsonBgBrightness->Put(
146 "dynamicLightUpDegree", propDynamicLightUpDegree.has_value() ? propDynamicLightUpDegree.value() : 0.0);
147 json->PutExtAttr("BackgroundBrightness", jsonBgBrightness, filter);
148 auto jsonShadow = JsonUtil::Create(true);
149 auto shadow = propBackShadow.value_or(Shadow());
150 if (shadow.GetStyle() == ShadowStyle::OuterDefaultXS) {
151 json->PutExtAttr("shadow", "ShadowStyle.OuterDefaultXS", filter);
152 } else if (shadow.GetStyle() == ShadowStyle::OuterDefaultSM) {
153 json->PutExtAttr("shadow", "ShadowStyle.OuterDefaultSM", filter);
154 } else if (shadow.GetStyle() == ShadowStyle::OuterDefaultMD) {
155 json->PutExtAttr("shadow", "ShadowStyle.OuterDefaultMD", filter);
156 } else if (shadow.GetStyle() == ShadowStyle::OuterDefaultLG) {
157 json->PutExtAttr("shadow", "ShadowStyle.OuterDefaultLG", filter);
158 } else if (shadow.GetStyle() == ShadowStyle::OuterFloatingSM) {
159 json->PutExtAttr("shadow", "ShadowStyle.OuterFloatingSM", filter);
160 } else if (shadow.GetStyle() == ShadowStyle::OuterFloatingMD) {
161 json->PutExtAttr("shadow", "ShadowStyle.OuterFloatingMD", filter);
162 } else {
163 jsonShadow->Put("radius", std::to_string(shadow.GetBlurRadius()).c_str());
164 if (shadow.GetShadowColorStrategy() == ShadowColorStrategy::AVERAGE) {
165 jsonShadow->Put("color", "ColoringStrategy.AVERAGE");
166 } else if (shadow.GetShadowColorStrategy() == ShadowColorStrategy::PRIMARY) {
167 jsonShadow->Put("color", "ColoringStrategy.PRIMARY");
168 } else {
169 jsonShadow->Put("color", shadow.GetColor().ColorToString().c_str());
170 }
171 jsonShadow->Put("offsetX", std::to_string(shadow.GetOffset().GetX()).c_str());
172 jsonShadow->Put("offsetY", std::to_string(shadow.GetOffset().GetY()).c_str());
173 jsonShadow->Put("type", std::to_string(static_cast<int32_t>(shadow.GetShadowType())).c_str());
174 jsonShadow->Put("fill", std::to_string(shadow.GetIsFilled()).c_str());
175 json->PutExtAttr("shadow", jsonShadow, filter);
176 }
177 if (propFrontInvert.has_value()) {
178 if (propFrontInvert->index() == 0) {
179 json->PutExtAttr("invert", std::get<float>(propFrontInvert.value()), filter);
180 } else {
181 InvertOption option = std::get<InvertOption>(propFrontInvert.value());
182 auto jsonInvert = JsonUtil::Create(true);
183 jsonInvert->Put("low", option.low_);
184 jsonInvert->Put("high", option.high_);
185 jsonInvert->Put("threshold", option.threshold_);
186 jsonInvert->Put("thresholdRange", option.thresholdRange_);
187 json->PutExtAttr("invert", jsonInvert, filter);
188 }
189 }
190 if (propLinearGradientBlur.has_value()) {
191 auto jsonLinearGradientBlur = JsonUtil::Create(true);
192 std::string value = propLinearGradientBlur->blurRadius_.ToString();
193 jsonLinearGradientBlur->Put("value", value.c_str());
194 auto options = JsonUtil::Create(true);
195 std::string direction = LinearGradientBlurDirection(propLinearGradientBlur->direction_);
196 options->Put("direction", direction.c_str());
197 auto fractionStops = JsonUtil::CreateArray(true);
198 int size = static_cast<int>(propLinearGradientBlur->fractionStops_.size());
199 for (auto i = 0; i < size; i++) {
200 auto fraction = propLinearGradientBlur->fractionStops_[i];
201 std::string stop = std::to_string(fraction.first) + "," + std::to_string(fraction.second);
202 fractionStops->Put(std::to_string(i).c_str(), stop.c_str());
203 }
204 options->Put("fractionStops", fractionStops);
205 jsonLinearGradientBlur->Put("options", options);
206 json->Put("linearGradientBlur", jsonLinearGradientBlur);
207 }
208 }
209
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const210 void BackgroundProperty::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
211 {
212 /* no fixed attr below, just return */
213 if (filter.IsFastFilter()) {
214 return;
215 }
216 std::string backgroundImage = "NONE";
217 if (propBackgroundImage.has_value()) {
218 backgroundImage = propBackgroundImage->GetSrc() + ", " +
219 ImageRepeatToString(propBackgroundImageRepeat.value_or(ImageRepeat::NO_REPEAT));
220 }
221 json->PutExtAttr("backgroundImage", backgroundImage.c_str(), filter);
222
223 json->PutExtAttr("backgroundImageSize", !propBackgroundImageSize.has_value() ?
224 "ImageSize.Auto" : propBackgroundImageSize->ToString().c_str(), filter);
225
226 if (propBackgroundImagePosition.has_value()) {
227 json->PutExtAttr("backgroundImagePosition", propBackgroundImagePosition->ToString().c_str(), filter);
228 } else {
229 auto jsonValue = JsonUtil::Create(true);
230 jsonValue->Put("x", 0.0);
231 jsonValue->Put("y", 0.0);
232 json->PutExtAttr("backgroundImagePosition", jsonValue, filter);
233 }
234 json->PutExtAttr("backdropBlur", (propBlurRadius.value_or(Dimension(0))).ConvertToPx(), filter);
235 json->PutExtAttr("backgroundImageResizable",
236 propBackgroundImageResizableSlice.value_or(ImageResizableSlice()).ToString().c_str(), filter);
237 }
238
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const239 void CustomBackgroundProperty::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
240 {
241 /* no fixed attr below, just return */
242 if (filter.IsFastFilter()) {
243 return;
244 }
245 std::string backgroundPixelMap = "NONE";
246 if (propBackgroundPixelMap.has_value()) {
247 backgroundPixelMap = std::to_string(propBackgroundPixelMap.value()->GetWidth()) + ", " +
248 std::to_string(propBackgroundPixelMap.value()->GetHeight());
249 }
250 json->PutExtAttr("backgroundPixelMap", backgroundPixelMap.c_str(), filter);
251 json->PutExtAttr("backgroundAlign", propBackgroundAlign.value().ToString().c_str(), filter);
252 }
253
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const254 void ForegroundProperty::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
255 {
256 /* no fixed attr below, just return */
257 if (filter.IsFastFilter()) {
258 return;
259 }
260 json->PutExtAttr("blur", (propBlurRadius.value_or(Dimension(0))).ConvertToPx(), filter);
261 auto jsonOption = JsonUtil::Create(true);
262 jsonOption->Put("radius", std::to_string(propForegroundEffect.value_or(0.0f)).c_str());
263 json->PutExtAttr("foregroundEffect", jsonOption, filter);
264 if (propMotionBlur.has_value()) {
265 auto motionBlur = JsonUtil::Create(true);
266 motionBlur->Put("radius", propMotionBlur->radius);
267 auto motionBlurAnchor = JsonUtil::Create(true);
268 motionBlurAnchor->Put("x", propMotionBlur->anchor.x);
269 motionBlurAnchor->Put("y", propMotionBlur->anchor.y);
270 motionBlur->Put("anchor", motionBlurAnchor);
271 json->Put("motionBlur", motionBlur);
272 }
273 }
274
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const275 void ClipProperty::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
276 {
277 /* no fixed attr below, just return */
278 if (filter.IsFastFilter()) {
279 return;
280 }
281 if (propClipShape.has_value()) {
282 auto jsonClip = JsonUtil::Create(true);
283 auto shape = propClipShape.value();
284 auto shapeType = BasicShapeTypeToString(shape->GetBasicShapeType());
285 if (!shapeType.empty()) {
286 jsonClip->Put("shape", shapeType.c_str());
287 }
288 json->PutExtAttr("clip", jsonClip->ToString().c_str(), filter);
289 } else {
290 json->PutExtAttr("clip", propClipEdge.value_or(false) ? "true" : "false", filter);
291 }
292
293 auto jsonMask = JsonUtil::Create(true);
294 if (propClipMask.has_value()) {
295 auto shape = propClipMask.value();
296 auto shapeType = BasicShapeTypeToString(shape->GetBasicShapeType());
297 if (!shapeType.empty()) {
298 jsonMask->Put("shape", shapeType.c_str());
299 }
300 }
301 json->PutExtAttr("mask", jsonMask, filter);
302 }
303
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const304 void GradientProperty::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
305 {
306 /* no fixed attr below, just return */
307 if (filter.IsFastFilter()) {
308 return;
309 }
310 if (propLinearGradient.has_value()) {
311 json->PutExtAttr("linearGradient", propLinearGradient->LinearGradientToJson(), filter);
312 } else {
313 json->PutExtAttr("linearGradient", JsonUtil::Create(true), filter);
314 }
315
316 if (propSweepGradient.has_value()) {
317 json->PutExtAttr("sweepGradient", propSweepGradient->SweepGradientToJson(), filter);
318 } else {
319 json->PutExtAttr("sweepGradient", JsonUtil::Create(true), filter);
320 }
321
322 if (propRadialGradient.has_value()) {
323 json->PutExtAttr("radialGradient", propRadialGradient->RadialGradientToJson(), filter);
324 } else {
325 json->PutExtAttr("radialGradient", JsonUtil::Create(true), filter);
326 }
327 }
328
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const329 void TransformProperty::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
330 {
331 const double halfDimension = 50.0;
332 auto center = propTransformCenter.value_or(DimensionOffset(
333 Dimension(halfDimension, DimensionUnit::PERCENT), Dimension(halfDimension, DimensionUnit::PERCENT)));
334 /* no fixed attr below, just return */
335 if (filter.IsFastFilter()) {
336 return;
337 }
338 if (propTransformRotate.has_value()) {
339 auto jsonValue = JsonUtil::Create(true);
340 jsonValue->Put("x", std::to_string(propTransformRotate->x).c_str());
341 jsonValue->Put("y", std::to_string(propTransformRotate->y).c_str());
342 jsonValue->Put("z", std::to_string(propTransformRotate->z).c_str());
343 jsonValue->Put("angle", std::to_string(propTransformRotate->w).c_str());
344 jsonValue->Put("perspective", std::to_string(propTransformRotate->v).c_str());
345 jsonValue->Put("centerX", center.GetX().ToString().c_str());
346 jsonValue->Put("centerY", center.GetY().ToString().c_str());
347 if (center.GetZ().has_value()) {
348 jsonValue->Put("centerZ", center.GetZ().value().ToString().c_str());
349 } else {
350 json->PutExtAttr("centerZ", JsonUtil::Create(true), filter);
351 }
352 json->PutExtAttr("rotate", jsonValue, filter);
353 } else {
354 json->PutExtAttr("rotate", JsonUtil::Create(true), filter);
355 }
356
357 if (propTransformScale.has_value()) {
358 auto jsonValue = JsonUtil::Create(true);
359 jsonValue->Put("x", std::to_string(propTransformScale->x).c_str());
360 jsonValue->Put("y", std::to_string(propTransformScale->y).c_str());
361 jsonValue->Put("centerX", center.GetX().ToString().c_str());
362 jsonValue->Put("centerY", center.GetY().ToString().c_str());
363 json->PutExtAttr("scale", jsonValue, filter);
364 } else {
365 json->PutExtAttr("scale", JsonUtil::Create(true), filter);
366 }
367
368 if (propTransformTranslate.has_value()) {
369 auto jsonValue = JsonUtil::Create(true);
370 jsonValue->Put("x", propTransformTranslate->x.ToString().c_str());
371 jsonValue->Put("y", propTransformTranslate->y.ToString().c_str());
372 jsonValue->Put("z", propTransformTranslate->z.ToString().c_str());
373 json->PutExtAttr("translate", jsonValue, filter);
374 } else {
375 json->PutExtAttr("translate", JsonUtil::Create(true), filter);
376 }
377 }
378
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const379 void BorderProperty::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
380 {
381 /* no fixed attr below, just return */
382 if (filter.IsFastFilter()) {
383 return;
384 }
385 auto jsonBorder = JsonUtil::Create(true);
386 propBorderStyle.value_or(BorderStyleProperty()).ToJsonValue(json, jsonBorder, filter);
387 propBorderColor.value_or(BorderColorProperty()).ToJsonValue(json, jsonBorder, filter);
388 propBorderWidth.value_or(BorderWidthProperty()).ToJsonValue(json, jsonBorder, filter);
389 propBorderRadius.value_or(BorderRadiusProperty()).ToJsonValue(json, jsonBorder, filter);
390 propDashGap.value_or(BorderWidthProperty()).ToDashJsonValue(json, jsonBorder, filter, "dashGap");
391 propDashWidth.value_or(BorderWidthProperty()).ToDashJsonValue(json, jsonBorder, filter, "dashWidth");
392
393 json->PutExtAttr("border", jsonBorder->ToString().c_str(), filter);
394 }
395
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const396 void OuterBorderProperty::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
397 {
398 /* no fixed attr below, just return */
399 if (filter.IsFastFilter()) {
400 return;
401 }
402 auto jsonOutline = JsonUtil::Create(true);
403 propOuterBorderStyle.value_or(BorderStyleProperty()).ToJsonValue(json, jsonOutline, filter, true);
404 propOuterBorderColor.value_or(BorderColorProperty()).ToJsonValue(json, jsonOutline, filter, true);
405 propOuterBorderWidth.value_or(BorderWidthProperty()).ToJsonValue(json, jsonOutline, filter, true);
406 propOuterBorderRadius.value_or(BorderRadiusProperty()).ToJsonValue(json, jsonOutline, filter, true);
407 json->PutExtAttr("outline", jsonOutline->ToString().c_str(), filter);
408 }
409
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const410 void PointLightProperty::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
411 {
412 /* no fixed attr below, just return */
413 if (filter.IsFastFilter()) {
414 return;
415 }
416 auto jsonLightIntensity = JsonUtil::Create(true);
417 jsonLightIntensity->Put("lightIntensity", propLightIntensity.has_value() ? propLightIntensity.value() : 0.0);
418 json->PutExtAttr("pointLight", jsonLightIntensity, filter);
419
420 if (propLightPosition.has_value()) {
421 auto jsonLightPosition = JsonUtil::Create(true);
422 jsonLightPosition->Put("x", propLightPosition->x.ToString().c_str());
423 jsonLightPosition->Put("y", propLightPosition->y.ToString().c_str());
424 jsonLightPosition->Put("z", propLightPosition->z.ToString().c_str());
425 json->PutExtAttr("LightPosition", jsonLightPosition, filter);
426 } else {
427 json->PutExtAttr("LightPosition", JsonUtil::Create(true), filter);
428 }
429 }
430 } // namespace OHOS::Ace::NG
431