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(GBool force
) {
140 if (noCurrentPoint()) {
141 return splashErrNoCurPt
;
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
;
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
;
169 void SplashPath::offset(SplashCoord dx
, SplashCoord dy
) {
172 for (i
= 0; i
< length
; ++i
) {
178 GBool
SplashPath::getCurPt(SplashCoord
*x
, SplashCoord
*y
) {
179 if (noCurrentPoint()) {
182 *x
= pts
[length
- 1].x
;
183 *y
= pts
[length
- 1].y
;