blob: fbe9f4db4b8d69eea4821757b0b8b47f7c50a1fb [file] [log] [blame]
caryclark@google.com07393ca2013-04-08 11:47:37 +00001/*
2* Copyright 2013 Google Inc.
3*
4* Use of this source code is governed by a BSD-style license that can be
5* found in the LICENSE file.
6*/
caryclark@google.com07393ca2013-04-08 11:47:37 +00007#include "SkOpContour.h"
caryclark54359292015-03-26 07:52:43 -07008#include "SkOpTAllocator.h"
caryclark@google.com07393ca2013-04-08 11:47:37 +00009#include "SkPathWriter.h"
caryclark54359292015-03-26 07:52:43 -070010#include "SkReduceOrder.h"
commit-bot@chromium.orgb76d3b62013-04-22 19:55:19 +000011#include "SkTSort.h"
caryclark@google.com07393ca2013-04-08 11:47:37 +000012
caryclark@google.com07393ca2013-04-08 11:47:37 +000013void SkOpContour::toPath(SkPathWriter* path) const {
caryclark54359292015-03-26 07:52:43 -070014 const SkOpSegment* segment = &fHead;
15 do {
caryclarkef784fb2015-10-30 12:03:06 -070016 SkAssertResult(segment->addCurveTo(segment->head(), segment->tail(), path));
caryclark54359292015-03-26 07:52:43 -070017 } while ((segment = segment->next()));
caryclarkeed356d2016-09-14 07:18:20 -070018 path->finishContour();
19 path->assemble();
caryclark@google.com07393ca2013-04-08 11:47:37 +000020}
21
caryclark5b5ddd72015-05-18 05:12:56 -070022void SkOpContour::toReversePath(SkPathWriter* path) const {
caryclark5b5ddd72015-05-18 05:12:56 -070023 const SkOpSegment* segment = fTail;
24 do {
caryclarkef784fb2015-10-30 12:03:06 -070025 SkAssertResult(segment->addCurveTo(segment->tail(), segment->head(), path));
caryclark5b5ddd72015-05-18 05:12:56 -070026 } while ((segment = segment->prev()));
caryclarkeed356d2016-09-14 07:18:20 -070027 path->finishContour();
28 path->assemble();
caryclark5b5ddd72015-05-18 05:12:56 -070029}
30
caryclark54359292015-03-26 07:52:43 -070031SkOpSegment* SkOpContour::undoneSegment(SkOpSpanBase** startPtr, SkOpSpanBase** endPtr) {
32 SkOpSegment* segment = &fHead;
33 do {
34 if (segment->done()) {
caryclark@google.com07393ca2013-04-08 11:47:37 +000035 continue;
36 }
caryclark54359292015-03-26 07:52:43 -070037 segment->undoneSpan(startPtr, endPtr);
38 return segment;
39 } while ((segment = segment->next()));
halcanary96fcdcc2015-08-27 07:41:13 -070040 return nullptr;
caryclark@google.com07393ca2013-04-08 11:47:37 +000041}
Cary Clarkff114282016-12-14 11:56:16 -050042
43void SkOpContourBuilder::addConic(SkPoint pts[3], SkScalar weight) {
44 this->flush();
45 fContour->addConic(pts, weight);
46}
47
48void SkOpContourBuilder::addCubic(SkPoint pts[4]) {
49 this->flush();
50 fContour->addCubic(pts);
51}
52
53void SkOpContourBuilder::addCurve(SkPath::Verb verb, const SkPoint pts[4], SkScalar weight) {
54 if (SkPath::kLine_Verb == verb) {
55 this->addLine(pts);
56 return;
57 }
58 SkChunkAlloc* allocator = fContour->globalState()->allocator();
59 switch (verb) {
60 case SkPath::kQuad_Verb: {
61 SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 3);
62 memcpy(ptStorage, pts, sizeof(SkPoint) * 3);
63 this->addQuad(ptStorage);
64 } break;
65 case SkPath::kConic_Verb: {
66 SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 3);
67 memcpy(ptStorage, pts, sizeof(SkPoint) * 3);
68 this->addConic(ptStorage, weight);
69 } break;
70 case SkPath::kCubic_Verb: {
71 SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 4);
72 memcpy(ptStorage, pts, sizeof(SkPoint) * 4);
73 this->addCubic(ptStorage);
74 } break;
75 default:
76 SkASSERT(0);
77 }
78}
79
80void SkOpContourBuilder::addLine(const SkPoint pts[2]) {
81 // if the previous line added is the exact opposite, eliminate both
82 if (fLastIsLine) {
83 if (fLastLine[0] == pts[1] && fLastLine[1] == pts[0]) {
84 fLastIsLine = false;
85 return;
86 } else {
87 flush();
88 }
89 }
90 memcpy(fLastLine, pts, sizeof(fLastLine));
91 fLastIsLine = true;
92}
93
94void SkOpContourBuilder::addQuad(SkPoint pts[3]) {
95 this->flush();
96 fContour->addQuad(pts);
97}
98
99void SkOpContourBuilder::flush() {
100 if (!fLastIsLine)
101 return;
102 SkChunkAlloc* allocator = fContour->globalState()->allocator();
103 SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 2);
104 memcpy(ptStorage, fLastLine, sizeof(fLastLine));
105 (void) fContour->addLine(ptStorage);
106 fLastIsLine = false;
107}