sync with trunk
[luatex.git] / source / libs / poppler / poppler-0.33.0 / splash / SplashPath.cc
blobbc4ccd524a49c1003098110ec1eea93c7e79451d
1 //========================================================================
2 //
3 // SplashPath.cc
4 //
5 //========================================================================
7 #include <config.h>
9 #ifdef USE_GCC_PRAGMAS
10 #pragma implementation
11 #endif
13 #include <string.h>
14 #include "goo/gmem.h"
15 #include "SplashErrorCodes.h"
16 #include "SplashPath.h"
18 //------------------------------------------------------------------------
19 // SplashPath
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() {
34 pts = NULL;
35 flags = NULL;
36 length = size = 0;
37 curSubpath = 0;
38 hints = NULL;
39 hintsLength = hintsSize = 0;
42 SplashPath::SplashPath(SplashPath *path) {
43 length = path->length;
44 size = path->size;
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;
50 if (path->hints) {
51 hintsLength = hintsSize = path->hintsLength;
52 hints = (SplashPathHint *)gmallocn(hintsSize, sizeof(SplashPathHint));
53 memcpy(hints, path->hints, hintsLength * sizeof(SplashPathHint));
54 } else {
55 hints = NULL;
59 SplashPath::~SplashPath() {
60 gfree(pts);
61 gfree(flags);
62 gfree(hints);
65 // Add space for <nPts> more points.
66 void SplashPath::grow(int nPts) {
67 if (length + nPts > size) {
68 if (size == 0) {
69 size = 32;
71 while (size < length + nPts) {
72 size *= 2;
74 pts = (SplashPathPoint *)greallocn(pts, size, sizeof(SplashPathPoint));
75 flags = (Guchar *)greallocn(flags, size, sizeof(Guchar));
79 void SplashPath::append(SplashPath *path) {
80 int i;
82 curSubpath = length + path->curSubpath;
83 grow(path->length);
84 for (i = 0; i < path->length; ++i) {
85 pts[length] = path->pts[i];
86 flags[length] = path->flags[i];
87 ++length;
91 SplashError SplashPath::moveTo(SplashCoord x, SplashCoord y) {
92 if (onePointSubpath()) {
93 return splashErrBogusPath;
95 grow(1);
96 pts[length].x = x;
97 pts[length].y = y;
98 flags[length] = splashPathFirst | splashPathLast;
99 curSubpath = length++;
100 return splashOk;
103 SplashError SplashPath::lineTo(SplashCoord x, SplashCoord y) {
104 if (noCurrentPoint()) {
105 return splashErrNoCurPt;
107 flags[length-1] &= ~splashPathLast;
108 grow(1);
109 pts[length].x = x;
110 pts[length].y = y;
111 flags[length] = splashPathLast;
112 ++length;
113 return splashOk;
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;
123 grow(3);
124 pts[length].x = x1;
125 pts[length].y = y1;
126 flags[length] = splashPathCurve;
127 ++length;
128 pts[length].x = x2;
129 pts[length].y = y2;
130 flags[length] = splashPathCurve;
131 ++length;
132 pts[length].x = x3;
133 pts[length].y = y3;
134 flags[length] = splashPathLast;
135 ++length;
136 return splashOk;
139 SplashError SplashPath::close(GBool force) {
140 if (noCurrentPoint()) {
141 return splashErrNoCurPt;
143 if (force ||
144 curSubpath == length - 1 ||
145 pts[length - 1].x != pts[curSubpath].x ||
146 pts[length - 1].y != pts[curSubpath].y) {
147 lineTo(pts[curSubpath].x, pts[curSubpath].y);
149 flags[curSubpath] |= splashPathClosed;
150 flags[length - 1] |= splashPathClosed;
151 curSubpath = length;
152 return splashOk;
155 void SplashPath::addStrokeAdjustHint(int ctrl0, int ctrl1,
156 int firstPt, int lastPt) {
157 if (hintsLength == hintsSize) {
158 hintsSize = hintsLength ? 2 * hintsLength : 8;
159 hints = (SplashPathHint *)greallocn(hints, hintsSize,
160 sizeof(SplashPathHint));
162 hints[hintsLength].ctrl0 = ctrl0;
163 hints[hintsLength].ctrl1 = ctrl1;
164 hints[hintsLength].firstPt = firstPt;
165 hints[hintsLength].lastPt = lastPt;
166 ++hintsLength;
169 void SplashPath::offset(SplashCoord dx, SplashCoord dy) {
170 int i;
172 for (i = 0; i < length; ++i) {
173 pts[i].x += dx;
174 pts[i].y += dy;
178 GBool SplashPath::getCurPt(SplashCoord *x, SplashCoord *y) {
179 if (noCurrentPoint()) {
180 return gFalse;
182 *x = pts[length - 1].x;
183 *y = pts[length - 1].y;
184 return gTrue;