• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 xLineStart = -outRadius_;
151     int16_t xLineStart2 = xLineStart - 1;
152     int16_t xLineStart3 = COORD_MIN;
153 
154     for (y_ = yEnd; y_ > yStart; y_--) {
155         ySqr_ = static_cast<int32_t>(y_) * y_;
156         bool isSetStartPot = false;
157         for (int16_t xi = xLineStart2; xi < 0; xi++) {
158             uint32_t currentSqr = static_cast<int32_t>(xi) * xi + ySqr_;
159             if (currentSqr > outRadiusSqr_) {
160                 continue;
161             }
162             if (!isSetStartPot) {
163                 xLineStart2 = xi;
164                 lineStart_ = xi;
165                 if (xLineStart3 != COORD_MIN) {
166                     xi = xLineStart3;
167                 }
168                 isSetStartPot = true;
169             }
170             if (y_ <= -inRadius_) {
171                 lineEnd_ = -1;
172                 break;
173             }
174             if (currentSqr < inRadiusSqr_) {
175                 xLineStart3 = xi - 1;
176                 lineEnd_ = xi - 1;
177                 break;
178             }
179         }
180         if (!isSetStartPot) {
181             continue;
182         }
183 #if ENABLE_ANTIALIAS
184         if (anti) {
185             DrawLineAnti(gfxDstBuffer, arcInfo, mask, style, opa);
186         }
187 #endif
188         DrawLineWithDegree(gfxDstBuffer, arcInfo, -lineEnd_, -lineStart_, y_, mask, style, opa, ARC_QUADRANT_ONE);
189 
190         DrawLineWithDegree(gfxDstBuffer, arcInfo, -lineEnd_, -lineStart_, -y_, mask, style, opa, ARC_QUADRANT_TWO);
191 
192         DrawLineWithDegree(gfxDstBuffer, arcInfo, lineStart_, lineEnd_, -y_, mask, style, opa, ARC_QUADRANT_THREE);
193 
194         DrawLineWithDegree(gfxDstBuffer, arcInfo, lineStart_, lineEnd_, y_, mask, style, opa, ARC_QUADRANT_FOUR);
195     }
196 }
197 
DrawAxisLine(BufferInfo & gfxDstBuffer,ArcInfo & arcInfo,const Rect & mask,const Style & style,uint8_t opa)198 void DrawArc::DrawAxisLine(BufferInfo& gfxDstBuffer,
199                            ArcInfo& arcInfo,
200                            const Rect& mask,
201                            const Style& style,
202                            uint8_t opa)
203 {
204     int16_t lineWidth = 0;
205     int16_t outRadius = outRadius_ - 1;
206     int16_t inRadius = inRadius_;
207     if (inRadius <= 0) {
208         inRadius = 1;
209         DrawHorLine(gfxDstBuffer, arcInfo.center, arcInfo.imgPos, mask, 0, style, opa, arcInfo.imgSrc);
210     }
211     lineWidth = outRadius - inRadius;
212 
213     if (isCircle_ || (IS_IN_DEGREERANE(THREE_QUARTER_IN_DEGREE, arcInfo.startAngle, arcInfo.endAngle))) {
214         DrawHorLine(gfxDstBuffer, Point { static_cast<int16_t>(arcInfo.center.x - outRadius), arcInfo.center.y },
215                     arcInfo.imgPos, mask, lineWidth, style, opa, arcInfo.imgSrc);
216     }
217 
218     if (isCircle_ || (IS_IN_DEGREERANE(QUARTER_IN_DEGREE, arcInfo.startAngle, arcInfo.endAngle))) {
219         DrawHorLine(gfxDstBuffer, Point { static_cast<int16_t>(arcInfo.center.x + inRadius), arcInfo.center.y },
220                     arcInfo.imgPos, mask, lineWidth, style, opa, arcInfo.imgSrc);
221     }
222 
223     if (isCircle_ || (IS_IN_DEGREERANE(0, arcInfo.startAngle, arcInfo.endAngle))) {
224         DrawVerLine(gfxDstBuffer, Point { arcInfo.center.x, static_cast<int16_t>(arcInfo.center.y - outRadius) },
225                     arcInfo.imgPos, mask, lineWidth, style, opa, arcInfo.imgSrc);
226     }
227 
228     if (isCircle_ || (IS_IN_DEGREERANE(SEMICIRCLE_IN_DEGREE, arcInfo.startAngle, arcInfo.endAngle))) {
229         DrawVerLine(gfxDstBuffer, Point { arcInfo.center.x, static_cast<int16_t>(arcInfo.center.y + inRadius) },
230                     arcInfo.imgPos, mask, lineWidth, style, opa, arcInfo.imgSrc);
231     }
232 }
233 
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)234 void DrawArc::DrawLineWithDegree(BufferInfo& gfxDstBuffer,
235                                  ArcInfo& arcInfo,
236                                  int16_t start,
237                                  int16_t end,
238                                  int16_t y,
239                                  const Rect& mask,
240                                  const Style& style,
241                                  uint8_t opaScale,
242                                  uint8_t quadrant)
243 {
244     if (isCircle_) {
245         DrawHorLine(gfxDstBuffer,
246                     Point {static_cast<int16_t>(arcInfo.center.x + start), static_cast<int16_t>(arcInfo.center.y + y)},
247                     arcInfo.imgPos, mask, end - start, style, opaScale, arcInfo.imgSrc);
248         return;
249     }
250     uint16_t degreeStart = GetDegreeInQuadrant(CalculateTanDegree(MATH_ABS(start), MATH_ABS(y)), quadrant);
251     uint16_t degreeEnd = GetDegreeInQuadrant(CalculateTanDegree(MATH_ABS(end), MATH_ABS(y)), quadrant);
252     if (degreeStart > degreeEnd) {
253         uint16_t tmp = degreeStart;
254         degreeStart = degreeEnd;
255         degreeEnd = tmp;
256     }
257 
258     int16_t lineDegreeRet = GetDegreeRangeIntersectState(degreeStart, degreeEnd, arcInfo.startAngle, arcInfo.endAngle);
259     int16_t drawEnd = 0;
260     switch (lineDegreeRet) {
261         case OUT_DEGREE_RANG:
262             return;
263         case IN_DEGREE_RANG:
264             DrawHorLine(gfxDstBuffer,
265                 Point { static_cast<int16_t>(arcInfo.center.x + start), static_cast<int16_t>(arcInfo.center.y + y) },
266                 arcInfo.imgPos, mask, end - start, style, opaScale, arcInfo.imgSrc);
267             return;
268         case INTERSECT:
269             DrawLineWithDegreeInner(gfxDstBuffer, arcInfo, start, end, y, mask, style, opaScale, quadrant);
270             return;
271         case DOUBLE_INTERSECT:
272             drawEnd = DrawLineWithDegreeInner(gfxDstBuffer, arcInfo, start, end, y, mask, style, opaScale, quadrant);
273             DrawLineWithDegreeInner(gfxDstBuffer, arcInfo, drawEnd + 1, end, y, mask, style, opaScale, quadrant);
274             return;
275         default:
276             return;
277     }
278 }
279 
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)280 int16_t DrawArc::DrawLineWithDegreeInner(BufferInfo& gfxDstBuffer,
281                                          ArcInfo& arcInfo,
282                                          int16_t start,
283                                          int16_t end,
284                                          int16_t y,
285                                          const Rect& mask,
286                                          const Style& style,
287                                          uint8_t opaScale,
288                                          uint8_t quadrant)
289 {
290     int16_t drawStart = COORD_MIN;
291     int16_t drawEnd = COORD_MIN;
292     for (int16_t xi = start; xi <= end; xi++) {
293         uint16_t degreeBase = CalculateTanDegree(MATH_ABS(xi), MATH_ABS(y));
294         uint16_t degree = GetDegreeInQuadrant(degreeBase, quadrant);
295         if (IS_IN_DEGREERANE(degree, arcInfo.startAngle, arcInfo.endAngle)) {
296             if (drawStart == COORD_MIN) {
297                 drawStart = xi;
298             }
299         } else {
300             if ((drawStart != COORD_MIN) && (drawEnd == COORD_MIN)) {
301                 drawEnd = xi - 1;
302                 break;
303             }
304         }
305     }
306     if (drawEnd == COORD_MIN) {
307         drawEnd = end;
308     }
309     if ((drawStart != COORD_MIN) && (drawEnd != COORD_MIN)) {
310         DrawHorLine(gfxDstBuffer,
311             Point { static_cast<int16_t>(arcInfo.center.x + drawStart), static_cast<int16_t>(arcInfo.center.y + y) },
312             arcInfo.imgPos, mask, drawEnd - drawStart, style, opaScale, arcInfo.imgSrc);
313     }
314     return drawEnd;
315 }
316 
317 #if ENABLE_ANTIALIAS
DrawLineAnti(BufferInfo & gfxDstBuffer,ArcInfo & arcInfo,const Rect & mask,const Style & style,uint8_t opa)318 void DrawArc::DrawLineAnti(BufferInfo& gfxDstBuffer, ArcInfo& arcInfo, const Rect& mask,
319                            const Style& style, uint8_t opa)
320 {
321     outAntiStart_ = lineStart_;
322     outAntiEnd_ = lineStart_;
323     inAntiStart_ = lineEnd_ + 1;
324     inAntiEnd_ = COORD_MIN;
325 
326     for (int16_t xAnti = lineStart_; xAnti <= lineEnd_; xAnti++) {
327         uint32_t currentSqr = static_cast<int32_t>(xAnti) * xAnti + ySqr_;
328         if ((currentSqr <= antiOutRadiusSqr_) || (xAnti == lineEnd_)) {
329             lineStart_ = xAnti;
330             outAntiEnd_ = xAnti - 1;
331             break;
332         }
333     }
334 
335     for (int16_t xAnti = lineEnd_ + 1; xAnti <= -1; xAnti++) {
336         uint32_t currentSqr = static_cast<int32_t>(xAnti) * xAnti + ySqr_;
337         if ((currentSqr <= antiInRadiusSqr_) || (xAnti == -1)) {
338             inAntiEnd_ = xAnti;
339             break;
340         }
341     }
342 
343     for (int16_t xAnti = outAntiStart_; xAnti <= outAntiEnd_; xAnti++) {
344         uint32_t currentSqr = static_cast<int32_t>(xAnti) * xAnti + ySqr_;
345         uint8_t antiOpa =
346             (((static_cast<uint64_t>(outRadius_) << 1) - 1 - (currentSqr - antiOutRadiusSqr_)) * OPA_OPAQUE) /
347             ((outRadius_ << 1) - 1);
348         antiOpa = (opa == OPA_OPAQUE) ? antiOpa : (static_cast<uint16_t>(antiOpa) * opa) >> SHIFT_8;
349         DrawPointAnti(gfxDstBuffer, arcInfo, xAnti, mask, style, antiOpa);
350     }
351 
352     for (int16_t xAnti = inAntiStart_; xAnti <= inAntiEnd_; xAnti++) {
353         uint32_t currentSqr = static_cast<int32_t>(xAnti) * xAnti + ySqr_;
354         if (currentSqr <= antiInRadiusSqr_) {
355             break;
356         }
357         uint8_t antiOpa = (static_cast<uint64_t>(currentSqr - antiInRadiusSqr_) * OPA_OPAQUE) / ((inRadius_ << 1) - 1);
358         antiOpa = (opa == OPA_OPAQUE) ? antiOpa : (static_cast<uint16_t>(antiOpa) * opa) >> SHIFT_8;
359         DrawPointAnti(gfxDstBuffer, arcInfo, xAnti, mask, style, antiOpa);
360     }
361 }
362 
DrawPointAnti(BufferInfo & gfxDstBuffer,ArcInfo & arcInfo,int16_t x,const Rect & mask,const Style & style,uint8_t antiOpa)363 void DrawArc::DrawPointAnti(BufferInfo& gfxDstBuffer, ArcInfo& arcInfo, int16_t x, const Rect& mask,
364                             const Style& style, uint8_t antiOpa)
365 {
366     int16_t startX;
367     int16_t starty;
368     uint16_t degreeBase = CalculateTanDegree(MATH_ABS(x), MATH_ABS(y_));
369     if (isCircle_ || (IS_IN_DEGREERANE(CIRCLE_IN_DEGREE - degreeBase, arcInfo.startAngle, arcInfo.endAngle))) {
370         startX = arcInfo.center.x + x;
371         starty = arcInfo.center.y + y_;
372         DrawHorLine(gfxDstBuffer, Point { startX, starty }, arcInfo.imgPos, mask, 0, style, antiOpa, arcInfo.imgSrc);
373     }
374     if (isCircle_ || (IS_IN_DEGREERANE(SEMICIRCLE_IN_DEGREE + degreeBase, arcInfo.startAngle, arcInfo.endAngle))) {
375         startX = arcInfo.center.x + x;
376         starty = arcInfo.center.y - y_;
377         DrawHorLine(gfxDstBuffer, Point { startX, starty }, arcInfo.imgPos, mask, 0, style, antiOpa, arcInfo.imgSrc);
378     }
379     if (isCircle_ || (IS_IN_DEGREERANE(degreeBase, arcInfo.startAngle, arcInfo.endAngle))) {
380         startX = arcInfo.center.x - x;
381         starty = arcInfo.center.y + y_;
382         DrawHorLine(gfxDstBuffer, Point { startX, starty }, arcInfo.imgPos, mask, 0, style, antiOpa, arcInfo.imgSrc);
383     }
384     if (isCircle_ || (IS_IN_DEGREERANE(SEMICIRCLE_IN_DEGREE - degreeBase, arcInfo.startAngle, arcInfo.endAngle))) {
385         startX = arcInfo.center.x - x;
386         starty = arcInfo.center.y - y_;
387         DrawHorLine(gfxDstBuffer, Point { startX, starty }, arcInfo.imgPos, mask, 0, style, antiOpa, arcInfo.imgSrc);
388     }
389 }
390 #endif
391 
GetDegreeInQuadrant(uint16_t degree,uint8_t quadrant)392 uint16_t DrawArc::GetDegreeInQuadrant(uint16_t degree, uint8_t quadrant)
393 {
394     switch (quadrant) {
395         case ARC_QUADRANT_ONE:
396             return degree;
397         case ARC_QUADRANT_TWO:
398             return SEMICIRCLE_IN_DEGREE - degree;
399         case ARC_QUADRANT_THREE:
400             return SEMICIRCLE_IN_DEGREE + degree;
401         case ARC_QUADRANT_FOUR:
402             return CIRCLE_IN_DEGREE - degree;
403         default:
404             return degree;
405     }
406 }
407 
Draw(BufferInfo & gfxDstBuffer,ArcInfo & arcInfo,const Rect & mask,const Style & style,uint8_t opaScale,uint8_t cap)408 void DrawArc::Draw(BufferInfo& gfxDstBuffer, ArcInfo& arcInfo, const Rect& mask,
409                    const Style& style, uint8_t opaScale, uint8_t cap)
410 {
411     OpacityType opa = DrawUtils::GetMixOpacity(opaScale, style.lineOpa_);
412     if ((opa == OPA_TRANSPARENT) || (style.lineWidth_ < 1)) {
413         return;
414     }
415 
416     SetArcInfo(arcInfo, style);
417     if (arcInfo.startAngle != arcInfo.endAngle) {
418         if ((arcInfo.imgSrc != nullptr) && (arcInfo.imgSrc->GetSrcType() != IMG_SRC_UNKNOWN)) {
419             DrawCircleNoEndpoint(gfxDstBuffer, arcInfo, mask, style, opa, false);
420         } else {
421             DrawCircleNoEndpoint(gfxDstBuffer, arcInfo, mask, style, opa, true);
422         }
423     }
424 
425     if (!isCircle_ && (cap != CapType::CAP_NONE)) {
426         int16_t lineWidth = style.lineWidth_;
427         if (lineWidth > arcInfo.radius) {
428             lineWidth = arcInfo.radius;
429         }
430 
431         ArcInfo endArcInfo = arcInfo;
432         endArcInfo.startAngle = 0;
433         endArcInfo.endAngle = CIRCLE_IN_DEGREE;
434 
435         int16_t outRadius = arcInfo.radius - 1;
436         lineWidth--;
437         /* the arc radius of the round cap should be half the line width */
438         endArcInfo.radius = (static_cast<uint16_t>(lineWidth + 1) >> 1) + 1;
439 
440         /* 0.5: round up */
441         float temp = (outRadius - endArcInfo.radius + 1) * Sin(arcInfo.startAngle);
442         int16_t startCapX = static_cast<int16_t>((temp > 0) ? (temp + 0.5f) : (temp - 0.5f));
443 
444         temp = (outRadius - endArcInfo.radius + 1) * Sin(QUARTER_IN_DEGREE - arcInfo.startAngle);
445         int16_t startCapY = static_cast<int16_t>((temp > 0) ? (temp + 0.5f) : (temp - 0.5f));
446 
447         endArcInfo.center.x += startCapX;
448         endArcInfo.center.y -= startCapY;
449         SetArcInfo(endArcInfo, style);
450 
451         temp = (outRadius - endArcInfo.radius + 1) * Sin(arcInfo.endAngle);
452         int16_t endCapX = static_cast<int16_t>((temp > 0) ? (temp + 0.5f) : (temp - 0.5f));
453 
454         temp = (outRadius - endArcInfo.radius + 1) * Sin(QUARTER_IN_DEGREE - arcInfo.endAngle);
455         int16_t endCapY = static_cast<int16_t>((temp > 0) ? (temp + 0.5f) : (temp - 0.5f));
456 
457         if ((endCapX == startCapX) && (endCapY == startCapY)) {
458             if (cap != CapType::CAP_ROUND_UNSHOW) {
459                 DrawCircleNoEndpoint(gfxDstBuffer, endArcInfo, mask, style, opa, true);
460             }
461         } else {
462             DrawCircleNoEndpoint(gfxDstBuffer, endArcInfo, mask, style, opa, true);
463         }
464 
465         endArcInfo.center = arcInfo.center;
466         endArcInfo.center.x += endCapX;
467         endArcInfo.center.y -= endCapY;
468         SetArcInfo(endArcInfo, style);
469         if (endCapX != 0) {
470             DrawCircleNoEndpoint(gfxDstBuffer, endArcInfo, mask, style, opa, true);
471         } else {
472             if (cap != CapType::CAP_ROUND_UNSHOW) {
473                 DrawCircleNoEndpoint(gfxDstBuffer, endArcInfo, mask, style, opa, true);
474             }
475         }
476     }
477 }
478 
GetDegreeRangeIntersectState(uint16_t degreeStart,uint16_t degreeEnd,uint16_t start,uint16_t end)479 int16_t DrawArc::GetDegreeRangeIntersectState(uint16_t degreeStart, uint16_t degreeEnd, uint16_t start, uint16_t end)
480 {
481     if (start <= end) {
482         if ((degreeStart >= start) && (degreeStart <= end) && (degreeEnd >= start) && (degreeEnd <= end)) {
483             return IN_DEGREE_RANG;
484         } else if ((degreeEnd < start) || (degreeStart > end)) {
485             return OUT_DEGREE_RANG;
486         } else {
487             return INTERSECT;
488         }
489     } else {
490         if (((degreeStart >= start) && (degreeEnd >= start)) || ((degreeStart <= end) && (degreeEnd <= end))) {
491             return IN_DEGREE_RANG;
492         } else if ((degreeStart > end) && (degreeEnd < start)) {
493             return OUT_DEGREE_RANG;
494         } else if ((degreeStart <= end) && (degreeEnd >= start)) {
495             return DOUBLE_INTERSECT;
496         } else {
497             return INTERSECT;
498         }
499     }
500 }
501 
SetArcInfo(ArcInfo & arcInfo,const Style & style)502 void DrawArc::SetArcInfo(ArcInfo& arcInfo, const Style& style)
503 {
504     outRadius_ = arcInfo.radius;
505     inRadius_ = outRadius_ - style.lineWidth_;
506     if (inRadius_ < 0) {
507         inRadius_ = 0;
508     }
509     outRadiusSqr_ = outRadius_ * outRadius_;
510     inRadiusSqr_ = inRadius_ * inRadius_;
511 
512     if ((arcInfo.startAngle == 0) && (arcInfo.endAngle == CIRCLE_IN_DEGREE)) {
513         isCircle_ = true;
514     } else {
515         isCircle_ = false;
516     }
517 
518 #if ENABLE_ANTIALIAS
519     antiOutRadiusSqr_ = (outRadius_ - 1) * (outRadius_ - 1);
520     if (inRadius_ == 0) {
521         antiInRadiusSqr_ = 0;
522     } else {
523         antiInRadiusSqr_ = (inRadius_ - 1) * (inRadius_ - 1);
524     }
525 #endif
526 }
527 } // namespace OHOS
528