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 graphic_geometry_depict_adaptor_vcgen.h
18  *
19  * @brief Defines Build geometry vertex generation process adapter
20  * Use the coordinate conversion pipeline to change the vertices generated by the vertex source,
21  * including coordinates, commands, generating new vertices, etc
22  * @since 1.0
23  * @version 1.0
24  */
25 
26 #ifndef GRAPHIC_LITE_DEPICT_ADAPTOR_VERTEX_GENERATE_H
27 #define GRAPHIC_LITE_DEPICT_ADAPTOR_VERTEX_GENERATE_H
28 #include <typeinfo>
29 
30 #include "gfx_utils/diagram/common/common_basics.h"
31 #include "gfx_utils/diagram/vertexgenerate/vertex_generate_dash.h"
32 
33 namespace OHOS {
34 /**
35  * @struct EmptyMarkers
36  * @brief Build a default empty geometry structure
37  * This structure is mainly used to set the default empty tag symbol for elements such as stroke
38  * @see template<class VertexSource, class Markers = EmptyMarkers>
39  * struct DepictStroke
40  * @since 1.0
41  * @version 1.0
42  */
43 struct EmptyMarkers {
44     /**
45      * @brief Clear all marker symbol elements
46      * @since 1.0
47      * @version 1.0
48      */
RemoveAllEmptyMarkers49     void RemoveAll() {}
50 
51     /**
52      * @brief Add or insert marker symbol elements
53      * @since 1.0
54      * @version 1.0
55      */
AddVertexEmptyMarkers56     void AddVertex(float, float, uint32_t) {}
57 
58     /**
59      * @brief Make relevant preparations before using this structure to build markers symbols
60      * @since 1.0
61      * @version 1.0
62      */
PrepareSrcEmptyMarkers63     void PrepareSrc() {}
64 
65     /**
66      * @brief A bunch of operation processing resets the new state
67      * @since 1.0
68      * @version 1.0
69      */
RewindEmptyMarkers70     void Rewind(uint32_t) {}
71 
72     /**
73      * @brief Move vertices or generate new vertices according to different states
74      * Return to the current operation status for subsequent processing
75      * @since 1.0
76      * @version 1.0
77      */
GenerateVertexEmptyMarkers78     uint32_t GenerateVertex(float*, float*)
79     {
80         return PATH_CMD_STOP;
81     }
82 };
83 
84 /**
85  * @template class DepictAdaptorVertexGenerator
86  * @brief This template class is the base class of vertex generation adapter
87  * It mainly uses the vertex construction and generation stage
88  * Change the vertices generated by the vertex source,
89  * including coordinates, commands, generating new vertices, etc.
90  * template Parameters include vertex source, specific entity generator, marker symbol, etc
91  * @since 1.0
92  * @version 1.0
93  */
94 template <class VertexSource,
95           class Generator,
96           class Markers = EmptyMarkers>
97 class DepictAdaptorVertexGenerate {
98     /**
99      * @brief Sets the state of the vertex adaptation generator
100      * It basically includes initialization preparation,
101      * cumulative generation of base points and generation of new point status of difference
102      * @since 1.0
103      * @version 1.0
104      */
105     enum VertexGenerator {
106         INITIAL,
107         ACCUMULATE,
108         GENERATE
109     };
110 
111 public:
112     /**
113      * @brief The constructor of the template class DepictAdaptorVertexGenerator
114      * Initialize the vertex source class, and the collocated state is the initial state
115      * @since 1.0
116      * @version 1.0
117      */
DepictAdaptorVertexGenerate(VertexSource & source)118     explicit DepictAdaptorVertexGenerate(VertexSource& source)
119         : msource_(&source), status_(INITIAL), lastCmd_(0), startX_(0), startY_(0) {}
120 
121     /**
122      * @brief Set vertex source directly
123      * @since 1.0
124      * @version 1.0
125      */
Attach(VertexSource & source)126     void Attach(VertexSource& source)
127     {
128         msource_ = &source;
129     }
130 
131     /**
132      * @brief Returns a variable generator reference
133      * @since 1.0
134      * @version 1.0
135      */
GetGenerator()136     Generator& GetGenerator()
137     {
138         return generator_;
139     }
140 
141     /**
142      * @brief Returns an immutable generator reference
143      * @since 1.0
144      * @version 1.0
145      */
GetGenerator()146     const Generator& GetGenerator() const
147     {
148         return generator_;
149     }
150 
151     /**
152      * @brief Returns a variable marker symbol reference
153      * @since 1.0
154      * @version 1.0
155      */
GetMarkers()156     Markers& GetMarkers()
157     {
158         return markers_;
159     }
160 
161     /**
162      * @brief Returns an immutable marker symbol reference
163      * @since 1.0
164      * @version 1.0
165      */
GetMarkers()166     const Markers& GetMarkers() const
167     {
168         return markers_;
169     }
170 
171     /**
172      * @brief Reset vertex state
173      * @since 1.0
174      * @version 1.0
175      */
Rewind(uint32_t pathId)176     void Rewind(uint32_t pathId)
177     {
178         msource_->Rewind(pathId);
179         status_ = INITIAL;
180     }
181 
182     /**
183      * @brief Move vertices or generate new vertices according to different states
184      * Return to the current operation status for subsequent processing
185      * @since 1.0
186      * @version 1.0
187      */
188     uint32_t GenerateVertex(float* x, float* y);
189     /**
190      * @brief Move vertices or generate new vertices according to accumulate state while func
191      * @since 1.0
192      * @version 1.0
193      */
194     void VertexAccumulateWhile(float* x, float* y);
195 
196 private:
197     DepictAdaptorVertexGenerate(const DepictAdaptorVertexGenerate<VertexSource, Generator, Markers>&);
198 
199     const DepictAdaptorVertexGenerate<VertexSource, Generator, Markers>& operator=
200     (const DepictAdaptorVertexGenerate<VertexSource, Generator, Markers>&);
201 
202     VertexSource* msource_;
203     Generator generator_;
204     Markers markers_;
205     VertexGenerator status_;
206     uint32_t lastCmd_;
207     float startX_;
208     float startY_;
209 };
210 
211 /**
212  * @brief Move vertices or generate new vertices according to different states
213  * Return to the current operation status for subsequent processing
214  * @since 1.0
215  * @version 1.0
216  */
217 template <class VertexSource, class Generator, class Markers>
GenerateVertex(float * x,float * y)218 uint32_t DepictAdaptorVertexGenerate<VertexSource, Generator, Markers>::GenerateVertex(float* x, float* y)
219 {
220     uint32_t cmd = PATH_CMD_STOP;
221     bool done = false;
222     while (!done) {
223         switch (status_) {
224             case INITIAL:
225                 lastCmd_ = msource_->GenerateVertex(&startX_, &startY_);
226                 markers_.RemoveAll();
227                 status_ = ACCUMULATE;
228                 break;
229             case ACCUMULATE:
230                 if (IsStop(lastCmd_)) {
231                     return PATH_CMD_STOP;
232                 }
233                 markers_.AddVertex(startX_, startY_, PATH_CMD_MOVE_TO);
234 #if defined(GRAPHIC_ENABLE_DASH_GENERATE_FLAG) && GRAPHIC_ENABLE_DASH_GENERATE_FLAG
235                 generator_.RemoveAll();
236                 generator_.AddVertex(startX_, startY_, PATH_CMD_MOVE_TO);
237 
238 #else
239                 if (generator_.GetGenerateFlags() != VertexGenerateFlags::GENERATE_DASH) {
240                     generator_.RemoveAll();
241                     generator_.AddVertex(startX_, startY_, PATH_CMD_MOVE_TO);
242                 }
243 #endif
244                 VertexAccumulateWhile(x, y);
245                 if (generator_.GetGenerateFlags() != VertexGenerateFlags::GENERATE_DASH) {
246                     generator_.Rewind(0);
247                 }
248                 status_ = GENERATE;
249                 break;
250             case GENERATE:
251                 cmd = generator_.GenerateVertex(x, y);
252                 if (IsStop(cmd)) {
253                     status_ = ACCUMULATE;
254                     break;
255                 }
256                 done = true;
257                 break;
258             default:
259                 break;
260         }
261     }
262     return cmd;
263 }
264 /**
265  * @brief Move vertices or generate new vertices according to accumulate state while func
266  * @since 1.0
267  * @version 1.0
268  */
269 template <class VertexSource, class Generator, class Markers>
VertexAccumulateWhile(float * x,float * y)270 void DepictAdaptorVertexGenerate<VertexSource, Generator, Markers>::VertexAccumulateWhile(float* x,
271                                                                                           float* y)
272 {
273     uint32_t cmd = PATH_CMD_STOP;
274     while (true) {
275         cmd = msource_->GenerateVertex(x, y);
276         if (IsVertex(cmd)) {
277             lastCmd_ = cmd;
278             if (IsMoveTo(cmd)) {
279                 startY_ = *y;
280                 startX_ = *x;
281                 break;
282             }
283             markers_.AddVertex(*x, *y, PATH_CMD_LINE_TO);
284 #if defined(GRAPHIC_ENABLE_DASH_GENERATE_FLAG) && GRAPHIC_ENABLE_DASH_GENERATE_FLAG
285             generator_.AddVertex(*x, *y, cmd);
286 #else
287             if (generator_.GetGenerateFlags() != VertexGenerateFlags::GENERATE_DASH) {
288                 generator_.AddVertex(*x, *y, cmd);
289             }
290 #endif
291         } else {
292             if (IsStop(cmd)) {
293                 lastCmd_ = PATH_CMD_STOP;
294                 break;
295             }
296             if (IsEndPoly(cmd)) {
297 #if defined(GRAPHIC_ENABLE_DASH_GENERATE_FLAG) && GRAPHIC_ENABLE_DASH_GENERATE_FLAG
298                 generator_.AddVertex(*x, *y, cmd);
299 #else
300                 if (generator_.GetGenerateFlags() != VertexGenerateFlags::GENERATE_DASH) {
301                     generator_.AddVertex(*x, *y, cmd);
302                 }
303 
304 #endif
305                 break;
306             }
307         }
308     }
309 }
310 } // namespace OHOS
311 #endif
312