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