Coverage Report

Created: 2025-07-11 07:47

/src/xpdf-4.05/splash/SplashState.cc
Line
Count
Source (jump to first uncovered line)
1
//========================================================================
2
//
3
// SplashState.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 "SplashPattern.h"
15
#include "SplashScreen.h"
16
#include "SplashClip.h"
17
#include "SplashBitmap.h"
18
#include "SplashState.h"
19
20
//------------------------------------------------------------------------
21
// SplashState
22
//------------------------------------------------------------------------
23
24
// number of components in each color mode
25
int splashColorModeNComps[] = {
26
  1, 1, 3, 3
27
#if SPLASH_CMYK
28
  , 4
29
#endif
30
};
31
32
SplashState::SplashState(int width, int height, GBool vectorAntialias,
33
0
       SplashScreenParams *screenParams) {
34
0
  SplashColor color;
35
0
  int i;
36
37
0
  matrix[0] = 1;  matrix[1] = 0;
38
0
  matrix[2] = 0;  matrix[3] = 1;
39
0
  matrix[4] = 0;  matrix[5] = 0;
40
0
  memset(&color, 0, sizeof(SplashColor));
41
0
  strokePattern = new SplashSolidColor(color);
42
0
  fillPattern = new SplashSolidColor(color);
43
0
  screen = new SplashScreen(screenParams);
44
0
  blendFunc = NULL;
45
0
  strokeAlpha = 1;
46
0
  fillAlpha = 1;
47
0
  lineWidth = 1;
48
0
  lineCap = splashLineCapButt;
49
0
  lineJoin = splashLineJoinMiter;
50
0
  miterLimit = 10;
51
0
  flatness = 1;
52
0
  lineDash = NULL;
53
0
  lineDashLength = 0;
54
0
  lineDashPhase = 0;
55
0
  strokeAdjust = splashStrokeAdjustOff;
56
0
  clip = new SplashClip(0, 0, width, height);
57
0
  clipIsShared = gFalse;
58
0
  softMask = NULL;
59
0
  deleteSoftMask = gFalse;
60
0
  inNonIsolatedGroup = gFalse;
61
0
  inKnockoutGroup = gFalse;
62
0
#if SPLASH_CMYK
63
0
  rgbTransferR = (Guchar *)gmalloc(8 * 256);
64
0
  rgbTransferG = rgbTransferR + 256;
65
0
  rgbTransferB = rgbTransferG + 256;
66
0
  grayTransfer = rgbTransferB + 256;
67
0
  cmykTransferC = grayTransfer + 256;
68
0
  cmykTransferM = cmykTransferC + 256;
69
0
  cmykTransferY = cmykTransferM + 256;
70
0
  cmykTransferK = cmykTransferY + 256;
71
#else
72
  rgbTransferR = (Guchar *)gmalloc(4 * 256);
73
  rgbTransferG = rgbTransferR + 256;
74
  rgbTransferB = rgbTransferG + 256;
75
  grayTransfer = rgbTransferB + 256;
76
#endif
77
0
  for (i = 0; i < 256; ++i) {
78
0
    rgbTransferR[i] = (Guchar)i;
79
0
    rgbTransferG[i] = (Guchar)i;
80
0
    rgbTransferB[i] = (Guchar)i;
81
0
    grayTransfer[i] = (Guchar)i;
82
0
#if SPLASH_CMYK
83
0
    cmykTransferC[i] = (Guchar)i;
84
0
    cmykTransferM[i] = (Guchar)i;
85
0
    cmykTransferY[i] = (Guchar)i;
86
0
    cmykTransferK[i] = (Guchar)i;
87
0
#endif
88
0
  }
89
0
  transferIsShared = gFalse;
90
0
  overprintMask = 0xffffffff;
91
0
  enablePathSimplification = gFalse;
92
0
  next = NULL;
93
0
}
94
95
SplashState::SplashState(int width, int height, GBool vectorAntialias,
96
0
       SplashScreen *screenA) {
97
0
  SplashColor color;
98
0
  int i;
99
100
0
  matrix[0] = 1;  matrix[1] = 0;
101
0
  matrix[2] = 0;  matrix[3] = 1;
102
0
  matrix[4] = 0;  matrix[5] = 0;
103
0
  memset(&color, 0, sizeof(SplashColor));
104
0
  strokePattern = new SplashSolidColor(color);
105
0
  fillPattern = new SplashSolidColor(color);
106
0
  screen = screenA->copy();
107
0
  blendFunc = NULL;
108
0
  strokeAlpha = 1;
109
0
  fillAlpha = 1;
110
0
  lineWidth = 1;
111
0
  lineCap = splashLineCapButt;
112
0
  lineJoin = splashLineJoinMiter;
113
0
  miterLimit = 10;
114
0
  flatness = 1;
115
0
  lineDash = NULL;
116
0
  lineDashLength = 0;
117
0
  lineDashPhase = 0;
118
0
  strokeAdjust = splashStrokeAdjustOff;
119
0
  clip = new SplashClip(0, 0, width, height);
120
0
  clipIsShared = gFalse;
121
0
  softMask = NULL;
122
0
  deleteSoftMask = gFalse;
123
0
  inNonIsolatedGroup = gFalse;
124
0
  inKnockoutGroup = gFalse;
125
0
#if SPLASH_CMYK
126
0
  rgbTransferR = (Guchar *)gmalloc(8 * 256);
127
0
  rgbTransferG = rgbTransferR + 256;
128
0
  rgbTransferB = rgbTransferG + 256;
129
0
  grayTransfer = rgbTransferB + 256;
130
0
  cmykTransferC = grayTransfer + 256;
131
0
  cmykTransferM = cmykTransferC + 256;
132
0
  cmykTransferY = cmykTransferM + 256;
133
0
  cmykTransferK = cmykTransferY + 256;
134
#else
135
  rgbTransferR = (Guchar *)gmalloc(4 * 256);
136
  rgbTransferG = rgbTransferR + 256;
137
  rgbTransferB = rgbTransferG + 256;
138
  grayTransfer = rgbTransferB + 256;
139
#endif
140
0
  for (i = 0; i < 256; ++i) {
141
0
    rgbTransferR[i] = (Guchar)i;
142
0
    rgbTransferG[i] = (Guchar)i;
143
0
    rgbTransferB[i] = (Guchar)i;
144
0
    grayTransfer[i] = (Guchar)i;
145
0
#if SPLASH_CMYK
146
0
    cmykTransferC[i] = (Guchar)i;
147
0
    cmykTransferM[i] = (Guchar)i;
148
0
    cmykTransferY[i] = (Guchar)i;
149
0
    cmykTransferK[i] = (Guchar)i;
150
0
#endif
151
0
  }
152
0
  transferIsShared = gFalse;
153
0
  overprintMask = 0xffffffff;
154
0
  enablePathSimplification = gFalse;
155
0
  next = NULL;
156
0
}
157
158
0
SplashState::SplashState(SplashState *state) {
159
0
  memcpy(matrix, state->matrix, 6 * sizeof(SplashCoord));
160
0
  strokePattern = state->strokePattern->copy();
161
0
  fillPattern = state->fillPattern->copy();
162
0
  screen = state->screen->copy();
163
0
  blendFunc = state->blendFunc;
164
0
  strokeAlpha = state->strokeAlpha;
165
0
  fillAlpha = state->fillAlpha;
166
0
  lineWidth = state->lineWidth;
167
0
  lineCap = state->lineCap;
168
0
  lineJoin = state->lineJoin;
169
0
  miterLimit = state->miterLimit;
170
0
  flatness = state->flatness;
171
0
  if (state->lineDash) {
172
0
    lineDashLength = state->lineDashLength;
173
0
    lineDash = (SplashCoord *)gmallocn(lineDashLength, sizeof(SplashCoord));
174
0
    memcpy(lineDash, state->lineDash, lineDashLength * sizeof(SplashCoord));
175
0
  } else {
176
0
    lineDash = NULL;
177
0
    lineDashLength = 0;
178
0
  }
179
0
  lineDashPhase = state->lineDashPhase;
180
0
  strokeAdjust = state->strokeAdjust;
181
0
  clip = state->clip;
182
0
  clipIsShared = gTrue;
183
0
  softMask = state->softMask;
184
0
  deleteSoftMask = gFalse;
185
0
  inNonIsolatedGroup = state->inNonIsolatedGroup;
186
0
  inKnockoutGroup = state->inKnockoutGroup;
187
0
  rgbTransferR = state->rgbTransferR;
188
0
  rgbTransferG = state->rgbTransferG;
189
0
  rgbTransferB = state->rgbTransferB;
190
0
  grayTransfer = state->grayTransfer;
191
0
#if SPLASH_CMYK
192
0
  cmykTransferC = state->cmykTransferC;
193
0
  cmykTransferM = state->cmykTransferM;
194
0
  cmykTransferY = state->cmykTransferY;
195
0
  cmykTransferK = state->cmykTransferK;
196
0
#endif
197
0
  transferIsShared = gTrue;
198
0
  overprintMask = state->overprintMask;
199
0
  enablePathSimplification = state->enablePathSimplification;
200
0
  next = NULL;
201
0
}
202
203
0
SplashState::~SplashState() {
204
0
  delete strokePattern;
205
0
  delete fillPattern;
206
0
  delete screen;
207
0
  gfree(lineDash);
208
0
  if (!clipIsShared) {
209
0
    delete clip;
210
0
  }
211
0
  if (!transferIsShared) {
212
0
    gfree(rgbTransferR);
213
0
  }
214
0
  if (deleteSoftMask && softMask) {
215
0
    delete softMask;
216
0
  }
217
0
}
218
219
0
void SplashState::setStrokePattern(SplashPattern *strokePatternA) {
220
0
  delete strokePattern;
221
0
  strokePattern = strokePatternA;
222
0
}
223
224
0
void SplashState::setFillPattern(SplashPattern *fillPatternA) {
225
0
  delete fillPattern;
226
0
  fillPattern = fillPatternA;
227
0
}
228
229
0
void SplashState::setScreen(SplashScreen *screenA) {
230
0
  delete screen;
231
0
  screen = screenA;
232
0
}
233
234
void SplashState::setLineDash(SplashCoord *lineDashA, int lineDashLengthA,
235
0
            SplashCoord lineDashPhaseA) {
236
0
  gfree(lineDash);
237
0
  lineDashLength = lineDashLengthA;
238
0
  if (lineDashLength > 0) {
239
0
    lineDash = (SplashCoord *)gmallocn(lineDashLength, sizeof(SplashCoord));
240
0
    memcpy(lineDash, lineDashA, lineDashLength * sizeof(SplashCoord));
241
0
  } else {
242
0
    lineDash = NULL;
243
0
  }
244
0
  lineDashPhase = lineDashPhaseA;
245
0
}
246
247
0
GBool SplashState::lineDashContainsZeroLengthDashes() {
248
0
  int i;
249
250
0
  if (lineDashLength == 0) {
251
0
    return gFalse;
252
0
  }
253
254
  // if the line dash array has an odd number of elements, we need to
255
  // check all of the elements; if the length is even, we only need to
256
  // check even-number elements
257
0
  if (lineDashLength & 1) {
258
0
    for (i = 0; i < lineDashLength; ++i) {
259
0
      if (lineDash[i] == 0) {
260
0
  return gTrue;
261
0
      }
262
0
    }
263
0
  } else {
264
0
    for (i = 0; i < lineDashLength; i += 2) {
265
0
      if (lineDash[i] == 0) {
266
0
  return gTrue;
267
0
      }
268
0
    }
269
0
  }
270
0
  return gFalse;
271
0
}
272
273
void SplashState::clipResetToRect(SplashCoord x0, SplashCoord y0,
274
0
          SplashCoord x1, SplashCoord y1) {
275
0
  if (clipIsShared) {
276
0
    clip = clip->copy();
277
0
    clipIsShared = gFalse;
278
0
  }
279
0
  clip->resetToRect(x0, y0, x1, y1);
280
0
}
281
282
SplashError SplashState::clipToRect(SplashCoord x0, SplashCoord y0,
283
0
            SplashCoord x1, SplashCoord y1) {
284
0
  if (clipIsShared) {
285
0
    clip = clip->copy();
286
0
    clipIsShared = gFalse;
287
0
  }
288
0
  return clip->clipToRect(x0, y0, x1, y1);
289
0
}
290
291
0
SplashError SplashState::clipToPath(SplashPath *path, GBool eo) {
292
0
  if (clipIsShared) {
293
0
    clip = clip->copy();
294
0
    clipIsShared = gFalse;
295
0
  }
296
0
  return clip->clipToPath(path, matrix, flatness, eo,
297
0
        enablePathSimplification, strokeAdjust);
298
0
}
299
300
0
void SplashState::setSoftMask(SplashBitmap *softMaskA, GBool deleteBitmap) {
301
0
  if (deleteSoftMask) {
302
0
    delete softMask;
303
0
  }
304
0
  softMask = softMaskA;
305
0
  deleteSoftMask = deleteBitmap;
306
0
}
307
308
void SplashState::setTransfer(Guchar *red, Guchar *green, Guchar *blue,
309
0
            Guchar *gray) {
310
0
#if SPLASH_CMYK
311
0
  int i;
312
0
#endif
313
314
0
  if (transferIsShared) {
315
0
#if SPLASH_CMYK
316
0
    rgbTransferR = (Guchar *)gmalloc(8 * 256);
317
0
    rgbTransferG = rgbTransferR + 256;
318
0
    rgbTransferB = rgbTransferG + 256;
319
0
    grayTransfer = rgbTransferB + 256;
320
0
    cmykTransferC = grayTransfer + 256;
321
0
    cmykTransferM = cmykTransferC + 256;
322
0
    cmykTransferY = cmykTransferM + 256;
323
0
    cmykTransferK = cmykTransferY + 256;
324
#else
325
    rgbTransferR = (Guchar *)gmalloc(4 * 256);
326
    rgbTransferG = rgbTransferR + 256;
327
    rgbTransferB = rgbTransferG + 256;
328
    grayTransfer = rgbTransferB + 256;
329
#endif
330
0
    transferIsShared = gFalse;
331
0
  }
332
0
  memcpy(rgbTransferR, red, 256);
333
0
  memcpy(rgbTransferG, green, 256);
334
0
  memcpy(rgbTransferB, blue, 256);
335
0
  memcpy(grayTransfer, gray, 256);
336
0
#if SPLASH_CMYK
337
0
  for (i = 0; i < 256; ++i) {
338
0
    cmykTransferC[i] = (Guchar)(255 - rgbTransferR[255 - i]);
339
0
    cmykTransferM[i] = (Guchar)(255 - rgbTransferG[255 - i]);
340
0
    cmykTransferY[i] = (Guchar)(255 - rgbTransferB[255 - i]);
341
0
    cmykTransferK[i] = (Guchar)(255 - grayTransfer[255 - i]);
342
0
  }
343
0
#endif
344
0
}
345