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