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  * @file depict_curve.h
18  *
19  * @brief Defines Building curve transformation pipes
20  * The curve drawing is usually approximated by a series of short line segments,
21  * which is the only efficient method to draw the curve
22  * @since 1.0
23  * @version 1.0
24  */
25 
26 #ifndef GRAPHIC_LITE_DEPICT_CURVE_H
27 #define GRAPHIC_LITE_DEPICT_CURVE_H
28 
29 #include "gfx_utils/diagram/common/common_basics.h"
30 #include "gfx_utils/diagram/vertexprimitive/geometry_curves.h"
31 #include "gfx_utils/diagram/vertexprimitive/geometry_path_storage.h"
32 
33 namespace OHOS {
34 /**
35  * @class DepictCurve
36  * @brief By PATH_CMD_CURVE3 and PATH_CMD_CURVE4
37  * The command calculates the generated curve points and
38  * saves the generated points to the curve using the conversion pipe
39  * move_to/line_to vertex sequence
40  * @since 1.0
41  * @version 1.0
42  */
43 class DepictCurve {
44 public:
45     /**
46      * @brief DepictCurve Class constructor
47      * The construction parameter is the vertexsource attribute, which determines the vertex source of the curve.
48      * @since 1.0
49      * @version 1.0
50      */
DepictCurve(UICanvasVertices & source)51     explicit DepictCurve(UICanvasVertices& source)
52         : source_(&source), lastX_(0), lastY_(0) {}
53 
Attach(UICanvasVertices & source)54     void Attach(UICanvasVertices& source)
55     {
56         source_ = &source;
57     }
58 
59     /**
60      * @brief Method for approximate estimation of curve
61      * There are two methods for defining and estimating quadratic or cubic (Bessel) curves.
62      * One is curve_ Inc, which is estimated by increasing the curve
63      * The second is curve_ Div is by equally dividing the curve into n div segments
64      * @since 1.0
65      * @version 1.0
66      */
ApproximationMethod(CurveApproximationMethod curvApproxiMethod)67     void ApproximationMethod(CurveApproximationMethod curvApproxiMethod)
68     {
69         quadraticBezier_.ApproximationMethod(curvApproxiMethod);
70         cubicBezier_.ApproximationMethod(curvApproxiMethod);
71     }
72 
ApproximationMethod()73     CurveApproximationMethod ApproximationMethod() const
74     {
75         return cubicBezier_.ApproximationMethod();
76     }
77 
78     /**
79      * @brief Finally determine the accuracy of the estimate
80      * In practical application, we need to convert the world coordinates of points to screen coordinates,
81      * so there will always be a certain scaling factor.
82      * Curves are usually processed in the world coordinate system and converted to pixel values when estimating.
83      * It usually looks like this: m_curved.approximation_scale(transform_.scale());
84      * Here, transform_ is a matrix of affine mapping,
85      * which contains all transformations,
86      * including viewpoint and scaling.
87      * @since 1.0
88      * @version 1.0
89      */
ApproximationScale(float aScale)90     void ApproximationScale(float aScale)
91     {
92         quadraticBezier_.SetApproximationScale(aScale);
93         cubicBezier_.SetApproximationScale(aScale);
94     }
95 
ApproximationScale()96     float ApproximationScale() const
97     {
98         return cubicBezier_.ApproximationScale();
99     }
100 
101     /**
102      * @brief Sets the angle estimate in radians. The less this value,
103      * the more accurate the estimation at the turn of the curve.
104      * However, if set to 0, it means that the angle condition is not considered at all.
105      * @since 1.0
106      * @version 1.0
107      */
AngleTolerance(float angleRate)108     void AngleTolerance(float angleRate)
109     {
110         quadraticBezier_.AngleTolerance(angleRate);
111         cubicBezier_.AngleTolerance(angleRate);
112     }
113 
AngleTolerance()114     float AngleTolerance() const
115     {
116         return cubicBezier_.AngleTolerance();
117     }
118 
119     /**
120      * @brief An angle set in radians. If 0,
121      * Then only the real cusp will have a bevel cut. If greater than 0,
122      * Then it will limit the curvature of the curve. The higher the value,
123      * the less sharp corners of the curve will be cut.
124      * Generally, this value should not be greater than 10-15 degrees.
125      * @since 1.0
126      * @version 1.0
127      */
CuspLimit(float v)128     void CuspLimit(float v)
129     {
130         quadraticBezier_.CuspLimit(v);
131         cubicBezier_.CuspLimit(v);
132     }
133 
CuspLimit()134     float CuspLimit() const
135     {
136         return cubicBezier_.CuspLimit();
137     }
138     /**
139      * Reset the status attribute of a path segment
140      * @path_id Is a path ID, calculated from 0
141      * @since 1.0
142      * @version 1.0
143      */
144     void Rewind(uint32_t pathId);
145 
146     /**
147      * According to PATH_CMD command returns the vertex coordinates generated in each stage
148      * @since 1.0
149      * @version 1.0
150      */
151     uint32_t GenerateVertex(float* x, float* y);
152 
153 private:
154     DepictCurve(const DepictCurve&);
155     const DepictCurve& operator=(const DepictCurve&);
156 
157     UICanvasVertices* source_;
158     float lastX_;
159     float lastY_;
160     QuadraticBezierCurve quadraticBezier_;
161     CubicBezierCurve cubicBezier_;
162 };
163 } // namespace OHOS
164 #endif
165