/src/ghostpdl/psi/zgstate.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2024 Artifex Software, Inc. |
2 | | All Rights Reserved. |
3 | | |
4 | | This software is provided AS-IS with no warranty, either express or |
5 | | implied. |
6 | | |
7 | | This software is distributed under license and may not be copied, |
8 | | modified or distributed except as expressly authorized under the terms |
9 | | of the license contained in the file LICENSE in this distribution. |
10 | | |
11 | | Refer to licensing information at http://www.artifex.com or contact |
12 | | Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco, |
13 | | CA 94129, USA, for further information. |
14 | | */ |
15 | | |
16 | | |
17 | | /* Graphics state operators */ |
18 | | #include "math_.h" |
19 | | #include "ghost.h" |
20 | | #include "oper.h" |
21 | | #include "ialloc.h" |
22 | | #include "icremap.h" |
23 | | #include "idict.h" |
24 | | #include "istruct.h" |
25 | | #include "igstate.h" |
26 | | #include "gsmatrix.h" |
27 | | #include "store.h" |
28 | | #include "gscspace.h" |
29 | | #include "iname.h" |
30 | | |
31 | | /* Structure descriptors */ |
32 | | private_st_int_gstate(); |
33 | | private_st_int_remap_color_info(); |
34 | | |
35 | | /* ------ Utilities ------ */ |
36 | | |
37 | | static int |
38 | | zset_real(i_ctx_t *i_ctx_p, int (*set_proc)(gs_gstate *, double)) |
39 | 174 | { |
40 | 174 | os_ptr op = osp; |
41 | 174 | double param; |
42 | 174 | int code = real_param(op, ¶m); |
43 | | |
44 | 174 | if (code < 0) |
45 | 174 | return_op_typecheck(op); |
46 | 161 | code = set_proc(igs, param); |
47 | 161 | if (code == 0) |
48 | 160 | pop(1); |
49 | 161 | return code; |
50 | 174 | } |
51 | | |
52 | | #if 0 /* Currently unused */ |
53 | | static int |
54 | | zcurrent_real(i_ctx_t *i_ctx_p, double (*current_proc)(const gs_gstate *)) |
55 | | { |
56 | | os_ptr op = osp; |
57 | | |
58 | | push(1); |
59 | | make_real(op, current_proc(igs)); |
60 | | return 0; |
61 | | } |
62 | | #endif |
63 | | |
64 | | static int |
65 | | zset_bool(i_ctx_t *i_ctx_p, void (*set_proc)(gs_gstate *, bool)) |
66 | 0 | { |
67 | 0 | os_ptr op = osp; |
68 | |
|
69 | 0 | check_type(*op, t_boolean); |
70 | 0 | set_proc(igs, op->value.boolval); |
71 | 0 | pop(1); |
72 | 0 | return 0; |
73 | 0 | } |
74 | | |
75 | | static int |
76 | | zcurrent_bool(i_ctx_t *i_ctx_p, bool (*current_proc)(const gs_gstate *)) |
77 | 0 | { |
78 | 0 | os_ptr op = osp; |
79 | |
|
80 | 0 | push(1); |
81 | 0 | make_bool(op, current_proc(igs)); |
82 | 0 | return 0; |
83 | 0 | } |
84 | | |
85 | | static int |
86 | | zset_uint(i_ctx_t *i_ctx_p, void (*set_proc)(gs_gstate *, uint)) |
87 | 8 | { |
88 | 8 | os_ptr op = osp; |
89 | | |
90 | 8 | check_type(*op, t_integer); |
91 | 1 | set_proc(igs, op->value.intval); |
92 | 1 | pop(1); |
93 | 1 | return 0; |
94 | 8 | } |
95 | | |
96 | | #if 0 /* Currently unused */ |
97 | | static int |
98 | | zcurrent_uint(i_ctx_t *i_ctx_p, uint (*current_proc)(const gs_gstate *)) |
99 | | { |
100 | | os_ptr op = osp; |
101 | | |
102 | | push(1); |
103 | | make_int(op, current_proc(igs)); |
104 | | return 0; |
105 | | } |
106 | | #endif |
107 | | |
108 | | /* ------ Operations on the entire graphics state ------ */ |
109 | | |
110 | | /* "Client" procedures */ |
111 | | static void *gs_istate_alloc(gs_memory_t * mem); |
112 | | static int gs_istate_copy(void *to, const void *from); |
113 | | static void gs_istate_free(void *old, gs_memory_t * mem, gs_gstate *pgs); |
114 | | static const gs_gstate_client_procs istate_procs = { |
115 | | gs_istate_alloc, |
116 | | gs_istate_copy, |
117 | | gs_istate_free, |
118 | | 0, /* copy_for */ |
119 | | }; |
120 | | |
121 | | /* Initialize the graphics stack. */ |
122 | | gs_gstate * |
123 | | int_gstate_alloc(const gs_dual_memory_t * dmem) |
124 | 162k | { |
125 | 162k | int_gstate *iigs; |
126 | 162k | ref proc0; |
127 | 162k | int_remap_color_info_t *prci; |
128 | 162k | gs_ref_memory_t *lmem = dmem->space_local; |
129 | 162k | gs_ref_memory_t *gmem = dmem->space_global; |
130 | 162k | gs_gstate *pgs = gs_gstate_alloc((gs_memory_t *)lmem); |
131 | | |
132 | 162k | if (pgs == NULL) |
133 | 0 | return NULL; |
134 | | |
135 | 162k | iigs = gs_alloc_struct((gs_memory_t *)lmem, int_gstate, &st_int_gstate, |
136 | 162k | "int_gstate_alloc(int_gstate)"); |
137 | 162k | if (iigs == NULL) |
138 | 0 | return NULL; |
139 | 6.01M | int_gstate_map_refs(iigs, make_null); |
140 | 162k | make_empty_array(&iigs->dash_pattern_array, a_all); |
141 | 162k | if (gs_alloc_ref_array(lmem, &proc0, a_readonly + a_executable, 2, |
142 | 162k | "int_gstate_alloc(proc0)") < 0) |
143 | 0 | return NULL; |
144 | 162k | make_oper(proc0.value.refs, 0, zpop); |
145 | 162k | make_real(proc0.value.refs + 1, 0.0); |
146 | 162k | iigs->black_generation = proc0; |
147 | 162k | iigs->undercolor_removal = proc0; |
148 | 162k | make_false(&iigs->use_cie_color); |
149 | | /* |
150 | | * Even though the gstate itself is allocated in local VM, the |
151 | | * container for the color remapping procedure must be allocated in |
152 | | * global VM so that the gstate can be copied into global VM. |
153 | | */ |
154 | 162k | prci = gs_alloc_struct((gs_memory_t *)gmem, int_remap_color_info_t, |
155 | 162k | &st_int_remap_color_info, |
156 | 162k | "int_gstate_alloc(remap color info)"); |
157 | 162k | if (prci == NULL) |
158 | 0 | return NULL; |
159 | 162k | make_struct(&iigs->remap_color_info, imemory_space(gmem), prci); |
160 | 162k | clear_pagedevice(iigs); |
161 | 162k | gs_gstate_set_client(pgs, iigs, &istate_procs, true); |
162 | | /* PostScript code wants limit clamping enabled. */ |
163 | 162k | gs_setlimitclamp(pgs, true); |
164 | | /* |
165 | | * gsave and grestore only work properly |
166 | | * if there are always at least 2 entries on the stack. |
167 | | * We count on the PostScript initialization code to do a gsave. |
168 | | */ |
169 | 162k | return pgs; |
170 | 162k | } |
171 | | |
172 | | /* - gsave - */ |
173 | | int |
174 | | zgsave(i_ctx_t *i_ctx_p) |
175 | 767 | { |
176 | 767 | return gs_gsave(igs); |
177 | 767 | } |
178 | | |
179 | | /* - grestore - */ |
180 | | int |
181 | | zgrestore(i_ctx_t *i_ctx_p) |
182 | 767 | { |
183 | 767 | return gs_grestore(igs); |
184 | 767 | } |
185 | | |
186 | | /* - grestoreall - */ |
187 | | int |
188 | | zgrestoreall(i_ctx_t *i_ctx_p) |
189 | 0 | { |
190 | 0 | return gs_grestoreall(igs); |
191 | 0 | } |
192 | | |
193 | | /* - initgraphics - */ |
194 | | static int |
195 | | zinitgraphics(i_ctx_t *i_ctx_p) |
196 | 1.06M | { |
197 | | /* |
198 | | * Although gs_initgraphics resets the color space to DeviceGray, it does |
199 | | * not modify the 'interpreter' gstate, which stores a copy of the PostScript |
200 | | * object used to set the colour space. We could do this here, with effort, |
201 | | * but instead we choose t do it in gs_cspace.ps and handle it all in PostScript. |
202 | | */ |
203 | 1.06M | make_empty_array(&istate->dash_pattern_array, a_all); |
204 | 1.06M | return gs_initgraphics(igs); |
205 | 1.06M | } |
206 | | |
207 | | /* ------ Operations on graphics state elements ------ */ |
208 | | |
209 | | /* <num> setlinewidth - */ |
210 | | static int |
211 | | zsetlinewidth(i_ctx_t *i_ctx_p) |
212 | 5.60k | { |
213 | 5.60k | os_ptr op = osp; |
214 | | /* |
215 | | * The Red Book doesn't say anything about this, but Adobe |
216 | | * interpreters return (or perhaps store) the absolute value |
217 | | * of the width. |
218 | | */ |
219 | 5.60k | double width; |
220 | 5.60k | int code; |
221 | | |
222 | 5.60k | check_op(1); |
223 | 5.58k | code = real_param(op, &width); |
224 | | |
225 | 5.58k | if (code < 0) |
226 | 5.58k | return_op_typecheck(op); |
227 | 5.57k | code = gs_setlinewidth(igs, fabs(width)); |
228 | 5.57k | if (code >= 0) |
229 | 5.57k | pop(1); |
230 | 5.57k | return code; |
231 | 5.58k | } |
232 | | |
233 | | /* - currentlinewidth <num> */ |
234 | | static int |
235 | | zcurrentlinewidth(i_ctx_t *i_ctx_p) |
236 | 604 | { |
237 | 604 | os_ptr op = osp; |
238 | | |
239 | 604 | push(1); |
240 | 604 | make_real(op, gs_currentlinewidth(igs)); |
241 | 604 | return 0; |
242 | 604 | } |
243 | | |
244 | | /* <cap_int> .setlinecap - */ |
245 | | static int |
246 | | zsetlinecap(i_ctx_t *i_ctx_p) |
247 | 112 | { |
248 | 112 | os_ptr op = osp; |
249 | 112 | int param; |
250 | 112 | int code; |
251 | | |
252 | 112 | check_op(1); |
253 | 112 | code = int_param(op, max_int, ¶m); |
254 | | |
255 | 112 | if (code < 0 || (code = gs_setlinecap(igs, (gs_line_cap) param)) < 0) |
256 | 14 | return code; |
257 | 98 | pop(1); |
258 | 98 | return 0; |
259 | 112 | } |
260 | | |
261 | | /* - currentlinecap <cap_int> */ |
262 | | static int |
263 | | zcurrentlinecap(i_ctx_t *i_ctx_p) |
264 | 263 | { |
265 | 263 | os_ptr op = osp; |
266 | | |
267 | 263 | push(1); |
268 | 263 | make_int(op, (int)gs_currentlinecap(igs)); |
269 | 263 | return 0; |
270 | 263 | } |
271 | | |
272 | | /* <join_int> .setlinejoin - */ |
273 | | static int |
274 | | zsetlinejoin(i_ctx_t *i_ctx_p) |
275 | 115 | { |
276 | 115 | os_ptr op = osp; |
277 | 115 | int param; |
278 | 115 | int code; |
279 | | |
280 | 115 | check_op(1); |
281 | 115 | code = int_param(op, max_int, ¶m); |
282 | | |
283 | 115 | if (code < 0 || (code = gs_setlinejoin(igs, (gs_line_join) param)) < 0) |
284 | 28 | return code; |
285 | 87 | pop(1); |
286 | 87 | return 0; |
287 | 115 | } |
288 | | |
289 | | /* - currentlinejoin <join_int> */ |
290 | | static int |
291 | | zcurrentlinejoin(i_ctx_t *i_ctx_p) |
292 | 1.35k | { |
293 | 1.35k | os_ptr op = osp; |
294 | | |
295 | 1.35k | push(1); |
296 | 1.35k | make_int(op, (int)gs_currentlinejoin(igs)); |
297 | 1.35k | return 0; |
298 | 1.35k | } |
299 | | |
300 | | /* <num> setmiterlimit - */ |
301 | | static int |
302 | | zsetmiterlimit(i_ctx_t *i_ctx_p) |
303 | 122 | { |
304 | 122 | os_ptr op = osp; |
305 | 122 | check_op(1); |
306 | 110 | return zset_real(i_ctx_p, gs_setmiterlimit); |
307 | 122 | } |
308 | | |
309 | | /* - currentmiterlimit <num> */ |
310 | | static int |
311 | | zcurrentmiterlimit(i_ctx_t *i_ctx_p) |
312 | 58 | { |
313 | 58 | os_ptr op = osp; |
314 | | |
315 | 58 | push(1); |
316 | 58 | make_real(op, gs_currentmiterlimit(igs)); |
317 | 58 | return 0; |
318 | 58 | } |
319 | | |
320 | | /* <array> <offset> setdash - */ |
321 | | static int |
322 | | zsetdash(i_ctx_t *i_ctx_p) |
323 | 516 | { |
324 | 516 | os_ptr op = osp; |
325 | 516 | os_ptr op1 = op - 1; |
326 | 516 | double offset; |
327 | 516 | int code; |
328 | 516 | uint i, n; |
329 | 516 | gs_memory_t *mem = imemory; |
330 | 516 | float *pattern; |
331 | | |
332 | 516 | check_op(2); |
333 | 508 | code = real_param(op, &offset); |
334 | 508 | if (code < 0) |
335 | 508 | return_op_typecheck(op); |
336 | 508 | if (!r_is_array(op1)) |
337 | 508 | return_op_typecheck(op1); |
338 | | /* Adobe interpreters apparently don't check the array for */ |
339 | | /* read access, so we won't either. */ |
340 | | /*check_read(*op1); */ |
341 | | /* Unpack the dash pattern and check it */ |
342 | 498 | n = r_size(op1); |
343 | 498 | pattern = |
344 | 498 | (float *)gs_alloc_byte_array(mem, n, sizeof(float), "setdash"); |
345 | | |
346 | 498 | if (pattern == 0) |
347 | 0 | return_error(gs_error_VMerror); |
348 | 499 | for (i = 0, code = 0; i < n && code >= 0; ++i) { |
349 | 1 | ref element; |
350 | | |
351 | 1 | array_get(mem, op1, (long)i, &element); |
352 | 1 | code = float_param(&element, &pattern[i]); |
353 | 1 | } |
354 | 498 | if (code >= 0) |
355 | 497 | code = gs_setdash(igs, pattern, n, offset); |
356 | 498 | gs_free_object(mem, pattern, "setdash"); /* gs_setdash copies this */ |
357 | 498 | if (code < 0) |
358 | 1 | return code; |
359 | 497 | ref_assign(&istate->dash_pattern_array, op1); |
360 | 497 | pop(2); |
361 | 497 | return code; |
362 | 498 | } |
363 | | |
364 | | /* - currentdash <array> <offset> */ |
365 | | static int |
366 | | zcurrentdash(i_ctx_t *i_ctx_p) |
367 | 1.68k | { |
368 | 1.68k | os_ptr op = osp; |
369 | | |
370 | 1.68k | push(2); |
371 | 1.68k | ref_assign(op - 1, &istate->dash_pattern_array); |
372 | 1.68k | make_real(op, gs_currentdash_offset(igs)); |
373 | 1.68k | return 0; |
374 | 1.68k | } |
375 | | |
376 | | /* <num> setflat - */ |
377 | | static int |
378 | | zsetflat(i_ctx_t *i_ctx_p) |
379 | 64 | { |
380 | 64 | return zset_real(i_ctx_p, gs_setflat); |
381 | 64 | } |
382 | | |
383 | | /* - currentflat <num> */ |
384 | | static int |
385 | | zcurrentflat(i_ctx_t *i_ctx_p) |
386 | 105 | { |
387 | 105 | os_ptr op = osp; |
388 | | |
389 | 105 | push(1); |
390 | 105 | make_real(op, gs_currentflat(igs)); |
391 | 105 | return 0; |
392 | 105 | } |
393 | | |
394 | | /* ------ Extensions ------ */ |
395 | | |
396 | | /* <bool> .setaccuratecurves - */ |
397 | | static int |
398 | | zsetaccuratecurves(i_ctx_t *i_ctx_p) |
399 | 0 | { |
400 | 0 | return zset_bool(i_ctx_p, gs_setaccuratecurves); |
401 | 0 | } |
402 | | |
403 | | /* - .currentaccuratecurves <bool> */ |
404 | | static int |
405 | | zcurrentaccuratecurves(i_ctx_t *i_ctx_p) |
406 | 0 | { |
407 | 0 | return zcurrent_bool(i_ctx_p, gs_currentaccuratecurves); |
408 | 0 | } |
409 | | |
410 | | /* <join_int|-1> .setcurvejoin - */ |
411 | | static int |
412 | | zsetcurvejoin(i_ctx_t *i_ctx_p) |
413 | 0 | { |
414 | 0 | os_ptr op = osp; |
415 | 0 | int code; |
416 | |
|
417 | 0 | check_type(*op, t_integer); |
418 | 0 | if (op->value.intval < -1 || op->value.intval > max_int) |
419 | 0 | return_error(gs_error_rangecheck); |
420 | 0 | code = gs_setcurvejoin(igs, (int)op->value.intval); |
421 | 0 | if (code < 0) |
422 | 0 | return code; |
423 | 0 | pop(1); |
424 | 0 | return 0; |
425 | 0 | } |
426 | | |
427 | | /* - .currentcurvejoin <join_int|-1> */ |
428 | | static int |
429 | | zcurrentcurvejoin(i_ctx_t *i_ctx_p) |
430 | 0 | { |
431 | 0 | os_ptr op = osp; |
432 | |
|
433 | 0 | push(1); |
434 | 0 | make_int(op, gs_currentcurvejoin(igs)); |
435 | 0 | return 0; |
436 | 0 | } |
437 | | |
438 | | /* <adjust.x> <adjust.y> .setfilladjust2 - */ |
439 | | static int |
440 | | zsetfilladjust2(i_ctx_t *i_ctx_p) |
441 | 162k | { |
442 | 162k | os_ptr op = osp; |
443 | 162k | double adjust[2]; |
444 | 162k | int code = num_params(op, 2, adjust); |
445 | | |
446 | 162k | if (code < 0) |
447 | 10 | return code; |
448 | 162k | code = gs_setfilladjust(igs, adjust[0], adjust[1]); |
449 | 162k | if (code < 0) |
450 | 0 | return code; |
451 | 162k | pop(2); |
452 | 162k | return 0; |
453 | 162k | } |
454 | | |
455 | | /* - .currentfilladjust2 <adjust.x> <adjust.y> */ |
456 | | static int |
457 | | zcurrentfilladjust2(i_ctx_t *i_ctx_p) |
458 | 6 | { |
459 | 6 | os_ptr op = osp; |
460 | 6 | gs_point adjust; |
461 | | |
462 | 6 | push(2); |
463 | 6 | gs_currentfilladjust(igs, &adjust); |
464 | 6 | make_real(op - 1, adjust.x); |
465 | 6 | make_real(op, adjust.y); |
466 | 6 | return 0; |
467 | 6 | } |
468 | | |
469 | | /* <bool> .setdashadapt - */ |
470 | | static int |
471 | | zsetdashadapt(i_ctx_t *i_ctx_p) |
472 | 0 | { |
473 | 0 | return zset_bool(i_ctx_p, gs_setdashadapt); |
474 | 0 | } |
475 | | |
476 | | /* - .currentdashadapt <bool> */ |
477 | | static int |
478 | | zcurrentdashadapt(i_ctx_t *i_ctx_p) |
479 | 0 | { |
480 | 0 | return zcurrent_bool(i_ctx_p, gs_currentdashadapt); |
481 | 0 | } |
482 | | |
483 | | /* <num> <bool> .setdotlength - */ |
484 | | static int |
485 | | zsetdotlength(i_ctx_t *i_ctx_p) |
486 | 0 | { |
487 | 0 | os_ptr op = osp; |
488 | 0 | double length; |
489 | 0 | int code = real_param(op - 1, &length); |
490 | |
|
491 | 0 | if (code < 0) |
492 | 0 | return code; |
493 | 0 | check_type(*op, t_boolean); |
494 | 0 | code = gs_setdotlength(igs, length, op->value.boolval); |
495 | 0 | if (code < 0) |
496 | 0 | return code; |
497 | 0 | pop(2); |
498 | 0 | return 0; |
499 | 0 | } |
500 | | |
501 | | /* - .currentdotlength <num> <bool> */ |
502 | | static int |
503 | | zcurrentdotlength(i_ctx_t *i_ctx_p) |
504 | 0 | { |
505 | 0 | os_ptr op = osp; |
506 | |
|
507 | 0 | push(2); |
508 | 0 | make_real(op - 1, gs_currentdotlength(igs)); |
509 | 0 | make_bool(op, gs_currentdotlength_absolute(igs)); |
510 | 0 | return 0; |
511 | 0 | } |
512 | | |
513 | | /* - .setdotorientation - */ |
514 | | static int |
515 | | zsetdotorientation(i_ctx_t *i_ctx_p) |
516 | 0 | { |
517 | 0 | return gs_setdotorientation(igs); |
518 | 0 | } |
519 | | |
520 | | /* - .dotorientation - */ |
521 | | static int |
522 | | zdotorientation(i_ctx_t *i_ctx_p) |
523 | 0 | { |
524 | 0 | return gs_dotorientation(igs); |
525 | 0 | } |
526 | | |
527 | | /* <bool> .setlimitclamp - */ |
528 | | static int |
529 | | zsetlimitclamp(i_ctx_t *i_ctx_p) |
530 | 0 | { |
531 | 0 | return zset_bool(i_ctx_p, gs_setlimitclamp); |
532 | 0 | } |
533 | | |
534 | | /* - .currentlimitclamp <bool> */ |
535 | | static int |
536 | | zcurrentlimitclamp(i_ctx_t *i_ctx_p) |
537 | 0 | { |
538 | 0 | return zcurrent_bool(i_ctx_p, gs_currentlimitclamp); |
539 | 0 | } |
540 | | |
541 | | /* We need this for the PScript5.DLL Idiom recognition, when outputting |
542 | | * to pdfwrite. This is used to turn the 'fake bold' text into text |
543 | | * rendering mode 2 (fill and then stroke). |
544 | | */ |
545 | | /* <int> .settextrenderingmode - */ |
546 | | static int |
547 | | zsettextrenderingmode(i_ctx_t *i_ctx_p) |
548 | 8 | { |
549 | 8 | return zset_uint(i_ctx_p, gs_settextrenderingmode); |
550 | 8 | } |
551 | | |
552 | | /* <bool> .sethpglpathmode - */ |
553 | | static int |
554 | | zsethpglpathmode(i_ctx_t *i_ctx_p) |
555 | 0 | { |
556 | 0 | return zset_bool(i_ctx_p, gs_sethpglpathmode); |
557 | 0 | } |
558 | | |
559 | | /* - .currenthpglpathmode <int> */ |
560 | | static int |
561 | | zcurrenthpglpathmode(i_ctx_t *i_ctx_p) |
562 | 0 | { |
563 | 0 | return zcurrent_bool(i_ctx_p, gs_currenthpglpathmode); |
564 | 0 | } |
565 | | |
566 | | /* ------ Initialization procedure ------ */ |
567 | | |
568 | | /* We need to split the table because of the 16-element limit. */ |
569 | | const op_def zgstate1_op_defs[] = { |
570 | | {"0.currentaccuratecurves", zcurrentaccuratecurves}, |
571 | | {"0.currentcurvejoin", zcurrentcurvejoin}, |
572 | | {"0currentdash", zcurrentdash}, |
573 | | {"0.currentdashadapt", zcurrentdashadapt}, |
574 | | {"0.currentdotlength", zcurrentdotlength}, |
575 | | {"0.currentfilladjust2", zcurrentfilladjust2}, |
576 | | {"0currentflat", zcurrentflat}, |
577 | | {"0.currentlimitclamp", zcurrentlimitclamp}, |
578 | | {"0currentlinecap", zcurrentlinecap}, |
579 | | {"0currentlinejoin", zcurrentlinejoin}, |
580 | | {"0currentlinewidth", zcurrentlinewidth}, |
581 | | {"0currentmiterlimit", zcurrentmiterlimit}, |
582 | | {"0.dotorientation", zdotorientation}, |
583 | | {"0grestore", zgrestore}, |
584 | | {"0grestoreall", zgrestoreall}, |
585 | | op_def_end(0) |
586 | | }; |
587 | | const op_def zgstate2_op_defs[] = { |
588 | | {"0gsave", zgsave}, |
589 | | {"0initgraphics", zinitgraphics}, |
590 | | {"1.setaccuratecurves", zsetaccuratecurves}, |
591 | | {"1.setcurvejoin", zsetcurvejoin}, |
592 | | {"2setdash", zsetdash}, |
593 | | {"1.setdashadapt", zsetdashadapt}, |
594 | | {"2.setdotlength", zsetdotlength}, |
595 | | {"0.setdotorientation", zsetdotorientation}, |
596 | | {"2.setfilladjust2", zsetfilladjust2}, |
597 | | {"1.setlimitclamp", zsetlimitclamp}, |
598 | | {"1setflat", zsetflat}, |
599 | | {"1.setlinecap", zsetlinecap}, |
600 | | {"1.setlinejoin", zsetlinejoin}, |
601 | | {"1setlinewidth", zsetlinewidth}, |
602 | | {"1setmiterlimit", zsetmiterlimit}, |
603 | | op_def_end(0) |
604 | | }; |
605 | | const op_def zgstate3_op_defs[] = { |
606 | | {"1.settextrenderingmode", zsettextrenderingmode}, |
607 | | {"0.sethpglpathmode", zsethpglpathmode}, |
608 | | {"0.currenthpglpathmode", zcurrenthpglpathmode}, |
609 | | op_def_end(0) |
610 | | }; |
611 | | |
612 | | /* ------ Internal routines ------ */ |
613 | | |
614 | | /* Allocate the interpreter's part of a graphics state. */ |
615 | | static void * |
616 | | gs_istate_alloc(gs_memory_t * mem) |
617 | 25.8M | { |
618 | 25.8M | return gs_alloc_struct(mem, int_gstate, &st_int_gstate, "int_gsave"); |
619 | 25.8M | } |
620 | | |
621 | | /* Copy the interpreter's part of a graphics state. */ |
622 | | static int |
623 | | gs_istate_copy(void *to, const void *from) |
624 | 51.5M | { |
625 | 51.5M | *(int_gstate *) to = *(const int_gstate *)from; |
626 | 51.5M | return 0; |
627 | 51.5M | } |
628 | | |
629 | | /* Free the interpreter's part of a graphics state. */ |
630 | | static void |
631 | | gs_istate_free(void *old, gs_memory_t * mem, gs_gstate *pgs) |
632 | 26.0M | { |
633 | 26.0M | gs_free_object(mem, old, "int_grestore"); |
634 | 26.0M | } |