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