aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/utils/SkShadowTessellator.cpp
diff options
context:
space:
mode:
authorGravatar Brian Salomon <bsalomon@google.com>2017-03-24 16:00:35 +0000
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-03-24 16:00:55 +0000
commite7c85c45c4c0a97adc6711bb12ecacc36af4ba11 (patch)
tree56656a9d1ee3912b7c43c472632482b594a2f325 /src/utils/SkShadowTessellator.cpp
parentadf7b330bde6ddb03c888143f16cb3b04c074ebd (diff)
Revert "Create new inset algorithm for spot shadows"
This reverts commit e5f5bf5175e426ebb6aa234f4387831c898f20ad. Reason for revert: Breaking a bunch of bots. e.g: https://luci-milo.appspot.com/swarming/task/3519cae0a03c7b10/steps/dm/0/stdout Original change's description: > Create new inset algorithm for spot shadows > > BUG=skia: > > Change-Id: If7c67c2a5b9beea28f86d13362a5156b46394d0e > Reviewed-on: https://skia-review.googlesource.com/9875 > Commit-Queue: Ravi Mistry <rmistry@google.com> > Reviewed-by: Brian Salomon <bsalomon@google.com> > Reviewed-by: Robert Phillips <robertphillips@google.com> > TBR=jvanverth@google.com,bsalomon@google.com,rmistry@google.com,robertphillips@google.com,msarett@google.com,reviews@skia.org NOPRESUBMIT=true NOTREECHECKS=true NOTRY=true BUG=skia: Change-Id: I3d119ff631dbb1a41f873b9c8753d542ec91254e Reviewed-on: https://skia-review.googlesource.com/10112 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Brian Salomon <bsalomon@google.com>
Diffstat (limited to 'src/utils/SkShadowTessellator.cpp')
-rw-r--r--src/utils/SkShadowTessellator.cpp379
1 files changed, 165 insertions, 214 deletions
diff --git a/src/utils/SkShadowTessellator.cpp b/src/utils/SkShadowTessellator.cpp
index ef8ce3212f..ed9e62af7a 100644
--- a/src/utils/SkShadowTessellator.cpp
+++ b/src/utils/SkShadowTessellator.cpp
@@ -8,7 +8,6 @@
#include "SkShadowTessellator.h"
#include "SkColorPriv.h"
#include "SkGeometry.h"
-#include "SkInsetConvexPolygon.h"
#include "SkPath.h"
#include "SkVertices.h"
@@ -440,28 +439,22 @@ public:
bool transparent);
private:
- void computeClipAndPathPolygons(const SkPath& path, const SkMatrix& ctm,
- SkScalar scale, const SkVector& xlate);
- void computeClipVectorsAndTestCentroid();
+ void computeClipBounds(const SkPath& path, const SkMatrix& ctm, SkPath* devPath);
+ void checkUmbraAndTransformCentroid(SkScalar scale, const SkVector& xlate,
+ bool useDistanceToPoint);
bool clipUmbraPoint(const SkPoint& umbraPoint, const SkPoint& centroid, SkPoint* clipPoint);
- int getClosestUmbraPoint(const SkPoint& point);
void handleLine(const SkPoint& p) override;
- void handlePolyPoint(const SkPoint& p);
void mapPoints(SkScalar scale, const SkVector& xlate, SkPoint* pts, int count);
- bool addInnerPoint(const SkPoint& pathPoint);
+ void addInnerPoint(const SkPoint& pathPoint);
void addEdge(const SkVector& nextPoint, const SkVector& nextNormal) override;
SkTDArray<SkPoint> fClipPolygon;
SkTDArray<SkVector> fClipVectors;
SkPoint fCentroid;
- SkScalar fArea;
- SkTDArray<SkPoint> fPathPolygon;
- SkTDArray<SkPoint> fUmbraPolygon;
- int fCurrClipPoint;
- int fCurrUmbraPoint;
+ int fCurrPolyPoint;
bool fPrevUmbraOutside;
bool fFirstUmbraOutside;
bool fValidUmbra;
@@ -474,11 +467,11 @@ SkSpotShadowTessellator::SkSpotShadowTessellator(const SkPath& path, const SkMat
SkScalar radius, SkColor umbraColor,
SkColor penumbraColor, bool transparent)
: INHERITED(radius, umbraColor, penumbraColor, transparent)
- , fCurrClipPoint(0)
+ , fCurrPolyPoint(0)
, fPrevUmbraOutside(false)
, fFirstUmbraOutside(false)
, fValidUmbra(true) {
- // TODO: calculate these reserves better
+ // TODO: calculate these better
// Penumbra ring: 3*numPts
// Umbra ring: numPts
// Inner ring: numPts
@@ -487,65 +480,61 @@ SkSpotShadowTessellator::SkSpotShadowTessellator(const SkPath& path, const SkMat
// Penumbra ring: 12*numPts
// Umbra ring: 3*numPts
fIndices.setReserve(15 * path.countPoints());
- fClipPolygon.setReserve(path.countPoints());
- // compute rough clip bounds for umbra, plus offset polygon, plus centroid
- this->computeClipAndPathPolygons(path, ctm, scale, translate);
- if (fClipPolygon.count() < 3 || fPathPolygon.count() < 3) {
+ fClipPolygon.setReserve(path.countPoints());
+ // compute rough clip bounds for umbra, plus centroid
+ SkPath devPath;
+ this->computeClipBounds(path, ctm, &devPath);
+ if (fClipPolygon.count() < 3) {
return;
}
+ // We are going to apply 'scale' and 'xlate' (in that order) to each computed path point. We
+ // want the effect to be to scale the points relative to the path centroid and then translate
+ // them by the 'translate' param we were passed.
+ SkVector xlate = fCentroid * (1.f - scale) + translate;
- // check to see if umbra collapses
- SkScalar minDistSq = fCentroid.distanceToLineSegmentBetweenSqd(fPathPolygon[0],
- fPathPolygon[1]);
- for (int i = 1; i < fPathPolygon.count(); ++i) {
- int j = i + 1;
- if (i == fPathPolygon.count() - 1) {
- j = 0;
- }
- SkPoint currPoint = fPathPolygon[i];
- SkPoint nextPoint = fPathPolygon[j];
- SkScalar distSq = fCentroid.distanceToLineSegmentBetweenSqd(currPoint, nextPoint);
- if (distSq < minDistSq) {
- minDistSq = distSq;
- }
- }
- static constexpr auto kTolerance = 1.0e-2f;
- if (minDistSq < (radius + kTolerance)*(radius + kTolerance)) {
- // if the umbra would collapse, we back off a bit on inner blur and adjust the alpha
- SkScalar newRadius = SkScalarSqrt(minDistSq) - kTolerance;
- SkScalar ratio = 256 * newRadius / radius;
- // they aren't PMColors, but the interpolation algorithm is the same
- fUmbraColor = SkPMLerp(fUmbraColor, fPenumbraColor, (unsigned)ratio);
- radius = newRadius;
- }
-
- // compute vectors for clip tests
- this->computeClipVectorsAndTestCentroid();
-
- // generate inner ring
- if (!SkInsetConvexPolygon(&fPathPolygon[0], fPathPolygon.count(), radius, &fUmbraPolygon)) {
- // this shouldn't happen, but just in case we'll inset using the centroid
- fValidUmbra = false;
- }
+ // check to see if we have a valid umbra at all
+ bool usePointCheck = path.isRRect(nullptr) || path.isRect(nullptr) || path.isOval(nullptr);
+ this->checkUmbraAndTransformCentroid(scale, translate, usePointCheck);
- // walk around the path polygon, generate outer ring and connect to inner ring
+ // walk around the path, tessellate and generate inner and outer rings
+ SkPath::Iter iter(devPath, true);
+ SkPoint pts[4];
+ SkPath::Verb verb;
if (fTransparent) {
*fPositions.push() = fCentroid;
*fColors.push() = fUmbraColor;
}
- fCurrUmbraPoint = 0;
- for (int i = 0; i < fPathPolygon.count(); ++i) {
- this->handlePolyPoint(fPathPolygon[i]);
+ SkMatrix shadowTransform;
+ shadowTransform.setScaleTranslate(scale, scale, xlate.fX, xlate.fY);
+ while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
+ switch (verb) {
+ case SkPath::kLine_Verb:
+ this->INHERITED::handleLine(shadowTransform, &pts[1]);
+ break;
+ case SkPath::kQuad_Verb:
+ this->handleQuad(shadowTransform, pts);
+ break;
+ case SkPath::kCubic_Verb:
+ this->handleCubic(shadowTransform, pts);
+ break;
+ case SkPath::kConic_Verb:
+ this->handleConic(shadowTransform, pts, iter.conicWeight());
+ break;
+ case SkPath::kMove_Verb:
+ case SkPath::kClose_Verb:
+ case SkPath::kDone_Verb:
+ break;
+ }
}
if (!this->indexCount()) {
return;
}
- // finish up the final verts
SkVector normal;
- if (compute_normal(fPrevPoint, fFirstPoint, fRadius, fDirection, &normal)) {
+ if (compute_normal(fPrevPoint, fFirstPoint, fRadius, fDirection,
+ &normal)) {
this->addArc(normal);
// close out previous arc
@@ -611,138 +600,175 @@ SkSpotShadowTessellator::SkSpotShadowTessellator(const SkPath& path, const SkMat
fSucceeded = true;
}
-void SkSpotShadowTessellator::computeClipAndPathPolygons(const SkPath& path, const SkMatrix& ctm,
- SkScalar scale, const SkVector& xlate) {
- // For the path polygon we are going to apply 'scale' and 'xlate' (in that order) to each
- // computed path point. We want the effect to be to scale the points relative to the path
- // bounds center and then translate them by the 'xlate' param we were passed.
- SkPoint center = SkPoint::Make(path.getBounds().centerX(), path.getBounds().centerY());
- ctm.mapPoints(&center, 1);
- SkVector translate = center * (1.f - scale) + xlate;
- SkMatrix shadowTransform;
- shadowTransform.setScaleTranslate(scale, scale, translate.fX, translate.fY);
-
- fPathPolygon.setReserve(path.countPoints());
-
- // Walk around the path and compute clip polygon and path polygon.
- // Will also accumulate sum of areas for centroid.
- // For Bezier curves, we compute additional interior points on curve.
+void SkSpotShadowTessellator::computeClipBounds(const SkPath& path, const SkMatrix& ctm,
+ SkPath* devPath) {
+ // walk around the path and compute clip polygon
+ // if original path is transparent, will accumulate sum of points for centroid
+ // for Bezier curves, we compute additional interior points on curve
SkPath::Iter iter(path, true);
SkPoint pts[4];
SkPath::Verb verb;
- fClipPolygon.reset();
-
- // init centroid
fCentroid = SkPoint::Make(0, 0);
- fArea = 0;
+ int centroidCount = 0;
+ fClipPolygon.reset();
// coefficients to compute cubic Bezier at t = 5/16
- static constexpr SkScalar kA = 0.32495117187f;
- static constexpr SkScalar kB = 0.44311523437f;
- static constexpr SkScalar kC = 0.20141601562f;
- static constexpr SkScalar kD = 0.03051757812f;
+ const SkScalar kA = 0.32495117187f;
+ const SkScalar kB = 0.44311523437f;
+ const SkScalar kC = 0.20141601562f;
+ const SkScalar kD = 0.03051757812f;
SkPoint curvePoint;
SkScalar w;
while ((verb = iter.next(pts)) != SkPath::kDone_Verb) {
switch (verb) {
+ case SkPath::kMove_Verb:
+ ctm.mapPoints(&pts[0], 1);
+ devPath->moveTo(pts[0]);
+ break;
case SkPath::kLine_Verb:
ctm.mapPoints(&pts[1], 1);
+ devPath->lineTo(pts[1]);
+ fCentroid += pts[1];
+ centroidCount++;
*fClipPolygon.push() = pts[1];
- this->INHERITED::handleLine(shadowTransform, &pts[1]);
break;
case SkPath::kQuad_Verb:
ctm.mapPoints(pts, 3);
+ devPath->quadTo(pts[1], pts[2]);
// point at t = 1/2
curvePoint.fX = 0.25f*pts[0].fX + 0.5f*pts[1].fX + 0.25f*pts[2].fX;
curvePoint.fY = 0.25f*pts[0].fY + 0.5f*pts[1].fY + 0.25f*pts[2].fY;
*fClipPolygon.push() = curvePoint;
+ fCentroid += curvePoint;
*fClipPolygon.push() = pts[2];
- this->handleQuad(shadowTransform, pts);
+ fCentroid += pts[2];
+ centroidCount += 2;
break;
case SkPath::kConic_Verb:
ctm.mapPoints(pts, 3);
w = iter.conicWeight();
+ devPath->conicTo(pts[1], pts[2], w);
// point at t = 1/2
curvePoint.fX = 0.25f*pts[0].fX + w*0.5f*pts[1].fX + 0.25f*pts[2].fX;
curvePoint.fY = 0.25f*pts[0].fY + w*0.5f*pts[1].fY + 0.25f*pts[2].fY;
curvePoint *= SkScalarInvert(0.5f + 0.5f*w);
*fClipPolygon.push() = curvePoint;
+ fCentroid += curvePoint;
*fClipPolygon.push() = pts[2];
- this->handleConic(shadowTransform, pts, w);
+ fCentroid += pts[2];
+ centroidCount += 2;
break;
case SkPath::kCubic_Verb:
ctm.mapPoints(pts, 4);
+ devPath->cubicTo(pts[1], pts[2], pts[3]);
// point at t = 5/16
curvePoint.fX = kA*pts[0].fX + kB*pts[1].fX + kC*pts[2].fX + kD*pts[3].fX;
curvePoint.fY = kA*pts[0].fY + kB*pts[1].fY + kC*pts[2].fY + kD*pts[3].fY;
*fClipPolygon.push() = curvePoint;
+ fCentroid += curvePoint;
// point at t = 11/16
curvePoint.fX = kD*pts[0].fX + kC*pts[1].fX + kB*pts[2].fX + kA*pts[3].fX;
curvePoint.fY = kD*pts[0].fY + kC*pts[1].fY + kB*pts[2].fY + kA*pts[3].fY;
*fClipPolygon.push() = curvePoint;
+ fCentroid += curvePoint;
*fClipPolygon.push() = pts[3];
- this->handleCubic(shadowTransform, pts);
+ fCentroid += pts[3];
+ centroidCount += 3;
break;
- case SkPath::kMove_Verb:
case SkPath::kClose_Verb:
- case SkPath::kDone_Verb:
+ devPath->close();
break;
default:
SkDEBUGFAIL("unknown verb");
}
}
- // finish centroid
- if (fPathPolygon.count() > 0) {
- SkPoint currPoint = fPathPolygon[fPathPolygon.count() - 1];
- SkPoint nextPoint = fPathPolygon[0];
- SkScalar quadArea = currPoint.cross(nextPoint);
- fCentroid.fX += (currPoint.fX + nextPoint.fX) * quadArea;
- fCentroid.fY += (currPoint.fY + nextPoint.fY) * quadArea;
- fArea += quadArea;
- fCentroid *= SK_Scalar1 / (3 * fArea);
- }
-
- fCurrClipPoint = fClipPolygon.count() - 1;
+ fCentroid *= SkScalarInvert(centroidCount);
+ fCurrPolyPoint = fClipPolygon.count() - 1;
}
-void SkSpotShadowTessellator::computeClipVectorsAndTestCentroid() {
+void SkSpotShadowTessellator::checkUmbraAndTransformCentroid(SkScalar scale,
+ const SkVector& xlate,
+ bool useDistanceToPoint) {
SkASSERT(fClipPolygon.count() >= 3);
+ SkPoint transformedCentroid = fCentroid;
+ transformedCentroid += xlate;
- // init clip vectors
+ SkScalar localRadius = fRadius / scale;
+ localRadius *= localRadius;
+
+ // init umbra check
+ SkVector w = fCentroid - fClipPolygon[0];
SkVector v0 = fClipPolygon[1] - fClipPolygon[0];
*fClipVectors.push() = v0;
+ bool validUmbra;
+ SkScalar minDistance;
+ // check distance against line segment
+ if (useDistanceToPoint) {
+ minDistance = w.lengthSqd();
+ } else {
+ SkScalar vSq = v0.dot(v0);
+ SkScalar wDotV = w.dot(v0);
+ minDistance = w.dot(w) - wDotV*wDotV/vSq;
+ }
+ validUmbra = (minDistance >= localRadius);
// init centroid check
bool hiddenCentroid = true;
- SkVector v1 = fCentroid - fClipPolygon[0];
+ SkVector v1 = transformedCentroid - fClipPolygon[0];
SkScalar initCross = v0.cross(v1);
for (int p = 1; p < fClipPolygon.count(); ++p) {
- // add to clip vectors
+ // Determine whether we have a real umbra by insetting clipPolygon by radius/scale
+ // and see if it extends past centroid.
+ // TODO: adjust this later for more accurate umbra calcs
+ w = fCentroid - fClipPolygon[p];
v0 = fClipPolygon[(p + 1) % fClipPolygon.count()] - fClipPolygon[p];
*fClipVectors.push() = v0;
+ // check distance against line segment
+ SkScalar distance;
+ if (useDistanceToPoint) {
+ distance = w.lengthSqd();
+ } else {
+ SkScalar vSq = v0.dot(v0);
+ SkScalar wDotV = w.dot(v0);
+ distance = w.dot(w) - wDotV*wDotV/vSq;
+ }
+ if (distance < localRadius) {
+ validUmbra = false;
+ }
+ if (distance < minDistance) {
+ minDistance = distance;
+ }
// Determine if transformed centroid is inside clipPolygon.
- v1 = fCentroid - fClipPolygon[p];
+ v1 = transformedCentroid - fClipPolygon[p];
if (initCross*v0.cross(v1) <= 0) {
hiddenCentroid = false;
}
}
SkASSERT(fClipVectors.count() == fClipPolygon.count());
- fTransparent = fTransparent || !hiddenCentroid;
+ if (!validUmbra) {
+ SkScalar ratio = 256 * SkScalarSqrt(minDistance / localRadius);
+ // they aren't PMColors, but the interpolation algorithm is the same
+ fUmbraColor = SkPMLerp(fUmbraColor, fPenumbraColor, (unsigned)ratio);
+ }
+
+ fTransparent = fTransparent || !hiddenCentroid || !validUmbra;
+ fValidUmbra = validUmbra;
+ fCentroid = transformedCentroid;
}
bool SkSpotShadowTessellator::clipUmbraPoint(const SkPoint& umbraPoint, const SkPoint& centroid,
SkPoint* clipPoint) {
SkVector segmentVector = centroid - umbraPoint;
- int startClipPoint = fCurrClipPoint;
+ int startPolyPoint = fCurrPolyPoint;
do {
- SkVector dp = umbraPoint - fClipPolygon[fCurrClipPoint];
- SkScalar denom = fClipVectors[fCurrClipPoint].cross(segmentVector);
+ SkVector dp = umbraPoint - fClipPolygon[fCurrPolyPoint];
+ SkScalar denom = fClipVectors[fCurrPolyPoint].cross(segmentVector);
SkScalar t_num = dp.cross(segmentVector);
// if line segments are nearly parallel
if (SkScalarNearlyZero(denom)) {
@@ -753,7 +779,7 @@ bool SkSpotShadowTessellator::clipUmbraPoint(const SkPoint& umbraPoint, const Sk
// otherwise are separate, will try the next poly segment
// else if crossing lies within poly segment
} else if (t_num >= 0 && t_num <= denom) {
- SkScalar s_num = dp.cross(fClipVectors[fCurrClipPoint]);
+ SkScalar s_num = dp.cross(fClipVectors[fCurrPolyPoint]);
// if umbra point is inside the clip polygon
if (s_num < 0) {
return false;
@@ -763,41 +789,12 @@ bool SkSpotShadowTessellator::clipUmbraPoint(const SkPoint& umbraPoint, const Sk
return true;
}
}
- fCurrClipPoint = (fCurrClipPoint + 1) % fClipPolygon.count();
- } while (fCurrClipPoint != startClipPoint);
+ fCurrPolyPoint = (fCurrPolyPoint + 1) % fClipPolygon.count();
+ } while (fCurrPolyPoint != startPolyPoint);
return false;
}
-int SkSpotShadowTessellator::getClosestUmbraPoint(const SkPoint& p) {
- SkScalar minDistance = p.distanceToSqd(fUmbraPolygon[fCurrUmbraPoint]);
- int index = fCurrUmbraPoint;
- int dir = 1;
- int next = (index + dir) % fUmbraPolygon.count();
-
- // init travel direction
- SkScalar distance = p.distanceToSqd(fUmbraPolygon[next]);
- if (distance < minDistance) {
- index = next;
- minDistance = distance;
- } else {
- dir = fUmbraPolygon.count()-1;
- }
-
- // iterate until we find a point that increases the distance
- next = (index + dir) % fUmbraPolygon.count();
- distance = p.distanceToSqd(fUmbraPolygon[next]);
- while (distance < minDistance) {
- index = next;
- minDistance = distance;
- next = (index + dir) % fUmbraPolygon.count();
- distance = p.distanceToSqd(fUmbraPolygon[next]);
- }
-
- fCurrUmbraPoint = index;
- return index;
-}
-
void SkSpotShadowTessellator::mapPoints(SkScalar scale, const SkVector& xlate,
SkPoint* pts, int count) {
// TODO: vectorize
@@ -807,44 +804,7 @@ void SkSpotShadowTessellator::mapPoints(SkScalar scale, const SkVector& xlate,
}
}
-static bool duplicate_pt(const SkPoint& p0, const SkPoint& p1) {
- static constexpr SkScalar kClose = (SK_Scalar1 / 16);
- static constexpr SkScalar kCloseSqd = kClose*kClose;
-
- SkScalar distSq = p0.distanceToSqd(p1);
- return distSq < kCloseSqd;
-}
-
-static bool is_collinear(const SkPoint& p0, const SkPoint& p1, const SkPoint& p2) {
- SkVector v0 = p1 - p0;
- SkVector v1 = p2 - p0;
- return (SkScalarNearlyZero(v0.cross(v1)));
-}
-
void SkSpotShadowTessellator::handleLine(const SkPoint& p) {
- // remove coincident points and add to centroid
- if (fPathPolygon.count() > 0) {
- const SkPoint& lastPoint = fPathPolygon[fPathPolygon.count() - 1];
- if (duplicate_pt(p, lastPoint)) {
- return;
- }
- SkScalar quadArea = lastPoint.cross(p);
- fCentroid.fX += (p.fX + lastPoint.fX) * quadArea;
- fCentroid.fY += (p.fY + lastPoint.fY) * quadArea;
- fArea += quadArea;
- }
-
- // try to remove collinear points
- if (fPathPolygon.count() > 1 && is_collinear(fPathPolygon[fPathPolygon.count()-2],
- fPathPolygon[fPathPolygon.count()-1],
- p)) {
- fPathPolygon[fPathPolygon.count() - 1] = p;
- } else {
- *fPathPolygon.push() = p;
- }
-}
-
-void SkSpotShadowTessellator::handlePolyPoint(const SkPoint& p) {
if (fInitPoints.count() < 2) {
*fInitPoints.push() = p;
return;
@@ -854,7 +814,7 @@ void SkSpotShadowTessellator::handlePolyPoint(const SkPoint& p) {
// determine if cw or ccw
SkVector v0 = fInitPoints[1] - fInitPoints[0];
SkVector v1 = p - fInitPoints[0];
- SkScalar perpDot = v0.cross(v1);
+ SkScalar perpDot = v0.fX*v1.fY - v0.fY*v1.fX;
if (SkScalarNearlyZero(perpDot)) {
// nearly parallel, just treat as straight line and continue
fInitPoints[1] = p;
@@ -907,47 +867,40 @@ void SkSpotShadowTessellator::handlePolyPoint(const SkPoint& p) {
}
}
-bool SkSpotShadowTessellator::addInnerPoint(const SkPoint& pathPoint) {
- SkPoint umbraPoint;
- if (!fValidUmbra) {
- SkVector v = fCentroid - pathPoint;
- v *= 0.95f;
- umbraPoint = pathPoint + v;
+void SkSpotShadowTessellator::addInnerPoint(const SkPoint& pathPoint) {
+ SkVector v = fCentroid - pathPoint;
+ SkScalar distance = v.length();
+ SkScalar t;
+ if (fValidUmbra) {
+ SkASSERT(distance >= fRadius);
+ t = fRadius / distance;
} else {
- umbraPoint = fUmbraPolygon[this->getClosestUmbraPoint(pathPoint)];
+ t = 0.95f;
}
+ v *= t;
+ SkPoint umbraPoint = pathPoint + v;
+ *fPositions.push() = umbraPoint;
+ *fColors.push() = fUmbraColor;
fPrevPoint = pathPoint;
-
- // merge "close" points
- if (fPrevUmbraIndex == fFirstVertex ||
- !duplicate_pt(umbraPoint, fPositions[fPrevUmbraIndex])) {
- *fPositions.push() = umbraPoint;
- *fColors.push() = fUmbraColor;
-
- return false;
- } else {
- return true;
- }
}
void SkSpotShadowTessellator::addEdge(const SkPoint& nextPoint, const SkVector& nextNormal) {
// add next umbra point
- bool duplicate = this->addInnerPoint(nextPoint);
- int prevPenumbraIndex = duplicate ? fPositions.count()-1 : fPositions.count()-2;
- int currUmbraIndex = duplicate ? fPrevUmbraIndex : fPositions.count()-1;
+ this->addInnerPoint(nextPoint);
+ int prevPenumbraIndex = fPositions.count() - 2;
+ int currUmbraIndex = fPositions.count() - 1;
- if (!duplicate) {
- // add to center fan if transparent or centroid showing
- if (fTransparent) {
- *fIndices.push() = 0;
- *fIndices.push() = fPrevUmbraIndex;
- *fIndices.push() = currUmbraIndex;
- // otherwise add to clip ring
- } else {
+ // add to center fan if transparent or centroid showing
+ if (fTransparent) {
+ *fIndices.push() = 0;
+ *fIndices.push() = fPrevUmbraIndex;
+ *fIndices.push() = currUmbraIndex;
+ // otherwise add to clip ring
+ } else {
+ if (!fTransparent) {
SkPoint clipPoint;
- bool isOutside = this->clipUmbraPoint(fPositions[currUmbraIndex], fCentroid,
- &clipPoint);
+ bool isOutside = clipUmbraPoint(fPositions[currUmbraIndex], fCentroid, &clipPoint);
if (isOutside) {
*fPositions.push() = clipPoint;
*fColors.push() = fUmbraColor;
@@ -976,11 +929,9 @@ void SkSpotShadowTessellator::addEdge(const SkPoint& nextPoint, const SkVector&
*fPositions.push() = newPoint;
*fColors.push() = fPenumbraColor;
- if (!duplicate) {
- *fIndices.push() = fPrevUmbraIndex;
- *fIndices.push() = prevPenumbraIndex;
- *fIndices.push() = currUmbraIndex;
- }
+ *fIndices.push() = fPrevUmbraIndex;
+ *fIndices.push() = prevPenumbraIndex;
+ *fIndices.push() = currUmbraIndex;
*fIndices.push() = prevPenumbraIndex;
*fIndices.push() = fPositions.count() - 1;