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