/src/ghostpdl/pcl/pcl/pcuptrn.c
Line | Count | Source |
1 | | /* Copyright (C) 2001-2026 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 | | /* pcuptrn.c - code for PCL and GL/2 user defined patterns */ |
18 | | |
19 | | #include "string_.h" |
20 | | #include "gx.h" |
21 | | #include "gsuid.h" |
22 | | #include "gscsel.h" |
23 | | #include "gsdevice.h" |
24 | | #include "gxdevice.h" |
25 | | #include "gscspace.h" |
26 | | #include "gxdcolor.h" |
27 | | #include "gxcolor2.h" |
28 | | #include "gxpcolor.h" |
29 | | #include "pldict.h" |
30 | | #include "pcindxed.h" |
31 | | #include "pcpatrn.h" |
32 | | #include "pcbiptrn.h" |
33 | | #include "pcuptrn.h" |
34 | | |
35 | | gs_private_st_simple(st_pattern_data_t, pcl_pattern_data_t, |
36 | | "PCL/GL pattern data"); |
37 | | gs_private_st_simple(st_pattern_t, pcl_pattern_t, "PCL/GL pattern"); |
38 | | |
39 | | /* |
40 | | * Free routine for pattern data structure. |
41 | | */ |
42 | | static void |
43 | | free_pattern_data(gs_memory_t * pmem, void *pvpat_data, client_name_t cname) |
44 | 9.59k | { |
45 | 9.59k | pcl_pattern_data_t *ppat_data = (pcl_pattern_data_t *) pvpat_data; |
46 | | |
47 | 9.59k | if ((ppat_data->storage != pcds_internal) |
48 | 8.10k | && (ppat_data->pixinfo.data != 0)) |
49 | 8.10k | gs_free_object(pmem, ppat_data->pixinfo.data, cname); |
50 | 9.59k | gs_free_object(pmem, pvpat_data, cname); |
51 | 9.59k | } |
52 | | |
53 | | /* |
54 | | * Build a pattern data structure. This routine is static as pattern |
55 | | * data structures may only be built as part of a pattern. |
56 | | * |
57 | | * All pattern data structure are built as "temporary". Routines that build |
58 | | * internal patterns should modify this as soon as the pattern is built. |
59 | | * |
60 | | * Returns 0 on success, < 0 in the event of an error. In the latter case, |
61 | | * *pppat_data will be set to NULL. |
62 | | */ |
63 | | static int |
64 | | build_pattern_data(pcl_pattern_data_t ** pppat_data, |
65 | | const gs_depth_bitmap * ppixinfo, |
66 | | pcl_pattern_type_t type, |
67 | | int xres, int yres, gs_memory_t * pmem) |
68 | 9.59k | { |
69 | 9.59k | pcl_pattern_data_t *ppat_data = 0; |
70 | | |
71 | 9.59k | *pppat_data = 0; |
72 | 9.59k | rc_alloc_struct_1(ppat_data, |
73 | 9.59k | pcl_pattern_data_t, |
74 | 9.59k | &st_pattern_data_t, |
75 | 9.59k | pmem, return e_Memory, "allocate PCL pattern data"); |
76 | 9.59k | ppat_data->rc.free = free_pattern_data; |
77 | | |
78 | 9.59k | ppat_data->pixinfo = *ppixinfo; |
79 | 9.59k | ppat_data->storage = pcds_temporary; |
80 | 9.59k | ppat_data->type = type; |
81 | 9.59k | ppat_data->xres = xres; |
82 | 9.59k | ppat_data->yres = yres; |
83 | | |
84 | 9.59k | *pppat_data = ppat_data; |
85 | 9.59k | return 0; |
86 | 9.59k | } |
87 | | |
88 | | /* |
89 | | * Free the rendered portion of a pattern. |
90 | | */ |
91 | | static void |
92 | | free_pattern_rendering(const gs_memory_t * mem, pcl_pattern_t * pptrn) |
93 | 9.59k | { |
94 | 9.59k | if (pptrn->pcol_ccolor != 0) { |
95 | 2.83k | pcl_ccolor_release(pptrn->pcol_ccolor); |
96 | 2.83k | pptrn->pcol_ccolor = 0; |
97 | 2.83k | } |
98 | 9.59k | if (pptrn->pmask_ccolor != 0) { |
99 | 1.93k | pcl_ccolor_release(pptrn->pmask_ccolor); |
100 | 1.93k | pptrn->pmask_ccolor = 0; |
101 | 1.93k | } |
102 | 9.59k | } |
103 | | |
104 | | /* |
105 | | * Free routine for patterns. This is exported for the benefit of the code |
106 | | * that handles PCL built-in patterns. |
107 | | */ |
108 | | void |
109 | | pcl_pattern_free_pattern(gs_memory_t * pmem, |
110 | | void *pvptrn, client_name_t cname) |
111 | 234k | { |
112 | 234k | pcl_pattern_t *pptrn = (pcl_pattern_t *) pvptrn; |
113 | | |
114 | 234k | if (pptrn == NULL) |
115 | 224k | return; |
116 | 9.59k | free_pattern_rendering(pmem, pptrn); |
117 | 9.59k | if (pptrn->ppat_data != 0) |
118 | 9.59k | pcl_pattern_data_release(pptrn->ppat_data); |
119 | 9.59k | gs_free_object(pmem, pvptrn, cname); |
120 | 9.59k | } |
121 | | |
122 | | /* |
123 | | * Build a PCL pattern. |
124 | | * |
125 | | * This is expoorted for use by the routines that create the "built in" |
126 | | * patterns. |
127 | | * |
128 | | * Returns 0 if successful, < 0 in the event of an error. In the latter case, |
129 | | * *ppptrn will be set to null. |
130 | | */ |
131 | | int |
132 | | pcl_pattern_build_pattern(pcl_pattern_t ** ppptrn, |
133 | | const gs_depth_bitmap * ppixinfo, |
134 | | pcl_pattern_type_t type, |
135 | | int xres, int yres, gs_memory_t * pmem) |
136 | 9.59k | { |
137 | 9.59k | pcl_pattern_t *pptrn = 0; |
138 | 9.59k | int code = 0; |
139 | | |
140 | 9.59k | *ppptrn = 0; |
141 | 9.59k | pptrn = gs_alloc_struct(pmem, |
142 | 9.59k | pcl_pattern_t, |
143 | 9.59k | &st_pattern_t, "create PCL pattern"); |
144 | 9.59k | if (pptrn == 0) |
145 | 0 | return e_Memory; |
146 | | |
147 | 9.59k | pptrn->pcol_ccolor = 0; |
148 | 9.59k | pptrn->pmask_ccolor = 0; |
149 | 9.59k | pptrn->orient = 0; |
150 | | /* provide a sentinel to guarantee the initial pattern is |
151 | | rendered */ |
152 | 9.59k | pptrn->ref_pt.x = pptrn->ref_pt.y = -1.0; |
153 | 9.59k | code = build_pattern_data(&(pptrn->ppat_data), |
154 | 9.59k | ppixinfo, type, xres, yres, pmem); |
155 | 9.59k | if (code < 0) { |
156 | 0 | pcl_pattern_free_pattern(pmem, pptrn, "create PCL pattern"); |
157 | 0 | return code; |
158 | 0 | } |
159 | | |
160 | 9.59k | *ppptrn = pptrn; |
161 | 9.59k | return 0; |
162 | 9.59k | } |
163 | | |
164 | | /* |
165 | | * Get a PCL user-defined pattern. A null return indicates the pattern is |
166 | | * not defined. |
167 | | */ |
168 | | pcl_pattern_t * |
169 | | pcl_pattern_get_pcl_uptrn(pcl_state_t * pcs, int id) |
170 | 73 | { |
171 | 73 | if (pcs->last_pcl_uptrn_id != id) { |
172 | 71 | pcl_id_t key; |
173 | | |
174 | 71 | pcs->last_pcl_uptrn_id = id; |
175 | 71 | id_set_value(key, id); |
176 | 71 | if (!pl_dict_lookup(&pcs->pcl_patterns, |
177 | 71 | id_key(key), |
178 | 71 | 2, (void **)&pcs->plast_pcl_uptrn, false, NULL)) |
179 | 71 | pcs->plast_pcl_uptrn = 0; |
180 | 71 | } |
181 | | |
182 | 73 | return pcs->plast_pcl_uptrn; |
183 | 73 | } |
184 | | |
185 | | /* |
186 | | * Define a PCL user-defined pattern. This procedure updates the cached |
187 | | * information, hence it should be used for all definitions. To undefine |
188 | | * an entry, set the second operard to null. |
189 | | * |
190 | | * Returns 0 on success, < 0 in the event of an error. |
191 | | */ |
192 | | static int |
193 | | define_pcl_ptrn(pcl_state_t * pcs, int id, pcl_pattern_t * pptrn, bool gl2) |
194 | 1.84k | { |
195 | 1.84k | pcl_id_t key; |
196 | 1.84k | pl_dict_t *pd = (gl2 ? &pcs->gl_patterns : &pcs->pcl_patterns); |
197 | | |
198 | 1.84k | id_set_value(key, id); |
199 | 1.84k | if (pptrn == 0) |
200 | 1.84k | pl_dict_undef(pd, id_key(key), 2); |
201 | 0 | else if (pl_dict_put(pd, id_key(key), 2, pptrn) < 0) { |
202 | | /* on error, pl_dict_put consumes pptrn */ |
203 | 0 | return e_Memory; |
204 | 0 | } |
205 | | |
206 | 1.84k | if (gl2) { |
207 | 1.84k | if (pcs->last_gl2_RF_indx == id) |
208 | 223 | pcs->plast_gl2_uptrn = pptrn; |
209 | 1.84k | } else { /* pcl pattern */ |
210 | 0 | if (pcs->last_pcl_uptrn_id == id) |
211 | 0 | pcs->plast_pcl_uptrn = pptrn; |
212 | 0 | } |
213 | 1.84k | return 0; |
214 | 1.84k | } |
215 | | |
216 | | /* |
217 | | * Delete all temporary patterns or all patterns, based on the value of |
218 | | * the operand. |
219 | | */ |
220 | | static int |
221 | | delete_all_pcl_ptrns(bool renderings, bool tmp_only, pcl_state_t * pcs) |
222 | 33.3k | { |
223 | 33.3k | pcl_pattern_t *pptrn; |
224 | 33.3k | pl_dict_enum_t denum; |
225 | 33.3k | gs_const_string plkey; |
226 | 33.3k | pl_dict_t *pdict[2]; |
227 | 33.3k | int code = 0; |
228 | 33.3k | int i; |
229 | | |
230 | 33.3k | pdict[0] = &pcs->pcl_patterns; |
231 | 33.3k | pdict[1] = &pcs->gl_patterns; |
232 | | |
233 | 100k | for (i = 0; i < 2; i++) { |
234 | 66.7k | pl_dict_enum_begin(pdict[i], &denum); |
235 | 68.6k | while (pl_dict_enum_next(&denum, &plkey, (void **)&pptrn)) { |
236 | 1.84k | if (!tmp_only || (pptrn->ppat_data->storage == pcds_temporary)) { |
237 | 1.84k | short idx = (plkey.data[0] << 8) + plkey.data[1]; |
238 | | |
239 | 1.84k | code = define_pcl_ptrn(pcs, idx, NULL, |
240 | 1.84k | (pdict[i] == &pcs->gl_patterns)); |
241 | 1.84k | if (code < 0) |
242 | 0 | return code; |
243 | | /* NB this should be checked - if instead of |
244 | | else-if? */ |
245 | 1.84k | } else if (renderings) |
246 | 0 | free_pattern_rendering(pcs->memory, pptrn); |
247 | 1.84k | } |
248 | 66.7k | } |
249 | 33.3k | return code; |
250 | 33.3k | } |
251 | | |
252 | | /* |
253 | | * Get a GL/2 user defined pattern. A null return indicates there is no pattern |
254 | | * defined for the index. |
255 | | */ |
256 | | pcl_pattern_t * |
257 | | pcl_pattern_get_gl_uptrn(pcl_state_t * pcs, int indx) |
258 | 32.4k | { |
259 | 32.4k | if (pcs->last_gl2_RF_indx != indx) { |
260 | 5.94k | pcl_id_t key; |
261 | | |
262 | 5.94k | pcs->last_gl2_RF_indx = indx; |
263 | 5.94k | id_set_value(key, indx); |
264 | 5.94k | if (!pl_dict_lookup(&pcs->gl_patterns, |
265 | 5.94k | id_key(key), |
266 | 5.94k | 2, (void **)(&pcs->plast_gl2_uptrn), false, NULL)) |
267 | 847 | pcs->plast_gl2_uptrn = 0; |
268 | 5.94k | } |
269 | | |
270 | 32.4k | return pcs->plast_gl2_uptrn; |
271 | 32.4k | } |
272 | | |
273 | | /* |
274 | | * Create and define a GL/2 user-define pattern. This is the only pattern- |
275 | | * control like facility provided for GL/2. To undefine patterns, use null |
276 | | * as the second operand. See pcpatrn.h for further information. |
277 | | * |
278 | | * Note that RF patterns may be either colored or uncolored. At the GL/2 level |
279 | | * the determination is made based on whether or not they contain pen indices |
280 | | * other than 0 or 1. At this level the determination is based on the depth |
281 | | * of the data pixmap: 1 for uncolored, 8 for colored. |
282 | | * |
283 | | * Returns 0 on success, < 0 in the event of an error. |
284 | | */ |
285 | | int |
286 | | pcl_pattern_RF(int indx, const gs_depth_bitmap * ppixmap, pcl_state_t * pcs) |
287 | 885k | { |
288 | 885k | pcl_id_t key; |
289 | 885k | pcl_pattern_t *pptrn = 0; |
290 | | |
291 | 885k | id_set_value(key, indx); |
292 | | |
293 | 885k | if (ppixmap != 0) { |
294 | 8.10k | pcl_pattern_type_t type = (ppixmap->pix_depth == 1 |
295 | 8.10k | ? pcl_pattern_uncolored |
296 | 8.10k | : pcl_pattern_colored); |
297 | | /* RF appears to use the resolution of the device contrary to |
298 | | what the pcl documentation implies */ |
299 | 8.10k | gx_device *pdev = gs_currentdevice(pcs->pgs); |
300 | 8.10k | int code = pcl_pattern_build_pattern(&pptrn, |
301 | 8.10k | ppixmap, |
302 | 8.10k | type, |
303 | 8.10k | (int)pdev->HWResolution[0], |
304 | 8.10k | (int)pdev->HWResolution[1], |
305 | 8.10k | pcs->memory); |
306 | | |
307 | 8.10k | if (code < 0) { |
308 | 0 | gs_free_object(pcs->memory, ppixmap->data, "pcl_pattern_RF"); |
309 | 0 | return code; |
310 | 0 | } |
311 | | |
312 | 8.10k | if (pl_dict_put(&pcs->gl_patterns, id_key(key), 2, pptrn) < 0) { |
313 | 0 | return e_Memory; |
314 | 0 | } |
315 | | |
316 | 8.10k | } else |
317 | 877k | pl_dict_undef(&pcs->gl_patterns, id_key(key), 2); |
318 | | |
319 | 885k | if (pcs->last_gl2_RF_indx == indx) |
320 | 55.5k | pcs->plast_gl2_uptrn = pptrn; |
321 | | |
322 | 885k | return 0; |
323 | 885k | } |
324 | | |
325 | | /* |
326 | | * The PCL user-define pattern type. For memory management reasons, this has |
327 | | * a transitory existence. |
328 | | * |
329 | | * This object comes in two forms, with and without resolution. Which form |
330 | | * applies is determined based on the size of the received data array as |
331 | | * compared to that indicated by the height, width, and depth fields |
332 | | * |
333 | | * Note: These structures are defined by HP. |
334 | | */ |
335 | | typedef struct pcl_upattern0_s |
336 | | { |
337 | | byte format; /* actually pcl_pattern_type_t */ |
338 | | byte cont; /* continuation; currently unused */ |
339 | | byte depth; /* bits per pixel; 1 or 8 */ |
340 | | byte dummy; /* reserved - currently unused */ |
341 | | byte height[2]; /* height in pixels */ |
342 | | byte width[2]; /* width in pixels */ |
343 | | byte data[1]; /* actual size derived from hgiht, width, and bits */ |
344 | | } pcl_upattern0_t; |
345 | | |
346 | | typedef struct pcl_upattern1_s |
347 | | { |
348 | | byte format; /* actually pcl_pattern_type_t */ |
349 | | byte cont; /* continuation; currently unused */ |
350 | | byte depth; /* bits per pixel; 1 or 8 */ |
351 | | byte dummy; /* reserved - currently unused */ |
352 | | byte height[2]; /* height in pixels */ |
353 | | byte width[2]; /* width in pixels */ |
354 | | byte xres[2]; /* width resolution */ |
355 | | byte yres[2]; /* height resolution */ |
356 | | byte data[1]; /* actual size derived from hgiht, width, and bits */ |
357 | | } pcl_upattern1_t; |
358 | | |
359 | | /* |
360 | | * ESC * c # W |
361 | | * |
362 | | * Download Pattern |
363 | | */ |
364 | | static int |
365 | | download_pcl_pattern(pcl_args_t * pargs, pcl_state_t * pcs) |
366 | 66 | { |
367 | 66 | uint count = arg_data_size(pargs); |
368 | 66 | const pcl_upattern0_t *puptrn0 = (pcl_upattern0_t *) arg_data(pargs); |
369 | 66 | uint format, depth, ndsize, dsize; |
370 | 66 | size_t rsize; |
371 | 66 | gs_depth_bitmap pixinfo; |
372 | 66 | int xres = 300, yres = 300; |
373 | 66 | pcl_pattern_t *pptrn = 0; |
374 | 66 | int code = 0; |
375 | | |
376 | | #ifdef DEBUG |
377 | | if (gs_debug_c('i')) { |
378 | | pcl_debug_dump_data(pcs->memory, arg_data(pargs), uint_arg(pargs)); |
379 | | } |
380 | | #endif |
381 | | |
382 | 66 | format = puptrn0->format; |
383 | 66 | if (format == 20) { |
384 | 0 | if (count < 12) |
385 | 0 | return e_Range; |
386 | | /* non data size - the size of the parameters that describe the data */ |
387 | 0 | ndsize = sizeof(pcl_upattern1_t) - 1; |
388 | 66 | } else { |
389 | 66 | if (count < 8) |
390 | 9 | return e_Range; |
391 | | /* non data size - the size of the parameters that describe the data */ |
392 | 57 | ndsize = sizeof(pcl_upattern0_t) - 1; |
393 | 57 | } |
394 | 57 | pixinfo.num_comps = 1; |
395 | 57 | pixinfo.size.x = (((uint) puptrn0->width[0]) << 8) + puptrn0->width[1]; |
396 | 57 | pixinfo.size.y = (((uint) puptrn0->height[0]) << 8) + puptrn0->height[1]; |
397 | 57 | depth = puptrn0->depth & 0xf; |
398 | 57 | pixinfo.pix_depth = depth; |
399 | 57 | pixinfo.raster = (pixinfo.size.x * depth + 7) / 8; |
400 | 57 | pixinfo.id = gx_no_bitmap_id; |
401 | 57 | rsize = pixinfo.raster * pixinfo.size.y; |
402 | 57 | dsize = min(count - ndsize, rsize); |
403 | | |
404 | | /* check for legitimate format */ |
405 | 57 | if ((format == 0) || (format == 20)) { |
406 | 3 | if (depth != 1) |
407 | 3 | return e_Range; |
408 | 54 | } else if ((format != 1) || |
409 | 0 | ((depth != 1) && (depth != 8)) || |
410 | 0 | (pixinfo.size.x == 0) || (pixinfo.size.y == 0)) |
411 | 54 | return e_Range; |
412 | | |
413 | 0 | if (rsize == 0) |
414 | 0 | return e_Range; |
415 | | |
416 | | /* allocate space for the array */ |
417 | 0 | pixinfo.data = gs_alloc_bytes(pcs->memory, rsize, "download PCL pattern"); |
418 | |
|
419 | 0 | if (pixinfo.data == 0) |
420 | 0 | return e_Memory; |
421 | | |
422 | 0 | if (format == 20) { |
423 | 0 | pcl_upattern1_t *puptrn1 = (pcl_upattern1_t *) puptrn0; |
424 | |
|
425 | 0 | xres = (((uint) puptrn1->xres[0]) << 8) + puptrn1->xres[1]; |
426 | 0 | yres = (((uint) puptrn1->yres[0]) << 8) + puptrn1->yres[1]; |
427 | 0 | memcpy(pixinfo.data, puptrn1->data, dsize); |
428 | 0 | } else { |
429 | 0 | memcpy(pixinfo.data, puptrn0->data, dsize); |
430 | 0 | } |
431 | 0 | if (dsize < rsize) |
432 | 0 | memset(pixinfo.data + dsize, 0, rsize - dsize); |
433 | | |
434 | | /* build the pattern */ |
435 | 0 | code = pcl_pattern_build_pattern(&(pptrn), |
436 | 0 | &pixinfo, |
437 | 0 | (format == 1 ? pcl_pattern_colored |
438 | 0 | : pcl_pattern_uncolored), |
439 | 0 | xres, yres, pcs->memory); |
440 | | |
441 | | /* place the pattern into the pattern dictionary */ |
442 | 0 | if ((code < 0) || |
443 | 0 | ((code = define_pcl_ptrn(pcs, pcs->pattern_id, pptrn, false)) < 0)) { |
444 | 0 | if (pptrn == NULL) |
445 | 0 | gs_free_object(pcs->memory, |
446 | 0 | (void *)pixinfo.data, "download PCL pattern"); |
447 | 0 | } |
448 | |
|
449 | 0 | return code; |
450 | 0 | } |
451 | | |
452 | | /* |
453 | | * ESC * c # Q |
454 | | * |
455 | | * Pattern contorl. |
456 | | */ |
457 | | static int |
458 | | pattern_control(pcl_args_t * pargs, pcl_state_t * pcs) |
459 | 60 | { |
460 | 60 | pcl_pattern_t *pptrn = 0; |
461 | 60 | int code = 0; |
462 | | |
463 | 60 | switch (int_arg(pargs)) { |
464 | | |
465 | | /* delete all patterns */ |
466 | 50 | case 0: |
467 | 50 | code = delete_all_pcl_ptrns(false, false, pcs); |
468 | 50 | break; |
469 | | |
470 | | /* delete all temporary patterns */ |
471 | 0 | case 1: |
472 | 0 | code = delete_all_pcl_ptrns(false, true, pcs); |
473 | 0 | break; |
474 | | |
475 | | /* delete last specified pattern */ |
476 | 0 | case 2: |
477 | 0 | define_pcl_ptrn(pcs, pcs->pattern_id, NULL, false); |
478 | | |
479 | | /* make last specified pattern temporary */ |
480 | 0 | case 4: |
481 | 0 | pptrn = pcl_pattern_get_pcl_uptrn(pcs, pcs->pattern_id); |
482 | 0 | if (pptrn != 0) |
483 | 0 | pptrn->ppat_data->storage = pcds_temporary; |
484 | 0 | break; |
485 | | |
486 | | /* make last specified pattern permanent */ |
487 | 0 | case 5: |
488 | 0 | pptrn = pcl_pattern_get_pcl_uptrn(pcs, pcs->pattern_id); |
489 | 0 | if (pptrn != 0) |
490 | 0 | pptrn->ppat_data->storage = pcds_permanent; |
491 | 0 | break; |
492 | | |
493 | 10 | default: |
494 | 10 | break; |
495 | 60 | } |
496 | | |
497 | 60 | return code; |
498 | 60 | } |
499 | | |
500 | | static int |
501 | | upattern_do_copy(pcl_state_t * psaved, const pcl_state_t * pcs, |
502 | | pcl_copy_operation_t operation) |
503 | 0 | { |
504 | 0 | int i; |
505 | | |
506 | | /* copy back any patterns created during macro invocation. */ |
507 | 0 | if ((operation & pcl_copy_after) != 0) { |
508 | 0 | for (i = 0; i < countof(pcs->bi_pattern_array); i++) |
509 | 0 | psaved->bi_pattern_array[i] = pcs->bi_pattern_array[i]; |
510 | 0 | psaved->gl_patterns = pcs->gl_patterns; |
511 | 0 | psaved->pcl_patterns = pcs->pcl_patterns; |
512 | 0 | psaved->last_pcl_uptrn_id = pcs->last_pcl_uptrn_id; |
513 | 0 | psaved->plast_pcl_uptrn = pcs->plast_pcl_uptrn; |
514 | 0 | psaved->last_gl2_RF_indx = pcs->last_gl2_RF_indx; |
515 | 0 | psaved->plast_gl2_uptrn = pcs->plast_gl2_uptrn; |
516 | 0 | psaved->punsolid_pattern = pcs->punsolid_pattern; |
517 | 0 | psaved->psolid_pattern = pcs->psolid_pattern; |
518 | 0 | } |
519 | 0 | return 0; |
520 | 0 | } |
521 | | |
522 | | /* |
523 | | * Initialization and reset routines. |
524 | | */ |
525 | | static int |
526 | | upattern_do_registration(pcl_parser_state_t * pcl_parser_state, |
527 | | gs_memory_t * pmem) |
528 | 16.1k | { |
529 | 16.1k | DEFINE_CLASS('*') { |
530 | 16.1k | 'c', 'W', |
531 | 16.1k | PCL_COMMAND("Download Pattern", download_pcl_pattern, |
532 | 16.1k | pca_bytes | pca_in_rtl) |
533 | 16.1k | }, { |
534 | 16.1k | 'c', 'Q', |
535 | 16.1k | PCL_COMMAND("Pattern Control", |
536 | 16.1k | pattern_control, |
537 | 16.1k | pca_neg_ignore | pca_big_ignore | pca_in_rtl) |
538 | 16.1k | }, END_CLASS return 0; |
539 | 16.1k | } |
540 | | |
541 | | static int |
542 | | upattern_do_reset(pcl_state_t * pcs, pcl_reset_type_t type) |
543 | 49.4k | { |
544 | 49.4k | int code = 0; |
545 | | |
546 | 49.4k | if ((type & pcl_reset_initial) != 0) { |
547 | 16.1k | pl_dict_init(&pcs->pcl_patterns, pcs->memory, |
548 | 16.1k | pcl_pattern_free_pattern); |
549 | 16.1k | pl_dict_init(&pcs->gl_patterns, pcs->memory, |
550 | 16.1k | pcl_pattern_free_pattern); |
551 | 16.1k | pcs->last_pcl_uptrn_id = -1; |
552 | 16.1k | pcs->plast_pcl_uptrn = 0; |
553 | 16.1k | pcs->last_gl2_RF_indx = -1; |
554 | 16.1k | pcs->plast_gl2_uptrn = 0; |
555 | | |
556 | 16.1k | } else |
557 | 33.3k | if ((type & |
558 | 33.3k | (pcl_reset_cold | pcl_reset_printer | pcl_reset_permanent)) != |
559 | 33.3k | 0) { |
560 | 33.3k | code = delete_all_pcl_ptrns(true, !(type & pcl_reset_permanent), pcs); |
561 | 33.3k | pcl_pattern_clear_bi_patterns(pcs); |
562 | | /* GL's IN command takes care of the GL patterns */ |
563 | 33.3k | } |
564 | | |
565 | 49.4k | return code; |
566 | 49.4k | } |
567 | | |
568 | | const pcl_init_t pcl_upattern_init = |
569 | | { upattern_do_registration, upattern_do_reset, upattern_do_copy }; |