/src/ghostpdl/pcl/pcl/pcommand.c
Line | Count | Source |
1 | | /* Copyright (C) 2001-2023 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 | | /* pcommand.c - Utilities for PCL 5 commands */ |
18 | | |
19 | | #include "std.h" |
20 | | #include "memory_.h" |
21 | | #include "gstypes.h" |
22 | | #include "gsmemory.h" |
23 | | #include "gsmatrix.h" |
24 | | #include "gxstate.h" |
25 | | #include "gsdevice.h" |
26 | | #include "pcindxed.h" |
27 | | #include "pcommand.h" |
28 | | #include "pcparse.h" |
29 | | #include "pcstate.h" |
30 | | #include "pcparam.h" |
31 | | #include "pcident.h" |
32 | | #include "pgmand.h" /* temporary */ |
33 | | /* |
34 | | * Get the command argument as an int, uint, or float. |
35 | | */ |
36 | | int |
37 | | int_value(const pcl_value_t * pv) |
38 | 194k | { |
39 | 194k | return (int)(value_is_neg(pv) ? -(int)pv->i : pv->i); |
40 | 194k | } |
41 | | |
42 | | uint |
43 | | uint_value(const pcl_value_t * pv) |
44 | 272k | { |
45 | 272k | return pv->i; |
46 | 272k | } |
47 | | |
48 | | float |
49 | | float_value(const pcl_value_t * pv) |
50 | 36.0k | { |
51 | 36.0k | return (value_is_float(pv) ? |
52 | 2.20k | (float)(value_is_neg(pv) ? -(int)pv->i - pv->fraction |
53 | 2.20k | : pv->i + pv->fraction) |
54 | 36.0k | : (float)int_value(pv)); |
55 | 36.0k | } |
56 | | |
57 | | /* |
58 | | * "put" parameters to the device. |
59 | | */ |
60 | | static int |
61 | | transfer_param1(gs_c_param_list * alist, pcl_state_t * pcs) |
62 | 411k | { |
63 | 411k | gs_c_param_list_read(alist); |
64 | | |
65 | 411k | return gs_gstate_putdeviceparams(pcs->pgs, gs_currentdevice(pcs->pgs), |
66 | 411k | (gs_param_list *) alist); |
67 | 411k | } |
68 | | |
69 | | /* |
70 | | * Set a Boolean parameter. |
71 | | */ |
72 | | int |
73 | | put_param1_bool(pcl_state_t * pcs, gs_param_name pkey, bool value) |
74 | 308k | { |
75 | 308k | gs_c_param_list list; |
76 | 308k | int code; |
77 | | |
78 | 308k | gs_c_param_list_write(&list, pcs->memory); |
79 | 308k | code = param_write_bool((gs_param_list *) & list, pkey, &value); |
80 | 308k | if (code >= 0) |
81 | 308k | code = transfer_param1(&list, pcs); |
82 | | |
83 | 308k | gs_c_param_list_release(&list); |
84 | 308k | return code; |
85 | 308k | } |
86 | | |
87 | | /* |
88 | | * Set a float parameter. |
89 | | */ |
90 | | int |
91 | | put_param1_float(pcl_state_t * pcs, gs_param_name pkey, double value) |
92 | 0 | { |
93 | 0 | gs_c_param_list list; |
94 | 0 | float fval = value; |
95 | 0 | int code; |
96 | |
|
97 | 0 | gs_c_param_list_write(&list, pcs->memory); |
98 | 0 | code = param_write_float((gs_param_list *) & list, pkey, &fval); |
99 | 0 | if (code >= 0) |
100 | 0 | code = transfer_param1(&list, pcs); |
101 | |
|
102 | 0 | gs_c_param_list_release(&list); |
103 | 0 | return code; |
104 | 0 | } |
105 | | |
106 | | /* |
107 | | * Set an integer parameter. |
108 | | */ |
109 | | int |
110 | | put_param1_int(pcl_state_t * pcs, gs_param_name pkey, int value) |
111 | 50.9k | { |
112 | 50.9k | gs_c_param_list list; |
113 | 50.9k | int code; |
114 | | |
115 | 50.9k | gs_c_param_list_write(&list, pcs->memory); |
116 | 50.9k | code = param_write_int((gs_param_list *) & list, pkey, &value); |
117 | 50.9k | if (code >= 0) |
118 | 50.9k | code = transfer_param1(&list, pcs); |
119 | | |
120 | 50.9k | gs_c_param_list_release(&list); |
121 | 50.9k | return code; |
122 | 50.9k | } |
123 | | |
124 | | /* |
125 | | * Set a parameter consisting of an array of two floats. This is used to pass |
126 | | * the paper size parameter to the device. |
127 | | */ |
128 | | int |
129 | | put_param1_float_array(pcl_state_t * pcs, gs_param_name pkey, float pf[2] |
130 | | ) |
131 | 51.8k | { |
132 | 51.8k | gs_c_param_list list; |
133 | 51.8k | gs_param_float_array pf_array; |
134 | 51.8k | int code = 0; |
135 | | |
136 | 51.8k | pf_array.data = pf; |
137 | 51.8k | pf_array.size = 2; |
138 | 51.8k | pf_array.persistent = false; |
139 | | |
140 | 51.8k | gs_c_param_list_write(&list, pcs->memory); |
141 | 51.8k | code = param_write_float_array((gs_param_list *) & list, pkey, &pf_array); |
142 | 51.8k | if (code >= 0) |
143 | 51.8k | code = transfer_param1(&list, pcs); |
144 | | |
145 | 51.8k | gs_c_param_list_release(&list); |
146 | 51.8k | return code; |
147 | 51.8k | } |
148 | | |
149 | | int |
150 | | put_param1_string(pcl_state_t * pcs, gs_param_name pkey, const char *str) |
151 | 0 | { |
152 | 0 | gs_c_param_list list; |
153 | 0 | gs_param_string paramstr; |
154 | 0 | int code; |
155 | |
|
156 | 0 | gs_c_param_list_write(&list, pcs->memory); |
157 | 0 | param_string_from_string(paramstr, str); |
158 | 0 | code = param_write_string((gs_param_list *) & list, pkey, ¶mstr); |
159 | 0 | if (code >= 0) |
160 | 0 | code = transfer_param1(&list, pcs); |
161 | |
|
162 | 0 | gs_c_param_list_release(&list); |
163 | 0 | return code; |
164 | 0 | } |
165 | | |
166 | | /* initilialize the parser states */ |
167 | | int |
168 | | pcl_do_registrations(pcl_state_t * pcs, pcl_parser_state_t * pst) |
169 | 16.1k | { |
170 | 16.1k | const pcl_init_t **init; |
171 | 16.1k | int code; |
172 | | |
173 | | /* initialize gl/2 command counter */ |
174 | 16.1k | hpgl_init_command_index(&pst->hpgl_parser_state, pcs->memory); |
175 | 16.1k | pcs->parse_data = pst->hpgl_parser_state; |
176 | | /* initialize pcl's command counter */ |
177 | 16.1k | code = pcl_init_command_index(pst, pcs); |
178 | 16.1k | if (code < 0) { |
179 | 0 | if (pst->hpgl_parser_state != NULL) |
180 | 0 | gs_free_object(pcs->memory, pst->hpgl_parser_state, "hpgl_init_command_index"); |
181 | 0 | return code; |
182 | 0 | } |
183 | 581k | for (init = pcl_init_table; *init; ++init) { |
184 | 565k | if ((*init)->do_registration) { |
185 | 532k | code = (*(*init)->do_registration) (pst, pcs->memory); |
186 | 532k | if (code < 0) { |
187 | 0 | lprintf1("Error %d during initialization!\n", code); |
188 | 0 | return code; |
189 | 0 | } |
190 | 532k | } |
191 | 565k | } |
192 | 16.1k | return 0; |
193 | 16.1k | } |
194 | | |
195 | | /* Similar to pcl_do_resets() but doesn't teminate loop immediately after |
196 | | error. */ |
197 | | static int |
198 | | pcl_do_resets_permanent(pcl_state_t * pcs) |
199 | 0 | { |
200 | 0 | const pcl_init_t **init = pcl_init_table; |
201 | 0 | int code = 0; |
202 | |
|
203 | 0 | for (; *init; ++init) { |
204 | 0 | if ((*init)->do_reset) { |
205 | 0 | int code2 = (*(*init)->do_reset) (pcs, pcl_reset_permanent); |
206 | 0 | if (code2 < 0 && code >= 0) { |
207 | 0 | code = code2; |
208 | 0 | } |
209 | 0 | } |
210 | 0 | } |
211 | 0 | return code; |
212 | 0 | } |
213 | | |
214 | | /* |
215 | | * Run the reset code of all the modules. |
216 | | */ |
217 | | int |
218 | | pcl_do_resets(pcl_state_t * pcs, pcl_reset_type_t type) |
219 | 48.9k | { |
220 | 48.9k | const pcl_init_t **init = pcl_init_table; |
221 | 48.9k | int code = 0; |
222 | 48.9k | if (type == pcl_reset_permanent) { |
223 | | /* We do not want early termination of the loop. */ |
224 | 0 | return pcl_do_resets_permanent(pcs); |
225 | 0 | } |
226 | | |
227 | 1.76M | for (; *init; ++init) { |
228 | 1.71M | if ((*init)->do_reset) { |
229 | 1.12M | code = (*(*init)->do_reset) (pcs, type); |
230 | 1.12M | if (code < 0) |
231 | 0 | break; |
232 | 1.12M | } |
233 | 1.71M | } |
234 | 48.9k | return code; |
235 | 48.9k | } |
236 | | |
237 | | /* |
238 | | * "Cold start" initialization of the graphic state. This is provided as a |
239 | | * special routine to avoid (as much as possible) order depedencies in the |
240 | | * various reset routines used by individual modules. Some of the values |
241 | | * selected may be subsequently overridden by the reset routines; this code |
242 | | * just attempts to set them to reasonable values. |
243 | | */ |
244 | | void |
245 | | pcl_init_state(pcl_state_t * pcs, gs_memory_t * pmem) |
246 | 16.1k | { |
247 | | /* some elementary fields */ |
248 | 16.1k | pcs->memory = pmem; |
249 | 16.1k | pcs->num_copies = 1; |
250 | 16.1k | pcs->output_bin = 1; |
251 | 16.1k | pcs->perforation_skip = 1; |
252 | | |
253 | 16.1k | pcs->font_id_type = numeric_id; |
254 | 16.1k | pcs->macro_id_type = numeric_id; |
255 | | |
256 | 16.1k | pcs->rotate_patterns = true; |
257 | 16.1k | pcs->source_transparent = true; |
258 | 16.1k | pcs->pattern_transparent = true; |
259 | | |
260 | 16.1k | pcs->logical_op = 252; |
261 | | |
262 | 16.1k | pcs->monochrome_mode = 0; |
263 | 16.1k | pcs->render_mode = 3; |
264 | | |
265 | 16.1k | pcs->next_id = 8UL; |
266 | 16.1k | pcl_init_gstate_stk(pcs); |
267 | 16.1k | pcs->configure_appletalk = 0; |
268 | 16.1k | pcs->uom_cp = 7200L / 300L; |
269 | 16.1k | pcs->palette_stack = 0; |
270 | 16.1k | pcs->pdflt_palette = 0; |
271 | 16.1k | pcs->pdflt_frgrnd = 0; |
272 | 16.1k | pcs->pdflt_ht = 0; |
273 | 16.1k | pcs->page_marked = false; |
274 | 16.1k | pcs->cursor_moved = false; |
275 | 16.1k | pcl_cs_base_init(pcs); |
276 | 16.1k | pcl_cs_indexed_init(pcs); |
277 | | |
278 | 16.1k | pcs->cap.x = pcs->cap.y = 0; |
279 | 16.1k | pcs->vmi_cp = 0; |
280 | 16.1k | pcs->halftone_set = false; |
281 | 16.1k | pcs->ppaper_type_table = 0; |
282 | | |
283 | 16.1k | pcs->hpgl_mode = -1; |
284 | 16.1k | } |
285 | | |
286 | | #ifdef DEBUG |
287 | | void |
288 | | pcl_debug_dump_data(gs_memory_t *mem, const byte *d, int len) |
289 | | { |
290 | | int i; |
291 | | |
292 | | dmprintf(mem, "BEGIN RAW DATA\n"); |
293 | | for (i = 0; i < len; i++) { |
294 | | dmprintf2(mem, "%02x%c", |
295 | | d[i], |
296 | | (i % 16 == 15 || i == len - 1) ? '\n' : ' '); |
297 | | } |
298 | | dmprintf(mem, "END RAW DATA\n"); |
299 | | return; |
300 | | } |
301 | | |
302 | | #endif |