aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/pathops/SkOpContour.cpp
diff options
context:
space:
mode:
authorGravatar Cary Clark <caryclark@google.com>2016-12-14 11:56:16 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-12-14 17:26:58 +0000
commitff11428526843d3e03feb6843bd21f2d80536415 (patch)
tree686d62dbafaadd50ff59f2e60f541f429c7e170c /src/pathops/SkOpContour.cpp
parent2052c86a30dffcf124fd7beac293e7fce87bf5cb (diff)
more simplify bugs
SkOpAngle::alignmentSameSide() Shifting an edge to align it for angle sorting may move a compared edge to the opposite side. For lines that are shifted, check to see if this is so. class SkOpContourBuilder If the path contains a pair of lines that cancel, skip them as early as possible. While not strictly necessary, this optimization is cheap and makes debugging much easier. SkOpEdgeBuilder::walk() case SkPath::kCubic_Verb: If max curvature or inflections break a cubic into pieces, make sure that the pieces are large enough to process. If not, add the broken piece back to a neighbor. Correct debugging that had gone stale. Add active span debugging cache so only changes are shown. TBR=reed@google.com BUG=skia:6401 Change-Id: I766f77e4fb9b76537cf5464961addb103114f5db Reviewed-on: https://skia-review.googlesource.com/5764 Reviewed-by: Cary Clark <caryclark@google.com> Commit-Queue: Cary Clark <caryclark@google.com>
Diffstat (limited to 'src/pathops/SkOpContour.cpp')
-rw-r--r--src/pathops/SkOpContour.cpp95
1 files changed, 66 insertions, 29 deletions
diff --git a/src/pathops/SkOpContour.cpp b/src/pathops/SkOpContour.cpp
index 981bd29573..fbe9f4db4b 100644
--- a/src/pathops/SkOpContour.cpp
+++ b/src/pathops/SkOpContour.cpp
@@ -10,35 +10,6 @@
#include "SkReduceOrder.h"
#include "SkTSort.h"
-SkOpSegment* SkOpContour::addCurve(SkPath::Verb verb, const SkPoint pts[4], SkScalar weight) {
- SkChunkAlloc* allocator = this->globalState()->allocator();
- switch (verb) {
- case SkPath::kLine_Verb: {
- SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 2);
- memcpy(ptStorage, pts, sizeof(SkPoint) * 2);
- return appendSegment().addLine(ptStorage, this);
- } break;
- case SkPath::kQuad_Verb: {
- SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 3);
- memcpy(ptStorage, pts, sizeof(SkPoint) * 3);
- return appendSegment().addQuad(ptStorage, this);
- } break;
- case SkPath::kConic_Verb: {
- SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 3);
- memcpy(ptStorage, pts, sizeof(SkPoint) * 3);
- return appendSegment().addConic(ptStorage, weight, this);
- } break;
- case SkPath::kCubic_Verb: {
- SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 4);
- memcpy(ptStorage, pts, sizeof(SkPoint) * 4);
- return appendSegment().addCubic(ptStorage, this);
- } break;
- default:
- SkASSERT(0);
- }
- return nullptr;
-}
-
void SkOpContour::toPath(SkPathWriter* path) const {
const SkOpSegment* segment = &fHead;
do {
@@ -68,3 +39,69 @@ SkOpSegment* SkOpContour::undoneSegment(SkOpSpanBase** startPtr, SkOpSpanBase**
} while ((segment = segment->next()));
return nullptr;
}
+
+void SkOpContourBuilder::addConic(SkPoint pts[3], SkScalar weight) {
+ this->flush();
+ fContour->addConic(pts, weight);
+}
+
+void SkOpContourBuilder::addCubic(SkPoint pts[4]) {
+ this->flush();
+ fContour->addCubic(pts);
+}
+
+void SkOpContourBuilder::addCurve(SkPath::Verb verb, const SkPoint pts[4], SkScalar weight) {
+ if (SkPath::kLine_Verb == verb) {
+ this->addLine(pts);
+ return;
+ }
+ SkChunkAlloc* allocator = fContour->globalState()->allocator();
+ switch (verb) {
+ case SkPath::kQuad_Verb: {
+ SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 3);
+ memcpy(ptStorage, pts, sizeof(SkPoint) * 3);
+ this->addQuad(ptStorage);
+ } break;
+ case SkPath::kConic_Verb: {
+ SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 3);
+ memcpy(ptStorage, pts, sizeof(SkPoint) * 3);
+ this->addConic(ptStorage, weight);
+ } break;
+ case SkPath::kCubic_Verb: {
+ SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 4);
+ memcpy(ptStorage, pts, sizeof(SkPoint) * 4);
+ this->addCubic(ptStorage);
+ } break;
+ default:
+ SkASSERT(0);
+ }
+}
+
+void SkOpContourBuilder::addLine(const SkPoint pts[2]) {
+ // if the previous line added is the exact opposite, eliminate both
+ if (fLastIsLine) {
+ if (fLastLine[0] == pts[1] && fLastLine[1] == pts[0]) {
+ fLastIsLine = false;
+ return;
+ } else {
+ flush();
+ }
+ }
+ memcpy(fLastLine, pts, sizeof(fLastLine));
+ fLastIsLine = true;
+}
+
+void SkOpContourBuilder::addQuad(SkPoint pts[3]) {
+ this->flush();
+ fContour->addQuad(pts);
+}
+
+void SkOpContourBuilder::flush() {
+ if (!fLastIsLine)
+ return;
+ SkChunkAlloc* allocator = fContour->globalState()->allocator();
+ SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 2);
+ memcpy(ptStorage, fLastLine, sizeof(fLastLine));
+ (void) fContour->addLine(ptStorage);
+ fLastIsLine = false;
+}