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

Unified Diff: src/pathops/SkPathOpsSimplify.cpp

Issue 2128633003: pathops coincidence and security rewrite (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: require resulting t to be between 0 and 1 Created 4 years, 5 months 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
Index: src/pathops/SkPathOpsSimplify.cpp
diff --git a/src/pathops/SkPathOpsSimplify.cpp b/src/pathops/SkPathOpsSimplify.cpp
index fa1003054eb76678582968626837b7b270d366bf..dcd75f166641b90f6c3b2f2fce9088d685cf9d57 100644
--- a/src/pathops/SkPathOpsSimplify.cpp
+++ b/src/pathops/SkPathOpsSimplify.cpp
@@ -10,8 +10,7 @@
#include "SkPathOpsCommon.h"
#include "SkPathWriter.h"
-static bool bridgeWinding(SkOpContourHead* contourList, SkPathWriter* simple,
- SkChunkAlloc* allocator, bool* closable) {
+static bool bridgeWinding(SkOpContourHead* contourList, SkPathWriter* simple, bool* closable) {
bool unsortable = false;
do {
SkOpSpan* span = FindSortableTop(contourList);
@@ -40,11 +39,9 @@ static bool bridgeWinding(SkOpContourHead* contourList, SkPathWriter* simple,
if (!current->addCurveTo(start, end, simple)) {
return false;
}
- #if DEBUG_ACTIVE_SPANS
if (!simple->isClosed()) {
- DebugShowActiveSpans(contourList);
+ SkPathOpsDebug::ShowActiveSpans(contourList);
}
- #endif
}
break;
}
@@ -86,9 +83,7 @@ static bool bridgeWinding(SkOpContourHead* contourList, SkPathWriter* simple,
}
}
current = FindChase(&chase, &start, &end);
- #if DEBUG_ACTIVE_SPANS
- DebugShowActiveSpans(contourList);
- #endif
+ SkPathOpsDebug::ShowActiveSpans(contourList);
if (!current) {
break;
}
@@ -99,8 +94,7 @@ static bool bridgeWinding(SkOpContourHead* contourList, SkPathWriter* simple,
}
// returns true if all edges were processed
-static bool bridgeXor(SkOpContourHead* contourList, SkPathWriter* simple,
- SkChunkAlloc* allocator, bool* closable) {
+static bool bridgeXor(SkOpContourHead* contourList, SkPathWriter* simple, bool* closable) {
SkOpSegment* current;
SkOpSpanBase* start;
SkOpSpanBase* end;
@@ -108,11 +102,9 @@ static bool bridgeXor(SkOpContourHead* contourList, SkPathWriter* simple,
*closable = true;
while ((current = FindUndone(contourList, &start, &end))) {
do {
- #if DEBUG_ACTIVE_SPANS
if (!unsortable && current->done()) {
- DebugShowActiveSpans(contourList);
+ SkPathOpsDebug::ShowActiveSpans(contourList);
}
- #endif
SkASSERT(unsortable || !current->done());
SkOpSpanBase* nextStart = start;
SkOpSpanBase* nextEnd = end;
@@ -124,11 +116,9 @@ static bool bridgeXor(SkOpContourHead* contourList, SkPathWriter* simple,
if (!current->addCurveTo(start, end, simple)) {
return false;
}
- #if DEBUG_ACTIVE_SPANS
if (!simple->isClosed()) {
- DebugShowActiveSpans(contourList);
+ SkPathOpsDebug::ShowActiveSpans(contourList);
}
- #endif
}
break;
}
@@ -156,16 +146,14 @@ static bool bridgeXor(SkOpContourHead* contourList, SkPathWriter* simple,
*closable = false;
}
simple->close();
- #if DEBUG_ACTIVE_SPANS
- DebugShowActiveSpans(contourList);
- #endif
+ SkPathOpsDebug::ShowActiveSpans(contourList);
}
return true;
}
// FIXME : add this as a member of SkPath
-bool Simplify(const SkPath& path, SkPath* result) {
- SkChunkAlloc allocator(4096); // FIXME: constant-ize, tune
+bool SimplifyDebug(const SkPath& path, SkPath* result
+ SkDEBUGPARAMS(bool skipAssert) SkDEBUGPARAMS(const char* testName)) {
// returns 1 for evenodd, -1 for winding, regardless of inverse-ness
SkPath::FillType fillType = path.isInverseFillType() ? SkPath::kInverseEvenOdd_FillType
: SkPath::kEvenOdd_FillType;
@@ -177,16 +165,26 @@ bool Simplify(const SkPath& path, SkPath* result) {
return true;
}
// turn path into list of segments
- SkOpCoincidence coincidence;
+ SkChunkAlloc allocator(4096); // FIXME: constant-ize, tune
SkOpContour contour;
SkOpContourHead* contourList = static_cast<SkOpContourHead*>(&contour);
- SkOpGlobalState globalState(&coincidence, contourList SkDEBUGPARAMS(false)
- SkDEBUGPARAMS(nullptr));
+ SkOpGlobalState globalState(contourList, &allocator
+ SkDEBUGPARAMS(skipAssert) SkDEBUGPARAMS(testName));
+ SkOpCoincidence coincidence(&globalState);
+ SkScalar scaleFactor = ScaleFactor(path);
+ SkPath scaledPath;
+ const SkPath* workingPath;
+ if (scaleFactor > SK_Scalar1) {
+ ScalePath(path, 1.f / scaleFactor, &scaledPath);
+ workingPath = &scaledPath;
+ } else {
+ workingPath = &path;
+ }
#if DEBUG_SORT
SkPathOpsDebug::gSortCount = SkPathOpsDebug::gSortCountDefault;
#endif
- SkOpEdgeBuilder builder(path, &contour, &allocator, &globalState);
- if (!builder.finish(&allocator)) {
+ SkOpEdgeBuilder builder(*workingPath, &contour, &globalState);
+ if (!builder.finish()) {
return false;
}
#if DEBUG_DUMP_SEGMENTS
@@ -201,13 +199,13 @@ bool Simplify(const SkPath& path, SkPath* result) {
SkOpContour* current = contourList;
do {
SkOpContour* next = current;
- while (AddIntersectTs(current, next, &coincidence, &allocator)
+ while (AddIntersectTs(current, next, &coincidence)
&& (next = next->next()));
} while ((current = current->next()));
#if DEBUG_VALIDATE
globalState.setPhase(SkOpGlobalState::kWalking);
#endif
- if (!HandleCoincidence(contourList, &coincidence, &allocator)) {
+ if (!HandleCoincidence(contourList, &coincidence)) {
return false;
}
#if DEBUG_DUMP_ALIGNMENT
@@ -219,8 +217,8 @@ bool Simplify(const SkPath& path, SkPath* result) {
SkPathWriter wrapper(*result);
bool closable SK_INIT_TO_AVOID_WARNING;
if (builder.xorMask() == kWinding_PathOpsMask
- ? !bridgeWinding(contourList, &wrapper, &allocator, &closable)
- : !bridgeXor(contourList, &wrapper, &allocator, &closable)) {
+ ? !bridgeWinding(contourList, &wrapper, &closable)
+ : !bridgeXor(contourList, &wrapper, &closable)) {
return false;
}
if (!closable)
@@ -232,6 +230,12 @@ bool Simplify(const SkPath& path, SkPath* result) {
*result = *assembled.nativePath();
result->setFillType(fillType);
}
+ if (scaleFactor > 1) {
+ ScalePath(*result, scaleFactor, result);
+ }
return true;
}
+bool Simplify(const SkPath& path, SkPath* result) {
+ return SimplifyDebug(path, result SkDEBUGPARAMS(true) SkDEBUGPARAMS(nullptr));
+}

Powered by Google App Engine
This is Rietveld 408576698