diff options
Diffstat (limited to 'gfx/skia/skia/src/pathops/SkOpContour.cpp')
-rw-r--r-- | gfx/skia/skia/src/pathops/SkOpContour.cpp | 109 |
1 files changed, 109 insertions, 0 deletions
diff --git a/gfx/skia/skia/src/pathops/SkOpContour.cpp b/gfx/skia/skia/src/pathops/SkOpContour.cpp new file mode 100644 index 0000000000..508c324725 --- /dev/null +++ b/gfx/skia/skia/src/pathops/SkOpContour.cpp @@ -0,0 +1,109 @@ +/* +* Copyright 2013 Google Inc. +* +* Use of this source code is governed by a BSD-style license that can be +* found in the LICENSE file. +*/ +#include "src/core/SkTSort.h" +#include "src/pathops/SkOpContour.h" +#include "src/pathops/SkPathWriter.h" +#include "src/pathops/SkReduceOrder.h" + +void SkOpContour::toPath(SkPathWriter* path) const { + if (!this->count()) { + return; + } + const SkOpSegment* segment = &fHead; + do { + SkAssertResult(segment->addCurveTo(segment->head(), segment->tail(), path)); + } while ((segment = segment->next())); + path->finishContour(); + path->assemble(); +} + +void SkOpContour::toReversePath(SkPathWriter* path) const { + const SkOpSegment* segment = fTail; + do { + SkAssertResult(segment->addCurveTo(segment->tail(), segment->head(), path)); + } while ((segment = segment->prev())); + path->finishContour(); + path->assemble(); +} + +SkOpSpan* SkOpContour::undoneSpan() { + SkOpSegment* testSegment = &fHead; + do { + if (testSegment->done()) { + continue; + } + return testSegment->undoneSpan(); + } while ((testSegment = testSegment->next())); + fDone = true; + 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; + } + SkArenaAlloc* allocator = fContour->globalState()->allocator(); + switch (verb) { + case SkPath::kQuad_Verb: { + SkPoint* ptStorage = allocator->makeArrayDefault<SkPoint>(3); + memcpy(ptStorage, pts, sizeof(SkPoint) * 3); + this->addQuad(ptStorage); + } break; + case SkPath::kConic_Verb: { + SkPoint* ptStorage = allocator->makeArrayDefault<SkPoint>(3); + memcpy(ptStorage, pts, sizeof(SkPoint) * 3); + this->addConic(ptStorage, weight); + } break; + case SkPath::kCubic_Verb: { + SkPoint* ptStorage = allocator->makeArrayDefault<SkPoint>(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; + SkArenaAlloc* allocator = fContour->globalState()->allocator(); + SkPoint* ptStorage = allocator->makeArrayDefault<SkPoint>(2); + memcpy(ptStorage, fLastLine, sizeof(fLastLine)); + (void) fContour->addLine(ptStorage); + fLastIsLine = false; +} |