1 /*
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 */
7 #include "SkOpContour.h"
8 #include "SkOpTAllocator.h"
9 #include "SkPathWriter.h"
10 #include "SkReduceOrder.h"
11 #include "SkTSort.h"
12 
addCurve(SkPath::Verb verb,const SkPoint pts[4],SkScalar weight)13 SkOpSegment* SkOpContour::addCurve(SkPath::Verb verb, const SkPoint pts[4], SkScalar weight) {
14     SkChunkAlloc* allocator = this->globalState()->allocator();
15     switch (verb) {
16         case SkPath::kLine_Verb: {
17             SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 2);
18             memcpy(ptStorage, pts, sizeof(SkPoint) * 2);
19             return appendSegment().addLine(ptStorage, this);
20         } break;
21         case SkPath::kQuad_Verb: {
22             SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 3);
23             memcpy(ptStorage, pts, sizeof(SkPoint) * 3);
24             return appendSegment().addQuad(ptStorage, this);
25         } break;
26         case SkPath::kConic_Verb: {
27             SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 3);
28             memcpy(ptStorage, pts, sizeof(SkPoint) * 3);
29             return appendSegment().addConic(ptStorage, weight, this);
30         } break;
31         case SkPath::kCubic_Verb: {
32             SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 4);
33             memcpy(ptStorage, pts, sizeof(SkPoint) * 4);
34             return appendSegment().addCubic(ptStorage, this);
35         } break;
36         default:
37             SkASSERT(0);
38     }
39     return nullptr;
40 }
41 
toPath(SkPathWriter * path) const42 void SkOpContour::toPath(SkPathWriter* path) const {
43     const SkOpSegment* segment = &fHead;
44     do {
45         SkAssertResult(segment->addCurveTo(segment->head(), segment->tail(), path));
46     } while ((segment = segment->next()));
47     path->finishContour();
48     path->assemble();
49 }
50 
toReversePath(SkPathWriter * path) const51 void SkOpContour::toReversePath(SkPathWriter* path) const {
52     const SkOpSegment* segment = fTail;
53     do {
54         SkAssertResult(segment->addCurveTo(segment->tail(), segment->head(), path));
55     } while ((segment = segment->prev()));
56     path->finishContour();
57     path->assemble();
58 }
59 
undoneSegment(SkOpSpanBase ** startPtr,SkOpSpanBase ** endPtr)60 SkOpSegment* SkOpContour::undoneSegment(SkOpSpanBase** startPtr, SkOpSpanBase** endPtr) {
61     SkOpSegment* segment = &fHead;
62     do {
63         if (segment->done()) {
64             continue;
65         }
66         segment->undoneSpan(startPtr, endPtr);
67         return segment;
68     } while ((segment = segment->next()));
69     return nullptr;
70 }
71