Loading libs/hwui/tests/unit/VectorDrawableTests.cpp +3 −42 Original line number Diff line number Diff line Loading @@ -85,32 +85,8 @@ const static TestData sTestDataSet[] = { outPath->rCubicTo(8.0, 8.0, 8.0, 8.0, 8.0, 8.0); outPath->cubicTo(16.0, 16.0, 9.0, 9.0, 9.0, 9.0); outPath->rCubicTo(0.0, 0.0, 9.0, 9.0, 9.0, 9.0); outPath->cubicTo(18.447775037328352, 20.404243860300607, 17.998389141249767, 22.8911717921705, 16.737515350332117, 24.986664170401575); outPath->cubicTo(15.476641559414468, 27.08215654863265, 13.489843598291483, 28.644011882390082, 11.155893964798905, 29.37447073281729); outPath->cubicTo(8.821944331306327, 30.1049295832445, 6.299226382436471, 29.954422532383525, 4.0686829203897235, 28.951642951534332); outPath->cubicTo(1.838139458342976, 27.94886337068514, 0.05113662931485696, 26.161860541657013, -0.9516429515343354, 23.931317079610267); outPath->cubicTo(-1.9544225323835278, 21.70077361756352, -2.1049295832444987, 19.178055668693663, -1.37447073281729, 16.844106035201087); outPath->cubicTo(-0.6440118823900814, 14.51015640170851, 0.9178434513673546, 12.523358440585524, 3.0133358295984305, 11.262484649667876); outPath->cubicTo(5.108828207829506, 10.001610858750228, 7.5957561396993984, 9.552224962671648, 10.000000000000005, 10.0); outPath->cubicTo(10.0, 7.348852265086975, 11.054287646850167, 4.803576729418881, 12.928932188134523, 2.9289321881345254); outPath->cubicTo(14.803576729418879, 1.0542876468501696, 17.348852265086972, 4.870079381441987E-16, 19.999999999999996, 0.0); outPath->cubicTo(22.65114773491302, -4.870079381441987E-16, 25.19642327058112, 1.0542876468501678, 27.071067811865476, 2.9289321881345227); outPath->cubicTo(28.94571235314983, 4.803576729418878, 30.0, 7.348852265086974, 30.0, 9.999999999999998); outPath->cubicTo(30.0, 12.651147734913023, 28.94571235314983, 15.19642327058112, 27.071067811865476, 17.071067811865476); outPath->cubicTo(25.19642327058112, 18.94571235314983, 22.651147734913028, 20.0, 20.000000000000004, 20.0); outPath->arcTo(10.0, 10.0, 0.0, SkPath::kLarge_ArcSize, SkPath::kCW_Direction, 10.0, 10.0); outPath->arcTo(10.0, 10.0, 0.0, SkPath::kLarge_ArcSize, SkPath::kCW_Direction, 20.0, 20.0); }}, // Check box VectorDrawable path data Loading Loading @@ -181,22 +157,7 @@ const static TestData sTestDataSet[] = { }, [](SkPath* outPath) { outPath->moveTo(300.0, 70.0); outPath->cubicTo(239.06697794203706, 70.13246340443499, 180.6164396449267, 94.47383115953485, 137.6004913602211, 137.6302781499585); outPath->cubicTo(94.58454307551551, 180.78672514038215, 70.43390412842275, 239.3163266242308, 70.50013586976587, 300.2494566687817); outPath->cubicTo(70.56636761110899, 361.1825867133326, 94.84418775550249, 419.65954850554147, 137.9538527586204, 462.72238058830936); outPath->cubicTo(181.06351776173827, 505.7852126710772, 239.5668339599056, 529.999456521097, 300.49999999999994, 529.999456521097); outPath->cubicTo(361.43316604009436, 529.999456521097, 419.93648223826176, 505.78521267107726, 463.0461472413797, 462.7223805883093); outPath->cubicTo(506.1558122444976, 419.65954850554135, 530.433632388891, 361.1825867133324, 530.4998641302341, 300.2494566687815); outPath->cubicTo(530.5660958715771, 239.31632662423056, 506.4154569244844, 180.7867251403819, 463.3995086397787, 137.6302781499583); outPath->cubicTo(420.383560355073, 94.47383115953468, 361.93302205796255, 70.13246340443492, 300.9999999999996, 70.00000000000003); outPath->arcTo(230.0, 230.0, 0.0, SkPath::kLarge_ArcSize, SkPath::kCCW_Direction, 301.0, 70.0); outPath->close(); outPath->moveTo(300.0, 70.0); }}, Loading libs/hwui/utils/VectorDrawableUtils.cpp +8 −132 Original line number Diff line number Diff line Loading @@ -96,132 +96,6 @@ void VectorDrawableUtils::interpolatePaths(PathData* outData, const PathData& fr } } /** * Converts an arc to cubic Bezier segments and records them in p. * * @param p The target for the cubic Bezier segments * @param cx The x coordinate center of the ellipse * @param cy The y coordinate center of the ellipse * @param a The radius of the ellipse in the horizontal direction * @param b The radius of the ellipse in the vertical direction * @param e1x E(eta1) x coordinate of the starting point of the arc * @param e1y E(eta2) y coordinate of the starting point of the arc * @param theta The angle that the ellipse bounding rectangle makes with horizontal plane * @param start The start angle of the arc on the ellipse * @param sweep The angle (positive or negative) of the sweep of the arc on the ellipse */ static void arcToBezier(SkPath* p, double cx, double cy, double a, double b, double e1x, double e1y, double theta, double start, double sweep) { // Taken from equations at: http://spaceroots.org/documents/ellipse/node8.html // and http://www.spaceroots.org/documents/ellipse/node22.html // Maximum of 45 degrees per cubic Bezier segment int numSegments = ceil(fabs(sweep * 4 / M_PI)); double eta1 = start; double cosTheta = cos(theta); double sinTheta = sin(theta); double cosEta1 = cos(eta1); double sinEta1 = sin(eta1); double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1); double ep1y = (-a * sinTheta * sinEta1) + (b * cosTheta * cosEta1); double anglePerSegment = sweep / numSegments; for (int i = 0; i < numSegments; i++) { double eta2 = eta1 + anglePerSegment; double sinEta2 = sin(eta2); double cosEta2 = cos(eta2); double e2x = cx + (a * cosTheta * cosEta2) - (b * sinTheta * sinEta2); double e2y = cy + (a * sinTheta * cosEta2) + (b * cosTheta * sinEta2); double ep2x = -a * cosTheta * sinEta2 - b * sinTheta * cosEta2; double ep2y = -a * sinTheta * sinEta2 + b * cosTheta * cosEta2; double tanDiff2 = tan((eta2 - eta1) / 2); double alpha = sin(eta2 - eta1) * (sqrt(4 + (3 * tanDiff2 * tanDiff2)) - 1) / 3; double q1x = e1x + alpha * ep1x; double q1y = e1y + alpha * ep1y; double q2x = e2x - alpha * ep2x; double q2y = e2y - alpha * ep2y; p->cubicTo((float)q1x, (float)q1y, (float)q2x, (float)q2y, (float)e2x, (float)e2y); eta1 = eta2; e1x = e2x; e1y = e2y; ep1x = ep2x; ep1y = ep2y; } } inline double toRadians(float theta) { return theta * M_PI / 180; } static void drawArc(SkPath* p, float x0, float y0, float x1, float y1, float a, float b, float theta, bool isMoreThanHalf, bool isPositiveArc) { /* Convert rotation angle from degrees to radians */ double thetaD = toRadians(theta); /* Pre-compute rotation matrix entries */ double cosTheta = cos(thetaD); double sinTheta = sin(thetaD); /* Transform (x0, y0) and (x1, y1) into unit space */ /* using (inverse) rotation, followed by (inverse) scale */ double x0p = (x0 * cosTheta + y0 * sinTheta) / a; double y0p = (-x0 * sinTheta + y0 * cosTheta) / b; double x1p = (x1 * cosTheta + y1 * sinTheta) / a; double y1p = (-x1 * sinTheta + y1 * cosTheta) / b; /* Compute differences and averages */ double dx = x0p - x1p; double dy = y0p - y1p; double xm = (x0p + x1p) / 2; double ym = (y0p + y1p) / 2; /* Solve for intersecting unit circles */ double dsq = dx * dx + dy * dy; if (dsq == 0.0) { VECTOR_DRAWABLE_LOGD("Points are coincident"); return; /* Points are coincident */ } double disc = 1.0 / dsq - 1.0 / 4.0; if (disc < 0.0) { VECTOR_DRAWABLE_LOGD("Points are too far apart %f", dsq); float adjust = (float)(sqrt(dsq) / 1.99999); drawArc(p, x0, y0, x1, y1, a * adjust, b * adjust, theta, isMoreThanHalf, isPositiveArc); return; /* Points are too far apart */ } double s = sqrt(disc); double sdx = s * dx; double sdy = s * dy; double cx; double cy; if (isMoreThanHalf == isPositiveArc) { cx = xm - sdy; cy = ym + sdx; } else { cx = xm + sdy; cy = ym - sdx; } double eta0 = atan2((y0p - cy), (x0p - cx)); double eta1 = atan2((y1p - cy), (x1p - cx)); double sweep = (eta1 - eta0); if (isPositiveArc != (sweep >= 0)) { if (sweep > 0) { sweep -= 2 * M_PI; } else { sweep += 2 * M_PI; } } cx *= a; cy *= b; double tcx = cx; cx = cx * cosTheta - cy * sinTheta; cy = tcx * sinTheta + cy * cosTheta; arcToBezier(p, cx, cy, a, b, x0, y0, thetaD, eta0, sweep); } // Use the given verb, and points in the range [start, end) to insert a command into the SkPath. void PathResolver::addCommand(SkPath* outPath, char previousCmd, char cmd, const std::vector<float>* points, size_t start, size_t end) { Loading Loading @@ -424,18 +298,20 @@ void PathResolver::addCommand(SkPath* outPath, char previousCmd, char cmd, break; case 'a': // Draws an elliptical arc // (rx ry x-axis-rotation large-arc-flag sweep-flag x y) drawArc(outPath, currentX, currentY, points->at(k + 5) + currentX, points->at(k + 6) + currentY, points->at(k + 0), points->at(k + 1), points->at(k + 2), points->at(k + 3) != 0, points->at(k + 4) != 0); outPath->arcTo(points->at(k + 0), points->at(k + 1), points->at(k + 2), (SkPath::ArcSize) (points->at(k + 3) != 0), (SkPath::Direction) (points->at(k + 4) == 0), points->at(k + 5) + currentX, points->at(k + 6) + currentY); currentX += points->at(k + 5); currentY += points->at(k + 6); ctrlPointX = currentX; ctrlPointY = currentY; break; case 'A': // Draws an elliptical arc drawArc(outPath, currentX, currentY, points->at(k + 5), points->at(k + 6), points->at(k + 0), points->at(k + 1), points->at(k + 2), points->at(k + 3) != 0, points->at(k + 4) != 0); outPath->arcTo(points->at(k + 0), points->at(k + 1), points->at(k + 2), (SkPath::ArcSize) (points->at(k + 3) != 0), (SkPath::Direction) (points->at(k + 4) == 0), points->at(k + 5), points->at(k + 6)); currentX = points->at(k + 5); currentY = points->at(k + 6); ctrlPointX = currentX; Loading Loading
libs/hwui/tests/unit/VectorDrawableTests.cpp +3 −42 Original line number Diff line number Diff line Loading @@ -85,32 +85,8 @@ const static TestData sTestDataSet[] = { outPath->rCubicTo(8.0, 8.0, 8.0, 8.0, 8.0, 8.0); outPath->cubicTo(16.0, 16.0, 9.0, 9.0, 9.0, 9.0); outPath->rCubicTo(0.0, 0.0, 9.0, 9.0, 9.0, 9.0); outPath->cubicTo(18.447775037328352, 20.404243860300607, 17.998389141249767, 22.8911717921705, 16.737515350332117, 24.986664170401575); outPath->cubicTo(15.476641559414468, 27.08215654863265, 13.489843598291483, 28.644011882390082, 11.155893964798905, 29.37447073281729); outPath->cubicTo(8.821944331306327, 30.1049295832445, 6.299226382436471, 29.954422532383525, 4.0686829203897235, 28.951642951534332); outPath->cubicTo(1.838139458342976, 27.94886337068514, 0.05113662931485696, 26.161860541657013, -0.9516429515343354, 23.931317079610267); outPath->cubicTo(-1.9544225323835278, 21.70077361756352, -2.1049295832444987, 19.178055668693663, -1.37447073281729, 16.844106035201087); outPath->cubicTo(-0.6440118823900814, 14.51015640170851, 0.9178434513673546, 12.523358440585524, 3.0133358295984305, 11.262484649667876); outPath->cubicTo(5.108828207829506, 10.001610858750228, 7.5957561396993984, 9.552224962671648, 10.000000000000005, 10.0); outPath->cubicTo(10.0, 7.348852265086975, 11.054287646850167, 4.803576729418881, 12.928932188134523, 2.9289321881345254); outPath->cubicTo(14.803576729418879, 1.0542876468501696, 17.348852265086972, 4.870079381441987E-16, 19.999999999999996, 0.0); outPath->cubicTo(22.65114773491302, -4.870079381441987E-16, 25.19642327058112, 1.0542876468501678, 27.071067811865476, 2.9289321881345227); outPath->cubicTo(28.94571235314983, 4.803576729418878, 30.0, 7.348852265086974, 30.0, 9.999999999999998); outPath->cubicTo(30.0, 12.651147734913023, 28.94571235314983, 15.19642327058112, 27.071067811865476, 17.071067811865476); outPath->cubicTo(25.19642327058112, 18.94571235314983, 22.651147734913028, 20.0, 20.000000000000004, 20.0); outPath->arcTo(10.0, 10.0, 0.0, SkPath::kLarge_ArcSize, SkPath::kCW_Direction, 10.0, 10.0); outPath->arcTo(10.0, 10.0, 0.0, SkPath::kLarge_ArcSize, SkPath::kCW_Direction, 20.0, 20.0); }}, // Check box VectorDrawable path data Loading Loading @@ -181,22 +157,7 @@ const static TestData sTestDataSet[] = { }, [](SkPath* outPath) { outPath->moveTo(300.0, 70.0); outPath->cubicTo(239.06697794203706, 70.13246340443499, 180.6164396449267, 94.47383115953485, 137.6004913602211, 137.6302781499585); outPath->cubicTo(94.58454307551551, 180.78672514038215, 70.43390412842275, 239.3163266242308, 70.50013586976587, 300.2494566687817); outPath->cubicTo(70.56636761110899, 361.1825867133326, 94.84418775550249, 419.65954850554147, 137.9538527586204, 462.72238058830936); outPath->cubicTo(181.06351776173827, 505.7852126710772, 239.5668339599056, 529.999456521097, 300.49999999999994, 529.999456521097); outPath->cubicTo(361.43316604009436, 529.999456521097, 419.93648223826176, 505.78521267107726, 463.0461472413797, 462.7223805883093); outPath->cubicTo(506.1558122444976, 419.65954850554135, 530.433632388891, 361.1825867133324, 530.4998641302341, 300.2494566687815); outPath->cubicTo(530.5660958715771, 239.31632662423056, 506.4154569244844, 180.7867251403819, 463.3995086397787, 137.6302781499583); outPath->cubicTo(420.383560355073, 94.47383115953468, 361.93302205796255, 70.13246340443492, 300.9999999999996, 70.00000000000003); outPath->arcTo(230.0, 230.0, 0.0, SkPath::kLarge_ArcSize, SkPath::kCCW_Direction, 301.0, 70.0); outPath->close(); outPath->moveTo(300.0, 70.0); }}, Loading
libs/hwui/utils/VectorDrawableUtils.cpp +8 −132 Original line number Diff line number Diff line Loading @@ -96,132 +96,6 @@ void VectorDrawableUtils::interpolatePaths(PathData* outData, const PathData& fr } } /** * Converts an arc to cubic Bezier segments and records them in p. * * @param p The target for the cubic Bezier segments * @param cx The x coordinate center of the ellipse * @param cy The y coordinate center of the ellipse * @param a The radius of the ellipse in the horizontal direction * @param b The radius of the ellipse in the vertical direction * @param e1x E(eta1) x coordinate of the starting point of the arc * @param e1y E(eta2) y coordinate of the starting point of the arc * @param theta The angle that the ellipse bounding rectangle makes with horizontal plane * @param start The start angle of the arc on the ellipse * @param sweep The angle (positive or negative) of the sweep of the arc on the ellipse */ static void arcToBezier(SkPath* p, double cx, double cy, double a, double b, double e1x, double e1y, double theta, double start, double sweep) { // Taken from equations at: http://spaceroots.org/documents/ellipse/node8.html // and http://www.spaceroots.org/documents/ellipse/node22.html // Maximum of 45 degrees per cubic Bezier segment int numSegments = ceil(fabs(sweep * 4 / M_PI)); double eta1 = start; double cosTheta = cos(theta); double sinTheta = sin(theta); double cosEta1 = cos(eta1); double sinEta1 = sin(eta1); double ep1x = (-a * cosTheta * sinEta1) - (b * sinTheta * cosEta1); double ep1y = (-a * sinTheta * sinEta1) + (b * cosTheta * cosEta1); double anglePerSegment = sweep / numSegments; for (int i = 0; i < numSegments; i++) { double eta2 = eta1 + anglePerSegment; double sinEta2 = sin(eta2); double cosEta2 = cos(eta2); double e2x = cx + (a * cosTheta * cosEta2) - (b * sinTheta * sinEta2); double e2y = cy + (a * sinTheta * cosEta2) + (b * cosTheta * sinEta2); double ep2x = -a * cosTheta * sinEta2 - b * sinTheta * cosEta2; double ep2y = -a * sinTheta * sinEta2 + b * cosTheta * cosEta2; double tanDiff2 = tan((eta2 - eta1) / 2); double alpha = sin(eta2 - eta1) * (sqrt(4 + (3 * tanDiff2 * tanDiff2)) - 1) / 3; double q1x = e1x + alpha * ep1x; double q1y = e1y + alpha * ep1y; double q2x = e2x - alpha * ep2x; double q2y = e2y - alpha * ep2y; p->cubicTo((float)q1x, (float)q1y, (float)q2x, (float)q2y, (float)e2x, (float)e2y); eta1 = eta2; e1x = e2x; e1y = e2y; ep1x = ep2x; ep1y = ep2y; } } inline double toRadians(float theta) { return theta * M_PI / 180; } static void drawArc(SkPath* p, float x0, float y0, float x1, float y1, float a, float b, float theta, bool isMoreThanHalf, bool isPositiveArc) { /* Convert rotation angle from degrees to radians */ double thetaD = toRadians(theta); /* Pre-compute rotation matrix entries */ double cosTheta = cos(thetaD); double sinTheta = sin(thetaD); /* Transform (x0, y0) and (x1, y1) into unit space */ /* using (inverse) rotation, followed by (inverse) scale */ double x0p = (x0 * cosTheta + y0 * sinTheta) / a; double y0p = (-x0 * sinTheta + y0 * cosTheta) / b; double x1p = (x1 * cosTheta + y1 * sinTheta) / a; double y1p = (-x1 * sinTheta + y1 * cosTheta) / b; /* Compute differences and averages */ double dx = x0p - x1p; double dy = y0p - y1p; double xm = (x0p + x1p) / 2; double ym = (y0p + y1p) / 2; /* Solve for intersecting unit circles */ double dsq = dx * dx + dy * dy; if (dsq == 0.0) { VECTOR_DRAWABLE_LOGD("Points are coincident"); return; /* Points are coincident */ } double disc = 1.0 / dsq - 1.0 / 4.0; if (disc < 0.0) { VECTOR_DRAWABLE_LOGD("Points are too far apart %f", dsq); float adjust = (float)(sqrt(dsq) / 1.99999); drawArc(p, x0, y0, x1, y1, a * adjust, b * adjust, theta, isMoreThanHalf, isPositiveArc); return; /* Points are too far apart */ } double s = sqrt(disc); double sdx = s * dx; double sdy = s * dy; double cx; double cy; if (isMoreThanHalf == isPositiveArc) { cx = xm - sdy; cy = ym + sdx; } else { cx = xm + sdy; cy = ym - sdx; } double eta0 = atan2((y0p - cy), (x0p - cx)); double eta1 = atan2((y1p - cy), (x1p - cx)); double sweep = (eta1 - eta0); if (isPositiveArc != (sweep >= 0)) { if (sweep > 0) { sweep -= 2 * M_PI; } else { sweep += 2 * M_PI; } } cx *= a; cy *= b; double tcx = cx; cx = cx * cosTheta - cy * sinTheta; cy = tcx * sinTheta + cy * cosTheta; arcToBezier(p, cx, cy, a, b, x0, y0, thetaD, eta0, sweep); } // Use the given verb, and points in the range [start, end) to insert a command into the SkPath. void PathResolver::addCommand(SkPath* outPath, char previousCmd, char cmd, const std::vector<float>* points, size_t start, size_t end) { Loading Loading @@ -424,18 +298,20 @@ void PathResolver::addCommand(SkPath* outPath, char previousCmd, char cmd, break; case 'a': // Draws an elliptical arc // (rx ry x-axis-rotation large-arc-flag sweep-flag x y) drawArc(outPath, currentX, currentY, points->at(k + 5) + currentX, points->at(k + 6) + currentY, points->at(k + 0), points->at(k + 1), points->at(k + 2), points->at(k + 3) != 0, points->at(k + 4) != 0); outPath->arcTo(points->at(k + 0), points->at(k + 1), points->at(k + 2), (SkPath::ArcSize) (points->at(k + 3) != 0), (SkPath::Direction) (points->at(k + 4) == 0), points->at(k + 5) + currentX, points->at(k + 6) + currentY); currentX += points->at(k + 5); currentY += points->at(k + 6); ctrlPointX = currentX; ctrlPointY = currentY; break; case 'A': // Draws an elliptical arc drawArc(outPath, currentX, currentY, points->at(k + 5), points->at(k + 6), points->at(k + 0), points->at(k + 1), points->at(k + 2), points->at(k + 3) != 0, points->at(k + 4) != 0); outPath->arcTo(points->at(k + 0), points->at(k + 1), points->at(k + 2), (SkPath::ArcSize) (points->at(k + 3) != 0), (SkPath::Direction) (points->at(k + 4) == 0), points->at(k + 5), points->at(k + 6)); currentX = points->at(k + 5); currentY = points->at(k + 6); ctrlPointX = currentX; Loading