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