xref: /plan9/sys/src/cmd/gs/src/gdevm8.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1994, 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: gdevm8.c,v 1.5 2002/06/16 05:48:55 lpd Exp $ */
18 /* 8-bit-per-pixel "memory" (stored bitmap) device */
19 #include "memory_.h"
20 #include "gx.h"
21 #include "gxdevice.h"
22 #include "gxdevmem.h"		/* semi-public definitions */
23 #include "gdevmem.h"		/* private definitions */
24 
25 #define mem_gray8_strip_copy_rop mem_gray8_rgb24_strip_copy_rop
26 
27 /* ================ Standard (byte-oriented) device ================ */
28 
29 #undef chunk
30 #define chunk byte
31 
32 /* Procedures */
33 declare_mem_procs(mem_mapped8_copy_mono, mem_mapped8_copy_color, mem_mapped8_fill_rectangle);
34 
35 /* The device descriptor. */
36 const gx_device_memory mem_mapped8_device =
37 mem_device("image8", 8, 0,
38 	   mem_mapped_map_rgb_color, mem_mapped_map_color_rgb,
39   mem_mapped8_copy_mono, mem_mapped8_copy_color, mem_mapped8_fill_rectangle,
40 	   mem_gray8_strip_copy_rop);
41 
42 /* Convert x coordinate to byte offset in scan line. */
43 #undef x_to_byte
44 #define x_to_byte(x) (x)
45 
46 /* Fill a rectangle with a color. */
47 private int
mem_mapped8_fill_rectangle(gx_device * dev,int x,int y,int w,int h,gx_color_index color)48 mem_mapped8_fill_rectangle(gx_device * dev,
49 			   int x, int y, int w, int h, gx_color_index color)
50 {
51     gx_device_memory * const mdev = (gx_device_memory *)dev;
52 
53     fit_fill(dev, x, y, w, h);
54     bytes_fill_rectangle(scan_line_base(mdev, y) + x, mdev->raster,
55 			 (byte) color, w, h);
56     return 0;
57 }
58 
59 /* Copy a monochrome bitmap. */
60 /* We split up this procedure because of limitations in the bcc32 compiler. */
61 private void mapped8_copy01(chunk *, const byte *, int, int, uint,
62 			    int, int, byte, byte);
63 private void mapped8_copyN1(chunk *, const byte *, int, int, uint,
64 			    int, int, byte);
65 private void mapped8_copy0N(chunk *, const byte *, int, int, uint,
66 			    int, int, byte);
67 private int
mem_mapped8_copy_mono(gx_device * dev,const byte * base,int sourcex,int sraster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index zero,gx_color_index one)68 mem_mapped8_copy_mono(gx_device * dev,
69 	       const byte * base, int sourcex, int sraster, gx_bitmap_id id,
70 	int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
71 {
72     gx_device_memory * const mdev = (gx_device_memory *)dev;
73     const byte *line;
74     int first_bit;
75 
76     declare_scan_ptr(dest);
77     fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
78     setup_rect(dest);
79     line = base + (sourcex >> 3);
80     first_bit = 0x80 >> (sourcex & 7);
81 #define is_color(c) ((int)(c) != (int)gx_no_color_index)
82     if (is_color(one)) {
83 	if (is_color(zero))
84 	    mapped8_copy01(dest, line, first_bit, sraster, draster,
85 			   w, h, (byte) zero, (byte) one);
86 	else
87 	    mapped8_copyN1(dest, line, first_bit, sraster, draster,
88 			   w, h, (byte) one);
89     } else if (is_color(zero))
90 	mapped8_copy0N(dest, line, first_bit, sraster, draster,
91 		       w, h, (byte) zero);
92 #undef is_color
93     return 0;
94 }
95 /* Macros for copy loops */
96 #define COPY_BEGIN\
97 	while ( h-- > 0 )\
98 	{	register byte *pptr = dest;\
99 		const byte *sptr = line;\
100 		register int sbyte = *sptr;\
101 		register uint bit = first_bit;\
102 		int count = w;\
103 		do\
104 		{
105 #define COPY_END\
106 			if ( (bit >>= 1) == 0 )\
107 				bit = 0x80, sbyte = *++sptr;\
108 			pptr++;\
109 		}\
110 		while ( --count > 0 );\
111 		line += sraster;\
112 		inc_ptr(dest, draster);\
113 	}
114 /* Halftone coloring */
115 private void
mapped8_copy01(chunk * dest,const byte * line,int first_bit,int sraster,uint draster,int w,int h,byte b0,byte b1)116 mapped8_copy01(chunk * dest, const byte * line, int first_bit,
117 	       int sraster, uint draster, int w, int h, byte b0, byte b1)
118 {
119     COPY_BEGIN
120 	* pptr = (sbyte & bit ? b1 : b0);
121     COPY_END
122 }
123 /* Stenciling */
124 private void
mapped8_copyN1(chunk * dest,const byte * line,int first_bit,int sraster,uint draster,int w,int h,byte b1)125 mapped8_copyN1(chunk * dest, const byte * line, int first_bit,
126 	       int sraster, uint draster, int w, int h, byte b1)
127 {
128     COPY_BEGIN
129 	if (sbyte & bit)
130 	*pptr = b1;
131     COPY_END
132 }
133 /* Reverse stenciling */
134 private void
mapped8_copy0N(chunk * dest,const byte * line,int first_bit,int sraster,uint draster,int w,int h,byte b0)135 mapped8_copy0N(chunk * dest, const byte * line, int first_bit,
136 	       int sraster, uint draster, int w, int h, byte b0)
137 {
138     COPY_BEGIN
139 	if (!(sbyte & bit))
140 	*pptr = b0;
141     COPY_END
142 }
143 #undef COPY_BEGIN
144 #undef COPY_END
145 
146 /* Copy a color bitmap. */
147 private int
mem_mapped8_copy_color(gx_device * dev,const byte * base,int sourcex,int sraster,gx_bitmap_id id,int x,int y,int w,int h)148 mem_mapped8_copy_color(gx_device * dev,
149 	       const byte * base, int sourcex, int sraster, gx_bitmap_id id,
150 		       int x, int y, int w, int h)
151 {
152     gx_device_memory * const mdev = (gx_device_memory *)dev;
153 
154     fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
155     mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h);
156     return 0;
157 }
158 
159 /* ================ "Word"-oriented device ================ */
160 
161 /* Note that on a big-endian machine, this is the same as the */
162 /* standard byte-oriented-device. */
163 
164 #if !arch_is_big_endian
165 
166 /* Procedures */
167 declare_mem_procs(mem8_word_copy_mono, mem8_word_copy_color, mem8_word_fill_rectangle);
168 
169 /* Here is the device descriptor. */
170 const gx_device_memory mem_mapped8_word_device =
171 mem_full_device("image8w", 8, 0, mem_open,
172 		mem_mapped_map_rgb_color, mem_mapped_map_color_rgb,
173 	mem8_word_copy_mono, mem8_word_copy_color, mem8_word_fill_rectangle,
174 		gx_default_map_cmyk_color, gx_default_strip_tile_rectangle,
175 		gx_no_strip_copy_rop, mem_word_get_bits_rectangle);
176 
177 /* Fill a rectangle with a color. */
178 private int
mem8_word_fill_rectangle(gx_device * dev,int x,int y,int w,int h,gx_color_index color)179 mem8_word_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
180 			 gx_color_index color)
181 {
182     gx_device_memory * const mdev = (gx_device_memory *)dev;
183     byte *base;
184     uint raster;
185 
186     fit_fill(dev, x, y, w, h);
187     base = scan_line_base(mdev, y);
188     raster = mdev->raster;
189     mem_swap_byte_rect(base, raster, x << 3, w << 3, h, true);
190     bytes_fill_rectangle(base + x, raster, (byte) color, w, h);
191     mem_swap_byte_rect(base, raster, x << 3, w << 3, h, true);
192     return 0;
193 }
194 
195 /* Copy a bitmap. */
196 private int
mem8_word_copy_mono(gx_device * dev,const byte * base,int sourcex,int sraster,gx_bitmap_id id,int x,int y,int w,int h,gx_color_index zero,gx_color_index one)197 mem8_word_copy_mono(gx_device * dev,
198 	       const byte * base, int sourcex, int sraster, gx_bitmap_id id,
199 	int x, int y, int w, int h, gx_color_index zero, gx_color_index one)
200 {
201     gx_device_memory * const mdev = (gx_device_memory *)dev;
202     byte *row;
203     uint raster;
204     bool store;
205 
206     fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
207     row = scan_line_base(mdev, y);
208     raster = mdev->raster;
209     store = (zero != gx_no_color_index && one != gx_no_color_index);
210     mem_swap_byte_rect(row, raster, x << 3, w << 3, h, store);
211     mem_mapped8_copy_mono(dev, base, sourcex, sraster, id,
212 			  x, y, w, h, zero, one);
213     mem_swap_byte_rect(row, raster, x << 3, w << 3, h, false);
214     return 0;
215 }
216 
217 /* Copy a color bitmap. */
218 private int
mem8_word_copy_color(gx_device * dev,const byte * base,int sourcex,int sraster,gx_bitmap_id id,int x,int y,int w,int h)219 mem8_word_copy_color(gx_device * dev,
220 	       const byte * base, int sourcex, int sraster, gx_bitmap_id id,
221 		     int x, int y, int w, int h)
222 {
223     gx_device_memory * const mdev = (gx_device_memory *)dev;
224     byte *row;
225     uint raster;
226 
227     fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
228     row = scan_line_base(mdev, y);
229     raster = mdev->raster;
230     mem_swap_byte_rect(row, raster, x << 3, w << 3, h, true);
231     mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h);
232     mem_swap_byte_rect(row, raster, x << 3, w << 3, h, false);
233     return 0;
234 }
235 
236 #endif /* !arch_is_big_endian */
237