1
//========================================================================
5
//========================================================================
10
#pragma implementation
15
#include "SplashErrorCodes.h"
16
#include "SplashPath.h"
18
//------------------------------------------------------------------------
20
//------------------------------------------------------------------------
22
// A path can be in three possible states:
24
// 1. no current point -- zero or more finished subpaths
25
// [curSubpath == length]
27
// 2. one point in subpath
28
// [curSubpath == length - 1]
30
// 3. open subpath with two or more points
31
// [curSubpath < length - 1]
33
SplashPath::SplashPath() {
39
hintsLength = hintsSize = 0;
42
SplashPath::SplashPath(SplashPath *path) {
43
length = path->length;
45
pts = (SplashPathPoint *)gmallocn(size, sizeof(SplashPathPoint));
46
flags = (Guchar *)gmallocn(size, sizeof(Guchar));
47
memcpy(pts, path->pts, length * sizeof(SplashPathPoint));
48
memcpy(flags, path->flags, length * sizeof(Guchar));
49
curSubpath = path->curSubpath;
51
hintsLength = hintsSize = path->hintsLength;
52
hints = (SplashPathHint *)gmallocn(hintsSize, sizeof(SplashPathHint));
53
memcpy(hints, path->hints, hintsLength * sizeof(SplashPathHint));
59
SplashPath::~SplashPath() {
65
// Add space for <nPts> more points.
66
void SplashPath::grow(int nPts) {
67
if (length + nPts > size) {
71
while (size < length + nPts) {
74
pts = (SplashPathPoint *)greallocn(pts, size, sizeof(SplashPathPoint));
75
flags = (Guchar *)greallocn(flags, size, sizeof(Guchar));
79
void SplashPath::append(SplashPath *path) {
82
curSubpath = length + path->curSubpath;
84
for (i = 0; i < path->length; ++i) {
85
pts[length] = path->pts[i];
86
flags[length] = path->flags[i];
91
SplashError SplashPath::moveTo(SplashCoord x, SplashCoord y) {
92
if (onePointSubpath()) {
93
return splashErrBogusPath;
98
flags[length] = splashPathFirst | splashPathLast;
99
curSubpath = length++;
103
SplashError SplashPath::lineTo(SplashCoord x, SplashCoord y) {
104
if (noCurrentPoint()) {
105
return splashErrNoCurPt;
107
flags[length-1] &= ~splashPathLast;
111
flags[length] = splashPathLast;
116
SplashError SplashPath::curveTo(SplashCoord x1, SplashCoord y1,
117
SplashCoord x2, SplashCoord y2,
118
SplashCoord x3, SplashCoord y3) {
119
if (noCurrentPoint()) {
120
return splashErrNoCurPt;
122
flags[length-1] &= ~splashPathLast;
126
flags[length] = splashPathCurve;
130
flags[length] = splashPathCurve;
134
flags[length] = splashPathLast;
139
SplashError SplashPath::close() {
140
if (noCurrentPoint()) {
141
return splashErrNoCurPt;
143
if (curSubpath == length - 1 ||
144
pts[length - 1].x != pts[curSubpath].x ||
145
pts[length - 1].y != pts[curSubpath].y) {
146
lineTo(pts[curSubpath].x, pts[curSubpath].y);
148
flags[curSubpath] |= splashPathClosed;
149
flags[length - 1] |= splashPathClosed;
154
void SplashPath::addStrokeAdjustHint(int ctrl0, int ctrl1,
155
int firstPt, int lastPt) {
156
if (hintsLength == hintsSize) {
157
hintsSize = hintsLength ? 2 * hintsLength : 8;
158
hints = (SplashPathHint *)greallocn(hints, hintsSize,
159
sizeof(SplashPathHint));
161
hints[hintsLength].ctrl0 = ctrl0;
162
hints[hintsLength].ctrl1 = ctrl1;
163
hints[hintsLength].firstPt = firstPt;
164
hints[hintsLength].lastPt = lastPt;
168
void SplashPath::offset(SplashCoord dx, SplashCoord dy) {
171
for (i = 0; i < length; ++i) {
177
GBool SplashPath::getCurPt(SplashCoord *x, SplashCoord *y) {
178
if (noCurrentPoint()) {
181
*x = pts[length - 1].x;
182
*y = pts[length - 1].y;