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 #include "gfx_utils/diagram/vertexgenerate/vertex_generate_stroke.h"
16
17 #include "gfx_utils/diagram/vertexprimitive/geometry_shorten_path.h"
18
19 namespace OHOS {
VertexGenerateStroke()20 VertexGenerateStroke::VertexGenerateStroke()
21 : stroker_(),
22 srcVertices_(),
23 outVertices_(),
24 strokeShorten_(0.0f),
25 closed_(0),
26 status_(INITIAL),
27 srcVertex_(0),
28 outVertex_(0)
29 {
30 }
31
RemoveAll()32 void VertexGenerateStroke::RemoveAll()
33 {
34 srcVertices_.Clear();
35 closed_ = 0;
36 status_ = INITIAL;
37 }
38
AddVertex(float x,float y,uint32_t cmd)39 void VertexGenerateStroke::AddVertex(float x, float y, uint32_t cmd)
40 {
41 status_ = INITIAL;
42 if (IsMoveTo(cmd)) {
43 srcVertices_.ModifyLast(VertexDist(x, y));
44 } else {
45 if (IsVertex(cmd)) {
46 srcVertices_.Add(VertexDist(x, y));
47 } else {
48 closed_ = GetCloseFlag(cmd);
49 }
50 }
51 }
52
Rewind(uint32_t)53 void VertexGenerateStroke::Rewind(uint32_t)
54 {
55 if (status_ == INITIAL) {
56 srcVertices_.Close(closed_ != 0);
57 ShortenPath(srcVertices_, strokeShorten_, closed_);
58 const uint32_t verticeNum = 3;
59 if (srcVertices_.Size() < verticeNum) {
60 closed_ = 0;
61 }
62 }
63 status_ = READY;
64 srcVertex_ = 0;
65 outVertex_ = 0;
66 }
67
GenerateVertex(float * x,float * y)68 uint32_t VertexGenerateStroke::GenerateVertex(float* x, float* y)
69 {
70 const uint32_t verticesNum = 2;
71 uint32_t cmd = PATH_CMD_LINE_TO;
72 while (!IsStop(cmd)) {
73 switch (status_) {
74 case INITIAL:
75 Rewind(0); // It will be ready immediately after initialization
76 /* fallthru */
77 case READY:
78 VertexReady(verticesNum, cmd);
79 break;
80 case LINECAP_START:
81 VertexLineCapStart();
82 break;
83 case LINECAP_END:
84 VertexLineCapEnd(verticesNum);
85 break;
86 case LINEJOIN_START:
87 VertexLineJoinStart();
88 break;
89 case CLOSE_FIRST:
90 VertexCloseFirst(cmd);
91 break;
92 case LINEJOIN_END:
93 VertexLineJoinEnd();
94 break;
95 case OUT_VERTICES:
96 if (IsVertexOutVertices(x, y)) {
97 return cmd;
98 }
99 break;
100 case CLOCKWISE_ENDPOLY:
101 status_ = prevStatus_;
102 return PATH_CMD_END_POLY | PATH_FLAGS_CLOSE | PATH_FLAGS_CLOCKWISE;
103 case ANTI_CLOCKWISE_ENDPOLY:
104 status_ = prevStatus_;
105 return PATH_CMD_END_POLY | PATH_FLAGS_CLOSE | PATH_FLAGS_ANTI_CLOCKWISE;
106 case STOP:
107 cmd = PATH_CMD_STOP;
108 break;
109 default: break;
110 }
111 }
112 return cmd;
113 }
114
VertexReady(const uint32_t & verticesNum,uint32_t & cmd)115 void VertexGenerateStroke::VertexReady(const uint32_t& verticesNum, uint32_t& cmd)
116 {
117 if (srcVertices_.Size() < verticesNum + uint32_t(closed_ != 0)) {
118 cmd = PATH_CMD_STOP;
119 return;
120 }
121 if (closed_) {
122 status_ = LINEJOIN_START;
123 } else {
124 status_ = LINECAP_START;
125 }
126 cmd = PATH_CMD_MOVE_TO;
127 srcVertex_ = 0;
128 outVertex_ = 0;
129 }
130
VertexLineCapStart()131 void VertexGenerateStroke::VertexLineCapStart()
132 {
133 #if defined(GRAPHIC_ENABLE_LINECAP_FLAG) && GRAPHIC_ENABLE_LINECAP_FLAG
134 stroker_.CalcCap(outVertices_,
135 srcVertices_[0],
136 srcVertices_[1],
137 srcVertices_[0].vertexDistance);
138 #endif
139 srcVertex_ = 1;
140 prevStatus_ = LINEJOIN_START;
141 status_ = OUT_VERTICES;
142 outVertex_ = 0;
143 }
144
VertexLineCapEnd(const uint32_t & verticesNum)145 void VertexGenerateStroke::VertexLineCapEnd(const uint32_t& verticesNum)
146 {
147 #if defined(GRAPHIC_ENABLE_LINECAP_FLAG) && GRAPHIC_ENABLE_LINECAP_FLAG
148 stroker_.CalcCap(outVertices_,
149 srcVertices_[srcVertices_.Size() - 1],
150 srcVertices_[srcVertices_.Size() - verticesNum],
151 srcVertices_[srcVertices_.Size() - verticesNum].vertexDistance);
152 #endif
153 prevStatus_ = LINEJOIN_END;
154 status_ = OUT_VERTICES;
155 outVertex_ = 0;
156 }
157
VertexLineJoinStart()158 void VertexGenerateStroke::VertexLineJoinStart()
159 {
160 if (closed_ && srcVertex_ >= srcVertices_.Size()) {
161 prevStatus_ = CLOSE_FIRST;
162 status_ = CLOCKWISE_ENDPOLY;
163 return;
164 }
165 if (!closed_ && srcVertex_ >= srcVertices_.Size() - 1) {
166 status_ = LINECAP_END;
167 return;
168 }
169 #if defined(GRAPHIC_ENABLE_LINEJOIN_FLAG) && GRAPHIC_ENABLE_LINEJOIN_FLAG
170 stroker_.CalcJoin(outVertices_,
171 srcVertices_.Prev(srcVertex_),
172 srcVertices_.Curr(srcVertex_),
173 srcVertices_.Next(srcVertex_),
174 srcVertices_.Prev(srcVertex_).vertexDistance,
175 srcVertices_.Curr(srcVertex_).vertexDistance);
176 #endif
177 ++srcVertex_;
178 prevStatus_ = status_;
179 status_ = OUT_VERTICES;
180 outVertex_ = 0;
181 }
182
VertexLineJoinEnd()183 void VertexGenerateStroke::VertexLineJoinEnd()
184 {
185 if (srcVertex_ <= uint32_t(closed_ == 0)) {
186 status_ = ANTI_CLOCKWISE_ENDPOLY;
187 prevStatus_ = STOP;
188 return;
189 }
190 --srcVertex_;
191 #if defined(GRAPHIC_ENABLE_LINEJOIN_FLAG) && GRAPHIC_ENABLE_LINEJOIN_FLAG
192 stroker_.CalcJoin(outVertices_,
193 srcVertices_.Next(srcVertex_),
194 srcVertices_.Curr(srcVertex_),
195 srcVertices_.Prev(srcVertex_),
196 srcVertices_.Curr(srcVertex_).vertexDistance,
197 srcVertices_.Prev(srcVertex_).vertexDistance);
198 #endif
199 outVertex_ = 0;
200 prevStatus_ = status_;
201 status_ = OUT_VERTICES;
202 }
203
VertexCloseFirst(uint32_t & cmd)204 void VertexGenerateStroke::VertexCloseFirst(uint32_t& cmd)
205 {
206 status_ = LINEJOIN_END;
207 cmd = PATH_CMD_MOVE_TO;
208 }
209
IsVertexOutVertices(float * x,float * y)210 bool VertexGenerateStroke::IsVertexOutVertices(float* x, float* y)
211 {
212 if (outVertex_ >= outVertices_.Size()) {
213 status_ = prevStatus_;
214 return false;
215 } else {
216 const PointF& c = outVertices_[outVertex_++];
217 *x = c.x;
218 *y = c.y;
219 return true;
220 }
221 }
222 } // namespace OHOS
223