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 /**
17  * @addtogroup GraphicGeometry
18  * @{
19  *
20  * @brief Defines ArcToBezier BezierArc BezierArcSvg.
21  *
22  * @since 1.0
23  * @version 1.0
24  */
25 
26 #ifndef GRAPHIC_LITE_GEOMETRY_BEZIER_ARC_H
27 #define GRAPHIC_LITE_GEOMETRY_BEZIER_ARC_H
28 
29 #include "gfx_utils/diagram/depiction/depict_transform.h"
30 #include "gfx_utils/heap_base.h"
31 namespace OHOS {
32 #if defined(GRAPHIC_ENABLE_BEZIER_ARC_FLAG) && GRAPHIC_ENABLE_BEZIER_ARC_FLAG
33 const int32_t BEZIER_ARC_VERTEX_NUM = 26; // Number of Bezier Arc Vertex Coordinates.
34 /**
35  * @brief Arcs are converted to Bezier curves.
36  *
37  * @since 1.0
38  * @version 1.0
39  */
40 void ArcToBezier(float cx, float cy, float rx, float ry,
41                  float startAngle, float sweepAngle,
42                  float* curve);
43 
44 /**
45  * @file geometry_bezier_arc.h
46  *
47  * @brief Defines Bezier arc structure class.
48  *
49  * @since 1.0
50  * @version 1.0
51  */
52 class BezierArc : public HeapBase {
53 public:
BezierArc()54     BezierArc()
55         : vertexIndex_(BEZIER_ARC_VERTEX_NUM), numberVertices_(0), currentCommand_(PATH_CMD_LINE_TO) {}
56 
57     /**
58      * @brief Bezier curves are initialized with arcs.
59      * @Param centerX centerY Arc Center.
60      * @Param rx ry Arc Transverse and Longitudinal Radius.
61      * @Param startAngle sweepAngle Arc start and end angle.
62      * @since 1.0
63      * @version 1.0
64      */
BezierArc(float centerX,float centerY,float rx,float ry,float startAngle,float sweepAngle)65     BezierArc(float centerX, float centerY,
66               float rx, float ry,
67               float startAngle,
68               float sweepAngle)
69     {
70         Init(centerX, centerY, rx, ry, startAngle, sweepAngle);
71     }
72 
73     /**
74      * @brief Initializing Bezier Curves with Arcs.
75      * @since 1.0
76      * @version 1.0
77      */
78     void Init(float centerX, float centerY,
79               float rx, float ry,
80               float startAngle,
81               float sweepAngle);
82 
83     /**
84      * @brief Back to the beginning.
85      *
86      * @since 1.0
87      * @version 1.0
88      */
Rewind(uint32_t)89     void Rewind(uint32_t)
90     {
91         vertexIndex_ = 0;
92     }
93 
94     /**
95      * @brief Called during the sampling phase.
96      * @param x is the pointer to the value of the point coordinate X.
97      * @param y is the pointer to the value of the point coordinate Y.
98      * @return Path command
99      * @since 1.0
100      * @version 1.0
101      */
GenerateVertex(float * x,float * y)102     uint32_t GenerateVertex(float* x, float* y)
103     {
104         if (vertexIndex_ >= numberVertices_) {
105             return PATH_CMD_STOP;
106         }
107         *x = arrayVertices_[vertexIndex_];
108         *y = arrayVertices_[vertexIndex_ + 1];
109         vertexIndex_ = vertexIndex_ + TWO_STEP;
110         if (vertexIndex_ == TWO_STEP) {
111             return uint32_t(PATH_CMD_MOVE_TO);
112         } else {
113             return currentCommand_;
114         }
115     }
116 
117     /**
118      * @brief Get the number of vertex sources.
119      * @return Number of vertices.
120      * @since 1.0
121      * @version 1.0
122      */
GetNumberVertices()123     uint32_t GetNumberVertices() const
124     {
125         return numberVertices_;
126     }
127 
128     /**
129      * @brief Get vertex source.
130      * @return Vertex Source Data.
131      * @since 1.0
132      * @version 1.0
133      */
GetVertices()134     const float* GetVertices() const
135     {
136         return arrayVertices_;
137     }
138 
139     /**
140      * @brief Get vertex source.
141      * @return Vertex Source Data.
142      * @since 1.0
143      * @version 1.0
144      */
GetVertices()145     float* GetVertices()
146     {
147         return arrayVertices_;
148     }
149 
150 private:
151     uint32_t vertexIndex_;
152     uint32_t numberVertices_;
153     float arrayVertices_[BEZIER_ARC_VERTEX_NUM];
154     uint32_t currentCommand_;
155 };
156 
157 /**
158  * @brief Compute SVG-style Bezier arcs.
159  *
160  * @since 1.0
161  * @version 1.0
162  */
163 class BezierArcSvg : public HeapBase {
164 public:
BezierArcSvg()165     BezierArcSvg() : bezierArcModel_(), isRadiusJoinPath_(false) {}
166 
167     /**
168      * @brief Calculates elliptical arcs from (x1, y1) to (x2, y2).
169      * The direction of the ellipse is defined by two radii (rx, ry).
170      * @param x1,y1 Starting point coordinates.
171      * @param x2,y2 End point coordinates.
172      * @param rx,ry Radius of major and minor axes
173      * @param angle angle,
174      * @param largeArcFlag Large Arc Mark
175      * @param sweepFlag Sweep angle sign
176      * @since 1.0
177      * @version 1.0
178      */
BezierArcSvg(float x1,float y1,float rx,float ry,float angle,bool largeArcFlag,bool sweepFlag,float x2,float y2)179     BezierArcSvg(float x1,
180                  float y1,
181                  float rx, float ry,
182                  float angle,
183                  bool largeArcFlag, // Large Arc Mark
184                  bool sweepFlag,    // Sweep angle sign
185                  float x2, float y2) : bezierArcModel_(), isRadiusJoinPath_(false)
186     {
187         Init(x1, y1, rx, ry, angle, largeArcFlag, sweepFlag, x2, y2);
188     }
189 
RadiiOK()190     bool RadiiOK() const
191     {
192         return isRadiusJoinPath_;
193     }
194 
195     void Init(float x1,
196               float y1,
197               float rx,
198               float ry,
199               float angle,
200               bool largeArcFlag,
201               bool sweepFlag,
202               float x2,
203               float y2);
204 
205     /**
206      * @brief Go back to the first step.
207      *
208      * @since 1.0
209      * @version 1.0
210      */
Rewind(uint32_t)211     void Rewind(uint32_t)
212     {
213         bezierArcModel_.Rewind(0);
214     }
215 
216     /**
217      * @brief Called during the sampling phase.
218      * @param X is the pointer to the value of the point coordinate X
219      * @param Y is the pointer to the value of the point coordinate Y
220      * @return Path command
221      * @since 1.0
222      * @version 1.0
223      */
GenerateVertex(float * x,float * y)224     uint32_t GenerateVertex(float* x, float* y)
225     {
226         return bezierArcModel_.GenerateVertex(x, y);
227     }
228 
229     /**
230      * @brief Returns the vertex data of a Bezier arc.
231      * @return Return vertex source.
232      * @since 1.0
233      * @version 1.0
234      */
GetVertices()235     const float* GetVertices() const
236     {
237         return bezierArcModel_.GetVertices();
238     }
239 
240     /**
241      * @brief Returns the vertex data of a Bezier arc.
242      * @return Returns the vertex data of a Bezier arc.
243      * @since 1.0
244      * @version 1.0
245      */
GetVertices()246     float* GetVertices()
247     {
248         return bezierArcModel_.GetVertices();
249     }
250 
251     /**
252      * @brief Returns twice the number of value vertices,that is, for a vertex, it returns 2.
253      * @since 1.0
254      * @version 1.0
255      */
GetNumberVertices()256     uint32_t GetNumberVertices() const
257     {
258         return bezierArcModel_.GetNumberVertices();
259     }
260 
261 private:
262     BezierArc bezierArcModel_;
263     bool isRadiusJoinPath_;
264 };
265 #endif
266 } // namespace OHOS
267 #endif
268