Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(158)

Unified Diff: src/core/SkStroke.cpp

Issue 1504043002: Ignore zero-length joins (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: let has_valid_tangent work with exhausted iter Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « gm/strokes.cpp ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkStroke.cpp
diff --git a/src/core/SkStroke.cpp b/src/core/SkStroke.cpp
index 65267d11fd4e181f260f9c75043d371c3ce09ab5..5a430752842f16ce47a28e9f1797950bdc19590e 100644
--- a/src/core/SkStroke.cpp
+++ b/src/core/SkStroke.cpp
@@ -126,7 +126,7 @@ public:
SkPoint moveToPt() const { return fFirstPt; }
void moveTo(const SkPoint&);
- void lineTo(const SkPoint&);
+ void lineTo(const SkPoint&, const SkPath::Iter* iter = nullptr);
void quadTo(const SkPoint&, const SkPoint&);
void conicTo(const SkPoint&, const SkPoint&, SkScalar weight);
void cubicTo(const SkPoint&, const SkPoint&, const SkPoint&);
@@ -187,6 +187,7 @@ private:
int fRecursionDepth; // track stack depth to abort if numerics run amok
bool fFoundTangents; // do less work until tangents meet (cubic)
+ bool fJoinCompleted; // previous join was not degenerate
void addDegenerateLine(const SkQuadConstruct* );
static ReductionType CheckConicLinear(const SkConic& , SkPoint* reduction);
@@ -273,6 +274,7 @@ bool SkPathStroker::preJoinTo(const SkPoint& currPt, SkVector* normal,
void SkPathStroker::postJoinTo(const SkPoint& currPt, const SkVector& normal,
const SkVector& unitNormal) {
+ fJoinCompleted = true;
fPrevPt = currPt;
fPrevUnitNormal = unitNormal;
fPrevNormal = normal;
@@ -359,6 +361,7 @@ void SkPathStroker::moveTo(const SkPoint& pt) {
}
fSegmentCount = 0;
fFirstPt = fPrevPt = pt;
+ fJoinCompleted = false;
}
void SkPathStroker::line_to(const SkPoint& currPt, const SkVector& normal) {
@@ -366,11 +369,46 @@ void SkPathStroker::line_to(const SkPoint& currPt, const SkVector& normal) {
fInner.lineTo(currPt.fX - normal.fX, currPt.fY - normal.fY);
}
-void SkPathStroker::lineTo(const SkPoint& currPt) {
+static bool has_valid_tangent(const SkPath::Iter* iter) {
+ SkPath::Iter copy = *iter;
+ SkPath::Verb verb;
+ SkPoint pts[4];
+ while ((verb = copy.next(pts))) {
+ switch (verb) {
+ case SkPath::kMove_Verb:
+ return false;
+ case SkPath::kLine_Verb:
+ if (pts[0] == pts[1]) {
+ continue;
+ }
+ return true;
+ case SkPath::kQuad_Verb:
+ case SkPath::kConic_Verb:
+ if (pts[0] == pts[1] && pts[0] == pts[2]) {
+ continue;
+ }
+ return true;
+ case SkPath::kCubic_Verb:
+ if (pts[0] == pts[1] && pts[0] == pts[2] && pts[0] == pts[3]) {
+ continue;
+ }
+ return true;
+ case SkPath::kClose_Verb:
+ case SkPath::kDone_Verb:
+ return false;
+ }
+ }
+ return false;
+}
+
+void SkPathStroker::lineTo(const SkPoint& currPt, const SkPath::Iter* iter) {
if (SkStrokerPriv::CapFactory(SkPaint::kButt_Cap) == fCapper
&& fPrevPt.equalsWithinTolerance(currPt, SK_ScalarNearlyZero * fInvResScale)) {
return;
}
+ if (fPrevPt == currPt && (fJoinCompleted || (iter && has_valid_tangent(iter)))) {
+ return;
+ }
SkVector normal, unitNormal;
if (!this->preJoinTo(currPt, &normal, &unitNormal, true)) {
@@ -1339,7 +1377,7 @@ void SkStroke::strokePath(const SkPath& src, SkPath* dst) const {
stroker.moveTo(pts[0]);
break;
case SkPath::kLine_Verb:
- stroker.lineTo(pts[1]);
+ stroker.lineTo(pts[1], &iter);
lastSegment = SkPath::kLine_Verb;
break;
case SkPath::kQuad_Verb:
« no previous file with comments | « gm/strokes.cpp ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698