1 /* Copyright (C) 1998, 1999 artofcode LLC. All rights reserved.
2
3 This program is free software; you can redistribute it and/or modify it
4 under the terms of the GNU General Public License as published by the
5 Free Software Foundation; either version 2 of the License, or (at your
6 option) any later version.
7
8 This program is distributed in the hope that it will be useful, but
9 WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 General Public License for more details.
12
13 You should have received a copy of the GNU General Public License along
14 with this program; if not, write to the Free Software Foundation, Inc.,
15 59 Temple Place, Suite 330, Boston, MA, 02111-1307.
16
17 */
18
19 /*$Id: gsropc.c,v 1.2.6.1.2.1 2003/01/17 00:49:03 giles Exp $ */
20 /* RasterOp-compositing implementation */
21 #include "gx.h"
22 #include "gserrors.h"
23 #include "gsutil.h" /* for gs_next_ids */
24 #include "gxdcolor.h"
25 #include "gxdevice.h"
26 #include "gxdevmem.h"
27 #include "gxropc.h"
28
29 /* ------ Object definition and creation ------ */
30
31 /* Define RasterOp-compositing objects. */
32 private composite_create_default_compositor_proc(c_rop_create_default_compositor);
33 private composite_equal_proc(c_rop_equal);
34 private composite_write_proc(c_rop_write);
35 private composite_read_proc(c_rop_read);
36 private const gs_composite_type_t gs_composite_rop_type =
37 {
38 {
39 c_rop_create_default_compositor,
40 c_rop_equal,
41 c_rop_write,
42 c_rop_read
43 }
44 };
45
46 private_st_composite_rop();
47
48 /* Create a RasterOp-compositing object. */
49 int
gs_create_composite_rop(gs_composite_t ** ppcte,const gs_composite_rop_params_t * params,gs_memory_t * mem)50 gs_create_composite_rop(gs_composite_t ** ppcte,
51 const gs_composite_rop_params_t * params, gs_memory_t * mem)
52 {
53 gs_composite_rop_t *pcte;
54
55 rc_alloc_struct_0(pcte, gs_composite_rop_t, &st_composite_rop,
56 mem, return_error(gs_error_VMerror),
57 "gs_create_composite_rop");
58 pcte->type = &gs_composite_rop_type;
59 pcte->id = gs_next_ids(1);
60 pcte->params = *params;
61 *ppcte = (gs_composite_t *) pcte;
62 return 0;
63 }
64
65 /* ------ Object implementation ------ */
66
67 #define prcte ((const gs_composite_rop_t *)pcte)
68
69 private bool
c_rop_equal(const gs_composite_t * pcte,const gs_composite_t * pcte2)70 c_rop_equal(const gs_composite_t * pcte, const gs_composite_t * pcte2)
71 {
72 return (pcte2->type == pcte->type &&
73 #define prcte2 ((const gs_composite_rop_t *)pcte2)
74 prcte2->params.log_op == prcte->params.log_op &&
75 (prcte->params.texture == 0 ? prcte2->params.texture == 0 :
76 prcte2->params.texture != 0 &&
77 gx_device_color_equal(prcte->params.texture,
78 prcte2->params.texture)));
79 #undef prcte2
80 }
81
82 private int
c_rop_write(const gs_composite_t * pcte,byte * data,uint * psize)83 c_rop_write(const gs_composite_t * pcte, byte * data, uint * psize)
84 {
85 /****** NYI ******/
86 }
87
88 private int
c_rop_read(gs_composite_t ** ppcte,const byte * data,uint size,gs_memory_t * mem)89 c_rop_read(gs_composite_t ** ppcte, const byte * data, uint size,
90 gs_memory_t * mem)
91 {
92 /****** NYI ******/
93 }
94
95 /* ---------------- RasterOp-compositing device ---------------- */
96
97 /* Define the default RasterOp-compositing device. */
98 typedef struct gx_device_composite_rop_s {
99 gx_device_forward_common;
100 gs_composite_rop_params_t params;
101 } gx_device_composite_rop;
102
103 gs_private_st_suffix_add1_final(st_device_composite_rop,
104 gx_device_composite_rop, "gx_device_composite_rop",
105 device_c_rop_enum_ptrs, device_c_rop_reloc_ptrs, gx_device_finalize,
106 st_device_forward, params.texture);
107 /* The device descriptor. */
108 private dev_proc_close_device(dcr_close);
109 private dev_proc_fill_rectangle(dcr_fill_rectangle);
110 private dev_proc_copy_mono(dcr_copy_mono);
111 private dev_proc_copy_color(dcr_copy_color);
112 private dev_proc_copy_alpha(dcr_copy_alpha);
113 private const gx_device_composite_rop gs_composite_rop_device =
114 {std_device_std_body_open(gx_device_composite_rop, 0,
115 "RasterOp compositor", 0, 0, 1, 1),
116 {gx_default_open_device,
117 gx_forward_get_initial_matrix,
118 gx_forward_sync_output,
119 gx_forward_output_page,
120 dcr_close,
121 gx_forward_map_rgb_color,
122 gx_forward_map_color_rgb,
123 dcr_fill_rectangle,
124 gx_default_tile_rectangle,
125 dcr_copy_mono,
126 dcr_copy_color,
127 gx_default_draw_line,
128 gx_default_get_bits,
129 gx_forward_get_params,
130 gx_forward_put_params,
131 gx_forward_map_cmyk_color,
132 gx_forward_get_xfont_procs,
133 gx_forward_get_xfont_device,
134 gx_forward_map_rgb_alpha_color,
135 gx_forward_get_page_device,
136 gx_forward_get_alpha_bits,
137 dcr_copy_alpha,
138 gx_forward_get_band,
139 gx_default_copy_rop,
140 gx_default_fill_path,
141 gx_default_stroke_path,
142 gx_default_fill_mask,
143 gx_default_fill_trapezoid,
144 gx_default_fill_parallelogram,
145 gx_default_fill_triangle,
146 gx_default_draw_thin_line,
147 gx_default_begin_image,
148 gx_default_image_data,
149 gx_default_end_image,
150 gx_default_strip_tile_rectangle,
151 gx_default_strip_copy_rop,
152 gx_forward_get_clipping_box,
153 gx_default_begin_typed_image,
154 gx_forward_get_bits_rectangle,
155 gx_forward_map_color_rgb_alpha,
156 gx_no_create_compositor
157 }
158 };
159
160 /* Create a RasterOp compositor. */
161 int
c_rop_create_default_compositor(const gs_composite_t * pcte,gx_device ** pcdev,gx_device * dev,const gs_imager_state * pis,gs_memory_t * mem)162 c_rop_create_default_compositor(const gs_composite_t * pcte,
163 gx_device ** pcdev, gx_device * dev, const gs_imager_state * pis,
164 gs_memory_t * mem)
165 {
166 gs_logical_operation_t log_op = prcte->params.log_op;
167 const gx_device_color *texture = prcte->params.texture;
168 gx_device_composite_rop *cdev;
169
170 #if 0 /*************** */
171 if (<<operation is identity >>) {
172 /* Just use the original device. */
173 *pcdev = dev;
174 return 0;
175 }
176 #endif /*************** */
177 cdev =
178 gs_alloc_struct_immovable(mem, gx_device_composite_rop,
179 &st_device_composite_rop,
180 "create default RasterOp compositor");
181 *pcdev = (gx_device *) cdev;
182 if (cdev == 0)
183 return_error(gs_error_VMerror);
184 gx_device_init((gx_device *)cdev,
185 (const gx_device *)&gs_composite_rop_device, mem, true);
186 gx_device_copy_params((gx_device *)cdev, dev);
187 /*
188 * Check for memory devices, and select the correct RasterOp
189 * implementation based on depth and device color space.
190 ****** NYI ******
191 */
192 gx_device_set_target((gx_device_forward *)cdev, dev);
193 cdev->params = prcte->params;
194 return 0;
195 }
196
197 /* Close the device and free its storage. */
198 private int
dcr_close(gx_device * dev)199 dcr_close(gx_device * dev)
200 { /*
201 * Finalization will call close again: avoid a recursion loop.
202 */
203 set_dev_proc(dev, close_device, gx_default_close_device);
204 gs_free_object(dev->memory, dev, "dcr_close");
205 return 0;
206 }
207
208 /* ------ Imaging ------ */
209
210 /* Import the existing RasterOp implementations. */
211 extern dev_proc_strip_copy_rop(gx_default_strip_copy_rop);
212
213 private int
dcr_fill_rectangle(gx_device * dev,int x,int y,int w,int h,gx_color_index color)214 dcr_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
215 gx_color_index color)
216 {
217 gx_device_composite_rop *rdev = (gx_device_composite_rop *) dev;
218
219 /*
220 * This is where all the work gets done right now.
221 * Sooner or later, we'll have to do the right thing here....
222 */
223 gs_logical_operation_t log_op = rdev->params.log_op;
224 const gx_device_color *texture = rdev->params.texture;
225 gx_color_index colors[2];
226 gx_color_index tcolors[2];
227
228 dev_proc_strip_copy_rop((*copy)) = gx_default_strip_copy_rop;
229
230 colors[0] = colors[1] = color;
231 if (gs_device_is_memory(dev)) {
232 /****** SHOULD CHECK FOR STANDARD COLOR REPRESENTATION ******/
233 switch (dev->color_info.depth) {
234 case 1:
235 copy = mem_mono_strip_copy_rop;
236 break;
237 case 2:
238 case 4:
239 copy = mem_gray_strip_copy_rop;
240 break;
241 case 8:
242 case 24:
243 copy = mem_gray8_rgb24_strip_copy_rop;
244 break;
245 case 16:
246 case 32:
247 /****** NOT IMPLEMENTED ******/
248 }
249 }
250 if (texture == 0) {
251 return (*copy)
252 (dev, (const byte *)0, 0, 0, gx_no_bitmap_id,
253 (const gx_color_index *)0, (const gx_strip_bitmap *)0, colors,
254 x, y, w, h, 0, 0, log_op);
255 }
256 /* Apply the texture, whatever it may be. */
257 if (gx_dc_is_pure(texture)) {
258 tcolors[0] = tcolors[1] = texture->colors.pure;
259 return (*copy)
260 (dev, (const byte *)0, 0, 0, gx_no_bitmap_id, colors,
261 (const gx_strip_bitmap *)0, tcolors,
262 x, y, w, h, 0, 0, log_op);
263 } else if (gx_dc_is_binary_halftone(texture)) {
264 tcolors[0] = texture->colors.binary.color[0];
265 tcolors[1] = texture->colors.binary.color[1];
266 return (*copy)
267 (dev, (const byte *)0, 0, 0, gx_no_bitmap_id, colors,
268 &texture->colors.binary.b_tile->tiles, tcolors,
269 x, y, w, h, texture->phase.x, texture->phase.y, log_op);
270 } else if (gx_dc_is_colored_halftone(texture)) {
271 /****** NO CAN DO ******/
272 } else
273 /****** WHAT ABOUT PATTERNS? ******/
274 return_error(gs_error_rangecheck);
275 }
276
277 private int
dcr_copy_mono(gx_device * dev,const byte * data,int dx,int raster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index zero,gx_color_index one)278 dcr_copy_mono(gx_device * dev, const byte * data,
279 int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h,
280 gx_color_index zero, gx_color_index one)
281 {
282 /****** TEMPORARY ******/
283 return gx_default_copy_mono(dev, data, dx, raster, id, x, y, w, h,
284 zero, one);
285 }
286
287 private int
dcr_copy_color(gx_device * dev,const byte * data,int dx,int raster,gx_bitmap_id id,int x,int y,int w,int h)288 dcr_copy_color(gx_device * dev, const byte * data,
289 int dx, int raster, gx_bitmap_id id,
290 int x, int y, int w, int h)
291 {
292 /****** TEMPORARY ******/
293 return gx_default_copy_color(dev, data, dx, raster, id, x, y, w, h);
294 }
295
296 private int
dcr_copy_alpha(gx_device * dev,const byte * data,int data_x,int raster,gx_bitmap_id id,int x,int y,int width,int height,gx_color_index color,int depth)297 dcr_copy_alpha(gx_device * dev, const byte * data, int data_x,
298 int raster, gx_bitmap_id id, int x, int y, int width, int height,
299 gx_color_index color, int depth)
300 {
301 /****** TEMPORARY ******/
302 return gx_default_copy_alpha(dev, data, data_x, raster, id, x, y,
303 width, height, color, depth);
304 }
305