Modify interface to GrPathUtils::convertCubicToQuads

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search2?unt=true&query=source_type%3Dgm&master=false&issue=1694403003

Review URL: https://codereview.chromium.org/1694403003
This commit is contained in:
bsalomon 2016-02-16 08:00:05 -08:00 committed by Commit bot
parent b8fea97a7a
commit 18fab30d7c
5 changed files with 34 additions and 25 deletions

View File

@ -545,21 +545,33 @@ void convert_noninflect_cubic_to_quads(const SkPoint p[4],
void GrPathUtils::convertCubicToQuads(const SkPoint p[4],
SkScalar tolScale,
bool constrainWithinTangents,
SkPathPriv::FirstDirection dir,
SkTArray<SkPoint, true>* quads) {
SkPoint chopped[10];
int count = SkChopCubicAtInflections(p, chopped);
// base tolerance is 1 pixel.
static const SkScalar kTolerance = SK_Scalar1;
const SkScalar tolSqd = SkScalarSquare(SkScalarMul(tolScale, kTolerance));
const SkScalar tolSqd = SkScalarSquare(tolScale);
for (int i = 0; i < count; ++i) {
SkPoint* cubic = chopped + 3*i;
convert_noninflect_cubic_to_quads(cubic, tolSqd, constrainWithinTangents, dir, quads);
// The direction param is ignored if the third param is false.
convert_noninflect_cubic_to_quads(cubic, tolSqd, false,
SkPathPriv::kCCW_FirstDirection, quads);
}
}
void GrPathUtils::convertCubicToQuadsConstrainToTangents(const SkPoint p[4],
SkScalar tolScale,
SkPathPriv::FirstDirection dir,
SkTArray<SkPoint, true>* quads) {
SkPoint chopped[10];
int count = SkChopCubicAtInflections(p, chopped);
const SkScalar tolSqd = SkScalarSquare(tolScale);
for (int i = 0; i < count; ++i) {
SkPoint* cubic = chopped + 3*i;
convert_noninflect_cubic_to_quads(cubic, tolSqd, true, dir, quads);
}
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -108,21 +108,22 @@ namespace GrPathUtils {
// Converts a cubic into a sequence of quads. If working in device space
// use tolScale = 1, otherwise set based on stretchiness of the matrix. The
// result is sets of 3 points in quads (TODO: share endpoints in returned
// array)
// result is sets of 3 points in quads.
void convertCubicToQuads(const SkPoint p[4],
SkScalar tolScale,
SkTArray<SkPoint, true>* quads);
// When we approximate a cubic {a,b,c,d} with a quadratic we may have to
// ensure that the new control point lies between the lines ab and cd. The
// convex path renderer requires this. It starts with a path where all the
// control points taken together form a convex polygon. It relies on this
// property and the quadratic approximation of cubics step cannot alter it.
// Setting constrainWithinTangents to true enforces this property. When this
// is true the cubic must be simple and dir must specify the orientation of
// the cubic. Otherwise, dir is ignored.
void convertCubicToQuads(const SkPoint p[4],
SkScalar tolScale,
bool constrainWithinTangents,
SkPathPriv::FirstDirection dir,
SkTArray<SkPoint, true>* quads);
// This variation enforces this constraint. The cubic must be simple and dir
// must specify the orientation of the contour containing the cubic.
void convertCubicToQuadsConstrainToTangents(const SkPoint p[4],
SkScalar tolScale,
SkPathPriv::FirstDirection dir,
SkTArray<SkPoint, true>* quads);
// Chops the cubic bezier passed in by src, at the double point (intersection point)
// if the curve is a cubic loop. If it is a loop, there will be two parametric values for

View File

@ -254,7 +254,7 @@ static inline void add_cubic_segments(const SkPoint pts[4],
SkPathPriv::FirstDirection dir,
SegmentArray* segments) {
SkSTArray<15, SkPoint, true> quads;
GrPathUtils::convertCubicToQuads(pts, SK_Scalar1, true, dir, &quads);
GrPathUtils::convertCubicToQuadsConstrainToTangents(pts, SK_Scalar1, dir, &quads);
int count = quads.count();
for (int q = 0; q < count; q += 3) {
add_quad_segment(&quads[q], segments);

View File

@ -345,17 +345,14 @@ static int gather_lines_and_quads(const SkPath& path,
bounds.roundOut(&ibounds);
if (SkIRect::Intersects(devClipBounds, ibounds)) {
PREALLOC_PTARRAY(32) q;
// we don't need a direction if we aren't constraining the subdivision
const SkPathPriv::FirstDirection kDummyDir = SkPathPriv::kCCW_FirstDirection;
// We convert cubics to quadratics (for now).
// In perspective have to do conversion in src space.
if (persp) {
SkScalar tolScale =
GrPathUtils::scaleToleranceToSrc(SK_Scalar1, m,
path.getBounds());
GrPathUtils::convertCubicToQuads(pathPts, tolScale, false, kDummyDir, &q);
GrPathUtils::scaleToleranceToSrc(SK_Scalar1, m, path.getBounds());
GrPathUtils::convertCubicToQuads(pathPts, tolScale, &q);
} else {
GrPathUtils::convertCubicToQuads(devPts, SK_Scalar1, false, kDummyDir, &q);
GrPathUtils::convertCubicToQuads(devPts, SK_Scalar1, &q);
}
for (int i = 0; i < q.count(); i += 3) {
SkPoint* qInDevSpace;

View File

@ -145,7 +145,6 @@ static bool get_geometry(const SkPath& path, const SkMatrix& m, PLSVertices& tri
SkPath linesOnlyPath;
linesOnlyPath.setFillType(path.getFillType());
SkSTArray<15, SkPoint, true> quadPoints;
SkPathPriv::FirstDirection dir = SkPathPriv::FirstDirection::kUnknown_FirstDirection;
SkPath::Iter iter(path, true);
bool done = false;
while (!done) {
@ -175,7 +174,7 @@ static bool get_geometry(const SkPath& path, const SkMatrix& m, PLSVertices& tri
case SkPath::kCubic_Verb: {
m.mapPoints(pts, 4);
SkSTArray<15, SkPoint, true> quads;
GrPathUtils::convertCubicToQuads(pts, kCubicTolerance, false, dir, &quads);
GrPathUtils::convertCubicToQuads(pts, kCubicTolerance, &quads);
int count = quads.count();
for (int q = 0; q < count; q += 3) {
linesOnlyPath.lineTo(quads[q + 2]);