Coverage Report

Created: 2023-09-25 06:41

/src/xpdf-4.04/splash/SplashPath.cc
Line
Count
Source (jump to first uncovered line)
1
//========================================================================
2
//
3
// SplashPath.cc
4
//
5
// Copyright 2003-2013 Glyph & Cog, LLC
6
//
7
//========================================================================
8
9
#include <aconf.h>
10
11
#ifdef USE_GCC_PRAGMAS
12
#pragma implementation
13
#endif
14
15
#include <string.h>
16
#include "gmem.h"
17
#include "gmempp.h"
18
#include "SplashErrorCodes.h"
19
#include "SplashPath.h"
20
21
//------------------------------------------------------------------------
22
// SplashPath
23
//------------------------------------------------------------------------
24
25
// A path can be in three possible states:
26
//
27
// 1. no current point -- zero or more finished subpaths
28
//    [curSubpath == length]
29
//
30
// 2. one point in subpath
31
//    [curSubpath == length - 1]
32
//
33
// 3. open subpath with two or more points
34
//    [curSubpath < length - 1]
35
36
0
SplashPath::SplashPath() {
37
0
  pts = NULL;
38
0
  flags = NULL;
39
0
  length = size = 0;
40
0
  curSubpath = 0;
41
0
  hints = NULL;
42
0
  hintsLength = hintsSize = 0;
43
0
}
44
45
0
SplashPath::SplashPath(SplashPath *path) {
46
0
  length = path->length;
47
0
  size = path->size;
48
0
  pts = (SplashPathPoint *)gmallocn(size, sizeof(SplashPathPoint));
49
0
  flags = (Guchar *)gmallocn(size, sizeof(Guchar));
50
0
  memcpy(pts, path->pts, length * sizeof(SplashPathPoint));
51
0
  memcpy(flags, path->flags, length * sizeof(Guchar));
52
0
  curSubpath = path->curSubpath;
53
0
  if (path->hints) {
54
0
    hintsLength = hintsSize = path->hintsLength;
55
0
    hints = (SplashPathHint *)gmallocn(hintsSize, sizeof(SplashPathHint));
56
0
    memcpy(hints, path->hints, hintsLength * sizeof(SplashPathHint));
57
0
  } else {
58
0
    hints = NULL;
59
0
    hintsLength = hintsSize = 0;
60
0
  }
61
0
}
62
63
0
SplashPath::~SplashPath() {
64
0
  gfree(pts);
65
0
  gfree(flags);
66
0
  gfree(hints);
67
0
}
68
69
// Add space for <nPts> more points.
70
0
void SplashPath::grow(int nPts) {
71
0
  if (length + nPts > size) {
72
0
    if (size == 0) {
73
0
      size = 32;
74
0
    }
75
0
    while (size < length + nPts) {
76
0
      size *= 2;
77
0
    }
78
0
    pts = (SplashPathPoint *)greallocn(pts, size, sizeof(SplashPathPoint));
79
0
    flags = (Guchar *)greallocn(flags, size, sizeof(Guchar));
80
0
  }
81
0
}
82
83
0
void SplashPath::append(SplashPath *path) {
84
0
  int i;
85
86
0
  curSubpath = length + path->curSubpath;
87
0
  grow(path->length);
88
0
  for (i = 0; i < path->length; ++i) {
89
0
    pts[length] = path->pts[i];
90
0
    flags[length] = path->flags[i];
91
0
    ++length;
92
0
  }
93
0
}
94
95
0
SplashError SplashPath::moveTo(SplashCoord x, SplashCoord y) {
96
0
  if (onePointSubpath()) {
97
0
    return splashErrBogusPath;
98
0
  }
99
0
  grow(1);
100
0
  pts[length].x = x;
101
0
  pts[length].y = y;
102
0
  flags[length] = splashPathFirst | splashPathLast;
103
0
  curSubpath = length++;
104
0
  return splashOk;
105
0
}
106
107
0
SplashError SplashPath::lineTo(SplashCoord x, SplashCoord y) {
108
0
  if (noCurrentPoint()) {
109
0
    return splashErrNoCurPt;
110
0
  }
111
0
  flags[length-1] &= (Guchar)~splashPathLast;
112
0
  grow(1);
113
0
  pts[length].x = x;
114
0
  pts[length].y = y;
115
0
  flags[length] = splashPathLast;
116
0
  ++length;
117
0
  return splashOk;
118
0
}
119
120
SplashError SplashPath::curveTo(SplashCoord x1, SplashCoord y1,
121
        SplashCoord x2, SplashCoord y2,
122
0
        SplashCoord x3, SplashCoord y3) {
123
0
  if (noCurrentPoint()) {
124
0
    return splashErrNoCurPt;
125
0
  }
126
0
  flags[length-1] &= (Guchar)~splashPathLast;
127
0
  grow(3);
128
0
  pts[length].x = x1;
129
0
  pts[length].y = y1;
130
0
  flags[length] = splashPathCurve;
131
0
  ++length;
132
0
  pts[length].x = x2;
133
0
  pts[length].y = y2;
134
0
  flags[length] = splashPathCurve;
135
0
  ++length;
136
0
  pts[length].x = x3;
137
0
  pts[length].y = y3;
138
0
  flags[length] = splashPathLast;
139
0
  ++length;
140
0
  return splashOk;
141
0
}
142
143
0
SplashError SplashPath::close(GBool force) {
144
0
  if (noCurrentPoint()) {
145
0
    return splashErrNoCurPt;
146
0
  }
147
0
  if (force ||
148
0
      curSubpath == length - 1 ||
149
0
      pts[length - 1].x != pts[curSubpath].x ||
150
0
      pts[length - 1].y != pts[curSubpath].y) {
151
0
    lineTo(pts[curSubpath].x, pts[curSubpath].y);
152
0
  }
153
0
  flags[curSubpath] |= splashPathClosed;
154
0
  flags[length - 1] |= splashPathClosed;
155
0
  curSubpath = length;
156
0
  return splashOk;
157
0
}
158
159
void SplashPath::addStrokeAdjustHint(int ctrl0, int ctrl1,
160
             int firstPt, int lastPt,
161
0
             GBool projectingCap) {
162
0
  if (hintsLength == hintsSize) {
163
0
    hintsSize = hintsLength ? 2 * hintsLength : 8;
164
0
    hints = (SplashPathHint *)greallocn(hints, hintsSize,
165
0
          sizeof(SplashPathHint));
166
0
  }
167
0
  hints[hintsLength].ctrl0 = ctrl0;
168
0
  hints[hintsLength].ctrl1 = ctrl1;
169
0
  hints[hintsLength].firstPt = firstPt;
170
0
  hints[hintsLength].lastPt = lastPt;
171
0
  hints[hintsLength].projectingCap = projectingCap;
172
0
  ++hintsLength;
173
0
}
174
175
0
void SplashPath::offset(SplashCoord dx, SplashCoord dy) {
176
0
  int i;
177
178
0
  for (i = 0; i < length; ++i) {
179
0
    pts[i].x += dx;
180
0
    pts[i].y += dy;
181
0
  }
182
0
}
183
184
0
GBool SplashPath::getCurPt(SplashCoord *x, SplashCoord *y) {
185
0
  if (noCurrentPoint()) {
186
0
    return gFalse;
187
0
  }
188
0
  *x = pts[length - 1].x;
189
0
  *y = pts[length - 1].y;
190
0
  return gTrue;
191
0
}
192
193
0
GBool SplashPath::containsZeroLengthSubpaths() {
194
0
  GBool zeroLength;
195
0
  int i;
196
197
0
  zeroLength = gTrue;  // make gcc happy
198
0
  for (i = 0; i < length; ++i) {
199
0
    if (flags[i] & splashPathFirst) {
200
0
      zeroLength = gTrue;
201
0
    } else {
202
0
      if (pts[i].x != pts[i-1].x || pts[i].y != pts[i-1].y) {
203
0
  zeroLength = gFalse;
204
0
      }
205
0
      if (flags[i] & splashPathLast) {
206
0
  if (zeroLength) {
207
0
    return gTrue;
208
0
  }
209
0
      }
210
0
    }
211
0
  }
212
0
  return gFalse;
213
0
}