1 /*
2  * Copyright (c) 2021 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/common/properties/decoration.h"
17 
18 namespace OHOS::Ace {
19 
SetContextAndCallback(const WeakPtr<PipelineContext> & context,const RenderNodeAnimationCallback & callback)20 void Decoration::SetContextAndCallback(
21     const WeakPtr<PipelineContext>& context, const RenderNodeAnimationCallback& callback)
22 {
23     backgroundColor_.SetContextAndCallback(context, callback);
24     border_.SetContextAndCallback(context, callback);
25     blurRadius_.SetContextAndCallback(context, callback);
26 }
27 
AddShadow(const Shadow & shadow)28 void Decoration::AddShadow(const Shadow& shadow)
29 {
30     shadows_.push_back(shadow);
31 }
32 
ClearAllShadow()33 void Decoration::ClearAllShadow()
34 {
35     shadows_.clear();
36 }
37 
GetOccupiedSize(double dipScale) const38 Size Decoration::GetOccupiedSize(double dipScale) const
39 {
40     return border_.GetLayoutSize(dipScale) + padding_.GetLayoutSizeInPx(dipScale);
41 }
42 
GetOffset(double dipScale) const43 Offset Decoration::GetOffset(double dipScale) const
44 {
45     return border_.GetOffset(dipScale) + padding_.GetOffsetInPx(dipScale);
46 }
47 
VerticalSpaceOccupied(double dipScale) const48 double Decoration::VerticalSpaceOccupied(double dipScale) const
49 {
50     return border_.VerticalWidth(dipScale) + padding_.VerticalInPx(dipScale);
51 }
52 
HorizontalSpaceOccupied(double dipScale) const53 double Decoration::HorizontalSpaceOccupied(double dipScale) const
54 {
55     return border_.HorizontalWidth(dipScale) + padding_.HorizontalInPx(dipScale);
56 }
57 
AddColor(const GradientColor & color)58 void Gradient::AddColor(const GradientColor& color)
59 {
60     colors_.push_back(color);
61 }
62 
ClearColors()63 void Gradient::ClearColors()
64 {
65     colors_.clear();
66 }
67 
SetSizeTypeX(BackgroundImageSizeType type)68 void BackgroundImageSize::SetSizeTypeX(BackgroundImageSizeType type)
69 {
70     typeX_ = type;
71 }
72 
SetSizeTypeY(BackgroundImageSizeType type)73 void BackgroundImageSize::SetSizeTypeY(BackgroundImageSizeType type)
74 {
75     if (type == BackgroundImageSizeType::CONTAIN || type == BackgroundImageSizeType::COVER) {
76         return;
77     }
78     typeY_ = type;
79 }
80 
SetSizeValueX(double value)81 void BackgroundImageSize::SetSizeValueX(double value)
82 {
83     if (value < -0.0) {
84         return;
85     }
86     valueX_ = value;
87 }
88 
SetSizeValueY(double value)89 void BackgroundImageSize::SetSizeValueY(double value)
90 {
91     if (value < -0.0) {
92         return;
93     }
94     valueY_ = value;
95 }
96 
IsValid() const97 bool BackgroundImageSize::IsValid() const
98 {
99     if (typeY_ == BackgroundImageSizeType::CONTAIN || typeY_ == BackgroundImageSizeType::COVER) {
100         return false;
101     }
102 
103     if ((typeX_ == BackgroundImageSizeType::LENGTH || typeX_ == BackgroundImageSizeType::PERCENT) &&
104         LessOrEqual(valueX_, 0.0)) {
105         return false;
106     }
107 
108     if ((typeY_ == BackgroundImageSizeType::LENGTH || typeY_ == BackgroundImageSizeType::PERCENT) &&
109         LessOrEqual(valueY_, 0.0)) {
110         return false;
111     }
112 
113     return true;
114 }
115 
GetSizeTypeX() const116 BackgroundImageSizeType BackgroundImageSize::GetSizeTypeX() const
117 {
118     return typeX_;
119 }
120 
GetSizeTypeY() const121 BackgroundImageSizeType BackgroundImageSize::GetSizeTypeY() const
122 {
123     return typeY_;
124 }
125 
GetSizeValueX() const126 double BackgroundImageSize::GetSizeValueX() const
127 {
128     return valueX_;
129 }
130 
GetSizeValueY() const131 double BackgroundImageSize::GetSizeValueY() const
132 {
133     return valueY_;
134 }
135 
operator +(const BackgroundImageSize & rhs) const136 BackgroundImageSize BackgroundImageSize::operator+(const BackgroundImageSize& rhs) const
137 {
138     if ((rhs.GetSizeTypeX() != GetSizeTypeX()) || (rhs.GetSizeTypeY() != GetSizeTypeY())) {
139         // error: unit not same, just return lhs value
140         return *this;
141     }
142     auto rhsX = rhs.GetSizeValueX();
143     auto rhsY = rhs.GetSizeValueY();
144     auto lhsX = GetSizeValueX();
145     auto lhsY = GetSizeValueY();
146     BackgroundImageSize size;
147     size.SetSizeValueX(rhsX + lhsX);
148     size.SetSizeTypeX(GetSizeTypeX());
149     size.SetSizeValueY(rhsY + lhsY);
150     size.SetSizeTypeY(GetSizeTypeY());
151     return size;
152 }
153 
operator -(const BackgroundImageSize & rhs) const154 BackgroundImageSize BackgroundImageSize::operator-(const BackgroundImageSize& rhs) const
155 {
156     auto rhsX = rhs.GetSizeValueX();
157     auto rhsY = rhs.GetSizeValueY();
158     auto lhsX = GetSizeValueX();
159     auto lhsY = GetSizeValueY();
160     if ((rhs.GetSizeTypeX() != GetSizeTypeX()) || (rhs.GetSizeTypeY() != GetSizeTypeY())) {
161         // error: unit not same, just return lhs value
162         return *this;
163     }
164     BackgroundImageSize size;
165     size.SetSizeValueX(lhsX - rhsX);
166     size.SetSizeTypeX(GetSizeTypeX());
167     size.SetSizeValueY(lhsY - rhsY);
168     size.SetSizeTypeY(GetSizeTypeY());
169     return size;
170 }
171 
operator *(double value) const172 BackgroundImageSize BackgroundImageSize::operator*(double value) const
173 {
174     BackgroundImageSize size;
175     size.SetSizeValueX(GetSizeValueX() * value);
176     size.SetSizeTypeX(GetSizeTypeX());
177     size.SetSizeValueY(GetSizeValueY() * value);
178     size.SetSizeTypeY(GetSizeTypeY());
179     return size;
180 }
181 
operator ==(const BackgroundImageSize & size) const182 bool BackgroundImageSize::operator==(const BackgroundImageSize& size) const
183 {
184     return typeX_ == size.GetSizeTypeX() && NearEqual(valueX_, size.GetSizeValueX()) && typeY_ == size.GetSizeTypeY() &&
185            NearEqual(valueY_, size.GetSizeValueY());
186 }
187 
operator !=(const BackgroundImageSize & size) const188 bool BackgroundImageSize::operator!=(const BackgroundImageSize& size) const
189 {
190     return !operator==(size);
191 }
192 
ToString() const193 std::string BackgroundImageSize::ToString() const
194 {
195     auto widthType = GetSizeTypeX();
196     if (widthType == BackgroundImageSizeType::CONTAIN) {
197         return "ImageSize.Contain";
198     }
199     if (widthType == BackgroundImageSizeType::COVER) {
200         return "ImageSize.Cover";
201     }
202     if (widthType == BackgroundImageSizeType::AUTO) {
203         return "ImageSize.Auto";
204     }
205     if (widthType == BackgroundImageSizeType::FILL) {
206         return "ImageSize.FILL";
207     }
208     auto jsonValue = JsonUtil::Create(true);
209     Dimension width = Dimension((GetSizeValueX()), DimensionUnit::PX);
210     Dimension height = Dimension((GetSizeValueY()), DimensionUnit::PX);
211     jsonValue->Put("width", width.ToString().c_str());
212     jsonValue->Put("height", height.ToString().c_str());
213     return jsonValue->ToString();
214 }
215 
operator +(const BackgroundImagePosition & rhs) const216 BackgroundImagePosition BackgroundImagePosition::operator+(const BackgroundImagePosition& rhs) const
217 {
218     auto rhsX = rhs.GetSizeValueX();
219     auto rhsY = rhs.GetSizeValueY();
220     auto lhsX = GetSizeValueX();
221     auto lhsY = GetSizeValueY();
222     if ((rhs.GetSizeTypeX() != GetSizeTypeX()) || (rhs.GetSizeTypeY() != GetSizeTypeY())) {
223         // error: unit not same, just return lhs value
224         return *this;
225     }
226     BackgroundImagePosition position;
227     position.SetSizeValueX(lhsX + rhsX);
228     position.SetSizeTypeX(GetSizeTypeX());
229     position.SetSizeValueY(lhsY + rhsY);
230     position.SetSizeTypeY(GetSizeTypeY());
231     return position;
232 }
233 
operator -(const BackgroundImagePosition & rhs) const234 BackgroundImagePosition BackgroundImagePosition::operator-(const BackgroundImagePosition& rhs) const
235 {
236     auto rhsX = rhs.GetSizeValueX();
237     auto rhsY = rhs.GetSizeValueY();
238     auto lhsX = GetSizeValueX();
239     auto lhsY = GetSizeValueY();
240     if ((rhs.GetSizeTypeX() != GetSizeTypeX()) || (rhs.GetSizeTypeY() != GetSizeTypeY())) {
241         // error: unit not same, just return lhs value
242         return *this;
243     }
244     BackgroundImagePosition position;
245     position.SetSizeValueX(lhsX - rhsX);
246     position.SetSizeTypeX(GetSizeTypeX());
247     position.SetSizeValueY(lhsY - rhsY);
248     position.SetSizeTypeY(GetSizeTypeY());
249     return position;
250 }
251 
operator *(double value) const252 BackgroundImagePosition BackgroundImagePosition::operator*(double value) const
253 {
254     BackgroundImagePosition position;
255     position.SetSizeValueX(GetSizeValueX() * value);
256     position.SetSizeTypeX(GetSizeTypeX());
257     position.SetSizeValueY(GetSizeValueY() * value);
258     position.SetSizeTypeY(GetSizeTypeY());
259     return position;
260 }
261 
operator ==(const BackgroundImagePosition & backgroundImagePosition) const262 bool BackgroundImagePosition::operator==(const BackgroundImagePosition& backgroundImagePosition) const
263 {
264     bool isXAxisEqual = (GetSizeX() == backgroundImagePosition.GetSizeX()) &&
265                         GetSizeTypeX() == backgroundImagePosition.GetSizeTypeX();
266     bool isYAxisEqual = (GetSizeY() == backgroundImagePosition.GetSizeY()) &&
267                         GetSizeTypeY() == backgroundImagePosition.GetSizeTypeY();
268     return isXAxisEqual && isYAxisEqual;
269 }
270 
operator !=(const BackgroundImagePosition & backgroundImagePosition) const271 bool BackgroundImagePosition::operator!=(const BackgroundImagePosition& backgroundImagePosition) const
272 {
273     return !operator==(backgroundImagePosition);
274 }
275 
GetAlignmentType(double width,double height)276 static std::string GetAlignmentType(double width, double height)
277 {
278     const double halfDimension = 50.0;
279     auto jsonValue = JsonUtil::Create(true);
280     if (NearZero(width)) {
281         if (NearZero(height)) {
282             return "Alignment.TopStart";
283         }
284         if (NearEqual(height, halfDimension)) { // Determine whether the vertical element is centered
285             return "Alignment.Start";
286         }
287         return "Alignment.BottomStart";
288     } else if (NearEqual(width, halfDimension)) { // Judge whether the horizontal element is centered
289         if (NearZero(height)) {
290             return "Alignment.Top";
291         }
292         if (NearEqual(height, halfDimension)) {
293             return "Alignment.Center";
294         }
295         return "Alignment.Bottom";
296     } else {
297         if (NearZero(height)) {
298             return "Alignment.TopEnd";
299         }
300         if (NearEqual(height, halfDimension)) {
301             return "Alignment.End";
302         }
303         return "Alignment.BottomEnd";
304     }
305 }
306 
ToString() const307 std::string BackgroundImagePosition::ToString() const
308 {
309     if (GetSizeTypeX() == BackgroundImagePositionType::PX) {
310         auto width = GetSizeValueX();
311         auto height = GetSizeValueY();
312         auto jsonValue = JsonUtil::Create(true);
313         jsonValue->Put("x", width);
314         jsonValue->Put("y", height);
315         return jsonValue->ToString();
316     }
317     auto width = GetSizeValueX();
318     auto height = GetSizeValueY();
319     return GetAlignmentType(width, height);
320 }
321 
CanvasPath2D(const std::string & cmds)322 CanvasPath2D::CanvasPath2D(const std::string& cmds)
323 {
324     PathArgs args;
325     args.cmds = cmds;
326     caches_.emplace_back(PathCmd::CMDS, args);
327 }
328 
CanvasPath2D(const RefPtr<CanvasPath2D> & path)329 CanvasPath2D::CanvasPath2D(const RefPtr<CanvasPath2D>& path)
330 {
331     if (path != nullptr) {
332         auto caches = path->GetCaches();
333         caches_.swap(caches);
334     }
335 }
336 
AddPath(const RefPtr<CanvasPath2D> & path)337 void CanvasPath2D::AddPath(const RefPtr<CanvasPath2D>& path)
338 {
339     if (path != nullptr) {
340         auto caches = path->GetCaches();
341         caches_.insert(caches_.end(), caches.begin(), caches.end());
342     }
343 }
344 
SetTransform(double a,double b,double c,double d,double e,double f)345 void CanvasPath2D::SetTransform(double a, double b, double c, double d, double e, double f)
346 {
347     PathArgs args;
348     args.para1 = a;
349     args.para2 = b;
350     args.para3 = c;
351     args.para4 = d;
352     args.para5 = e;
353     args.para6 = f;
354     caches_.emplace_back(PathCmd::TRANSFORM, args);
355 }
356 
MoveTo(double x,double y)357 void CanvasPath2D::MoveTo(double x, double y)
358 {
359     PathArgs args;
360     args.para1 = x;
361     args.para2 = y;
362     caches_.emplace_back(PathCmd::MOVE_TO, args);
363 }
364 
LineTo(double x,double y)365 void CanvasPath2D::LineTo(double x, double y)
366 {
367     PathArgs args;
368     args.para1 = x;
369     args.para2 = y;
370     caches_.emplace_back(PathCmd::LINE_TO, args);
371 }
372 
Arc(double x,double y,double radius,double startAngle,double endAngle,double ccw)373 void CanvasPath2D::Arc(double x, double y, double radius, double startAngle, double endAngle, double ccw)
374 {
375     PathArgs args;
376     args.para1 = x;
377     args.para2 = y;
378     args.para3 = radius;
379     args.para4 = startAngle;
380     args.para5 = endAngle;
381     args.para6 = ccw;
382     caches_.emplace_back(PathCmd::ARC, args);
383 }
384 
ArcTo(double x1,double y1,double x2,double y2,double radius)385 void CanvasPath2D::ArcTo(double x1, double y1, double x2, double y2, double radius)
386 {
387     PathArgs args;
388     args.para1 = x1;
389     args.para2 = y1;
390     args.para3 = x2;
391     args.para4 = y2;
392     args.para5 = radius;
393     caches_.emplace_back(PathCmd::ARC_TO, args);
394 }
395 
QuadraticCurveTo(double cpx,double cpy,double x,double y)396 void CanvasPath2D::QuadraticCurveTo(double cpx, double cpy, double x, double y)
397 {
398     PathArgs args;
399     args.para1 = cpx;
400     args.para2 = cpy;
401     args.para3 = x;
402     args.para4 = y;
403     caches_.emplace_back(PathCmd::QUADRATIC_CURVE_TO, args);
404 }
405 
BezierCurveTo(double cp1x,double cp1y,double cp2x,double cp2y,double x,double y)406 void CanvasPath2D::BezierCurveTo(double cp1x, double cp1y, double cp2x, double cp2y, double x, double y)
407 {
408     PathArgs args;
409     args.para1 = cp1x;
410     args.para2 = cp1y;
411     args.para3 = cp2x;
412     args.para4 = cp2y;
413     args.para5 = x;
414     args.para6 = y;
415     caches_.emplace_back(PathCmd::BEZIER_CURVE_TO, args);
416 }
417 
Ellipse(double x,double y,double radiusX,double radiusY,double rotation,double startAngle,double endAngle,double ccw)418 void CanvasPath2D::Ellipse(
419     double x, double y, double radiusX, double radiusY, double rotation, double startAngle, double endAngle, double ccw)
420 {
421     PathArgs args;
422     args.para1 = x;
423     args.para2 = y;
424     args.para3 = radiusX;
425     args.para4 = radiusY;
426     args.para5 = rotation;
427     args.para6 = startAngle;
428     args.para7 = endAngle;
429     args.para8 = ccw;
430     caches_.emplace_back(PathCmd::ELLIPSE, args);
431 }
432 
Rect(double x,double y,double width,double height)433 void CanvasPath2D::Rect(double x, double y, double width, double height)
434 {
435     PathArgs args;
436     args.para1 = x;
437     args.para2 = y;
438     args.para3 = width;
439     args.para4 = height;
440     caches_.emplace_back(PathCmd::RECT, args);
441 }
442 
ClosePath()443 void CanvasPath2D::ClosePath()
444 {
445     PathArgs args;
446     caches_.emplace_back(PathCmd::CLOSE_PATH, args);
447 }
448 
GetCaches() const449 const std::vector<std::pair<PathCmd, PathArgs>>& CanvasPath2D::GetCaches() const
450 {
451     return caches_;
452 }
453 
ToString() const454 std::string CanvasPath2D::ToString() const
455 {
456     std::string str;
457     for (const auto& cache : caches_) {
458         switch (cache.first) {
459             case PathCmd::CMDS: {
460                 str.append("CMDS:");
461                 str.append(cache.second.cmds).append(" ");
462                 break;
463             }
464             case PathCmd::TRANSFORM: {
465                 str.append("TRANSFORM:");
466                 str.append(std::to_string(cache.second.para1)).append(",");
467                 str.append(std::to_string(cache.second.para2)).append(",");
468                 str.append(std::to_string(cache.second.para3)).append(",");
469                 str.append(std::to_string(cache.second.para4)).append(",");
470                 str.append(std::to_string(cache.second.para5)).append(",");
471                 str.append(std::to_string(cache.second.para6)).append(" ");
472                 break;
473             }
474             case PathCmd::MOVE_TO: {
475                 str.append("MOVE_TO:");
476                 str.append(std::to_string(cache.second.para1)).append(",");
477                 str.append(std::to_string(cache.second.para2)).append(" ");
478                 break;
479             }
480             case PathCmd::LINE_TO: {
481                 str.append("LINE_TO:");
482                 str.append(std::to_string(cache.second.para1)).append(",");
483                 str.append(std::to_string(cache.second.para2)).append(" ");
484                 break;
485             }
486             case PathCmd::ARC: {
487                 str.append("ARC:");
488                 str.append(std::to_string(cache.second.para1)).append(",");
489                 str.append(std::to_string(cache.second.para2)).append(",");
490                 str.append(std::to_string(cache.second.para3)).append(",");
491                 str.append(std::to_string(cache.second.para4)).append(",");
492                 str.append(std::to_string(cache.second.para5)).append(",");
493                 str.append(std::to_string(cache.second.para6)).append(" ");
494                 break;
495             }
496             case PathCmd::ARC_TO: {
497                 str.append("ARC_TO:");
498                 str.append(std::to_string(cache.second.para1)).append(",");
499                 str.append(std::to_string(cache.second.para2)).append(",");
500                 str.append(std::to_string(cache.second.para3)).append(",");
501                 str.append(std::to_string(cache.second.para4)).append(",");
502                 str.append(std::to_string(cache.second.para5)).append(" ");
503                 break;
504             }
505             case PathCmd::QUADRATIC_CURVE_TO: {
506                 str.append("QUADRATIC_CURVE_TO:");
507                 str.append(std::to_string(cache.second.para1)).append(",");
508                 str.append(std::to_string(cache.second.para2)).append(",");
509                 str.append(std::to_string(cache.second.para3)).append(",");
510                 str.append(std::to_string(cache.second.para4)).append(" ");
511                 break;
512             }
513             case PathCmd::BEZIER_CURVE_TO: {
514                 str.append("BEZIER_CURVE_TO:");
515                 str.append(std::to_string(cache.second.para1)).append(",");
516                 str.append(std::to_string(cache.second.para2)).append(",");
517                 str.append(std::to_string(cache.second.para3)).append(",");
518                 str.append(std::to_string(cache.second.para4)).append(",");
519                 str.append(std::to_string(cache.second.para5)).append(",");
520                 str.append(std::to_string(cache.second.para6)).append(" ");
521                 break;
522             }
523             case PathCmd::ELLIPSE: {
524                 str.append("ELLIPSE:");
525                 str.append(std::to_string(cache.second.para1)).append(",");
526                 str.append(std::to_string(cache.second.para2)).append(",");
527                 str.append(std::to_string(cache.second.para3)).append(",");
528                 str.append(std::to_string(cache.second.para4)).append(",");
529                 str.append(std::to_string(cache.second.para5)).append(",");
530                 str.append(std::to_string(cache.second.para6)).append(",");
531                 str.append(std::to_string(cache.second.para7)).append(",");
532                 str.append(std::to_string(cache.second.para8)).append(" ");
533                 break;
534             }
535             case PathCmd::RECT: {
536                 str.append("RECT:");
537                 str.append(std::to_string(cache.second.para1)).append(",");
538                 str.append(std::to_string(cache.second.para2)).append(",");
539                 str.append(std::to_string(cache.second.para3)).append(",");
540                 str.append(std::to_string(cache.second.para4)).append(" ");
541                 break;
542             }
543             case PathCmd::CLOSE_PATH: {
544                 str.append("CLOSE_PATH").append(" ");
545                 break;
546             }
547             default: {
548                 break;
549             }
550         }
551     }
552     return str;
553 }
554 
555 } // namespace OHOS::Ace
556