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