/src/ghostpdl/base/gdevepo.c
Line | Count | Source (jump to first uncovered line) |
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 | | /* Device for erasepage optimization subclass device */ |
17 | | |
18 | | #include "math_.h" |
19 | | #include "memory_.h" |
20 | | #include "gx.h" |
21 | | #include "gserrors.h" |
22 | | #include "gsparam.h" |
23 | | #include "gxdevice.h" |
24 | | #include "gsdevice.h" /* requires gsmatrix.h */ |
25 | | #include "gxdcolor.h" /* for gx_device_black/white */ |
26 | | #include "gxiparam.h" /* for image source size */ |
27 | | #include "gxgstate.h" |
28 | | #include "gxpaint.h" |
29 | | #include "gxpath.h" |
30 | | #include "gxcpath.h" |
31 | | #include "gxcmap.h" /* color mapping procs */ |
32 | | #include "gsstype.h" |
33 | | #include "gdevprn.h" |
34 | | #include "gdevp14.h" /* Needed to patch up the procs after compositor creation */ |
35 | | #include "gximage.h" /* For gx_image_enum */ |
36 | | #include "gdevsclass.h" |
37 | | #include "gsstate.h" |
38 | | #include "gxdevsop.h" |
39 | | #include "gdevepo.h" |
40 | | #include <stdlib.h> |
41 | | |
42 | | /* Shorter macros for sanity's sake */ |
43 | 1.16M | #define DPRINTF(m,f) if_debug0m(gs_debug_flag_epo_details, m,f) |
44 | 1.42M | #define DPRINTF1(m,f,a1) if_debug1m(gs_debug_flag_epo_details, m,f, a1) |
45 | | |
46 | | /* This is only called for debugging */ |
47 | | extern void epo_disable(int flag); |
48 | | |
49 | | /* Device procedures, we need quite a lot of them */ |
50 | | static dev_proc_output_page(epo_output_page); |
51 | | static dev_proc_fill_rectangle(epo_fill_rectangle); |
52 | | static dev_proc_fill_path(epo_fill_path); |
53 | | static dev_proc_fill_mask(epo_fill_mask); |
54 | | static dev_proc_fill_trapezoid(epo_fill_trapezoid); |
55 | | static dev_proc_fill_parallelogram(epo_fill_parallelogram); |
56 | | static dev_proc_fill_triangle(epo_fill_triangle); |
57 | | static dev_proc_draw_thin_line(epo_draw_thin_line); |
58 | | static dev_proc_fill_rectangle_hl_color(epo_fill_rectangle_hl_color); |
59 | | static dev_proc_fill_linear_color_scanline(epo_fill_linear_color_scanline); |
60 | | static dev_proc_fill_linear_color_trapezoid(epo_fill_linear_color_trapezoid); |
61 | | static dev_proc_fill_linear_color_triangle(epo_fill_linear_color_triangle); |
62 | | static dev_proc_put_image(epo_put_image); |
63 | | static dev_proc_fillpage(epo_fillpage); |
64 | | static dev_proc_composite(epo_composite); |
65 | | static dev_proc_text_begin(epo_text_begin); |
66 | | static dev_proc_initialize_device_procs(epo_initialize_device_procs); |
67 | | static dev_proc_begin_typed_image(epo_begin_typed_image); |
68 | | static dev_proc_stroke_path(epo_stroke_path); |
69 | | static dev_proc_copy_mono(epo_copy_mono); |
70 | | static dev_proc_copy_color(epo_copy_color); |
71 | | static dev_proc_copy_alpha(epo_copy_alpha); |
72 | | static dev_proc_get_bits_rectangle(epo_get_bits_rectangle); |
73 | | static dev_proc_strip_tile_rectangle(epo_strip_tile_rectangle); |
74 | | static dev_proc_strip_copy_rop2(epo_strip_copy_rop2); |
75 | | static dev_proc_copy_planes(epo_copy_planes); |
76 | | static dev_proc_copy_alpha_hl_color(epo_copy_alpha_hl_color); |
77 | | static dev_proc_process_page(epo_process_page); |
78 | | static dev_proc_transform_pixel_region(epo_transform_pixel_region); |
79 | | static dev_proc_fill_stroke_path(epo_fill_stroke_path); |
80 | | |
81 | | /* The device prototype */ |
82 | | #define MAX_COORD (max_int_in_fixed - 1000) |
83 | | #define MAX_RESOLUTION 4000 |
84 | | |
85 | | #define public_st_epo_device() /* in gsdevice.c */\ |
86 | | gs_public_st_complex_only(st_epo_device, gx_device, EPO_DEVICENAME,\ |
87 | | 0, epo_enum_ptrs, epo_reloc_ptrs, default_subclass_finalize) |
88 | | |
89 | | static |
90 | 198k | ENUM_PTRS_WITH(epo_enum_ptrs, gx_device *dev); |
91 | 66.3k | return 0; /* default case */ |
92 | 66.3k | case 0:ENUM_RETURN(gx_device_enum_ptr(dev->parent)); |
93 | 66.3k | case 1:ENUM_RETURN(gx_device_enum_ptr(dev->child)); |
94 | 198k | ENUM_PTRS_END |
95 | 66.3k | static RELOC_PTRS_WITH(epo_reloc_ptrs, gx_device *dev) |
96 | 66.3k | { |
97 | 66.3k | dev->parent = gx_device_reloc_ptr(dev->parent, gcst); |
98 | 66.3k | dev->child = gx_device_reloc_ptr(dev->child, gcst); |
99 | 66.3k | }RELOC_PTRS_END |
100 | | |
101 | | public_st_epo_device(); |
102 | | |
103 | | const |
104 | | gx_device_epo gs_epo_device = |
105 | | { |
106 | | std_device_dci_type_body_sc(gx_device_epo, epo_initialize_device_procs, |
107 | | EPO_DEVICENAME, &st_epo_device, |
108 | | MAX_COORD, MAX_COORD, |
109 | | MAX_RESOLUTION, MAX_RESOLUTION, |
110 | | 1, 8, 255, 0, 256, 1, NULL, NULL, NULL) |
111 | | }; |
112 | | |
113 | | #undef MAX_COORD |
114 | | #undef MAX_RESOLUTION |
115 | | |
116 | | /* Starting at the top of the device chain (top parent) find */ |
117 | | /* and return the epo device, or NULL if not found. */ |
118 | | static gx_device * |
119 | | find_installed_epo_device(gx_device *dev) |
120 | 1.16M | { |
121 | 1.16M | gx_device *next_dev = dev; |
122 | | |
123 | 1.16M | while (next_dev->parent != NULL) |
124 | 0 | next_dev = next_dev->parent; |
125 | | |
126 | 2.14M | while (next_dev) { |
127 | 1.16M | if (next_dev->procs.fillpage == epo_fillpage) { |
128 | 194k | return next_dev; |
129 | 194k | } |
130 | 974k | next_dev = next_dev->child; |
131 | 974k | } |
132 | 974k | return NULL; |
133 | 1.16M | } |
134 | | |
135 | | /* See if this is a device we can optimize |
136 | | * (currently only the ones that use gx_default_fillpage, which |
137 | | * automatically excludes clist and pdfwrite, etc) |
138 | | */ |
139 | | static bool |
140 | | device_wants_optimization(gx_device *dev) |
141 | 1.16M | { |
142 | 1.16M | gx_device *terminal = dev; |
143 | | |
144 | 1.16M | while(terminal->child != NULL) |
145 | 0 | terminal = terminal->child; |
146 | | |
147 | 1.16M | return (!gs_is_null_device(terminal) && dev_proc(terminal, fillpage) == gx_default_fillpage); |
148 | 1.16M | } |
149 | | |
150 | | /* Use this when debugging to enable/disable epo |
151 | | * (1 - disable, 0 - enable) |
152 | | */ |
153 | | void |
154 | | epo_disable(int flag) |
155 | 0 | { |
156 | 0 | gs_debug[gs_debug_flag_epo_disable] = flag; |
157 | 0 | } |
158 | | |
159 | | static void |
160 | | enable_procs(gx_device *dev) |
161 | 225k | { |
162 | 225k | set_dev_proc(dev, output_page, epo_output_page); |
163 | 225k | set_dev_proc(dev, fill_rectangle, epo_fill_rectangle); |
164 | 225k | set_dev_proc(dev, copy_mono, epo_copy_mono); |
165 | 225k | set_dev_proc(dev, copy_color, epo_copy_color); |
166 | 225k | set_dev_proc(dev, copy_alpha, epo_copy_alpha); |
167 | 225k | set_dev_proc(dev, get_bits_rectangle, epo_get_bits_rectangle); |
168 | 225k | set_dev_proc(dev, fill_path, epo_fill_path); |
169 | 225k | set_dev_proc(dev, stroke_path, epo_stroke_path); |
170 | 225k | set_dev_proc(dev, fill_mask, epo_fill_mask); |
171 | 225k | set_dev_proc(dev, fill_trapezoid, epo_fill_trapezoid); |
172 | 225k | set_dev_proc(dev, fill_parallelogram, epo_fill_parallelogram); |
173 | 225k | set_dev_proc(dev, fill_triangle, epo_fill_triangle); |
174 | 225k | set_dev_proc(dev, draw_thin_line, epo_draw_thin_line); |
175 | 225k | set_dev_proc(dev, strip_tile_rectangle, epo_strip_tile_rectangle); |
176 | 225k | set_dev_proc(dev, begin_typed_image, epo_begin_typed_image); |
177 | 225k | set_dev_proc(dev, composite, epo_composite); |
178 | 225k | set_dev_proc(dev, text_begin, epo_text_begin); |
179 | 225k | set_dev_proc(dev, fill_rectangle_hl_color, epo_fill_rectangle_hl_color); |
180 | 225k | set_dev_proc(dev, fill_linear_color_scanline, epo_fill_linear_color_scanline); |
181 | 225k | set_dev_proc(dev, fill_linear_color_trapezoid, epo_fill_linear_color_trapezoid); |
182 | 225k | set_dev_proc(dev, fill_linear_color_triangle, epo_fill_linear_color_triangle); |
183 | 225k | set_dev_proc(dev, fillpage, epo_fillpage); |
184 | 225k | set_dev_proc(dev, put_image, epo_put_image); |
185 | 225k | set_dev_proc(dev, copy_planes, epo_copy_planes); |
186 | 225k | set_dev_proc(dev, strip_copy_rop2, epo_strip_copy_rop2); |
187 | 225k | set_dev_proc(dev, copy_alpha_hl_color, epo_copy_alpha_hl_color); |
188 | 225k | set_dev_proc(dev, process_page, epo_process_page); |
189 | 225k | set_dev_proc(dev, transform_pixel_region, epo_transform_pixel_region); |
190 | 225k | set_dev_proc(dev, fill_stroke_path, epo_fill_stroke_path); |
191 | 225k | } |
192 | | |
193 | | static void |
194 | | enable_self(gx_device *dev) |
195 | 194k | { |
196 | 194k | erasepage_subclass_data *data = (erasepage_subclass_data *)dev->subclass_data; |
197 | | |
198 | 194k | data->disabled = 0; |
199 | 194k | enable_procs(dev); |
200 | 194k | } |
201 | | |
202 | | static void |
203 | | disable_self(gx_device *dev) |
204 | 27.7k | { |
205 | 27.7k | erasepage_subclass_data *data = (erasepage_subclass_data *)dev->subclass_data; |
206 | | |
207 | 27.7k | data->disabled = 1; |
208 | | |
209 | 27.7k | set_dev_proc(dev, output_page, default_subclass_output_page); |
210 | 27.7k | set_dev_proc(dev, fill_rectangle, default_subclass_fill_rectangle); |
211 | 27.7k | set_dev_proc(dev, copy_mono, default_subclass_copy_mono); |
212 | 27.7k | set_dev_proc(dev, copy_color, default_subclass_copy_color); |
213 | 27.7k | set_dev_proc(dev, copy_alpha, default_subclass_copy_alpha); |
214 | 27.7k | set_dev_proc(dev, get_bits_rectangle, default_subclass_get_bits_rectangle); |
215 | 27.7k | set_dev_proc(dev, fill_path, default_subclass_fill_path); |
216 | 27.7k | set_dev_proc(dev, stroke_path, default_subclass_stroke_path); |
217 | 27.7k | set_dev_proc(dev, fill_mask, default_subclass_fill_mask); |
218 | 27.7k | set_dev_proc(dev, fill_trapezoid, default_subclass_fill_trapezoid); |
219 | 27.7k | set_dev_proc(dev, fill_parallelogram, default_subclass_fill_parallelogram); |
220 | 27.7k | set_dev_proc(dev, fill_triangle, default_subclass_fill_triangle); |
221 | 27.7k | set_dev_proc(dev, draw_thin_line, default_subclass_draw_thin_line); |
222 | 27.7k | set_dev_proc(dev, strip_tile_rectangle, default_subclass_strip_tile_rectangle); |
223 | 27.7k | set_dev_proc(dev, begin_typed_image, default_subclass_begin_typed_image); |
224 | 27.7k | set_dev_proc(dev, composite, default_subclass_composite); |
225 | 27.7k | set_dev_proc(dev, text_begin, default_subclass_text_begin); |
226 | 27.7k | set_dev_proc(dev, fill_rectangle_hl_color, default_subclass_fill_rectangle_hl_color); |
227 | 27.7k | set_dev_proc(dev, fill_linear_color_scanline, default_subclass_fill_linear_color_scanline); |
228 | 27.7k | set_dev_proc(dev, fill_linear_color_trapezoid, default_subclass_fill_linear_color_trapezoid); |
229 | 27.7k | set_dev_proc(dev, fill_linear_color_triangle, default_subclass_fill_linear_color_triangle); |
230 | | /* NOT fillpage! */ |
231 | 27.7k | set_dev_proc(dev, put_image, default_subclass_put_image); |
232 | 27.7k | set_dev_proc(dev, copy_planes, default_subclass_copy_planes); |
233 | 27.7k | set_dev_proc(dev, strip_copy_rop2, default_subclass_strip_copy_rop2); |
234 | 27.7k | set_dev_proc(dev, copy_alpha_hl_color, default_subclass_copy_alpha_hl_color); |
235 | 27.7k | set_dev_proc(dev, process_page, default_subclass_process_page); |
236 | 27.7k | set_dev_proc(dev, transform_pixel_region, default_subclass_transform_pixel_region); |
237 | 27.7k | set_dev_proc(dev, fill_stroke_path, default_subclass_fill_stroke_path); |
238 | 27.7k | set_dev_proc(dev, lock_pattern, default_subclass_lock_pattern); |
239 | 27.7k | } |
240 | | |
241 | | int |
242 | | epo_check_and_install(gx_device *dev) |
243 | 1.16M | { |
244 | 1.16M | int code = 0; |
245 | 1.16M | gx_device *installed_epo_device = NULL; |
246 | 1.16M | bool can_optimize = false; |
247 | | |
248 | | /* Debugging mode to totally disable this */ |
249 | 1.16M | if (gs_debug_c(gs_debug_flag_epo_disable)) { |
250 | 0 | return code; |
251 | 0 | } |
252 | | |
253 | 1.16M | DPRINTF1(dev->memory, "current device is %s\n", dev->dname); |
254 | | |
255 | 1.16M | installed_epo_device = find_installed_epo_device(dev); |
256 | | |
257 | 1.16M | if (installed_epo_device != NULL) { |
258 | 194k | DPRINTF1(dev->memory, "device %s already installed\n", EPO_DEVICENAME); |
259 | | /* This is looking for the case where the device |
260 | | * changed into something we can't optimize, after it was already installed |
261 | | * (could be clist or some other weird thing) |
262 | | */ |
263 | 194k | if (installed_epo_device->child) { |
264 | 194k | can_optimize = device_wants_optimization(installed_epo_device->child); |
265 | 194k | } |
266 | 194k | if (!can_optimize) { |
267 | 0 | DPRINTF1(dev->memory, "child %s can't be optimized, uninstalling\n", installed_epo_device->child->dname); |
268 | | /* Not doing any pending fillpages because we are about to do a fillpage anyway */ |
269 | 0 | disable_self(installed_epo_device); |
270 | 0 | return code; |
271 | 0 | } |
272 | 974k | } else { |
273 | 974k | can_optimize = device_wants_optimization(dev); |
274 | 974k | } |
275 | | |
276 | | /* Already installed, nothing to do */ |
277 | 1.16M | if (installed_epo_device != NULL) { |
278 | 194k | enable_self(installed_epo_device); |
279 | 194k | return code; |
280 | 194k | } |
281 | | |
282 | | /* See if we can optimize */ |
283 | 974k | if (!can_optimize) { |
284 | 942k | DPRINTF(dev->memory, "device doesn't want optimization, not installing\n"); |
285 | 942k | return code; |
286 | 942k | } |
287 | | |
288 | | /* Always install us as low down the chain as possible. */ |
289 | 31.6k | while (dev->child) |
290 | 0 | dev = dev->child; |
291 | | |
292 | | /* Install subclass for optimization */ |
293 | 31.6k | code = gx_device_subclass(dev, (gx_device *)&gs_epo_device, sizeof(erasepage_subclass_data)); |
294 | 31.6k | if (code < 0) { |
295 | 6 | DPRINTF1(dev->memory, "ERROR installing device %s\n", EPO_DEVICENAME); |
296 | 6 | return code; |
297 | 6 | } |
298 | | |
299 | 31.6k | DPRINTF1(dev->memory, "SUCCESS installed device %s\n", dev->dname); |
300 | 31.6k | return code; |
301 | 31.6k | } |
302 | | |
303 | | static int |
304 | | epo_handle_erase_page(gx_device *dev) |
305 | 27.7k | { |
306 | 27.7k | erasepage_subclass_data *data = (erasepage_subclass_data *)dev->subclass_data; |
307 | 27.7k | int code = 0; |
308 | | |
309 | 27.7k | if (data->disabled) |
310 | 0 | return 0; |
311 | | |
312 | 27.7k | if (gs_debug_c(gs_debug_flag_epo_install_only)) { |
313 | 0 | disable_self(dev); |
314 | 0 | DPRINTF1(dev->memory, "Uninstall erasepage, device=%s\n", dev->dname); |
315 | 0 | return code; |
316 | 0 | } |
317 | | |
318 | 27.7k | DPRINTF1(dev->memory, "Do fillpage, Uninstall erasepage, device %s\n", dev->dname); |
319 | | |
320 | | /* Just do a fill_rectangle (using saved color) */ |
321 | 27.7k | if (dev->child && dev->child->is_open && data->queued && dev_proc(dev->child, fill_rectangle) != NULL) { |
322 | 27.7k | code = dev_proc(dev->child, fill_rectangle)(dev->child, |
323 | 27.7k | 0, 0, |
324 | 27.7k | dev->child->width, |
325 | 27.7k | dev->child->height, |
326 | 27.7k | data->last_color); |
327 | 27.7k | } |
328 | | /* Disable the epo device */ |
329 | 27.7k | disable_self(dev); |
330 | | |
331 | 27.7k | return code; |
332 | 27.7k | } |
333 | | |
334 | | int epo_fillpage(gx_device *dev, gs_gstate * pgs, gx_device_color *pdevc) |
335 | 225k | { |
336 | 225k | erasepage_subclass_data *data = (erasepage_subclass_data *)dev->subclass_data; |
337 | | |
338 | 225k | if (data->disabled || gs_debug_c(gs_debug_flag_epo_install_only)) { |
339 | 0 | return default_subclass_fillpage(dev, pgs, pdevc); |
340 | 0 | } |
341 | | |
342 | | /* If color is not pure, don't defer this, uninstall and do it now */ |
343 | 225k | if (!color_is_pure(pdevc)) { |
344 | 0 | DPRINTF(dev->memory, "epo_fillpage(), color is not pure, uninstalling\n"); |
345 | 0 | disable_self(dev); |
346 | 0 | return dev_proc(dev->child, fillpage)(dev->child, pgs, pdevc); |
347 | 0 | } |
348 | | |
349 | | /* Save the color being requested, and swallow the fillpage */ |
350 | 225k | data->last_color = pdevc->colors.pure; |
351 | 225k | data->queued = 1; |
352 | | |
353 | 225k | DPRINTF(dev->memory, "Swallowing fillpage\n"); |
354 | 225k | return 0; |
355 | 225k | } |
356 | | |
357 | | int epo_output_page(gx_device *dev, int num_copies, int flush) |
358 | 0 | { |
359 | 0 | int code = epo_handle_erase_page(dev); |
360 | |
|
361 | 0 | if (code != 0) |
362 | 0 | return code; |
363 | 0 | dev = dev->child; |
364 | 0 | return dev_proc(dev, output_page)(dev, num_copies, flush); |
365 | 0 | } |
366 | | |
367 | | int epo_fill_rectangle(gx_device *dev, int x, int y, int width, int height, gx_color_index color) |
368 | 375 | { |
369 | 375 | int code = epo_handle_erase_page(dev); |
370 | | |
371 | 375 | if (code != 0) |
372 | 0 | return code; |
373 | 375 | dev = dev->child; |
374 | 375 | if (dev_proc(dev, fill_rectangle) != NULL) |
375 | 375 | return dev_proc(dev, fill_rectangle)(dev, x, y, width, height, color); |
376 | 0 | else |
377 | 0 | return 0; |
378 | 375 | } |
379 | | |
380 | | int epo_fill_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, |
381 | | const gx_fill_params *params, |
382 | | const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) |
383 | 11.2k | { |
384 | 11.2k | int code = epo_handle_erase_page(dev); |
385 | | |
386 | 11.2k | if (code != 0) |
387 | 0 | return code; |
388 | 11.2k | dev = dev->child; |
389 | 11.2k | return dev_proc(dev, fill_path)(dev, pgs, ppath, params, pdcolor, pcpath); |
390 | 11.2k | } |
391 | | |
392 | | int epo_fill_mask(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, |
393 | | int x, int y, int width, int height, |
394 | | const gx_drawing_color *pdcolor, int depth, |
395 | | gs_logical_operation_t lop, const gx_clip_path *pcpath) |
396 | 0 | { |
397 | 0 | int code = epo_handle_erase_page(dev); |
398 | |
|
399 | 0 | if (code != 0) |
400 | 0 | return code; |
401 | 0 | dev = dev->child; |
402 | 0 | return dev_proc(dev, fill_mask)(dev, data, data_x, raster, id, x, y, width, height, pdcolor, depth, lop, pcpath); |
403 | 0 | } |
404 | | |
405 | | int epo_fill_trapezoid(gx_device *dev, const gs_fixed_edge *left, const gs_fixed_edge *right, |
406 | | fixed ybot, fixed ytop, bool swap_axes, |
407 | | const gx_drawing_color *pdcolor, gs_logical_operation_t lop) |
408 | 0 | { |
409 | 0 | int code = epo_handle_erase_page(dev); |
410 | |
|
411 | 0 | if (code != 0) |
412 | 0 | return code; |
413 | 0 | dev = dev->child; |
414 | 0 | return dev_proc(dev, fill_trapezoid)(dev, left, right, ybot, ytop, swap_axes, pdcolor, lop); |
415 | 0 | } |
416 | | |
417 | | int epo_fill_parallelogram(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, |
418 | | const gx_drawing_color *pdcolor, gs_logical_operation_t lop) |
419 | 0 | { |
420 | 0 | int code = epo_handle_erase_page(dev); |
421 | |
|
422 | 0 | if (code != 0) |
423 | 0 | return code; |
424 | 0 | dev = dev->child; |
425 | 0 | return dev_proc(dev, fill_parallelogram)(dev, px, py, ax, ay, bx, by, pdcolor, lop); |
426 | 0 | } |
427 | | |
428 | | int epo_fill_triangle(gx_device *dev, fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, |
429 | | const gx_drawing_color *pdcolor, gs_logical_operation_t lop) |
430 | 0 | { |
431 | 0 | int code = epo_handle_erase_page(dev); |
432 | |
|
433 | 0 | if (code != 0) |
434 | 0 | return code; |
435 | 0 | dev = dev->child; |
436 | 0 | return dev_proc(dev, fill_triangle)(dev, px, py, ax, ay, bx, by, pdcolor, lop); |
437 | 0 | } |
438 | | |
439 | | int epo_draw_thin_line(gx_device *dev, fixed fx0, fixed fy0, fixed fx1, fixed fy1, |
440 | | const gx_drawing_color *pdcolor, gs_logical_operation_t lop, |
441 | | fixed adjustx, fixed adjusty) |
442 | 0 | { |
443 | 0 | int code = epo_handle_erase_page(dev); |
444 | |
|
445 | 0 | if (code != 0) |
446 | 0 | return code; |
447 | 0 | dev = dev->child; |
448 | 0 | return dev_proc(dev, draw_thin_line)(dev, fx0, fy0, fx1, fy1, pdcolor, lop, adjustx, adjusty); |
449 | 0 | } |
450 | | |
451 | | int epo_fill_rectangle_hl_color(gx_device *dev, const gs_fixed_rect *rect, |
452 | | const gs_gstate *pgs, const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) |
453 | 0 | { |
454 | 0 | int code = epo_handle_erase_page(dev); |
455 | |
|
456 | 0 | if (code != 0) |
457 | 0 | return code; |
458 | 0 | dev = dev->child; |
459 | 0 | return dev_proc(dev, fill_rectangle_hl_color)(dev, rect, pgs, pdcolor, pcpath); |
460 | 0 | } |
461 | | |
462 | | int epo_fill_linear_color_scanline(gx_device *dev, const gs_fill_attributes *fa, |
463 | | int i, int j, int w, const frac31 *c0, const int32_t *c0_f, const int32_t *cg_num, |
464 | | int32_t cg_den) |
465 | 0 | { |
466 | 0 | int code = epo_handle_erase_page(dev); |
467 | |
|
468 | 0 | if (code != 0) |
469 | 0 | return code; |
470 | 0 | dev = dev->child; |
471 | 0 | return dev_proc(dev, fill_linear_color_scanline)(dev, fa, i, j, w, c0, c0_f, cg_num, cg_den); |
472 | 0 | } |
473 | | |
474 | | int epo_fill_linear_color_trapezoid(gx_device *dev, const gs_fill_attributes *fa, |
475 | | const gs_fixed_point *p0, const gs_fixed_point *p1, |
476 | | const gs_fixed_point *p2, const gs_fixed_point *p3, |
477 | | const frac31 *c0, const frac31 *c1, |
478 | | const frac31 *c2, const frac31 *c3) |
479 | 0 | { |
480 | 0 | int code = epo_handle_erase_page(dev); |
481 | |
|
482 | 0 | if (code != 0) |
483 | 0 | return code; |
484 | 0 | dev = dev->child; |
485 | 0 | return dev_proc(dev, fill_linear_color_trapezoid)(dev, fa, p0, p1, p2, p3, c0, c1, c2, c3); |
486 | 0 | } |
487 | | |
488 | | int epo_fill_linear_color_triangle(gx_device *dev, const gs_fill_attributes *fa, |
489 | | const gs_fixed_point *p0, const gs_fixed_point *p1, |
490 | | const gs_fixed_point *p2, const frac31 *c0, const frac31 *c1, const frac31 *c2) |
491 | 0 | { |
492 | 0 | int code = epo_handle_erase_page(dev); |
493 | |
|
494 | 0 | if (code != 0) |
495 | 0 | return code; |
496 | 0 | dev = dev->child; |
497 | 0 | return dev_proc(dev, fill_linear_color_triangle)(dev, fa, p0, p1, p2, c0, c1, c2); |
498 | 0 | } |
499 | | |
500 | | int epo_put_image(gx_device *dev, gx_device *mdev, const byte **buffers, int num_chan, int x, int y, |
501 | | int width, int height, int row_stride, |
502 | | int alpha_plane_index, int tag_plane_index) |
503 | 0 | { |
504 | 0 | int code = epo_handle_erase_page(dev); |
505 | |
|
506 | 0 | if (code != 0) |
507 | 0 | return code; |
508 | 0 | dev = dev->child; |
509 | 0 | return dev_proc(dev, put_image)(dev, mdev, buffers, num_chan, x, y, width, height, row_stride, alpha_plane_index, tag_plane_index); |
510 | 0 | } |
511 | | |
512 | | int epo_composite(gx_device *dev, gx_device **pcdev, const gs_composite_t *pcte, |
513 | | gs_gstate *pgs, gs_memory_t *memory, gx_device *cdev) |
514 | 3.48k | { |
515 | 3.48k | int code = epo_handle_erase_page(dev); |
516 | | |
517 | 3.48k | if (code != 0) |
518 | 0 | return code; |
519 | 3.48k | return default_subclass_composite(dev, pcdev, pcte, pgs, memory, cdev); |
520 | 3.48k | } |
521 | | |
522 | | int epo_text_begin(gx_device *dev, gs_gstate *pgs, const gs_text_params_t *text, |
523 | | gs_font *font, const gx_clip_path *pcpath, |
524 | | gs_text_enum_t **ppte) |
525 | 8.90k | { |
526 | 8.90k | int code = epo_handle_erase_page(dev); |
527 | | |
528 | 8.90k | if (code != 0) |
529 | 0 | return code; |
530 | 8.90k | dev = dev->child; |
531 | 8.90k | return dev_proc(dev, text_begin)(dev, pgs, text, font, pcpath, ppte); |
532 | 8.90k | } |
533 | | |
534 | | static int epo_initialize_device(gx_device *dev) |
535 | 0 | { |
536 | | /* We musn't allow the following pointers to remain shared with the from_dev |
537 | | because we're about to tell the caller it's only allowed to copy the prototype |
538 | | and free the attempted copy of a non-prototype. If from_dev is the prototype |
539 | | these pointers won't be set, anyway. |
540 | | */ |
541 | 0 | dev->child = NULL; |
542 | 0 | dev->parent = NULL; |
543 | 0 | dev->subclass_data = NULL; |
544 | 0 | return 0; |
545 | 0 | } |
546 | | |
547 | | void epo_initialize_device_procs(gx_device *dev) |
548 | 31.6k | { |
549 | 31.6k | default_subclass_initialize_device_procs(dev); |
550 | | |
551 | 31.6k | set_dev_proc(dev, initialize_device, epo_initialize_device); |
552 | 31.6k | enable_procs(dev); |
553 | 31.6k | } |
554 | | |
555 | | int epo_begin_typed_image(gx_device *dev, const gs_gstate *pgs, const gs_matrix *pmat, |
556 | | const gs_image_common_t *pic, const gs_int_rect *prect, |
557 | | const gx_drawing_color *pdcolor, const gx_clip_path *pcpath, |
558 | | gs_memory_t *memory, gx_image_enum_common_t **pinfo) |
559 | 2.79k | { |
560 | 2.79k | int code = epo_handle_erase_page(dev); |
561 | | |
562 | 2.79k | if (code != 0) |
563 | 0 | return code; |
564 | 2.79k | dev = dev->child; |
565 | 2.79k | return dev_proc(dev, begin_typed_image)(dev, pgs, pmat, pic, prect, pdcolor, pcpath, memory, pinfo); |
566 | 2.79k | } |
567 | | |
568 | | int epo_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, |
569 | | const gx_stroke_params *params, |
570 | | const gx_drawing_color *pdcolor, const gx_clip_path *pcpath) |
571 | 789 | { |
572 | 789 | int code = epo_handle_erase_page(dev); |
573 | | |
574 | 789 | if (code != 0) |
575 | 0 | return code; |
576 | 789 | dev = dev->child; |
577 | 789 | return dev_proc(dev, stroke_path)(dev, pgs, ppath, params, pdcolor, pcpath); |
578 | 789 | } |
579 | | |
580 | | int epo_copy_mono(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, |
581 | | int x, int y, int width, int height, |
582 | | gx_color_index color0, gx_color_index color1) |
583 | 0 | { |
584 | 0 | int code = epo_handle_erase_page(dev); |
585 | |
|
586 | 0 | if (code != 0) |
587 | 0 | return code; |
588 | 0 | dev = dev->child; |
589 | 0 | return dev_proc(dev, copy_mono)(dev, data, data_x, raster, id, x, y, width, height, color0, color1); |
590 | 0 | } |
591 | | |
592 | | int epo_copy_color(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id,\ |
593 | | int x, int y, int width, int height) |
594 | 0 | { |
595 | 0 | int code = epo_handle_erase_page(dev); |
596 | |
|
597 | 0 | if (code != 0) |
598 | 0 | return code; |
599 | 0 | dev = dev->child; |
600 | 0 | return dev_proc(dev, copy_color)(dev, data, data_x, raster, id, x, y, width, height); |
601 | 0 | } |
602 | | |
603 | | int epo_get_bits_rectangle(gx_device *dev, const gs_int_rect *prect, |
604 | | gs_get_bits_params_t *params) |
605 | 0 | { |
606 | 0 | int code = epo_handle_erase_page(dev); |
607 | |
|
608 | 0 | if (code != 0) |
609 | 0 | return code; |
610 | 0 | dev = dev->child; |
611 | 0 | return dev_proc(dev, get_bits_rectangle)(dev, prect, params); |
612 | 0 | } |
613 | | |
614 | | int epo_copy_alpha(gx_device *dev, const byte *data, int data_x, |
615 | | int raster, gx_bitmap_id id, int x, int y, int width, int height, |
616 | | gx_color_index color, int depth) |
617 | 0 | { |
618 | 0 | int code = epo_handle_erase_page(dev); |
619 | |
|
620 | 0 | if (code != 0) |
621 | 0 | return code; |
622 | 0 | dev = dev->child; |
623 | 0 | return dev_proc(dev, copy_alpha)(dev, data, data_x, raster, id, x, y, width, height, color, depth); |
624 | 0 | } |
625 | | |
626 | | int epo_strip_tile_rectangle(gx_device *dev, const gx_strip_bitmap *tiles, int x, int y, int width, int height, |
627 | | gx_color_index color0, gx_color_index color1, |
628 | | int phase_x, int phase_y) |
629 | 0 | { |
630 | 0 | int code = epo_handle_erase_page(dev); |
631 | |
|
632 | 0 | if (code != 0) |
633 | 0 | return code; |
634 | 0 | dev = dev->child; |
635 | 0 | return dev_proc(dev, strip_tile_rectangle)(dev, tiles, x, y, width, height, color0, color1, phase_x, phase_y); |
636 | 0 | } |
637 | | |
638 | | int epo_strip_copy_rop2(gx_device *dev, const byte *sdata, int sourcex, uint sraster, gx_bitmap_id id, |
639 | | const gx_color_index *scolors, const gx_strip_bitmap *textures, const gx_color_index *tcolors, |
640 | | int x, int y, int width, int height, int phase_x, int phase_y, gs_logical_operation_t lop, uint planar_height) |
641 | 0 | { |
642 | 0 | int code = epo_handle_erase_page(dev); |
643 | |
|
644 | 0 | if (code != 0) |
645 | 0 | return code; |
646 | 0 | dev = dev->child; |
647 | 0 | return dev_proc(dev, strip_copy_rop2)(dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop, planar_height); |
648 | 0 | } |
649 | | |
650 | | int epo_copy_planes(gx_device *dev, const byte *data, int data_x, int raster, gx_bitmap_id id, |
651 | | int x, int y, int width, int height, int plane_height) |
652 | 0 | { |
653 | 0 | int code = epo_handle_erase_page(dev); |
654 | |
|
655 | 0 | if (code != 0) |
656 | 0 | return code; |
657 | 0 | dev = dev->child; |
658 | 0 | return dev_proc(dev, copy_planes)(dev, data, data_x, raster, id, x, y, width, height, plane_height); |
659 | 0 | } |
660 | | |
661 | | int epo_copy_alpha_hl_color(gx_device *dev, const byte *data, int data_x, |
662 | | int raster, gx_bitmap_id id, int x, int y, int width, int height, |
663 | | const gx_drawing_color *pdcolor, int depth) |
664 | 0 | { |
665 | 0 | int code = epo_handle_erase_page(dev); |
666 | |
|
667 | 0 | if (code != 0) |
668 | 0 | return code; |
669 | 0 | dev = dev->child; |
670 | 0 | return dev_proc(dev, copy_alpha_hl_color)(dev, data, data_x, raster, id, x, y, width, height, pdcolor, depth); |
671 | 0 | } |
672 | | |
673 | | int epo_process_page(gx_device *dev, gx_process_page_options_t *options) |
674 | 0 | { |
675 | 0 | int code = epo_handle_erase_page(dev); |
676 | |
|
677 | 0 | if (code != 0) |
678 | 0 | return code; |
679 | 0 | dev = dev->child; |
680 | 0 | return dev_proc(dev, process_page)(dev, options); |
681 | 0 | } |
682 | | |
683 | | int epo_fill_stroke_path(gx_device *dev, const gs_gstate *pgs, gx_path *ppath, |
684 | | const gx_fill_params *fill_params, const gx_drawing_color *pdcolor_fill, |
685 | | const gx_stroke_params *stroke_params, const gx_drawing_color *pdcolor_stroke, |
686 | | const gx_clip_path *pcpath) |
687 | 189 | { |
688 | 189 | int code = epo_handle_erase_page(dev); |
689 | | |
690 | 189 | if (code != 0) |
691 | 0 | return code; |
692 | 189 | dev = dev->child; |
693 | 189 | return dev_proc(dev, fill_stroke_path)(dev, pgs, ppath, fill_params, pdcolor_fill, |
694 | 189 | stroke_params, pdcolor_stroke, pcpath); |
695 | 189 | } |
696 | | |
697 | | int epo_transform_pixel_region(gx_device *dev, transform_pixel_region_reason reason, transform_pixel_region_data *data) |
698 | 0 | { |
699 | 0 | int code = epo_handle_erase_page(dev); |
700 | |
|
701 | 0 | if (code != 0) |
702 | 0 | return code; |
703 | 0 | dev = dev->child; |
704 | 0 | return dev_proc(dev, transform_pixel_region)(dev, reason, data); |
705 | 0 | } |