1 /*
2 * Copyright (c) 2020-2021 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 "draw/draw_arc.h"
17 #include "common/image.h"
18 #include "gfx_utils/graphic_math.h"
19
20 namespace OHOS {
21 #define IS_IN_DEGREERANE(d, s, e) ((s) <= (e)) ? (((d) >= (s)) && ((d) <= (e))) : (((d) >= (s)) || ((d) <= (e)))
GetInstance()22 DrawArc* DrawArc::GetInstance()
23 {
24 static DrawArc drawArc;
25 return &drawArc;
26 }
27
DrawImg(BufferInfo & gfxDstBuffer,const Point & imgPos,Rect & area,const Rect & invalidatedArea,const Style & style,uint8_t opaScale,const Image * image)28 void DrawArc::DrawImg(BufferInfo& gfxDstBuffer,
29 const Point& imgPos,
30 Rect& area,
31 const Rect& invalidatedArea,
32 const Style& style,
33 uint8_t opaScale,
34 const Image* image)
35 {
36 if (image == nullptr) {
37 return;
38 }
39 ImageHeader header = {0};
40 image->GetHeader(header);
41
42 Rect cordsTmp;
43 cordsTmp.SetPosition(imgPos.x, imgPos.y);
44 cordsTmp.SetHeight(header.height);
45 cordsTmp.SetWidth(header.width);
46 if (area.Intersect(area, invalidatedArea)) {
47 image->DrawImage(gfxDstBuffer, cordsTmp, area, style, opaScale);
48 }
49 }
50
DrawVerLine(BufferInfo & gfxDstBuffer,const Point & begin,const Point & imgPos,const Rect & mask,int16_t len,const Style & style,uint8_t opaScale,const Image * image)51 void DrawArc::DrawVerLine(BufferInfo& gfxDstBuffer,
52 const Point& begin,
53 const Point& imgPos,
54 const Rect& mask,
55 int16_t len,
56 const Style& style,
57 uint8_t opaScale,
58 const Image* image)
59 {
60 Rect rect(begin.x, begin.y, begin.x, begin.y + len);
61 if ((image != nullptr) && (image->GetSrcType() != IMG_SRC_UNKNOWN)) {
62 DrawImg(gfxDstBuffer, imgPos, rect, mask, style, opaScale, image);
63 } else {
64 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, rect, mask, style.lineColor_, opaScale);
65 }
66 }
67
DrawHorLine(BufferInfo & gfxDstBuffer,const Point & begin,const Point & imgPos,const Rect & mask,int16_t len,const Style & style,uint8_t opaScale,const Image * image)68 void DrawArc::DrawHorLine(BufferInfo& gfxDstBuffer,
69 const Point& begin,
70 const Point& imgPos,
71 const Rect& mask,
72 int16_t len,
73 const Style& style,
74 uint8_t opaScale,
75 const Image* image)
76 {
77 if ((image != nullptr) && (image->GetSrcType() != IMG_SRC_UNKNOWN)) {
78 Rect rect(begin.x, begin.y, begin.x + len, begin.y);
79 DrawImg(gfxDstBuffer, imgPos, rect, mask, style, opaScale, image);
80 } else {
81 if (len == 0) {
82 DrawUtils::GetInstance()->DrawPixel(gfxDstBuffer, begin.x, begin.y, mask, style.lineColor_, opaScale);
83 } else {
84 Rect rect(begin.x, begin.y, begin.x + len, begin.y);
85 DrawUtils::GetInstance()->DrawColorArea(gfxDstBuffer, rect, mask, style.lineColor_, opaScale);
86 }
87 }
88 }
89
GetDrawAngle(int16_t angle)90 int16_t DrawArc::GetDrawAngle(int16_t angle)
91 {
92 if (angle < 0) {
93 angle = (angle % CIRCLE_IN_DEGREE) + CIRCLE_IN_DEGREE;
94 } else if (angle > CIRCLE_IN_DEGREE) {
95 angle = angle % CIRCLE_IN_DEGREE;
96 }
97 return angle;
98 }
99
GetDrawRange(int16_t & start,int16_t & end)100 void DrawArc::GetDrawRange(int16_t& start, int16_t& end)
101 {
102 int16_t tempAngle = GetDrawAngle(start);
103 if (start == end) {
104 start = tempAngle;
105 end = tempAngle;
106 } else if (end - start >= CIRCLE_IN_DEGREE) {
107 // draw circle
108 start = 0;
109 end = CIRCLE_IN_DEGREE;
110 } else {
111 start = tempAngle;
112 end = GetDrawAngle(end);
113 }
114 }
115
CalculateTanDegree(uint16_t x,uint16_t y)116 uint16_t DrawArc::CalculateTanDegree(uint16_t x, uint16_t y)
117 {
118 uint16_t degree = FastAtan2(x, y);
119 if ((degree == QUARTER_IN_DEGREE) && (y != 0)) {
120 degree--;
121 }
122 if ((degree == 0) && (x != 0)) {
123 degree++;
124 }
125 return degree;
126 }
127
DrawCircleNoEndpoint(BufferInfo & gfxDstBuffer,ArcInfo & arcInfo,const Rect & mask,const Style & style,uint8_t opa,bool anti)128 void DrawArc::DrawCircleNoEndpoint(BufferInfo& gfxDstBuffer,
129 ArcInfo& arcInfo,
130 const Rect& mask,
131 const Style& style,
132 uint8_t opa,
133 bool anti)
134 {
135 DrawAxisLine(gfxDstBuffer, arcInfo, mask, style, opa);
136
137 int16_t yStart = mask.GetTop() - arcInfo.center.y;
138 int16_t yEnd = mask.GetBottom() - arcInfo.center.y;
139 if ((yStart >= 0) && (yEnd >= 0)) {
140 int16_t tmp = yStart;
141 yStart = -yEnd;
142 yEnd = -tmp;
143 } else if ((yStart < 0) && (yEnd > 0)) {
144 yStart = MATH_MIN(yStart, -yEnd);
145 yEnd = -1;
146 }
147 yStart = MATH_MAX(yStart, -outRadius_) - 1;
148 yEnd = MATH_MIN(yEnd, -1);
149
150 int16_t xi;
151 int16_t xLineStart = -outRadius_;
152 int16_t xLineStart2 = xLineStart - 1;
153 int16_t xLineStart3 = COORD_MIN;
154
155 for (y_ = yEnd; y_ > yStart; y_--) {
156 ySqr_ = static_cast<int32_t>(y_) * y_;
157 bool isSetStartPot = false;
158 for (xi = xLineStart2; xi < 0; xi++) {
159 uint32_t currentSqr = static_cast<int32_t>(xi) * xi + ySqr_;
160 if (currentSqr > outRadiusSqr_) {
161 continue;
162 }
163 if (!isSetStartPot) {
164 xLineStart2 = xi;
165 lineStart_ = xi;
166 if (xLineStart3 != COORD_MIN) {
167 xi = xLineStart3;
168 }
169 isSetStartPot = true;
170 }
171 if (y_ <= -inRadius_) {
172 lineEnd_ = -1;
173 xi = -1;
174 break;
175 }
176 if (currentSqr < inRadiusSqr_) {
177 xLineStart3 = xi - 1;
178 lineEnd_ = xi - 1;
179 break;
180 }
181 }
182 if (!isSetStartPot) {
183 continue;
184 }
185 #if ENABLE_ANTIALIAS
186 if (anti) {
187 DrawLineAnti(gfxDstBuffer, arcInfo, mask, style, opa);
188 }
189 #endif
190 DrawLineWithDegree(gfxDstBuffer, arcInfo, -lineEnd_, -lineStart_, y_, mask, style, opa, ARC_QUADRANT_ONE);
191
192 DrawLineWithDegree(gfxDstBuffer, arcInfo, -lineEnd_, -lineStart_, -y_, mask, style, opa, ARC_QUADRANT_TWO);
193
194 DrawLineWithDegree(gfxDstBuffer, arcInfo, lineStart_, lineEnd_, -y_, mask, style, opa, ARC_QUADRANT_THREE);
195
196 DrawLineWithDegree(gfxDstBuffer, arcInfo, lineStart_, lineEnd_, y_, mask, style, opa, ARC_QUADRANT_FOUR);
197 }
198 }
199
DrawAxisLine(BufferInfo & gfxDstBuffer,ArcInfo & arcInfo,const Rect & mask,const Style & style,uint8_t opa)200 void DrawArc::DrawAxisLine(BufferInfo& gfxDstBuffer,
201 ArcInfo& arcInfo,
202 const Rect& mask,
203 const Style& style,
204 uint8_t opa)
205 {
206 int16_t lineWidth = 0;
207 int16_t outRadius = outRadius_ - 1;
208 int16_t inRadius = inRadius_;
209 if (inRadius <= 0) {
210 inRadius = 1;
211 DrawHorLine(gfxDstBuffer, arcInfo.center, arcInfo.imgPos, mask, 0, style, opa, arcInfo.imgSrc);
212 }
213 lineWidth = outRadius - inRadius;
214
215 if (isCircle_ || (IS_IN_DEGREERANE(THREE_QUARTER_IN_DEGREE, arcInfo.startAngle, arcInfo.endAngle))) {
216 DrawHorLine(gfxDstBuffer, Point { static_cast<int16_t>(arcInfo.center.x - outRadius), arcInfo.center.y },
217 arcInfo.imgPos, mask, lineWidth, style, opa, arcInfo.imgSrc);
218 }
219
220 if (isCircle_ || (IS_IN_DEGREERANE(QUARTER_IN_DEGREE, arcInfo.startAngle, arcInfo.endAngle))) {
221 DrawHorLine(gfxDstBuffer, Point { static_cast<int16_t>(arcInfo.center.x + inRadius), arcInfo.center.y },
222 arcInfo.imgPos, mask, lineWidth, style, opa, arcInfo.imgSrc);
223 }
224
225 if (isCircle_ || (IS_IN_DEGREERANE(0, arcInfo.startAngle, arcInfo.endAngle))) {
226 DrawVerLine(gfxDstBuffer, Point { arcInfo.center.x, static_cast<int16_t>(arcInfo.center.y - outRadius) },
227 arcInfo.imgPos, mask, lineWidth, style, opa, arcInfo.imgSrc);
228 }
229
230 if (isCircle_ || (IS_IN_DEGREERANE(SEMICIRCLE_IN_DEGREE, arcInfo.startAngle, arcInfo.endAngle))) {
231 DrawVerLine(gfxDstBuffer, Point { arcInfo.center.x, static_cast<int16_t>(arcInfo.center.y + inRadius) },
232 arcInfo.imgPos, mask, lineWidth, style, opa, arcInfo.imgSrc);
233 }
234 }
235
DrawLineWithDegree(BufferInfo & gfxDstBuffer,ArcInfo & arcInfo,int16_t start,int16_t end,int16_t y,const Rect & mask,const Style & style,uint8_t opaScale,uint8_t quadrant)236 void DrawArc::DrawLineWithDegree(BufferInfo& gfxDstBuffer,
237 ArcInfo& arcInfo,
238 int16_t start,
239 int16_t end,
240 int16_t y,
241 const Rect& mask,
242 const Style& style,
243 uint8_t opaScale,
244 uint8_t quadrant)
245 {
246 if (isCircle_) {
247 DrawHorLine(gfxDstBuffer,
248 Point {static_cast<int16_t>(arcInfo.center.x + start), static_cast<int16_t>(arcInfo.center.y + y)},
249 arcInfo.imgPos, mask, end - start, style, opaScale, arcInfo.imgSrc);
250 return;
251 }
252 uint16_t degreeStart = GetDegreeInQuadrant(CalculateTanDegree(MATH_ABS(start), MATH_ABS(y)), quadrant);
253 uint16_t degreeEnd = GetDegreeInQuadrant(CalculateTanDegree(MATH_ABS(end), MATH_ABS(y)), quadrant);
254 if (degreeStart > degreeEnd) {
255 uint16_t tmp = degreeStart;
256 degreeStart = degreeEnd;
257 degreeEnd = tmp;
258 }
259
260 int16_t lineDegreeRet = GetDegreeRangeIntersectState(degreeStart, degreeEnd, arcInfo.startAngle, arcInfo.endAngle);
261 int16_t drawEnd = 0;
262 switch (lineDegreeRet) {
263 case OUT_DEGREE_RANG:
264 return;
265 case IN_DEGREE_RANG:
266 DrawHorLine(gfxDstBuffer,
267 Point { static_cast<int16_t>(arcInfo.center.x + start), static_cast<int16_t>(arcInfo.center.y + y) },
268 arcInfo.imgPos, mask, end - start, style, opaScale, arcInfo.imgSrc);
269 return;
270 case INTERSECT:
271 DrawLineWithDegreeInner(gfxDstBuffer, arcInfo, start, end, y, mask, style, opaScale, quadrant);
272 return;
273 case DOUBLE_INTERSECT:
274 drawEnd = DrawLineWithDegreeInner(gfxDstBuffer, arcInfo, start, end, y, mask, style, opaScale, quadrant);
275 DrawLineWithDegreeInner(gfxDstBuffer, arcInfo, drawEnd + 1, end, y, mask, style, opaScale, quadrant);
276 return;
277 default:
278 return;
279 }
280 }
281
DrawLineWithDegreeInner(BufferInfo & gfxDstBuffer,ArcInfo & arcInfo,int16_t start,int16_t end,int16_t y,const Rect & mask,const Style & style,uint8_t opaScale,uint8_t quadrant)282 int16_t DrawArc::DrawLineWithDegreeInner(BufferInfo& gfxDstBuffer,
283 ArcInfo& arcInfo,
284 int16_t start,
285 int16_t end,
286 int16_t y,
287 const Rect& mask,
288 const Style& style,
289 uint8_t opaScale,
290 uint8_t quadrant)
291 {
292 int16_t drawStart = COORD_MIN;
293 int16_t drawEnd = COORD_MIN;
294 for (int16_t xi = start; xi <= end; xi++) {
295 uint16_t degreeBase = CalculateTanDegree(MATH_ABS(xi), MATH_ABS(y));
296 uint16_t degree = GetDegreeInQuadrant(degreeBase, quadrant);
297 if (IS_IN_DEGREERANE(degree, arcInfo.startAngle, arcInfo.endAngle)) {
298 if (drawStart == COORD_MIN) {
299 drawStart = xi;
300 }
301 } else {
302 if ((drawStart != COORD_MIN) && (drawEnd == COORD_MIN)) {
303 drawEnd = xi - 1;
304 break;
305 }
306 }
307 }
308 if (drawEnd == COORD_MIN) {
309 drawEnd = end;
310 }
311 if ((drawStart != COORD_MIN) && (drawEnd != COORD_MIN)) {
312 DrawHorLine(gfxDstBuffer,
313 Point { static_cast<int16_t>(arcInfo.center.x + drawStart), static_cast<int16_t>(arcInfo.center.y + y) },
314 arcInfo.imgPos, mask, drawEnd - drawStart, style, opaScale, arcInfo.imgSrc);
315 }
316 return drawEnd;
317 }
318
319 #if ENABLE_ANTIALIAS
DrawLineAnti(BufferInfo & gfxDstBuffer,ArcInfo & arcInfo,const Rect & mask,const Style & style,uint8_t opa)320 void DrawArc::DrawLineAnti(BufferInfo& gfxDstBuffer, ArcInfo& arcInfo, const Rect& mask,
321 const Style& style, uint8_t opa)
322 {
323 outAntiStart_ = lineStart_;
324 outAntiEnd_ = lineStart_;
325 inAntiStart_ = lineEnd_ + 1;
326 inAntiEnd_ = COORD_MIN;
327
328 for (int16_t xAnti = lineStart_; xAnti <= lineEnd_; xAnti++) {
329 uint32_t currentSqr = static_cast<int32_t>(xAnti) * xAnti + ySqr_;
330 if ((currentSqr <= antiOutRadiusSqr_) || (xAnti == lineEnd_)) {
331 lineStart_ = xAnti;
332 outAntiEnd_ = xAnti - 1;
333 break;
334 }
335 }
336
337 for (int16_t xAnti = lineEnd_ + 1; xAnti <= -1; xAnti++) {
338 uint32_t currentSqr = static_cast<int32_t>(xAnti) * xAnti + ySqr_;
339 if ((currentSqr <= antiInRadiusSqr_) || (xAnti == -1)) {
340 inAntiEnd_ = xAnti;
341 break;
342 }
343 }
344
345 for (int16_t xAnti = outAntiStart_; xAnti <= outAntiEnd_; xAnti++) {
346 uint32_t currentSqr = static_cast<int32_t>(xAnti) * xAnti + ySqr_;
347 uint8_t antiOpa =
348 (((static_cast<uint64_t>(outRadius_) << 1) - 1 - (currentSqr - antiOutRadiusSqr_)) * OPA_OPAQUE) /
349 ((outRadius_ << 1) - 1);
350 antiOpa = (opa == OPA_OPAQUE) ? antiOpa : (static_cast<uint16_t>(antiOpa) * opa) >> SHIFT_8;
351 DrawPointAnti(gfxDstBuffer, arcInfo, xAnti, mask, style, antiOpa);
352 }
353
354 for (int16_t xAnti = inAntiStart_; xAnti <= inAntiEnd_; xAnti++) {
355 uint32_t currentSqr = static_cast<int32_t>(xAnti) * xAnti + ySqr_;
356 if (currentSqr <= antiInRadiusSqr_) {
357 break;
358 }
359 uint8_t antiOpa = (static_cast<uint64_t>(currentSqr - antiInRadiusSqr_) * OPA_OPAQUE) / ((inRadius_ << 1) - 1);
360 antiOpa = (opa == OPA_OPAQUE) ? antiOpa : (static_cast<uint16_t>(antiOpa) * opa) >> SHIFT_8;
361 DrawPointAnti(gfxDstBuffer, arcInfo, xAnti, mask, style, antiOpa);
362 }
363 }
364
DrawPointAnti(BufferInfo & gfxDstBuffer,ArcInfo & arcInfo,int16_t x,const Rect & mask,const Style & style,uint8_t antiOpa)365 void DrawArc::DrawPointAnti(BufferInfo& gfxDstBuffer, ArcInfo& arcInfo, int16_t x, const Rect& mask,
366 const Style& style, uint8_t antiOpa)
367 {
368 int16_t startX;
369 int16_t starty;
370 uint16_t degreeBase = CalculateTanDegree(MATH_ABS(x), MATH_ABS(y_));
371 if (isCircle_ || (IS_IN_DEGREERANE(CIRCLE_IN_DEGREE - degreeBase, arcInfo.startAngle, arcInfo.endAngle))) {
372 startX = arcInfo.center.x + x;
373 starty = arcInfo.center.y + y_;
374 DrawHorLine(gfxDstBuffer, Point { startX, starty }, arcInfo.imgPos, mask, 0, style, antiOpa, arcInfo.imgSrc);
375 }
376 if (isCircle_ || (IS_IN_DEGREERANE(SEMICIRCLE_IN_DEGREE + degreeBase, arcInfo.startAngle, arcInfo.endAngle))) {
377 startX = arcInfo.center.x + x;
378 starty = arcInfo.center.y - y_;
379 DrawHorLine(gfxDstBuffer, Point { startX, starty }, arcInfo.imgPos, mask, 0, style, antiOpa, arcInfo.imgSrc);
380 }
381 if (isCircle_ || (IS_IN_DEGREERANE(degreeBase, arcInfo.startAngle, arcInfo.endAngle))) {
382 startX = arcInfo.center.x - x;
383 starty = arcInfo.center.y + y_;
384 DrawHorLine(gfxDstBuffer, Point { startX, starty }, arcInfo.imgPos, mask, 0, style, antiOpa, arcInfo.imgSrc);
385 }
386 if (isCircle_ || (IS_IN_DEGREERANE(SEMICIRCLE_IN_DEGREE - degreeBase, arcInfo.startAngle, arcInfo.endAngle))) {
387 startX = arcInfo.center.x - x;
388 starty = arcInfo.center.y - y_;
389 DrawHorLine(gfxDstBuffer, Point { startX, starty }, arcInfo.imgPos, mask, 0, style, antiOpa, arcInfo.imgSrc);
390 }
391 }
392 #endif
393
GetDegreeInQuadrant(uint16_t degree,uint8_t quadrant)394 uint16_t DrawArc::GetDegreeInQuadrant(uint16_t degree, uint8_t quadrant)
395 {
396 switch (quadrant) {
397 case ARC_QUADRANT_ONE:
398 return degree;
399 case ARC_QUADRANT_TWO:
400 return SEMICIRCLE_IN_DEGREE - degree;
401 case ARC_QUADRANT_THREE:
402 return SEMICIRCLE_IN_DEGREE + degree;
403 case ARC_QUADRANT_FOUR:
404 return CIRCLE_IN_DEGREE - degree;
405 default:
406 return degree;
407 }
408 }
409
Draw(BufferInfo & gfxDstBuffer,ArcInfo & arcInfo,const Rect & mask,const Style & style,uint8_t opaScale,uint8_t cap)410 void DrawArc::Draw(BufferInfo& gfxDstBuffer, ArcInfo& arcInfo, const Rect& mask,
411 const Style& style, uint8_t opaScale, uint8_t cap)
412 {
413 OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.lineOpa_);
414 if ((opa == OPA_TRANSPARENT) || (style.lineWidth_ < 1)) {
415 return;
416 }
417
418 SetArcInfo(arcInfo, style);
419 if (arcInfo.startAngle != arcInfo.endAngle) {
420 if ((arcInfo.imgSrc != nullptr) && (arcInfo.imgSrc->GetSrcType() != IMG_SRC_UNKNOWN)) {
421 DrawCircleNoEndpoint(gfxDstBuffer, arcInfo, mask, style, opa, false);
422 } else {
423 DrawCircleNoEndpoint(gfxDstBuffer, arcInfo, mask, style, opa, true);
424 }
425 }
426
427 if (!isCircle_ && (cap == CapType::CAP_ROUND)) {
428 int16_t lineWidth = style.lineWidth_;
429 if (lineWidth > arcInfo.radius) {
430 lineWidth = arcInfo.radius;
431 }
432
433 ArcInfo endArcInfo = arcInfo;
434 endArcInfo.startAngle = 0;
435 endArcInfo.endAngle = CIRCLE_IN_DEGREE;
436
437 int16_t outRadius = arcInfo.radius - 1;
438 lineWidth--;
439 /* the arc radius of the round cap should be half the line width */
440 endArcInfo.radius = (static_cast<uint16_t>(lineWidth + 1) >> 1) + 1;
441
442 /* 0.5: round up */
443 float temp = (outRadius - endArcInfo.radius + 1) * Sin(arcInfo.startAngle);
444 int16_t startCapX = static_cast<int16_t>((temp > 0) ? (temp + 0.5f) : (temp - 0.5f));
445
446 temp = (outRadius - endArcInfo.radius + 1) * Sin(QUARTER_IN_DEGREE - arcInfo.startAngle);
447 int16_t startCapY = static_cast<int16_t>((temp > 0) ? (temp + 0.5f) : (temp - 0.5f));
448
449 endArcInfo.center.x += startCapX;
450 endArcInfo.center.y -= startCapY;
451 SetArcInfo(endArcInfo, style);
452 DrawCircleNoEndpoint(gfxDstBuffer, endArcInfo, mask, style, opa, true);
453
454 temp = (outRadius - endArcInfo.radius + 1) * Sin(arcInfo.endAngle);
455 int16_t endCapX = static_cast<int16_t>((temp > 0) ? (temp + 0.5f) : (temp - 0.5f));
456
457 temp = (outRadius - endArcInfo.radius + 1) * Sin(QUARTER_IN_DEGREE - arcInfo.endAngle);
458 int16_t endCapY = static_cast<int16_t>((temp > 0) ? (temp + 0.5f) : (temp - 0.5f));
459
460 endArcInfo.center = arcInfo.center;
461 endArcInfo.center.x += endCapX;
462 endArcInfo.center.y -= endCapY;
463 SetArcInfo(endArcInfo, style);
464 DrawCircleNoEndpoint(gfxDstBuffer, endArcInfo, mask, style, opa, true);
465 }
466 }
467
GetDegreeRangeIntersectState(uint16_t degreeStart,uint16_t degreeEnd,uint16_t start,uint16_t end)468 int16_t DrawArc::GetDegreeRangeIntersectState(uint16_t degreeStart, uint16_t degreeEnd, uint16_t start, uint16_t end)
469 {
470 if (start <= end) {
471 if ((degreeStart >= start) && (degreeStart <= end) && (degreeEnd >= start) && (degreeEnd <= end)) {
472 return IN_DEGREE_RANG;
473 } else if ((degreeEnd < start) || (degreeStart > end)) {
474 return OUT_DEGREE_RANG;
475 } else {
476 return INTERSECT;
477 }
478 } else {
479 if (((degreeStart >= start) && (degreeEnd >= start)) || ((degreeStart <= end) && (degreeEnd <= end))) {
480 return IN_DEGREE_RANG;
481 } else if ((degreeStart > end) && (degreeEnd < start)) {
482 return OUT_DEGREE_RANG;
483 } else if ((degreeStart <= end) && (degreeEnd >= start)) {
484 return DOUBLE_INTERSECT;
485 } else {
486 return INTERSECT;
487 }
488 }
489 }
490
SetArcInfo(ArcInfo & arcInfo,const Style & style)491 void DrawArc::SetArcInfo(ArcInfo& arcInfo, const Style& style)
492 {
493 outRadius_ = arcInfo.radius;
494 inRadius_ = outRadius_ - style.lineWidth_;
495 if (inRadius_ < 0) {
496 inRadius_ = 0;
497 }
498 outRadiusSqr_ = outRadius_ * outRadius_;
499 inRadiusSqr_ = inRadius_ * inRadius_;
500
501 if ((arcInfo.startAngle == 0) && (arcInfo.endAngle == CIRCLE_IN_DEGREE)) {
502 isCircle_ = true;
503 } else {
504 isCircle_ = false;
505 }
506
507 #if ENABLE_ANTIALIAS
508 antiOutRadiusSqr_ = (outRadius_ - 1) * (outRadius_ - 1);
509 if (inRadius_ == 0) {
510 antiInRadiusSqr_ = 0;
511 } else {
512 antiInRadiusSqr_ = (inRadius_ - 1) * (inRadius_ - 1);
513 }
514 #endif
515 }
516 } // namespace OHOS