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],SkChunkAlloc * allocator)13 SkOpSegment* SkOpContour::addCurve(SkPath::Verb verb, const SkPoint pts[4],
14         SkChunkAlloc* 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(allocator).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(allocator).addQuad(ptStorage, this);
25         } break;
26         case SkPath::kConic_Verb: {
27             SkASSERT(0);  // the original curve is a cubic, which will never reduce to a conic
28         } break;
29         case SkPath::kCubic_Verb: {
30             SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 4);
31             memcpy(ptStorage, pts, sizeof(SkPoint) * 4);
32             return appendSegment(allocator).addCubic(ptStorage, this);
33         } break;
34         default:
35             SkASSERT(0);
36     }
37     return NULL;
38 }
39 
toPath(SkPathWriter * path) const40 void SkOpContour::toPath(SkPathWriter* path) const {
41     const SkPoint& pt = fHead.pts()[0];
42     path->deferredMove(pt);
43     const SkOpSegment* segment = &fHead;
44     do {
45         segment->addCurveTo(segment->head(), segment->tail(), path, true);
46     } while ((segment = segment->next()));
47     path->close();
48 }
49 
undoneSegment(SkOpSpanBase ** startPtr,SkOpSpanBase ** endPtr)50 SkOpSegment* SkOpContour::undoneSegment(SkOpSpanBase** startPtr, SkOpSpanBase** endPtr) {
51     SkOpSegment* segment = &fHead;
52     do {
53         if (segment->done()) {
54             continue;
55         }
56         segment->undoneSpan(startPtr, endPtr);
57         return segment;
58     } while ((segment = segment->next()));
59     return NULL;
60 }
61