Coverage Report

Created: 2026-06-22 07:14

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