OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2006 The Android Open Source Project | 2 * Copyright 2006 The Android Open Source Project |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include <cmath> | 8 #include <cmath> |
9 #include "SkBuffer.h" | 9 #include "SkBuffer.h" |
10 #include "SkCubicClipper.h" | 10 #include "SkCubicClipper.h" |
(...skipping 1272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1283 if (arc_is_lone_point(oval, startAngle, sweepAngle, &lonePt)) { | 1283 if (arc_is_lone_point(oval, startAngle, sweepAngle, &lonePt)) { |
1284 forceMoveTo ? this->moveTo(lonePt) : this->lineTo(lonePt); | 1284 forceMoveTo ? this->moveTo(lonePt) : this->lineTo(lonePt); |
1285 return; | 1285 return; |
1286 } | 1286 } |
1287 | 1287 |
1288 SkVector startV, stopV; | 1288 SkVector startV, stopV; |
1289 SkRotationDirection dir; | 1289 SkRotationDirection dir; |
1290 angles_to_unit_vectors(startAngle, sweepAngle, &startV, &stopV, &dir); | 1290 angles_to_unit_vectors(startAngle, sweepAngle, &startV, &stopV, &dir); |
1291 | 1291 |
1292 SkPoint singlePt; | 1292 SkPoint singlePt; |
| 1293 |
| 1294 // At this point, we know that the arc is not a lone point, but startV == st
opV |
| 1295 // indicates that the sweepAngle is too small such that angles_to_unit_vecto
rs |
| 1296 // cannot handle it. |
| 1297 if (startV == stopV) { |
| 1298 SkScalar endAngle = SkDegreesToRadians(startAngle + sweepAngle); |
| 1299 SkScalar radiusX = oval.width() / 2; |
| 1300 SkScalar radiusY = oval.height() / 2; |
| 1301 // We cannot use SkScalarSinCos function in the next line because |
| 1302 // SkScalarSinCos has a threshold *SkScalarNearlyZero*. When sin(startAn
gle) |
| 1303 // is 0 and sweepAngle is very small and radius is huge, the expected |
| 1304 // behavior here is to draw a line. But calling SkScalarSinCos will |
| 1305 // make sin(endAngle) to be 0 which will then draw a dot. |
| 1306 singlePt.set(oval.centerX() + radiusX * sk_float_cos(endAngle), |
| 1307 oval.centerY() + radiusY * sk_float_sin(endAngle)); |
| 1308 forceMoveTo ? this->moveTo(singlePt) : this->lineTo(singlePt); |
| 1309 return; |
| 1310 } |
| 1311 |
1293 SkConic conics[SkConic::kMaxConicsForArc]; | 1312 SkConic conics[SkConic::kMaxConicsForArc]; |
1294 int count = build_arc_conics(oval, startV, stopV, dir, conics, &singlePt); | 1313 int count = build_arc_conics(oval, startV, stopV, dir, conics, &singlePt); |
1295 if (count) { | 1314 if (count) { |
1296 this->incReserve(count * 2 + 1); | 1315 this->incReserve(count * 2 + 1); |
1297 const SkPoint& pt = conics[0].fPts[0]; | 1316 const SkPoint& pt = conics[0].fPts[0]; |
1298 forceMoveTo ? this->moveTo(pt) : this->lineTo(pt); | 1317 forceMoveTo ? this->moveTo(pt) : this->lineTo(pt); |
1299 for (int i = 0; i < count; ++i) { | 1318 for (int i = 0; i < count; ++i) { |
1300 this->conicTo(conics[i].fPts[1], conics[i].fPts[2], conics[i].fW); | 1319 this->conicTo(conics[i].fPts[1], conics[i].fPts[2], conics[i].fW); |
1301 } | 1320 } |
1302 } else { | 1321 } else { |
(...skipping 2073 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3376 path->arcTo(oval, startAngle, 180.f, false); | 3395 path->arcTo(oval, startAngle, 180.f, false); |
3377 startAngle += 180.f; | 3396 startAngle += 180.f; |
3378 forceMoveTo = false; | 3397 forceMoveTo = false; |
3379 sweepAngle -= 360.f; | 3398 sweepAngle -= 360.f; |
3380 } | 3399 } |
3381 path->arcTo(oval, startAngle, sweepAngle, forceMoveTo); | 3400 path->arcTo(oval, startAngle, sweepAngle, forceMoveTo); |
3382 if (useCenter) { | 3401 if (useCenter) { |
3383 path->close(); | 3402 path->close(); |
3384 } | 3403 } |
3385 } | 3404 } |
OLD | NEW |