diff options
Diffstat (limited to 'chromium/third_party/skia/src/gpu/GrPathUtils.cpp')
-rw-r--r-- | chromium/third_party/skia/src/gpu/GrPathUtils.cpp | 142 |
1 files changed, 73 insertions, 69 deletions
diff --git a/chromium/third_party/skia/src/gpu/GrPathUtils.cpp b/chromium/third_party/skia/src/gpu/GrPathUtils.cpp index e2b1ac76343..464231a8dc3 100644 --- a/chromium/third_party/skia/src/gpu/GrPathUtils.cpp +++ b/chromium/third_party/skia/src/gpu/GrPathUtils.cpp @@ -7,15 +7,15 @@ #include "GrPathUtils.h" -#include "GrPoint.h" +#include "GrTypes.h" #include "SkGeometry.h" SkScalar GrPathUtils::scaleToleranceToSrc(SkScalar devTol, const SkMatrix& viewM, const SkRect& pathBounds) { // In order to tesselate the path we get a bound on how much the matrix can - // stretch when mapping to screen coordinates. - SkScalar stretch = viewM.getMaxStretch(); + // scale when mapping to screen coordinates. + SkScalar stretch = viewM.getMaxScale(); SkScalar srcTol = devTol; if (stretch < 0) { @@ -36,7 +36,7 @@ SkScalar GrPathUtils::scaleToleranceToSrc(SkScalar devTol, static const int MAX_POINTS_PER_CURVE = 1 << 10; static const SkScalar gMinCurveTol = 0.0001f; -uint32_t GrPathUtils::quadraticPointCount(const GrPoint points[], +uint32_t GrPathUtils::quadraticPointCount(const SkPoint points[], SkScalar tol) { if (tol < gMinCurveTol) { tol = gMinCurveTol; @@ -51,7 +51,7 @@ uint32_t GrPathUtils::quadraticPointCount(const GrPoint points[], // subdivide x = log4(d/tol) times. x subdivisions creates 2^(x) // points. // 2^(log4(x)) = sqrt(x); - int temp = SkScalarCeil(SkScalarSqrt(SkScalarDiv(d, tol))); + int temp = SkScalarCeilToInt(SkScalarSqrt(SkScalarDiv(d, tol))); int pow2 = GrNextPow2(temp); // Because of NaNs & INFs we can wind up with a degenerate temp // such that pow2 comes out negative. Also, our point generator @@ -59,15 +59,15 @@ uint32_t GrPathUtils::quadraticPointCount(const GrPoint points[], if (pow2 < 1) { pow2 = 1; } - return GrMin(pow2, MAX_POINTS_PER_CURVE); + return SkTMin(pow2, MAX_POINTS_PER_CURVE); } } -uint32_t GrPathUtils::generateQuadraticPoints(const GrPoint& p0, - const GrPoint& p1, - const GrPoint& p2, +uint32_t GrPathUtils::generateQuadraticPoints(const SkPoint& p0, + const SkPoint& p1, + const SkPoint& p2, SkScalar tolSqd, - GrPoint** points, + SkPoint** points, uint32_t pointsLeft) { if (pointsLeft < 2 || (p1.distanceToLineSegmentBetweenSqd(p0, p2)) < tolSqd) { @@ -76,11 +76,11 @@ uint32_t GrPathUtils::generateQuadraticPoints(const GrPoint& p0, return 1; } - GrPoint q[] = { + SkPoint q[] = { { SkScalarAve(p0.fX, p1.fX), SkScalarAve(p0.fY, p1.fY) }, { SkScalarAve(p1.fX, p2.fX), SkScalarAve(p1.fY, p2.fY) }, }; - GrPoint r = { SkScalarAve(q[0].fX, q[1].fX), SkScalarAve(q[0].fY, q[1].fY) }; + SkPoint r = { SkScalarAve(q[0].fX, q[1].fX), SkScalarAve(q[0].fY, q[1].fY) }; pointsLeft >>= 1; uint32_t a = generateQuadraticPoints(p0, q[0], r, tolSqd, points, pointsLeft); @@ -88,21 +88,21 @@ uint32_t GrPathUtils::generateQuadraticPoints(const GrPoint& p0, return a + b; } -uint32_t GrPathUtils::cubicPointCount(const GrPoint points[], +uint32_t GrPathUtils::cubicPointCount(const SkPoint points[], SkScalar tol) { if (tol < gMinCurveTol) { tol = gMinCurveTol; } SkASSERT(tol > 0); - SkScalar d = GrMax( + SkScalar d = SkTMax( points[1].distanceToLineSegmentBetweenSqd(points[0], points[3]), points[2].distanceToLineSegmentBetweenSqd(points[0], points[3])); d = SkScalarSqrt(d); if (d <= tol) { return 1; } else { - int temp = SkScalarCeil(SkScalarSqrt(SkScalarDiv(d, tol))); + int temp = SkScalarCeilToInt(SkScalarSqrt(SkScalarDiv(d, tol))); int pow2 = GrNextPow2(temp); // Because of NaNs & INFs we can wind up with a degenerate temp // such that pow2 comes out negative. Also, our point generator @@ -110,16 +110,16 @@ uint32_t GrPathUtils::cubicPointCount(const GrPoint points[], if (pow2 < 1) { pow2 = 1; } - return GrMin(pow2, MAX_POINTS_PER_CURVE); + return SkTMin(pow2, MAX_POINTS_PER_CURVE); } } -uint32_t GrPathUtils::generateCubicPoints(const GrPoint& p0, - const GrPoint& p1, - const GrPoint& p2, - const GrPoint& p3, +uint32_t GrPathUtils::generateCubicPoints(const SkPoint& p0, + const SkPoint& p1, + const SkPoint& p2, + const SkPoint& p3, SkScalar tolSqd, - GrPoint** points, + SkPoint** points, uint32_t pointsLeft) { if (pointsLeft < 2 || (p1.distanceToLineSegmentBetweenSqd(p0, p3) < tolSqd && @@ -128,16 +128,16 @@ uint32_t GrPathUtils::generateCubicPoints(const GrPoint& p0, *points += 1; return 1; } - GrPoint q[] = { + SkPoint q[] = { { SkScalarAve(p0.fX, p1.fX), SkScalarAve(p0.fY, p1.fY) }, { SkScalarAve(p1.fX, p2.fX), SkScalarAve(p1.fY, p2.fY) }, { SkScalarAve(p2.fX, p3.fX), SkScalarAve(p2.fY, p3.fY) } }; - GrPoint r[] = { + SkPoint r[] = { { SkScalarAve(q[0].fX, q[1].fX), SkScalarAve(q[0].fY, q[1].fY) }, { SkScalarAve(q[1].fX, q[2].fX), SkScalarAve(q[1].fY, q[2].fY) } }; - GrPoint s = { SkScalarAve(r[0].fX, r[1].fX), SkScalarAve(r[0].fY, r[1].fY) }; + SkPoint s = { SkScalarAve(r[0].fX, r[1].fX), SkScalarAve(r[0].fY, r[1].fY) }; pointsLeft >>= 1; uint32_t a = generateCubicPoints(p0, q[0], r[0], s, tolSqd, points, pointsLeft); uint32_t b = generateCubicPoints(s, r[1], q[2], p3, tolSqd, points, pointsLeft); @@ -159,7 +159,7 @@ int GrPathUtils::worstCasePointCount(const SkPath& path, int* subpaths, SkPath::Iter iter(path, false); SkPath::Verb verb; - GrPoint pts[4]; + SkPoint pts[4]; while ((verb = iter.next(pts)) != SkPath::kDone_Verb) { switch (verb) { @@ -186,10 +186,7 @@ int GrPathUtils::worstCasePointCount(const SkPath& path, int* subpaths, return pointCount; } -void GrPathUtils::QuadUVMatrix::set(const GrPoint qPts[3]) { -#ifndef SK_SCALAR_IS_FLOAT - GrCrash("Expected scalar is float."); -#endif +void GrPathUtils::QuadUVMatrix::set(const SkPoint qPts[3]) { SkMatrix m; // We want M such that M * xy_pt = uv_pt // We know M * control_pts = [0 1/2 1] @@ -229,11 +226,11 @@ void GrPathUtils::QuadUVMatrix::set(const GrPoint qPts[3]) { // We could have a tolerance here, not sure if it would improve anything if (maxD > 0) { // Set the matrix to give (u = 0, v = distance_to_line) - GrVec lineVec = qPts[(maxEdge + 1)%3] - qPts[maxEdge]; + SkVector lineVec = qPts[(maxEdge + 1)%3] - qPts[maxEdge]; // when looking from the point 0 down the line we want positive // distances to be to the left. This matches the non-degenerate // case. - lineVec.setOrthog(lineVec, GrPoint::kLeft_Side); + lineVec.setOrthog(lineVec, SkPoint::kLeft_Side); lineVec.dot(qPts[0]); // first row fM[0] = 0; @@ -408,49 +405,56 @@ void convert_noninflect_cubic_to_quads(const SkPoint p[4], dc = p[1] - p[3]; } - // When the ab and cd tangents are nearly parallel with vector from d to a the constraint that - // the quad point falls between the tangents becomes hard to enforce and we are likely to hit - // the max subdivision count. However, in this case the cubic is approaching a line and the - // accuracy of the quad point isn't so important. We check if the two middle cubic control - // points are very close to the baseline vector. If so then we just pick quadratic points on the - // control polygon. + // When the ab and cd tangents are degenerate or nearly parallel with vector from d to a the + // constraint that the quad point falls between the tangents becomes hard to enforce and we are + // likely to hit the max subdivision count. However, in this case the cubic is approaching a + // line and the accuracy of the quad point isn't so important. We check if the two middle cubic + // control points are very close to the baseline vector. If so then we just pick quadratic + // points on the control polygon. if (constrainWithinTangents) { SkVector da = p[0] - p[3]; - SkScalar invDALengthSqd = da.lengthSqd(); - if (invDALengthSqd > SK_ScalarNearlyZero) { - invDALengthSqd = SkScalarInvert(invDALengthSqd); - // cross(ab, da)^2/length(da)^2 == sqd distance from b to line from d to a. - // same goed for point c using vector cd. - SkScalar detABSqd = ab.cross(da); - detABSqd = SkScalarSquare(detABSqd); - SkScalar detDCSqd = dc.cross(da); - detDCSqd = SkScalarSquare(detDCSqd); - if (SkScalarMul(detABSqd, invDALengthSqd) < toleranceSqd && - SkScalarMul(detDCSqd, invDALengthSqd) < toleranceSqd) { - SkPoint b = p[0] + ab; - SkPoint c = p[3] + dc; - SkPoint mid = b + c; - mid.scale(SK_ScalarHalf); - // Insert two quadratics to cover the case when ab points away from d and/or dc - // points away from a. - if (SkVector::DotProduct(da, dc) < 0 || SkVector::DotProduct(ab,da) > 0) { - SkPoint* qpts = quads->push_back_n(6); - qpts[0] = p[0]; - qpts[1] = b; - qpts[2] = mid; - qpts[3] = mid; - qpts[4] = c; - qpts[5] = p[3]; - } else { - SkPoint* qpts = quads->push_back_n(3); - qpts[0] = p[0]; - qpts[1] = mid; - qpts[2] = p[3]; + bool doQuads = dc.lengthSqd() < SK_ScalarNearlyZero || + ab.lengthSqd() < SK_ScalarNearlyZero; + if (!doQuads) { + SkScalar invDALengthSqd = da.lengthSqd(); + if (invDALengthSqd > SK_ScalarNearlyZero) { + invDALengthSqd = SkScalarInvert(invDALengthSqd); + // cross(ab, da)^2/length(da)^2 == sqd distance from b to line from d to a. + // same goes for point c using vector cd. + SkScalar detABSqd = ab.cross(da); + detABSqd = SkScalarSquare(detABSqd); + SkScalar detDCSqd = dc.cross(da); + detDCSqd = SkScalarSquare(detDCSqd); + if (SkScalarMul(detABSqd, invDALengthSqd) < toleranceSqd && + SkScalarMul(detDCSqd, invDALengthSqd) < toleranceSqd) { + doQuads = true; } - return; } } + if (doQuads) { + SkPoint b = p[0] + ab; + SkPoint c = p[3] + dc; + SkPoint mid = b + c; + mid.scale(SK_ScalarHalf); + // Insert two quadratics to cover the case when ab points away from d and/or dc + // points away from a. + if (SkVector::DotProduct(da, dc) < 0 || SkVector::DotProduct(ab,da) > 0) { + SkPoint* qpts = quads->push_back_n(6); + qpts[0] = p[0]; + qpts[1] = b; + qpts[2] = mid; + qpts[3] = mid; + qpts[4] = c; + qpts[5] = p[3]; + } else { + SkPoint* qpts = quads->push_back_n(3); + qpts[0] = p[0]; + qpts[1] = mid; + qpts[2] = p[3]; + } + return; + } } static const SkScalar kLengthScale = 3 * SK_Scalar1 / 2; @@ -522,7 +526,7 @@ void convert_noninflect_cubic_to_quads(const SkPoint p[4], } } -void GrPathUtils::convertCubicToQuads(const GrPoint p[4], +void GrPathUtils::convertCubicToQuads(const SkPoint p[4], SkScalar tolScale, bool constrainWithinTangents, SkPath::Direction dir, |