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