1 /*
2  * Copyright (c) 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_SHAPE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_SHAPE_H
18 
19 #include "base/geometry/dimension.h"
20 #include "base/geometry/dimension_offset.h"
21 #include "base/memory/ace_type.h"
22 #include "core/components/common/properties/color.h"
23 #ifndef FUZZTEST
24 #include "core/components/common/properties/radius.h"
25 #else
26 #include "test/fuzztest/utilmost_fuzzer/radius.h"
27 #endif
28 
29 namespace OHOS::Ace {
30 
31 using ShapePoint = std::pair<Dimension, Dimension>;
32 using ShapePoints = std::vector<ShapePoint>;
33 
34 enum class ShapeType {
35     RECT = 0,
36     CIRCLE,
37     ELLIPSE,
38     LINE,
39     POLYGON,
40     POLYLINE,
41     PATH,
42 };
43 
44 enum class BasicShapeType { NONE, INSET, CIRCLE, ELLIPSE, POLYGON, PATH, RECT };
45 
46 class BasicShape : public AceType {
47     DECLARE_ACE_TYPE(BasicShape, AceType);
48 
49 public:
50     BasicShape() = default;
BasicShape(BasicShapeType basicShapeType)51     explicit BasicShape(BasicShapeType basicShapeType) : basicShapeType_(basicShapeType) {}
52     ~BasicShape() override = default;
53 
SetBasicShapeType(BasicShapeType basicShapeType)54     void SetBasicShapeType(BasicShapeType basicShapeType)
55     {
56         basicShapeType_ = basicShapeType;
57     }
58 
GetBasicShapeType()59     BasicShapeType GetBasicShapeType() const
60     {
61         return basicShapeType_;
62     }
63 
GetWidth()64     const Dimension& GetWidth() const
65     {
66         return width_;
67     }
68 
GetHeight()69     const Dimension& GetHeight() const
70     {
71         return height_;
72     }
73 
GetOffset()74     const DimensionOffset& GetOffset() const
75     {
76         return offset_;
77     }
78 
SetWidth(const Dimension & width)79     void SetWidth(const Dimension& width)
80     {
81         width_ = width;
82     }
83 
SetHeight(const Dimension & height)84     void SetHeight(const Dimension& height)
85     {
86         height_ = height;
87     }
88 
SetOffset(const DimensionOffset & offset)89     void SetOffset(const DimensionOffset& offset)
90     {
91         offset_ = offset;
92     }
93 
SetColor(const Color & color)94     void SetColor(const Color& color)
95     {
96         color_ = color;
97     }
98 
SetPosition(const DimensionOffset & position)99     void SetPosition(const DimensionOffset& position)
100     {
101         position_ = position;
102     }
103 
GetPosition()104     const DimensionOffset& GetPosition() const
105     {
106         return position_;
107     }
108 
GetColor()109     Color GetColor() const
110     {
111         return color_;
112     }
113 
SetStrokeColor(uint32_t strokeColor)114     void SetStrokeColor(uint32_t strokeColor)
115     {
116         strokeColor_ = strokeColor;
117     }
118 
GetStrokeColor()119     uint32_t GetStrokeColor() const
120     {
121         return strokeColor_;
122     }
123 
SetStrokeWidth(float strokeWidth)124     void SetStrokeWidth(float strokeWidth)
125     {
126         strokeWidth_ = strokeWidth;
127     }
128 
GetStrokeWidth()129     float GetStrokeWidth() const
130     {
131         return strokeWidth_;
132     }
133 
134     bool operator==(const BasicShape& other) const
135     {
136         return (basicShapeType_ == other.GetBasicShapeType() && width_ == other.GetWidth() &&
137                 height_ == other.GetHeight() && offset_ == other.GetOffset() && color_ == other.GetColor());
138     }
139 
140     BasicShape& operator=(const BasicShape& other)
141     {
142         if (this != &other) {
143             basicShapeType_ = other.basicShapeType_;
144             width_ = other.width_;
145             height_ = other.height_;
146             offset_ = other.offset_;
147             color_ = other.color_;
148         }
149         return *this;
150     }
151 
152 protected:
153     BasicShapeType basicShapeType_ = BasicShapeType::NONE;
154     Dimension width_;
155     Dimension height_;
156     DimensionOffset offset_;
157     DimensionOffset position_;
158     Color color_;
159     uint32_t strokeColor_ = 0;
160     float strokeWidth_ = 0.0f;
161 };
162 
163 // inset(<top> <right> <bottom> <left> round <top-radius> <right-radius> <bottom-radius> <left-radius>)
164 class Inset : public BasicShape {
165     DECLARE_ACE_TYPE(Inset, BasicShape);
166 
167 public:
Inset()168     Inset() : BasicShape(BasicShapeType::INSET) {}
169     ~Inset() override = default;
170     bool SetLength(const std::vector<Dimension>& lengths);
171     void SetRadius(const std::vector<Dimension>& rounds, bool isX = true);
172 
GetTop()173     const Dimension& GetTop() const
174     {
175         return top_;
176     }
177 
GetRight()178     const Dimension& GetRight() const
179     {
180         return right_;
181     }
182 
GetBottom()183     const Dimension& GetBottom() const
184     {
185         return bottom_;
186     }
187 
GetLeft()188     const Dimension& GetLeft() const
189     {
190         return left_;
191     }
192 
GetTopLeftRadius()193     const Radius& GetTopLeftRadius() const
194     {
195         return topLeftRadius_;
196     }
197 
GetTopRightRadius()198     const Radius& GetTopRightRadius() const
199     {
200         return topRightRadius_;
201     }
202 
GetBottomRightRadius()203     const Radius& GetBottomRightRadius() const
204     {
205         return bottomRightRadius_;
206     }
207 
GetBottomLeftRadius()208     const Radius& GetBottomLeftRadius() const
209     {
210         return bottomLeftRadius_;
211     }
212 
SetTop(const Dimension & top)213     void SetTop(const Dimension& top)
214     {
215         top_ = top;
216     }
217 
SetRight(const Dimension & right)218     void SetRight(const Dimension& right)
219     {
220         right_ = right;
221     }
222 
SetBottom(const Dimension & bottom)223     void SetBottom(const Dimension& bottom)
224     {
225         bottom_ = bottom;
226     }
227 
SetLeft(const Dimension & left)228     void SetLeft(const Dimension& left)
229     {
230         left_ = left;
231     }
232 
233     void SetTopLeftRadius(const Dimension& topLeftRadius, bool isX = true)
234     {
235         if (!topLeftRadius.IsValid()) {
236             return;
237         }
238         if (isX) {
239             topLeftRadius_.SetX(topLeftRadius);
240         }
241         topLeftRadius_.SetY(topLeftRadius);
242     }
243 
244     void SetTopRightRadius(const Dimension& topRightRadius, bool isX = true)
245     {
246         if (!topRightRadius.IsValid()) {
247             return;
248         }
249         if (isX) {
250             topRightRadius_.SetX(topRightRadius);
251         }
252         topRightRadius_.SetY(topRightRadius);
253     }
254 
255     void SetBottomRightRadius(const Dimension& bottomRightRadius, bool isX = true)
256     {
257         if (!bottomRightRadius.IsValid()) {
258             return;
259         }
260         if (isX) {
261             bottomRightRadius_.SetX(bottomRightRadius);
262         }
263         bottomRightRadius_.SetY(bottomRightRadius);
264     }
265 
266     void SetBottomLeftRadius(const Dimension& bottomLeftRadius, bool isX = true)
267     {
268         if (!bottomLeftRadius.IsValid()) {
269             return;
270         }
271         if (isX) {
272             bottomLeftRadius_.SetX(bottomLeftRadius);
273         }
274         bottomLeftRadius_.SetY(bottomLeftRadius);
275     }
276 
277 private:
278     void SetLength(const Dimension& top, const Dimension& right, const Dimension& bottom, const Dimension& left);
279     void SetRadius(
280         const Dimension& top, const Dimension& right, const Dimension& bottom, const Dimension& left, bool isX);
281 
282     Dimension top_;
283     Dimension right_;
284     Dimension bottom_;
285     Dimension left_;
286     Radius topLeftRadius_;
287     Radius topRightRadius_;
288     Radius bottomRightRadius_;
289     Radius bottomLeftRadius_;
290 };
291 
292 // circle(radius at x-axis y-axis)
293 class Circle : public BasicShape {
294     DECLARE_ACE_TYPE(Circle, BasicShape);
295 
296 public:
Circle()297     Circle() : BasicShape(BasicShapeType::CIRCLE) {}
298     ~Circle() override = default;
299 
GetRadius()300     const Dimension& GetRadius() const
301     {
302         return radius_;
303     }
304 
GetAxisX()305     const Dimension& GetAxisX() const
306     {
307         return axisX_;
308     }
309 
GetAxisY()310     const Dimension& GetAxisY() const
311     {
312         return axisY_;
313     }
314 
SetRadius(const Dimension & radius)315     void SetRadius(const Dimension& radius)
316     {
317         if (radius.IsValid()) {
318             radius_ = radius;
319         }
320     }
321 
SetAxisX(const Dimension & axisX)322     void SetAxisX(const Dimension& axisX)
323     {
324         axisX_ = axisX;
325     }
326 
SetAxisY(const Dimension & axisY)327     void SetAxisY(const Dimension& axisY)
328     {
329         axisY_ = axisY;
330     }
331 
332     bool operator==(const Circle& other) const
333     {
334         return (radius_ == other.GetRadius() && axisX_ == other.GetAxisX() && axisY_ == other.GetAxisY());
335     }
336 
337 private:
338     Dimension radius_;
339     Dimension axisX_ = Dimension(0.5, DimensionUnit::PERCENT);
340     Dimension axisY_ = Dimension(0.5, DimensionUnit::PERCENT);
341 };
342 
343 // ellipse(x-rad y-rad at x-axis y-axis)
344 class Ellipse : public BasicShape {
345     DECLARE_ACE_TYPE(Ellipse, BasicShape);
346 
347 public:
Ellipse()348     Ellipse() : BasicShape(BasicShapeType::ELLIPSE) {}
349     ~Ellipse() override = default;
350 
GetRadiusX()351     const Dimension& GetRadiusX() const
352     {
353         return radiusX_;
354     }
355 
GetRadiusY()356     const Dimension& GetRadiusY() const
357     {
358         return radiusY_;
359     }
360 
GetAxisX()361     const Dimension& GetAxisX() const
362     {
363         return axisX_;
364     }
365 
GetAxisY()366     const Dimension& GetAxisY() const
367     {
368         return axisY_;
369     }
370 
SetRadiusX(const Dimension & radiusX)371     void SetRadiusX(const Dimension& radiusX)
372     {
373         if (radiusX.IsValid()) {
374             radiusX_ = radiusX;
375         }
376     }
377 
SetRadiusY(const Dimension & radiusY)378     void SetRadiusY(const Dimension& radiusY)
379     {
380         if (radiusY.IsValid()) {
381             radiusY_ = radiusY;
382         }
383     }
384 
SetAxisX(const Dimension & axisX)385     void SetAxisX(const Dimension& axisX)
386     {
387         axisX_ = axisX;
388     }
389 
SetAxisY(const Dimension & axisY)390     void SetAxisY(const Dimension& axisY)
391     {
392         axisY_ = axisY;
393     }
394 
395     bool operator==(const Ellipse& other) const
396     {
397         return (radiusX_ == other.GetRadiusX() && radiusY_ == other.GetRadiusY() && axisX_ == other.GetAxisX() &&
398                 axisY_ == other.GetAxisY());
399     }
400 
401 private:
402     Dimension radiusX_;
403     Dimension radiusY_;
404     Dimension axisX_ = Dimension(0.5, DimensionUnit::PERCENT);
405     Dimension axisY_ = Dimension(0.5, DimensionUnit::PERCENT);
406 };
407 
408 // polygon(x-axis y-axis, x-axis y-axis, … )
409 class Polygon : public BasicShape {
410     DECLARE_ACE_TYPE(Polygon, BasicShape);
411 
412 public:
Polygon()413     Polygon() : BasicShape(BasicShapeType::POLYGON) {}
414     ~Polygon() override = default;
415 
GetPoints()416     const std::vector<std::pair<Dimension, Dimension>>& GetPoints() const
417     {
418         return points_;
419     }
420 
PushPoint(const Dimension & x,const Dimension & y)421     void PushPoint(const Dimension& x, const Dimension& y)
422     {
423         points_.emplace_back(std::make_pair(x, y));
424     }
425 
IsValid()426     bool IsValid() const
427     {
428         return !points_.empty();
429     }
430 
431     bool operator==(const Polygon& other) const
432     {
433         return points_ == other.GetPoints();
434     }
435 
436 private:
437     std::vector<std::pair<Dimension, Dimension>> points_;
438 };
439 
440 // path('value')
441 class Path : public BasicShape {
442     DECLARE_ACE_TYPE(Path, BasicShape);
443 
444 public:
Path()445     Path() : BasicShape(BasicShapeType::PATH) {}
446     ~Path() override = default;
447 
GetValue()448     const std::string& GetValue() const
449     {
450         return value_;
451     }
452 
SetValue(const std::string & value)453     void SetValue(const std::string& value)
454     {
455         value_ = value;
456     }
457 
458     bool operator==(const Path& other) const
459     {
460         return value_ == other.GetValue();
461     }
462 
463 private:
464     std::string value_;
465 };
466 
467 class ShapeRect : public BasicShape {
468     DECLARE_ACE_TYPE(ShapeRect, BasicShape);
469 
470 public:
ShapeRect()471     ShapeRect() : BasicShape(BasicShapeType::RECT) {}
472     ~ShapeRect() override = default;
473 
SetTopLeftRadius(const Radius & topLeftRadius)474     void SetTopLeftRadius(const Radius& topLeftRadius)
475     {
476         topLeftRadius_ = topLeftRadius;
477     }
478 
SetTopRightRadius(const Radius & topRightRadius)479     void SetTopRightRadius(const Radius& topRightRadius)
480     {
481         topRightRadius_ = topRightRadius;
482     }
483 
SetBottomRightRadius(const Radius & bottomRightRadius)484     void SetBottomRightRadius(const Radius& bottomRightRadius)
485     {
486         bottomRightRadius_ = bottomRightRadius;
487     }
488 
SetBottomLeftRadius(const Radius & bottomLeftRadius)489     void SetBottomLeftRadius(const Radius& bottomLeftRadius)
490     {
491         bottomLeftRadius_ = bottomLeftRadius;
492     }
493 
GetTopLeftRadius()494     Radius GetTopLeftRadius() const
495     {
496         return topLeftRadius_;
497     }
498 
GetTopRightRadius()499     Radius GetTopRightRadius() const
500     {
501         return topRightRadius_;
502     }
503 
GetBottomRightRadius()504     Radius GetBottomRightRadius() const
505     {
506         return bottomRightRadius_;
507     }
508 
GetBottomLeftRadius()509     Radius GetBottomLeftRadius() const
510     {
511         return bottomLeftRadius_;
512     }
513 
514     void SetRadiusWidth(const Dimension& value, const AnimationOption& option = AnimationOption())
515     {
516         topLeftRadius_.SetX(value, option);
517         topRightRadius_.SetX(value, option);
518         bottomRightRadius_.SetX(value, option);
519         bottomLeftRadius_.SetX(value, option);
520     }
521 
522     void SetRadiusHeight(const Dimension& value, const AnimationOption& option = AnimationOption())
523     {
524         topLeftRadius_.SetY(value, option);
525         topRightRadius_.SetY(value, option);
526         bottomRightRadius_.SetY(value, option);
527         bottomLeftRadius_.SetY(value, option);
528     }
529 
530 private:
531     Radius topLeftRadius_ = Radius(-1.0);
532     Radius topRightRadius_ = Radius(-1.0);
533     Radius bottomRightRadius_ = Radius(-1.0);
534     Radius bottomLeftRadius_ = Radius(-1.0);
535 };
536 
537 } // namespace OHOS::Ace
538 
539 #endif // FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_SHAPE_H