1 /* Copyright (C) 2001-2019 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., 1305 Grant Avenue - Suite 200, Novato,
13 CA 94945, U.S.A., +1(415)492-9861, for further information.
14 */
15
16 /* RasterOp implementation for 2- and 4-bit memory devices */
17 #include "memory_.h"
18 #include "gx.h"
19 #include "gsbittab.h"
20 #include "gserrors.h"
21 #include "gsropt.h"
22 #include "gxcindex.h"
23 #include "gxdcolor.h"
24 #include "gxdevice.h"
25 #include "gxdevmem.h"
26 #include "gxdevrop.h"
27 #include "gdevmem.h"
28 #include "gdevmrop.h"
29
30 /* Calculate the X offset for a given Y value, */
31 /* taking shift into account if necessary. */
32 #define x_offset(px, ty, textures)\
33 ((textures)->shift == 0 ? (px) :\
34 (px) + (ty) / (textures)->rep_height * (textures)->rep_shift)
35
36 /* ---------------- Fake RasterOp for 2- and 4-bit devices ---------------- */
37
38 /*
39 * Define patched versions of the driver procedures that may be called
40 * by mem_mono_strip_copy_rop (see below). Currently we just punt to
41 * the slow, general case; we could do a lot better.
42 */
43 static int
mem_gray_rop_fill_rectangle(gx_device * dev,int x,int y,int w,int h,gx_color_index color)44 mem_gray_rop_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
45 gx_color_index color)
46 {
47 return -1;
48 }
49 static 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)50 mem_gray_rop_copy_mono(gx_device * dev, const byte * data,
51 int dx, int raster, gx_bitmap_id id,
52 int x, int y, int w, int h,
53 gx_color_index zero, gx_color_index one)
54 {
55 return -1;
56 }
57 static 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)58 mem_gray_rop_strip_tile_rectangle(gx_device * dev,
59 const gx_strip_bitmap * tiles,
60 int x, int y, int w, int h,
61 gx_color_index color0, gx_color_index color1,
62 int px, int py)
63 {
64 return -1;
65 }
66
67 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)68 mem_gray_strip_copy_rop(gx_device * dev,
69 const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id,
70 const gx_color_index * scolors,
71 const gx_strip_bitmap * textures, const gx_color_index * tcolors,
72 int x, int y, int width, int height,
73 int phase_x, int phase_y, gs_logical_operation_t lop)
74 {
75 gx_color_index scolors2[2];
76 const gx_color_index *real_scolors = scolors;
77 gx_color_index tcolors2[2];
78 const gx_color_index *real_tcolors = tcolors;
79 gx_strip_bitmap texture2;
80 const gx_strip_bitmap *real_texture = textures;
81 long tdata;
82 int depth = dev->color_info.depth;
83 int log2_depth = depth >> 1; /* works for 2, 4 */
84 gx_color_index max_pixel = ((gx_color_index)1 << depth) - 1;
85 int code;
86
87 #ifdef DEBUG
88 if (gs_debug_c('b'))
89 trace_copy_rop("mem_gray_strip_copy_rop",
90 dev, sdata, sourcex, sraster,
91 id, scolors, textures, tcolors,
92 x, y, width, height, phase_x, phase_y, lop);
93 #endif
94 lop = lop_sanitize(lop);
95 if (gx_device_has_color(dev) ||
96 (scolors && /* must be (0,0) or (max,max) */
97 ((scolors[0] | scolors[1]) != 0) &&
98 ((scolors[0] & scolors[1]) != max_pixel)) ||
99 (tcolors && (tcolors[0] != tcolors[1]))
100 ) {
101 /* We can't fake it: do it the slow, painful way. */
102 return mem_default_strip_copy_rop(dev, sdata, sourcex, sraster, id,
103 scolors, textures, tcolors,
104 x, y, width, height,
105 phase_x, phase_y, lop);
106 }
107 if (scolors) { /* Must be a solid color: see above. */
108 scolors2[0] = scolors2[1] = scolors[0] & 1;
109 real_scolors = scolors2;
110 }
111 if (textures) {
112 texture2 = *textures;
113 texture2.size.x <<= log2_depth;
114 texture2.rep_width <<= log2_depth;
115 texture2.shift <<= log2_depth;
116 texture2.rep_shift <<= log2_depth;
117 texture2.num_planes = 1;
118 real_texture = &texture2;
119 }
120 if (tcolors) {
121 /* For polybit textures with colors other than */
122 /* all 0s or all 1s, fabricate the data. */
123 if (tcolors[0] != 0 && tcolors[0] != max_pixel) {
124 real_tcolors = 0;
125 *(byte *) & tdata = (byte) tcolors[0] << (8 - depth);
126 texture2.data = (byte *) & tdata;
127 texture2.raster = align_bitmap_mod;
128 texture2.size.x = texture2.rep_width = depth;
129 texture2.size.y = texture2.rep_height = 1;
130 texture2.id = gx_no_bitmap_id;
131 texture2.shift = texture2.rep_shift = 0;
132 real_texture = &texture2;
133 } else {
134 tcolors2[0] = tcolors2[1] = tcolors[0] & 1;
135 real_tcolors = tcolors2;
136 }
137 }
138 /*
139 * mem_mono_strip_copy_rop may call fill_rectangle, copy_mono, or
140 * strip_tile_rectangle for special cases. Patch those procedures
141 * temporarily so they will either do the right thing or return
142 * an error.
143 */
144 {
145 dev_proc_fill_rectangle((*fill_rectangle)) =
146 dev_proc(dev, fill_rectangle);
147 dev_proc_copy_mono((*copy_mono)) =
148 dev_proc(dev, copy_mono);
149 dev_proc_strip_tile_rectangle((*strip_tile_rectangle)) =
150 dev_proc(dev, strip_tile_rectangle);
151
152 set_dev_proc(dev, fill_rectangle, mem_gray_rop_fill_rectangle);
153 set_dev_proc(dev, copy_mono, mem_gray_rop_copy_mono);
154 set_dev_proc(dev, strip_tile_rectangle,
155 mem_gray_rop_strip_tile_rectangle);
156 dev->width <<= log2_depth;
157 code = mem_mono_strip_copy_rop(dev, sdata,
158 (real_scolors == NULL ?
159 sourcex << log2_depth : sourcex),
160 sraster, id, real_scolors,
161 real_texture, real_tcolors,
162 x << log2_depth, y,
163 width << log2_depth, height,
164 phase_x << log2_depth, phase_y, lop);
165 set_dev_proc(dev, fill_rectangle, fill_rectangle);
166 set_dev_proc(dev, copy_mono, copy_mono);
167 set_dev_proc(dev, strip_tile_rectangle, strip_tile_rectangle);
168 dev->width >>= log2_depth;
169 }
170 /* If we punted, use the general procedure. */
171 if (code < 0)
172 return mem_default_strip_copy_rop(dev, sdata, sourcex, sraster, id,
173 scolors, textures, tcolors,
174 x, y, width, height,
175 phase_x, phase_y, lop);
176 return code;
177 }
178