]> www.fi.muni.cz Git - evince.git/blob - pdf/splash/SplashPath.cc
My 2005-01-05 change didn't actually fix the problem. Now I just
[evince.git] / pdf / splash / SplashPath.cc
1 //========================================================================
2 //
3 // SplashPath.cc
4 //
5 //========================================================================
6
7 #include <aconf.h>
8
9 #ifdef USE_GCC_PRAGMAS
10 #pragma implementation
11 #endif
12
13 #include <string.h>
14 #include "gmem.h"
15 #include "SplashErrorCodes.h"
16 #include "SplashPath.h"
17
18 //------------------------------------------------------------------------
19 // SplashPath
20 //------------------------------------------------------------------------
21
22 // A path can be in three possible states:
23 //
24 // 1. no current point -- zero or more finished subpaths
25 //    [curSubpath == length]
26 //
27 // 2. one point in subpath
28 //    [curSubpath == length - 1]
29 //
30 // 3. open subpath with two or more points
31 //    [curSubpath < length - 1]
32
33 SplashPath::SplashPath() {
34   pts = NULL;
35   flags = NULL;
36   length = size = 0;
37   curSubpath = 0;
38 }
39
40 SplashPath::SplashPath(SplashPath *path) {
41   length = path->length;
42   size = path->size;
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;
48 }
49
50 SplashPath::~SplashPath() {
51   gfree(pts);
52   gfree(flags);
53 }
54
55 // Add space for <nPts> more points.
56 void SplashPath::grow(int nPts) {
57   if (length + nPts > size) {
58     if (size == 0) {
59       size = 32;
60     }
61     while (size < length + nPts) {
62       size *= 2;
63     }
64     pts = (SplashPathPoint *)grealloc(pts, size * sizeof(SplashPathPoint));
65     flags = (Guchar *)grealloc(flags, size * sizeof(Guchar));
66   }
67 }
68
69 void SplashPath::append(SplashPath *path) {
70   int i;
71
72   curSubpath = length + path->curSubpath;
73   grow(path->length);
74   for (i = 0; i < path->length; ++i) {
75     pts[length] = path->pts[i];
76     flags[length] = path->flags[i];
77     ++length;
78   }
79 }
80
81 SplashError SplashPath::moveTo(SplashCoord x, SplashCoord y) {
82   if (onePointSubpath()) {
83     return splashErrBogusPath;
84   }
85   grow(1);
86   pts[length].x = x;
87   pts[length].y = y;
88   flags[length] = splashPathFirst | splashPathLast;
89   curSubpath = length++;
90   return splashOk;
91 }
92
93 SplashError SplashPath::lineTo(SplashCoord x, SplashCoord y) {
94   if (noCurrentPoint()) {
95     return splashErrNoCurPt;
96   }
97   flags[length-1] &= ~splashPathLast;
98   grow(1);
99   pts[length].x = x;
100   pts[length].y = y;
101   flags[length] = splashPathLast;
102   ++length;
103   return splashOk;
104 }
105
106 SplashError SplashPath::curveTo(SplashCoord x1, SplashCoord y1,
107                                 SplashCoord x2, SplashCoord y2,
108                                 SplashCoord x3, SplashCoord y3) {
109   if (noCurrentPoint()) {
110     return splashErrNoCurPt;
111   }
112   flags[length-1] &= ~splashPathLast;
113   grow(3);
114   pts[length].x = x1;
115   pts[length].y = y1;
116   flags[length] = splashPathCurve;
117   ++length;
118   pts[length].x = x2;
119   pts[length].y = y2;
120   flags[length] = splashPathCurve;
121   ++length;
122   pts[length].x = x3;
123   pts[length].y = y3;
124   flags[length] = splashPathLast;
125   ++length;
126   return splashOk;
127 }
128
129 SplashError SplashPath::arcCWTo(SplashCoord x1, SplashCoord y1,
130                                 SplashCoord xc, SplashCoord yc) {
131   if (noCurrentPoint()) {
132     return splashErrNoCurPt;
133   }
134   flags[length-1] &= ~splashPathLast;
135   grow(2);
136   pts[length].x = xc;
137   pts[length].y = yc;
138   flags[length] = splashPathArcCW;
139   ++length;
140   pts[length].x = x1;
141   pts[length].y = y1;
142   flags[length] = splashPathLast;
143   ++length;
144   return splashOk;
145 }
146
147 SplashError SplashPath::close() {
148   if (noCurrentPoint()) {
149     return splashErrNoCurPt;
150   }
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);
154   }
155   flags[curSubpath] |= splashPathClosed;
156   flags[length - 1] |= splashPathClosed;
157   curSubpath = length;
158   return splashOk;
159 }
160
161 void SplashPath::offset(SplashCoord dx, SplashCoord dy) {
162   int i;
163
164   for (i = 0; i < length; ++i) {
165     pts[i].x += dx;
166     pts[i].y += dy;
167   }
168 }
169
170 GBool SplashPath::getCurPt(SplashCoord *x, SplashCoord *y) {
171   if (noCurrentPoint()) {
172     return gFalse;
173   }
174   *x = pts[length - 1].x;
175   *y = pts[length - 1].y;
176   return gTrue;
177 }