blob: 98467c558ceb645db7fc77f9f2ef515d3c3143f2 [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 {
Cary Clark0eb6ed42016-12-16 16:31:11 -050014 if (!this->count()) {
15 return;
16 }
caryclark54359292015-03-26 07:52:43 -070017 const SkOpSegment* segment = &fHead;
18 do {
caryclarkef784fb2015-10-30 12:03:06 -070019 SkAssertResult(segment->addCurveTo(segment->head(), segment->tail(), path));
caryclark54359292015-03-26 07:52:43 -070020 } while ((segment = segment->next()));
caryclarkeed356d2016-09-14 07:18:20 -070021 path->finishContour();
22 path->assemble();
caryclark@google.com07393ca2013-04-08 11:47:37 +000023}
24
caryclark5b5ddd72015-05-18 05:12:56 -070025void SkOpContour::toReversePath(SkPathWriter* path) const {
caryclark5b5ddd72015-05-18 05:12:56 -070026 const SkOpSegment* segment = fTail;
27 do {
caryclarkef784fb2015-10-30 12:03:06 -070028 SkAssertResult(segment->addCurveTo(segment->tail(), segment->head(), path));
caryclark5b5ddd72015-05-18 05:12:56 -070029 } while ((segment = segment->prev()));
caryclarkeed356d2016-09-14 07:18:20 -070030 path->finishContour();
31 path->assemble();
caryclark5b5ddd72015-05-18 05:12:56 -070032}
33
caryclark54359292015-03-26 07:52:43 -070034SkOpSegment* SkOpContour::undoneSegment(SkOpSpanBase** startPtr, SkOpSpanBase** endPtr) {
35 SkOpSegment* segment = &fHead;
36 do {
37 if (segment->done()) {
caryclark@google.com07393ca2013-04-08 11:47:37 +000038 continue;
39 }
caryclark54359292015-03-26 07:52:43 -070040 segment->undoneSpan(startPtr, endPtr);
41 return segment;
42 } while ((segment = segment->next()));
halcanary96fcdcc2015-08-27 07:41:13 -070043 return nullptr;
caryclark@google.com07393ca2013-04-08 11:47:37 +000044}
Cary Clarkff114282016-12-14 11:56:16 -050045
46void SkOpContourBuilder::addConic(SkPoint pts[3], SkScalar weight) {
47 this->flush();
48 fContour->addConic(pts, weight);
49}
50
51void SkOpContourBuilder::addCubic(SkPoint pts[4]) {
52 this->flush();
53 fContour->addCubic(pts);
54}
55
56void SkOpContourBuilder::addCurve(SkPath::Verb verb, const SkPoint pts[4], SkScalar weight) {
57 if (SkPath::kLine_Verb == verb) {
58 this->addLine(pts);
59 return;
60 }
61 SkChunkAlloc* allocator = fContour->globalState()->allocator();
62 switch (verb) {
63 case SkPath::kQuad_Verb: {
64 SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 3);
65 memcpy(ptStorage, pts, sizeof(SkPoint) * 3);
66 this->addQuad(ptStorage);
67 } break;
68 case SkPath::kConic_Verb: {
69 SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 3);
70 memcpy(ptStorage, pts, sizeof(SkPoint) * 3);
71 this->addConic(ptStorage, weight);
72 } break;
73 case SkPath::kCubic_Verb: {
74 SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 4);
75 memcpy(ptStorage, pts, sizeof(SkPoint) * 4);
76 this->addCubic(ptStorage);
77 } break;
78 default:
79 SkASSERT(0);
80 }
81}
82
83void SkOpContourBuilder::addLine(const SkPoint pts[2]) {
84 // if the previous line added is the exact opposite, eliminate both
85 if (fLastIsLine) {
86 if (fLastLine[0] == pts[1] && fLastLine[1] == pts[0]) {
87 fLastIsLine = false;
88 return;
89 } else {
90 flush();
91 }
92 }
93 memcpy(fLastLine, pts, sizeof(fLastLine));
94 fLastIsLine = true;
95}
96
97void SkOpContourBuilder::addQuad(SkPoint pts[3]) {
98 this->flush();
99 fContour->addQuad(pts);
100}
101
102void SkOpContourBuilder::flush() {
103 if (!fLastIsLine)
104 return;
105 SkChunkAlloc* allocator = fContour->globalState()->allocator();
106 SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 2);
107 memcpy(ptStorage, fLastLine, sizeof(fLastLine));
108 (void) fContour->addLine(ptStorage);
109 fLastIsLine = false;
110}