diff options
author | Cary Clark <caryclark@google.com> | 2016-12-14 11:56:16 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-12-14 17:26:58 +0000 |
commit | ff11428526843d3e03feb6843bd21f2d80536415 (patch) | |
tree | 686d62dbafaadd50ff59f2e60f541f429c7e170c /src/pathops/SkOpContour.cpp | |
parent | 2052c86a30dffcf124fd7beac293e7fce87bf5cb (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.cpp | 95 |
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; +} |