xref: /plan9/sys/src/cmd/gs/src/gdevmem.h (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
1 /* Copyright (C) 1991, 2000 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: gdevmem.h,v 1.7 2002/08/22 07:12:28 henrys Exp $ */
18 /* Private definitions for memory devices. */
19 
20 #ifndef gdevmem_INCLUDED
21 #  define gdevmem_INCLUDED
22 
23 #include "gxbitops.h"
24 
25 /*
26    The representation for a "memory" device is simply a
27    contiguous bitmap stored in something like the PostScript
28    representation, i.e., each scan line (in left-to-right order), padded
29    to a multiple of bitmap_align_mod bytes, followed immediately by
30    the next one.
31 
32    The representation of strings in the interpreter limits
33    the size of a string to 64K-1 bytes, which means we can't simply use
34    a string for the contents of a memory device.
35    We get around this problem by making the client read out the
36    contents of a memory device bitmap in pieces.
37 
38    On 80x86 PCs running in 16-bit mode, there may be no way to
39    obtain a contiguous block of storage larger than 64K bytes,
40    which typically isn't big enough for a full-screen bitmap.
41    We take the following compromise position: if the PC is running in
42    native mode (pseudo-segmenting), we limit the bitmap to 64K;
43    if the PC is running in protected mode (e.g., under MS Windows),
44    we assume that blocks larger than 64K have sequential segment numbers,
45    and that the client arranges things so that an individual scan line,
46    the scan line pointer table, and any single call on a drawing routine
47    do not cross a segment boundary.
48 
49    Even though the scan lines are stored contiguously, we store a table
50    of their base addresses, because indexing into it is faster than
51    the multiplication that would otherwise be needed.
52  */
53 
54 /*
55  * Macros for scan line access.
56  * x_to_byte is different for each number of bits per pixel.
57  * Note that these macros depend on the definition of chunk:
58  * each procedure that uses the scanning macros should #define
59  * (not typedef) chunk as either uint or byte.
60  */
61 #define declare_scan_ptr(ptr)\
62 	DECLARE_SCAN_PTR_VARS(ptr, chunk *, draster)
63 #define DECLARE_SCAN_PTR_VARS(ptr, ptype, draster)\
64 	register ptype ptr;\
65 	uint draster
66 #define setup_rect(ptr)\
67 	SETUP_RECT_VARS(ptr, chunk *, draster)
68 #define SETUP_RECT_VARS(ptr, ptype, draster)\
69 	draster = mdev->raster;\
70 	ptr = (ptype)(scan_line_base(mdev, y) +\
71 	  (x_to_byte(x) & -chunk_align_bytes))
72 
73 /* ------ Generic macros ------ */
74 
75 /* Macro for declaring the essential device procedures. */
76 dev_proc_get_initial_matrix(mem_get_initial_matrix);
77 dev_proc_close_device(mem_close);
78 #define declare_mem_map_procs(map_rgb_color, map_color_rgb)\
79   private dev_proc_map_rgb_color(map_rgb_color);\
80   private dev_proc_map_color_rgb(map_color_rgb)
81 #define declare_mem_procs(copy_mono, copy_color, fill_rectangle)\
82   private dev_proc_copy_mono(copy_mono);\
83   private dev_proc_copy_color(copy_color);\
84   private dev_proc_fill_rectangle(fill_rectangle)
85 /*
86  * We define one relatively low-usage drawing procedure that is common to
87  * all memory devices so that we have a reliable way to implement
88  * gs_is_memory_device.  It is equivalent to gx_default_draw_thin_line.
89  */
90 dev_proc_draw_thin_line(mem_draw_thin_line);
91 
92 /* The following are used for all except planar or word-oriented devices. */
93 dev_proc_open_device(mem_open);
94 dev_proc_get_bits_rectangle(mem_get_bits_rectangle);
95 /* The following are for word-oriented devices. */
96 #if arch_is_big_endian
97 #  define mem_word_get_bits_rectangle mem_get_bits_rectangle
98 #else
99 dev_proc_get_bits_rectangle(mem_word_get_bits_rectangle);
100 #endif
101 /* The following are used for the non-true-color devices. */
102 dev_proc_map_rgb_color(mem_mapped_map_rgb_color);
103 dev_proc_map_color_rgb(mem_mapped_map_color_rgb);
104 /* Default implementation */
105 dev_proc_strip_copy_rop(mem_default_strip_copy_rop);
106 
107 /*
108  * Macro for generating the device descriptor.
109  * Various compilers have problems with the obvious definition
110  * for max_value, namely:
111  *      (depth >= 8 ? 255 : (1 << depth) - 1)
112  * I tried changing (1 << depth) to (1 << (depth & 15)) to forestall bogus
113  * error messages about invalid shift counts, but the H-P compiler chokes
114  * on this.  Since the only values of depth we ever plan to support are
115  * powers of 2 (and 24), we just go ahead and enumerate them.
116  */
117 #define max_value_gray(rgb_depth, gray_depth)\
118   (gray_depth ? (1 << gray_depth) - 1 : max_value_rgb(rgb_depth, 0))
119 #define max_value_rgb(rgb_depth, gray_depth)\
120   (rgb_depth >= 8 ? 255 : rgb_depth == 4 ? 15 : rgb_depth == 2 ? 3 :\
121    rgb_depth == 1 ? 1 : (1 << gray_depth) - 1)
122 #define mem_full_alpha_device(name, rgb_depth, gray_depth, open, map_rgb_color, map_color_rgb, copy_mono, copy_color, fill_rectangle, map_cmyk_color, copy_alpha, strip_tile_rectangle, strip_copy_rop, get_bits_rectangle)\
123 {	std_device_dci_body(gx_device_memory, 0, name,\
124 	  0, 0, 72, 72,\
125 	  (rgb_depth ? 3 : 0) + (gray_depth ? 1 : 0),	/* num_components */\
126 	  rgb_depth + gray_depth,	/* depth */\
127 	  max_value_gray(rgb_depth, gray_depth),	/* max_gray */\
128 	  max_value_rgb(rgb_depth, gray_depth),	/* max_color */\
129 	  max_value_gray(rgb_depth, gray_depth) + 1, /* dither_grays */\
130 	  max_value_rgb(rgb_depth, gray_depth) + 1 /* dither_colors */\
131 	),\
132 	{	open,			/* differs */\
133 		mem_get_initial_matrix,\
134 		gx_default_sync_output,\
135 		gx_default_output_page,\
136 		mem_close,\
137 		map_rgb_color,		/* differs */\
138 		map_color_rgb,		/* differs */\
139 		fill_rectangle,		/* differs */\
140 		gx_default_tile_rectangle,\
141 		copy_mono,		/* differs */\
142 		copy_color,		/* differs */\
143 		gx_default_draw_line,\
144 		gx_default_get_bits,\
145 		gx_default_get_params,\
146 		gx_default_put_params,\
147 		map_cmyk_color,		/* differs */\
148 		gx_forward_get_xfont_procs,\
149 		gx_forward_get_xfont_device,\
150 		gx_default_map_rgb_alpha_color,\
151 		gx_forward_get_page_device,\
152 		gx_default_get_alpha_bits,	/* default is no alpha */\
153 		copy_alpha,		/* differs */\
154 		gx_default_get_band,\
155 		gx_default_copy_rop,\
156 		gx_default_fill_path,\
157 		gx_default_stroke_path,\
158 		gx_default_fill_mask,\
159 		gx_default_fill_trapezoid,\
160 		gx_default_fill_parallelogram,\
161 		gx_default_fill_triangle,\
162 		mem_draw_thin_line,	/* see above */\
163 		gx_default_begin_image,\
164 		gx_default_image_data,\
165 		gx_default_end_image,\
166 		strip_tile_rectangle,	/* differs */\
167 		strip_copy_rop,		/* differs */\
168 		gx_default_get_clipping_box,\
169 		gx_default_begin_typed_image,\
170 		get_bits_rectangle,	/* differs */\
171 		gx_default_map_color_rgb_alpha,\
172 		gx_default_create_compositor,\
173 		gx_default_get_hardware_params,\
174 		gx_default_text_begin,\
175 		gx_default_finish_copydevice\
176 	},\
177 	0,			/* target */\
178 	mem_device_init_private	/* see gxdevmem.h */\
179 }
180 #define mem_full_device(name, rgb_depth, gray_depth, open, map_rgb_color, map_color_rgb, copy_mono, copy_color, fill_rectangle, map_cmyk_color, strip_tile_rectangle, strip_copy_rop, get_bits_rectangle)\
181   mem_full_alpha_device(name, rgb_depth, gray_depth, open, map_rgb_color,\
182 			map_color_rgb, copy_mono, copy_color, fill_rectangle,\
183 			map_cmyk_color, gx_default_copy_alpha,\
184 			strip_tile_rectangle, strip_copy_rop,\
185 			get_bits_rectangle)
186 #define mem_device(name, rgb_depth, gray_depth, map_rgb_color, map_color_rgb, copy_mono, copy_color, fill_rectangle, strip_copy_rop)\
187   mem_full_device(name, rgb_depth, gray_depth, mem_open, map_rgb_color,\
188 		  map_color_rgb, copy_mono, copy_color, fill_rectangle,\
189 		  gx_default_map_cmyk_color, gx_default_strip_tile_rectangle,\
190 		  strip_copy_rop, mem_get_bits_rectangle)
191 
192 /* Swap a rectangle of bytes, for converting between word- and */
193 /* byte-oriented representation. */
194 void mem_swap_byte_rect(byte *, uint, int, int, int, bool);
195 
196 /* Copy a rectangle of bytes from a source to a destination. */
197 #define mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h)\
198   bytes_copy_rectangle(scan_line_base(mdev, y) + x_to_byte(x),\
199 		       (mdev)->raster,\
200 		       base + x_to_byte(sourcex), sraster,\
201 		       x_to_byte(w), h)
202 
203 /* ------ Implementations ------ */
204 
205 extern const gx_device_memory mem_mono_device;
206 extern const gx_device_memory mem_mapped2_device;
207 extern const gx_device_memory mem_mapped4_device;
208 extern const gx_device_memory mem_mapped8_device;
209 extern const gx_device_memory mem_true16_device;
210 extern const gx_device_memory mem_true24_device;
211 extern const gx_device_memory mem_true32_device;
212 extern const gx_device_memory mem_true40_device;
213 extern const gx_device_memory mem_true48_device;
214 extern const gx_device_memory mem_true56_device;
215 extern const gx_device_memory mem_true64_device;
216 extern const gx_device_memory mem_planar_device;
217 /*
218  * We declare the RasterOp implementation procedures here because they are
219  * referenced in several implementation modules.
220  */
221 dev_proc_strip_copy_rop(mem_mono_strip_copy_rop);
222 dev_proc_strip_copy_rop(mem_gray_strip_copy_rop);
223 dev_proc_strip_copy_rop(mem_gray8_rgb24_strip_copy_rop);
224 
225 #if arch_is_big_endian
226 #  define mem_mono_word_device mem_mono_device
227 #  define mem_mapped2_word_device mem_mapped2_device
228 #  define mem_mapped4_word_device mem_mapped4_device
229 #  define mem_mapped8_word_device mem_mapped8_device
230 #  define mem_true24_word_device mem_true24_device
231 #  define mem_true32_word_device mem_true32_device
232 #  define mem_true40_word_device mem_true40_device
233 #  define mem_true48_word_device mem_true48_device
234 #  define mem_true56_word_device mem_true56_device
235 #  define mem_true64_word_device mem_true64_device
236 #else
237 extern const gx_device_memory mem_mono_word_device;
238 extern const gx_device_memory mem_mapped2_word_device;
239 extern const gx_device_memory mem_mapped4_word_device;
240 extern const gx_device_memory mem_mapped8_word_device;
241 extern const gx_device_memory mem_true24_word_device;
242 extern const gx_device_memory mem_true32_word_device;
243 extern const gx_device_memory mem_true40_word_device;
244 extern const gx_device_memory mem_true48_word_device;
245 extern const gx_device_memory mem_true56_word_device;
246 extern const gx_device_memory mem_true64_word_device;
247 
248 #endif
249 /* Provide standard palettes for 1-bit devices. */
250 extern const gs_const_string mem_mono_b_w_palette;	/* black=1, white=0 */
251 extern const gs_const_string mem_mono_w_b_palette;	/* black=0, white=1 */
252 
253 #endif /* gdevmem_INCLUDED */
254