aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gm/beziereffects.cpp14
-rw-r--r--src/gpu/GrPathUtils.cpp38
-rw-r--r--src/gpu/GrPathUtils.h10
-rw-r--r--src/gpu/effects/GrBezierEffect.cpp6
4 files changed, 36 insertions, 32 deletions
diff --git a/gm/beziereffects.cpp b/gm/beziereffects.cpp
index 54c28a7e5f..9167410e9f 100644
--- a/gm/beziereffects.cpp
+++ b/gm/beziereffects.cpp
@@ -156,15 +156,16 @@ protected:
};
SkPoint chopped[10];
SkScalar klmEqs[9];
- SkScalar klmSigns[3];
+ int loopIndex;
int cnt = GrPathUtils::chopCubicAtLoopIntersection(controlPts,
chopped,
klmEqs,
- klmSigns);
+ &loopIndex);
SkPaint ctrlPtPaint;
ctrlPtPaint.setColor(rand.nextU() | 0xFF000000);
- for (int i = 0; i < 4; ++i) {
+ canvas->drawCircle(controlPts[0].fX, controlPts[0].fY, 8.f, ctrlPtPaint);
+ for (int i = 1; i < 4; ++i) {
canvas->drawCircle(controlPts[i].fX, controlPts[i].fY, 6.f, ctrlPtPaint);
}
@@ -196,8 +197,13 @@ protected:
GrPaint grPaint;
grPaint.setXPFactory(GrPorterDuffXPFactory::Get(SkBlendMode::kSrc));
+ SkScalar sign = 1.0f;
+ if (c == loopIndex && cnt != 3) {
+ sign = -1.0f;
+ }
+
std::unique_ptr<GrMeshDrawOp> op =
- BezierCubicOrConicTestOp::Make(gp, bounds, color, klmEqs, klmSigns[c]);
+ BezierCubicOrConicTestOp::Make(gp, bounds, color, klmEqs, sign);
renderTargetContext->priv().testingOnly_addMeshDrawOp(
std::move(grPaint), GrAAType::kNone, std::move(op));
diff --git a/src/gpu/GrPathUtils.cpp b/src/gpu/GrPathUtils.cpp
index 867407d9e4..0bc84795b3 100644
--- a/src/gpu/GrPathUtils.cpp
+++ b/src/gpu/GrPathUtils.cpp
@@ -621,7 +621,7 @@ static void set_serp_klm(const SkScalar d[3], SkScalar k[4], SkScalar l[4], SkSc
m[2] = mt_ms * mt_ms * ms;
m[3] = -1.f * mt_ms * mt_ms * mt_ms;
- // If d0 < 0 we need to flip the orientation of our curve
+ // If d0 > 0 we need to flip the orientation of our curve
// This is done by negating the k and l values
// We want negative distance values to be on the inside
if ( d[0] > 0) {
@@ -655,10 +655,12 @@ static void set_loop_klm(const SkScalar d[3], SkScalar k[4], SkScalar l[4], SkSc
m[3] = -1.f * (lt - ls) * (mt - ms) * (mt - ms);
- // If (d0 < 0 && sign(k1) > 0) || (d0 > 0 && sign(k1) < 0),
- // we need to flip the orientation of our curve.
- // This is done by negating the k and l values
- if ( (d[0] < 0 && k[1] > 0) || (d[0] > 0 && k[1] < 0)) {
+ // For the general loop curve, we flip the orientation in the same pattern as the serp case
+ // above. Thus we only check d[0]. Technically we should check the value of the hessian as well
+ // cause we care about the sign of d[0]*Hessian. However, the Hessian is always negative outside
+ // the loop section and positive inside. We take care of the flipping for the loop sections
+ // later on.
+ if (d[0] > 0) {
for (int i = 0; i < 4; ++i) {
k[i] = -k[i];
l[i] = -l[i];
@@ -709,8 +711,8 @@ static void set_quadratic_klm(const SkScalar d[3], SkScalar k[4], SkScalar l[4],
m[2] = 2.f/3.f;
m[3] = 1.f;
- // If d2 < 0 we need to flip the orientation of our curve
- // This is done by negating the k and l values
+ // If d2 < 0 we need to flip the orientation of our curve since we want negative values to be on
+ // the "inside" of the curve. This is done by negating the k and l values
if ( d[2] > 0) {
for (int i = 0; i < 4; ++i) {
k[i] = -k[i];
@@ -720,7 +722,7 @@ static void set_quadratic_klm(const SkScalar d[3], SkScalar k[4], SkScalar l[4],
}
int GrPathUtils::chopCubicAtLoopIntersection(const SkPoint src[4], SkPoint dst[10], SkScalar klm[9],
- SkScalar klm_rev[3]) {
+ int* loopIndex) {
// Variable to store the two parametric values at the loop double point
SkScalar smallS = 0.f;
SkScalar largeS = 0.f;
@@ -762,28 +764,24 @@ int GrPathUtils::chopCubicAtLoopIntersection(const SkPoint src[4], SkPoint dst[1
}
}
- if (klm && klm_rev) {
- // Set klm_rev to to match the sub_section of cubic that needs to have its orientation
- // flipped. This will always be the section that is the "loop"
+ if (loopIndex) {
if (2 == chop_count) {
- klm_rev[0] = 1.f;
- klm_rev[1] = -1.f;
- klm_rev[2] = 1.f;
+ *loopIndex = 1;
} else if (1 == chop_count) {
if (smallS < 0.f) {
- klm_rev[0] = -1.f;
- klm_rev[1] = 1.f;
+ *loopIndex = 0;
} else {
- klm_rev[0] = 1.f;
- klm_rev[1] = -1.f;
+ *loopIndex = 1;
}
} else {
if (smallS < 0.f && largeS > 1.f) {
- klm_rev[0] = -1.f;
+ *loopIndex = 0;
} else {
- klm_rev[0] = 1.f;
+ *loopIndex = -1;
}
}
+ }
+ if (klm) {
SkScalar controlK[4];
SkScalar controlL[4];
SkScalar controlM[4];
diff --git a/src/gpu/GrPathUtils.h b/src/gpu/GrPathUtils.h
index fcc32c89c4..8b844180b7 100644
--- a/src/gpu/GrPathUtils.h
+++ b/src/gpu/GrPathUtils.h
@@ -146,16 +146,16 @@ namespace GrPathUtils {
// K = (klm[0], klm[1], klm[2])
// L = (klm[3], klm[4], klm[5])
// M = (klm[6], klm[7], klm[8])
- // klm_rev: These values are flags for the corresponding sub cubic saying whether or not
- // the K and L values need to be flipped. A value of -1.f means flip K and L and
- // a value of 1.f means do nothing.
- // *****DO NOT FLIP M, JUST K AND L*****
+ // loopIndex: This value will tell the caller which of the chopped sections are the the actual
+ // loop once we've chopped. A value of -1 means there is no loop section. The caller
+ // can then use this value to decide how/if they want to flip the orientation of this
+ // section. This flip should be done by negating the K and L values.
//
// Notice that the klm lines are calculated in the same space as the input control points.
// If you transform the points the lines will also need to be transformed. This can be done
// by mapping the lines with the inverse-transpose of the matrix used to map the points.
int chopCubicAtLoopIntersection(const SkPoint src[4], SkPoint dst[10] = nullptr,
- SkScalar klm[9] = nullptr, SkScalar klm_rev[3] = nullptr);
+ SkScalar klm[9] = nullptr, int* loopIndex = nullptr);
// Input is p which holds the 4 control points of a non-rational cubic Bezier curve.
// Output is the coefficients of the three linear functionals K, L, & M which
diff --git a/src/gpu/effects/GrBezierEffect.cpp b/src/gpu/effects/GrBezierEffect.cpp
index 6c01f70028..e8476c8243 100644
--- a/src/gpu/effects/GrBezierEffect.cpp
+++ b/src/gpu/effects/GrBezierEffect.cpp
@@ -183,7 +183,7 @@ void GrGLConicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
func.c_str(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppendf("%s = %s / %s;",
edgeAlpha.c_str(), func.c_str(), gFM.c_str());
- fragBuilder->codeAppendf("%s = clamp(1.0 - %s, 0.0, 1.0);",
+ fragBuilder->codeAppendf("%s = clamp(0.5 - %s, 0.0, 1.0);",
edgeAlpha.c_str(), edgeAlpha.c_str());
// Add line below for smooth cubic ramp
// fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
@@ -390,7 +390,7 @@ void GrGLQuadEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
fragBuilder->codeAppendf("edgeAlpha = (%s.x * %s.x - %s.y);",
v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppend("edgeAlpha = edgeAlpha / sqrt(dot(gF, gF));");
- fragBuilder->codeAppend("edgeAlpha = clamp(1.0 - edgeAlpha, 0.0, 1.0);");
+ fragBuilder->codeAppend("edgeAlpha = clamp(0.5 - edgeAlpha, 0.0, 1.0);");
// Add line below for smooth cubic ramp
// fragBuilder->codeAppend("edgeAlpha = edgeAlpha*edgeAlpha*(3.0-2.0*edgeAlpha);");
break;
@@ -624,7 +624,7 @@ void GrGLCubicEffect::onEmitCode(EmitArgs& args, GrGPArgs* gpArgs) {
v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn(), v.fsIn());
fragBuilder->codeAppendf("%s = %s / %s;",
edgeAlpha.c_str(), func.c_str(), gFM.c_str());
- fragBuilder->codeAppendf("%s = clamp(1.0 - %s, 0.0, 1.0);",
+ fragBuilder->codeAppendf("%s = clamp(0.5 - %s, 0.0, 1.0);",
edgeAlpha.c_str(), edgeAlpha.c_str());
// Add line below for smooth cubic ramp
// fragBuilder->codeAppendf("%s = %s * %s * (3.0 - 2.0 * %s);",