• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
toPath(SkPathWriter * path) const13 void SkOpContour::toPath(SkPathWriter* path) const {
14     if (!this->count()) {
15         return;
16     }
17     const SkOpSegment* segment = &fHead;
18     do {
19         SkAssertResult(segment->addCurveTo(segment->head(), segment->tail(), path));
20     } while ((segment = segment->next()));
21     path->finishContour();
22     path->assemble();
23 }
24 
toReversePath(SkPathWriter * path) const25 void SkOpContour::toReversePath(SkPathWriter* path) const {
26     const SkOpSegment* segment = fTail;
27     do {
28         SkAssertResult(segment->addCurveTo(segment->tail(), segment->head(), path));
29     } while ((segment = segment->prev()));
30     path->finishContour();
31     path->assemble();
32 }
33 
undoneSpan()34 SkOpSpan* SkOpContour::undoneSpan() {
35     SkOpSegment* testSegment = &fHead;
36     bool allDone = true;
37     do {
38         if (testSegment->done()) {
39             continue;
40         }
41         allDone = false;
42         return testSegment->undoneSpan();
43     } while ((testSegment = testSegment->next()));
44     if (allDone) {
45       fDone = true;
46     }
47     return nullptr;
48 }
49 
addConic(SkPoint pts[3],SkScalar weight)50 void SkOpContourBuilder::addConic(SkPoint pts[3], SkScalar weight) {
51     this->flush();
52     fContour->addConic(pts, weight);
53 }
54 
addCubic(SkPoint pts[4])55 void SkOpContourBuilder::addCubic(SkPoint pts[4]) {
56     this->flush();
57     fContour->addCubic(pts);
58 }
59 
addCurve(SkPath::Verb verb,const SkPoint pts[4],SkScalar weight)60 void SkOpContourBuilder::addCurve(SkPath::Verb verb, const SkPoint pts[4], SkScalar weight) {
61     if (SkPath::kLine_Verb == verb) {
62         this->addLine(pts);
63         return;
64     }
65     SkArenaAlloc* allocator = fContour->globalState()->allocator();
66     switch (verb) {
67         case SkPath::kQuad_Verb: {
68             SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 3);
69             memcpy(ptStorage, pts, sizeof(SkPoint) * 3);
70             this->addQuad(ptStorage);
71         } break;
72         case SkPath::kConic_Verb: {
73             SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 3);
74             memcpy(ptStorage, pts, sizeof(SkPoint) * 3);
75             this->addConic(ptStorage, weight);
76         } break;
77         case SkPath::kCubic_Verb: {
78             SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 4);
79             memcpy(ptStorage, pts, sizeof(SkPoint) * 4);
80             this->addCubic(ptStorage);
81         } break;
82         default:
83             SkASSERT(0);
84     }
85 }
86 
addLine(const SkPoint pts[2])87 void SkOpContourBuilder::addLine(const SkPoint pts[2]) {
88     // if the previous line added is the exact opposite, eliminate both
89     if (fLastIsLine) {
90         if (fLastLine[0] == pts[1] && fLastLine[1] == pts[0]) {
91             fLastIsLine = false;
92             return;
93         } else {
94             flush();
95         }
96     }
97     memcpy(fLastLine, pts, sizeof(fLastLine));
98     fLastIsLine = true;
99 }
100 
addQuad(SkPoint pts[3])101 void SkOpContourBuilder::addQuad(SkPoint pts[3]) {
102     this->flush();
103     fContour->addQuad(pts);
104 }
105 
flush()106 void SkOpContourBuilder::flush() {
107     if (!fLastIsLine)
108         return;
109     SkArenaAlloc* allocator = fContour->globalState()->allocator();
110     SkPoint* ptStorage = SkOpTAllocator<SkPoint>::AllocateArray(allocator, 2);
111     memcpy(ptStorage, fLastLine, sizeof(fLastLine));
112     (void) fContour->addLine(ptStorage);
113     fLastIsLine = false;
114 }
115