• 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 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