/src/libspectre/ghostscript/base/gdevmr2n.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* Copyright (C) 2001-2020 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 |
44 | | mem_gray_rop_fill_rectangle(gx_device * dev, int x, int y, int w, int h, |
45 | | gx_color_index color) |
46 | 0 | { |
47 | 0 | return -1; |
48 | 0 | } |
49 | | static int |
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 | 0 | { |
55 | 0 | return -1; |
56 | 0 | } |
57 | | static int |
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 | 0 | { |
64 | 0 | return -1; |
65 | 0 | } |
66 | | |
67 | | int |
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 | 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 | | #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 | 0 | lop = lop_sanitize(lop); |
95 | 0 | if (gx_device_has_color(dev) || |
96 | 0 | (scolors && /* must be (0,0) or (max,max) */ |
97 | 0 | ((scolors[0] | scolors[1]) != 0) && |
98 | 0 | ((scolors[0] & scolors[1]) != max_pixel)) || |
99 | 0 | (tcolors && (tcolors[0] != tcolors[1])) |
100 | 0 | ) { |
101 | | /* We can't fake it: do it the slow, painful way. */ |
102 | 0 | return mem_default_strip_copy_rop(dev, sdata, sourcex, sraster, id, |
103 | 0 | scolors, textures, tcolors, |
104 | 0 | x, y, width, height, |
105 | 0 | phase_x, phase_y, lop); |
106 | 0 | } |
107 | 0 | if (scolors) { /* Must be a solid color: see above. */ |
108 | 0 | scolors2[0] = scolors2[1] = scolors[0] & 1; |
109 | 0 | real_scolors = scolors2; |
110 | 0 | } |
111 | 0 | if (textures) { |
112 | 0 | texture2 = *textures; |
113 | 0 | texture2.size.x <<= log2_depth; |
114 | 0 | texture2.rep_width <<= log2_depth; |
115 | 0 | texture2.shift <<= log2_depth; |
116 | 0 | texture2.rep_shift <<= log2_depth; |
117 | 0 | texture2.num_planes = 1; |
118 | 0 | real_texture = &texture2; |
119 | 0 | } |
120 | 0 | if (tcolors) { |
121 | | /* For polybit textures with colors other than */ |
122 | | /* all 0s or all 1s, fabricate the data. */ |
123 | 0 | if (tcolors[0] != 0 && tcolors[0] != max_pixel) { |
124 | 0 | real_tcolors = 0; |
125 | 0 | *(byte *) & tdata = (byte) tcolors[0] << (8 - depth); |
126 | 0 | texture2.data = (byte *) & tdata; |
127 | 0 | texture2.raster = align_bitmap_mod; |
128 | 0 | texture2.size.x = texture2.rep_width = depth; |
129 | 0 | texture2.size.y = texture2.rep_height = 1; |
130 | 0 | texture2.id = gx_no_bitmap_id; |
131 | 0 | texture2.shift = texture2.rep_shift = 0; |
132 | 0 | real_texture = &texture2; |
133 | 0 | } else { |
134 | 0 | tcolors2[0] = tcolors2[1] = tcolors[0] & 1; |
135 | 0 | real_tcolors = tcolors2; |
136 | 0 | } |
137 | 0 | } |
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 | 0 | { |
145 | 0 | dev_proc_fill_rectangle((*fill_rectangle)) = |
146 | 0 | dev_proc(dev, fill_rectangle); |
147 | 0 | dev_proc_copy_mono((*copy_mono)) = |
148 | 0 | dev_proc(dev, copy_mono); |
149 | 0 | dev_proc_strip_tile_rectangle((*strip_tile_rectangle)) = |
150 | 0 | dev_proc(dev, strip_tile_rectangle); |
151 | |
|
152 | 0 | set_dev_proc(dev, fill_rectangle, mem_gray_rop_fill_rectangle); |
153 | 0 | set_dev_proc(dev, copy_mono, mem_gray_rop_copy_mono); |
154 | 0 | set_dev_proc(dev, strip_tile_rectangle, |
155 | 0 | mem_gray_rop_strip_tile_rectangle); |
156 | 0 | dev->width <<= log2_depth; |
157 | 0 | code = mem_mono_strip_copy_rop(dev, sdata, |
158 | 0 | (real_scolors == NULL ? |
159 | 0 | sourcex << log2_depth : sourcex), |
160 | 0 | sraster, id, real_scolors, |
161 | 0 | real_texture, real_tcolors, |
162 | 0 | x << log2_depth, y, |
163 | 0 | width << log2_depth, height, |
164 | 0 | phase_x << log2_depth, phase_y, lop); |
165 | 0 | set_dev_proc(dev, fill_rectangle, fill_rectangle); |
166 | 0 | set_dev_proc(dev, copy_mono, copy_mono); |
167 | 0 | set_dev_proc(dev, strip_tile_rectangle, strip_tile_rectangle); |
168 | 0 | dev->width >>= log2_depth; |
169 | 0 | } |
170 | | /* If we punted, use the general procedure. */ |
171 | 0 | if (code < 0) |
172 | 0 | return mem_default_strip_copy_rop(dev, sdata, sourcex, sraster, id, |
173 | 0 | scolors, textures, tcolors, |
174 | 0 | x, y, width, height, |
175 | 0 | phase_x, phase_y, lop); |
176 | 0 | return code; |
177 | 0 | } |