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() {
40 SplashPath::SplashPath(SplashPath *path) {
41 length = path->length;
43 pts = (SplashPathPoint *)gmalloc(size * sizeof(SplashPathPoint));
44 flags = (Guchar *)gmalloc(size * sizeof(Guchar));
45 memcpy(pts, path->pts, length * sizeof(SplashPathPoint));
46 memcpy(flags, path->flags, length * sizeof(Guchar));
47 curSubpath = path->curSubpath;
50 SplashPath::~SplashPath() {
55 // Add space for <nPts> more points.
56 void SplashPath::grow(int nPts) {
57 if (length + nPts > size) {
61 while (size < length + nPts) {
64 pts = (SplashPathPoint *)grealloc(pts, size * sizeof(SplashPathPoint));
65 flags = (Guchar *)grealloc(flags, size * sizeof(Guchar));
69 void SplashPath::append(SplashPath *path) {
72 curSubpath = length + path->curSubpath;
74 for (i = 0; i < path->length; ++i) {
75 pts[length] = path->pts[i];
76 flags[length] = path->flags[i];
81 SplashError SplashPath::moveTo(SplashCoord x, SplashCoord y) {
82 if (onePointSubpath()) {
83 return splashErrBogusPath;
88 flags[length] = splashPathFirst | splashPathLast;
89 curSubpath = length++;
93 SplashError SplashPath::lineTo(SplashCoord x, SplashCoord y) {
94 if (noCurrentPoint()) {
95 return splashErrNoCurPt;
97 flags[length-1] &= ~splashPathLast;
101 flags[length] = splashPathLast;
106 SplashError SplashPath::curveTo(SplashCoord x1, SplashCoord y1,
107 SplashCoord x2, SplashCoord y2,
108 SplashCoord x3, SplashCoord y3) {
109 if (noCurrentPoint()) {
110 return splashErrNoCurPt;
112 flags[length-1] &= ~splashPathLast;
116 flags[length] = splashPathCurve;
120 flags[length] = splashPathCurve;
124 flags[length] = splashPathLast;
129 SplashError SplashPath::arcCWTo(SplashCoord x1, SplashCoord y1,
130 SplashCoord xc, SplashCoord yc) {
131 if (noCurrentPoint()) {
132 return splashErrNoCurPt;
134 flags[length-1] &= ~splashPathLast;
138 flags[length] = splashPathArcCW;
142 flags[length] = splashPathLast;
147 SplashError SplashPath::close() {
148 if (noCurrentPoint()) {
149 return splashErrNoCurPt;
151 if (pts[length - 1].x != pts[curSubpath].x ||
152 pts[length - 1].y != pts[curSubpath].y) {
153 lineTo(pts[curSubpath].x, pts[curSubpath].y);
155 flags[curSubpath] |= splashPathClosed;
156 flags[length - 1] |= splashPathClosed;
161 void SplashPath::offset(SplashCoord dx, SplashCoord dy) {
164 for (i = 0; i < length; ++i) {
170 GBool SplashPath::getCurPt(SplashCoord *x, SplashCoord *y) {
171 if (noCurrentPoint()) {
174 *x = pts[length - 1].x;
175 *y = pts[length - 1].y;