xref: /plan9/sys/src/cmd/gs/src/gdevmr2n.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1995, 1996, 1997, 1998, 1999 Aladdin Enterprises.  All rights reserved.
2 
3   This software is provided AS-IS with no warranty, either express or
4   implied.
5 
6   This software is distributed under license and may not be copied,
7   modified or distributed except as expressly authorized under the terms
8   of the license contained in the file LICENSE in this distribution.
9 
10   For more information about licensing, please refer to
11   http://www.ghostscript.com/licensing/. For information on
12   commercial licensing, go to http://www.artifex.com/licensing/ or
13   contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14   San Rafael, CA  94903, U.S.A., +1(415)492-9861.
15 */
16 
17 /* $Id: gdevmr2n.c,v 1.4 2002/02/21 22:24:51 giles Exp $ */
18 /* RasterOp implementation for 2- and 4-bit memory devices */
19 #include "memory_.h"
20 #include "gx.h"
21 #include "gsbittab.h"
22 #include "gserrors.h"
23 #include "gsropt.h"
24 #include "gxcindex.h"
25 #include "gxdcolor.h"
26 #include "gxdevice.h"
27 #include "gxdevmem.h"
28 #include "gxdevrop.h"
29 #include "gdevmem.h"
30 #include "gdevmrop.h"
31 
32 /* Calculate the X offset for a given Y value, */
33 /* taking shift into account if necessary. */
34 #define x_offset(px, ty, textures)\
35   ((textures)->shift == 0 ? (px) :\
36    (px) + (ty) / (textures)->rep_height * (textures)->rep_shift)
37 
38 /* ---------------- Fake RasterOp for 2- and 4-bit devices ---------------- */
39 
40 /*
41  * Define patched versions of the driver procedures that may be called
42  * by mem_mono_strip_copy_rop (see below).  Currently we just punt to
43  * the slow, general case; we could do a lot better.
44  */
45 private int
mem_gray_rop_fill_rectangle(gx_device * dev,int x,int y,int w,int h,gx_color_index color)46 mem_gray_rop_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
47 			    gx_color_index color)
48 {
49     return -1;
50 }
51 private int
mem_gray_rop_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)52 mem_gray_rop_copy_mono(gx_device * dev, const byte * data,
53 		       int dx, int raster, gx_bitmap_id id,
54 		       int x, int y, int w, int h,
55 		       gx_color_index zero, gx_color_index one)
56 {
57     return -1;
58 }
59 private int
mem_gray_rop_strip_tile_rectangle(gx_device * dev,const gx_strip_bitmap * tiles,int x,int y,int w,int h,gx_color_index color0,gx_color_index color1,int px,int py)60 mem_gray_rop_strip_tile_rectangle(gx_device * dev,
61 				  const gx_strip_bitmap * tiles,
62 				  int x, int y, int w, int h,
63 				  gx_color_index color0, gx_color_index color1,
64 				  int px, int py)
65 {
66     return -1;
67 }
68 
69 int
mem_gray_strip_copy_rop(gx_device * dev,const byte * sdata,int sourcex,uint sraster,gx_bitmap_id id,const gx_color_index * scolors,const gx_strip_bitmap * textures,const gx_color_index * tcolors,int x,int y,int width,int height,int phase_x,int phase_y,gs_logical_operation_t lop)70 mem_gray_strip_copy_rop(gx_device * dev,
71 	     const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id,
72 			const gx_color_index * scolors,
73 	   const gx_strip_bitmap * textures, const gx_color_index * tcolors,
74 			int x, int y, int width, int height,
75 			int phase_x, int phase_y, gs_logical_operation_t lop)
76 {
77     gx_color_index scolors2[2];
78     const gx_color_index *real_scolors = scolors;
79     gx_color_index tcolors2[2];
80     const gx_color_index *real_tcolors = tcolors;
81     gx_strip_bitmap texture2;
82     const gx_strip_bitmap *real_texture = textures;
83     long tdata;
84     int depth = dev->color_info.depth;
85     int log2_depth = depth >> 1;	/* works for 2, 4 */
86     gx_color_index max_pixel = (1 << depth) - 1;
87     int code;
88 
89 #ifdef DEBUG
90     if (gs_debug_c('b'))
91 	trace_copy_rop("mem_gray_strip_copy_rop",
92 		       dev, sdata, sourcex, sraster,
93 		       id, scolors, textures, tcolors,
94 		       x, y, width, height, phase_x, phase_y, lop);
95 #endif
96     if (gx_device_has_color(dev) ||
97 	(lop & (lop_S_transparent | lop_T_transparent)) ||
98 	(scolors &&		/* must be (0,0) or (max,max) */
99 	 ((scolors[0] | scolors[1]) != 0) &&
100 	 ((scolors[0] & scolors[1]) != max_pixel)) ||
101 	(tcolors && (tcolors[0] != tcolors[1]))
102 	) {
103 	/* We can't fake it: do it the slow, painful way. */
104 	return mem_default_strip_copy_rop(dev, sdata, sourcex, sraster, id,
105 					  scolors, textures, tcolors,
106 					  x, y, width, height,
107 					  phase_x, phase_y, lop);
108     }
109     if (scolors) {		/* Must be a solid color: see above. */
110 	scolors2[0] = scolors2[1] = scolors[0] & 1;
111 	real_scolors = scolors2;
112     }
113     if (textures) {
114 	texture2 = *textures;
115 	texture2.size.x <<= log2_depth;
116 	texture2.rep_width <<= log2_depth;
117 	texture2.shift <<= log2_depth;
118 	texture2.rep_shift <<= log2_depth;
119 	real_texture = &texture2;
120     }
121     if (tcolors) {
122 	/* For polybit textures with colors other than */
123 	/* all 0s or all 1s, fabricate the data. */
124 	if (tcolors[0] != 0 && tcolors[0] != max_pixel) {
125 	    real_tcolors = 0;
126 	    *(byte *) & tdata = (byte) tcolors[0] << (8 - depth);
127 	    texture2.data = (byte *) & tdata;
128 	    texture2.raster = align_bitmap_mod;
129 	    texture2.size.x = texture2.rep_width = depth;
130 	    texture2.size.y = texture2.rep_height = 1;
131 	    texture2.id = gx_no_bitmap_id;
132 	    texture2.shift = texture2.rep_shift = 0;
133 	    real_texture = &texture2;
134 	} else {
135 	    tcolors2[0] = tcolors2[1] = tcolors[0] & 1;
136 	    real_tcolors = tcolors2;
137 	}
138     }
139     /*
140      * mem_mono_strip_copy_rop may call fill_rectangle, copy_mono, or
141      * strip_tile_rectangle for special cases.  Patch those procedures
142      * temporarily so they will either do the right thing or return
143      * an error.
144      */
145     {
146 	dev_proc_fill_rectangle((*fill_rectangle)) =
147 	    dev_proc(dev, fill_rectangle);
148 	dev_proc_copy_mono((*copy_mono)) =
149 	    dev_proc(dev, copy_mono);
150 	dev_proc_strip_tile_rectangle((*strip_tile_rectangle)) =
151 	    dev_proc(dev, strip_tile_rectangle);
152 
153 	set_dev_proc(dev, fill_rectangle, mem_gray_rop_fill_rectangle);
154 	set_dev_proc(dev, copy_mono, mem_gray_rop_copy_mono);
155 	set_dev_proc(dev, strip_tile_rectangle,
156 		     mem_gray_rop_strip_tile_rectangle);
157 	dev->width <<= log2_depth;
158 	code = mem_mono_strip_copy_rop(dev, sdata,
159 				       (real_scolors == NULL ?
160 					sourcex << log2_depth : sourcex),
161 				       sraster, id, real_scolors,
162 				       real_texture, real_tcolors,
163 				       x << log2_depth, y,
164 				       width << log2_depth, height,
165 				       phase_x << log2_depth, phase_y, lop);
166 	set_dev_proc(dev, fill_rectangle, fill_rectangle);
167 	set_dev_proc(dev, copy_mono, copy_mono);
168 	set_dev_proc(dev, strip_tile_rectangle, strip_tile_rectangle);
169 	dev->width >>= log2_depth;
170     }
171     /* If we punted, use the general procedure. */
172     if (code < 0)
173 	return mem_default_strip_copy_rop(dev, sdata, sourcex, sraster, id,
174 					  scolors, textures, tcolors,
175 					  x, y, width, height,
176 					  phase_x, phase_y, lop);
177     return code;
178 }
179