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