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 #include "gfx_utils/diagram/vertexgenerate/vertex_generate_dash.h"
17
18 #include "gfx_utils/diagram/vertexprimitive/geometry_shorten_path.h"
19
20 namespace OHOS {
21 #if defined(GRAPHIC_ENABLE_DASH_GENERATE_FLAG) && GRAPHIC_ENABLE_DASH_GENERATE_FLAG
VertexGenerateDash()22 VertexGenerateDash::VertexGenerateDash()
23 : totalDashLen_(0.0f),
24 numDashes_(0),
25 dashStart_(0.0f),
26 shorten_(0.0f),
27 currDashStart_(0.0f),
28 currDash_(0),
29 currRest_(0.0f),
30 srcVertices_(),
31 closed_(0),
32 status_(INITIAL),
33 srcVertex_(0) {}
34
GetGenerateFlags()35 VertexGenerateFlags VertexGenerateDash::GetGenerateFlags()
36 {
37 return GENERATE_DASH;
38 }
39
RemoveAllDashes()40 void VertexGenerateDash::RemoveAllDashes()
41 {
42 totalDashLen_ = 0.0;
43 numDashes_ = 0;
44 currDashStart_ = 0.0;
45 currDash_ = 0;
46 }
47
AddDash(float dashLen,float gapLen)48 void VertexGenerateDash::AddDash(float dashLen, float gapLen)
49 {
50 if (numDashes_ < MAX_DASHES) {
51 totalDashLen_ += dashLen + gapLen;
52 dashes_[numDashes_++] = dashLen;
53 dashes_[numDashes_++] = gapLen;
54 }
55 }
56
DashStart(float ds)57 void VertexGenerateDash::DashStart(float ds)
58 {
59 dashStart_ = ds;
60 CalcDashStart(MATH_ABS(ds));
61 }
62
CalcDashStart(float ds)63 void VertexGenerateDash::CalcDashStart(float ds)
64 {
65 currDash_ = 0;
66 currDashStart_ = 0.0f;
67 for (; ds > 0.0f;) {
68 if (ds > dashes_[currDash_]) {
69 ds -= dashes_[currDash_];
70 ++currDash_;
71 currDashStart_ = 0.0f;
72 if (currDash_ >= numDashes_) {
73 currDash_ = 0;
74 }
75 } else {
76 currDashStart_ = ds;
77 ds = 0.0f;
78 }
79 }
80 }
81
RemoveAll()82 void VertexGenerateDash::RemoveAll()
83 {
84 status_ = INITIAL;
85 srcVertices_.Clear();
86 closed_ = 0;
87 }
88
AddVertex(float x,float y,uint32_t cmd)89 void VertexGenerateDash::AddVertex(float x, float y, uint32_t cmd)
90 {
91 status_ = INITIAL;
92 if (IsMoveTo(cmd)) {
93 srcVertices_.ModifyLast(VertexDist(x, y));
94 } else {
95 if (IsVertex(cmd)) {
96 srcVertices_.Add(VertexDist(x, y));
97 } else {
98 closed_ = GetCloseFlag(cmd);
99 }
100 }
101 }
102
Rewind(uint32_t)103 void VertexGenerateDash::Rewind(uint32_t)
104 {
105 if (status_ == INITIAL) {
106 srcVertices_.Close(closed_ != 0);
107 ShortenPath(srcVertices_, shorten_, closed_);
108 }
109 status_ = READY;
110 srcVertex_ = 0;
111 }
112
CompareSize()113 void VertexGenerateDash::CompareSize()
114 {
115 if (currDash_ >= numDashes_) {
116 currDash_ = 0;
117 }
118 }
119
CompareVertexSize()120 void VertexGenerateDash::CompareVertexSize()
121 {
122 if (closed_) {
123 if (srcVertex_ > srcVertices_.Size()) {
124 status_ = STOP;
125 } else {
126 if (srcVertex_ >= srcVertices_.Size()) {
127 vertexDist2_ = &srcVertices_[0];
128 } else {
129 vertexDist2_ = &srcVertices_[srcVertex_];
130 }
131 }
132 } else {
133 if (srcVertex_ >= srcVertices_.Size()) {
134 status_ = STOP;
135 } else {
136 vertexDist2_ = &srcVertices_[srcVertex_];
137 }
138 }
139 }
140
GenerateVertex(float * x,float * y)141 uint32_t VertexGenerateDash::GenerateVertex(float* x, float* y)
142 {
143 uint32_t cmd = PATH_CMD_MOVE_TO;
144 while (!IsStop(cmd)) {
145 switch (status_) {
146 case INITIAL:
147 Rewind(0); // fall-through
148 case READY:
149 if (numDashes_ < FLOATNUM || srcVertices_.Size() < FLOATNUM) {
150 return PATH_CMD_STOP;
151 }
152 status_ = POLYLINE;
153 srcVertex_ = 1;
154 vertexDist1_ = &srcVertices_[0];
155 vertexDist2_ = &srcVertices_[1];
156 currRest_ = vertexDist1_->vertexDistance;
157 *x = vertexDist1_->vertexXCoord;
158 *y = vertexDist1_->vertexYCoord;
159 if (dashStart_ >= 0.0f) {
160 CalcDashStart(dashStart_);
161 };
162 return PATH_CMD_MOVE_TO;
163 case POLYLINE: {
164 float dashRest = dashes_[currDash_] - currDashStart_;
165 if (currDash_ & 1) {
166 cmd = PATH_CMD_MOVE_TO;
167 } else {
168 cmd = PATH_CMD_LINE_TO;
169 }
170 if (currRest_ > dashRest) {
171 currRest_ -= dashRest;
172 ++currDash_;
173 CompareSize();
174 currDashStart_ = 0.0f;
175 *x = vertexDist2_->vertexXCoord -
176 (vertexDist2_->vertexXCoord - vertexDist1_->vertexXCoord) * currRest_
177 / vertexDist1_->vertexDistance;
178 *y = vertexDist2_->vertexYCoord -
179 (vertexDist2_->vertexYCoord - vertexDist1_->vertexYCoord) * currRest_
180 / vertexDist1_->vertexDistance;
181 } else {
182 currDashStart_ += currRest_;
183 *x = vertexDist2_->vertexXCoord;
184 *y = vertexDist2_->vertexYCoord;
185 ++srcVertex_;
186 vertexDist1_ = vertexDist2_;
187 currRest_ = vertexDist1_->vertexDistance;
188 CompareVertexSize();
189 }
190 return cmd;
191 }
192 case STOP:
193 return PATH_CMD_STOP;
194 }
195 }
196 return PATH_CMD_STOP;
197 }
198 #endif
199 } // namespace OHOS
200