Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 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: gdevm2.c,v 1.5 2002/11/05 01:03:14 dan Exp $ */
18
/* 2-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
/* ================ Standard (byte-oriented) device ================ */
26
 
27
#undef chunk
28
#define chunk byte
29
#define fpat(byt) mono_fill_make_pattern(byt)
30
 
31
/* Procedures */
32
declare_mem_procs(mem_mapped2_copy_mono, mem_mapped2_copy_color, mem_mapped2_fill_rectangle);
33
 
34
/* The device descriptor. */
35
const gx_device_memory mem_mapped2_device =
36
mem_device("image2", 2, 0,
37
	   mem_mapped_map_rgb_color, mem_mapped_map_color_rgb,
38
	   mem_mapped2_copy_mono, mem_mapped2_copy_color,
39
	   mem_mapped2_fill_rectangle, mem_gray_strip_copy_rop);
40
 
41
/* Convert x coordinate to byte offset in scan line. */
42
#undef x_to_byte
43
#define x_to_byte(x) ((x) >> 2)
44
 
45
/* Define the 2-bit fill patterns. */
46
static const mono_fill_chunk tile_patterns[4] = {
47
    fpat(0x00), fpat(0x55), fpat(0xaa), fpat(0xff)
48
};
49
 
50
/* Fill a rectangle with a color. */
51
private int
52
mem_mapped2_fill_rectangle(gx_device * dev,
53
			   int x, int y, int w, int h, gx_color_index color)
54
{
55
    gx_device_memory * const mdev = (gx_device_memory *)dev;
56
 
57
    fit_fill(dev, x, y, w, h);
58
    bits_fill_rectangle(scan_line_base(mdev, y), x << 1, mdev->raster,
59
			tile_patterns[color], w << 1, h);
60
    return 0;
61
}
62
 
63
/* Copy a bitmap. */
64
private int
65
mem_mapped2_copy_mono(gx_device * dev,
66
		      const byte * base, int sourcex, int sraster,
67
		      gx_bitmap_id id, int x, int y, int w, int h,
68
		      gx_color_index zero, gx_color_index one)
69
{
70
    gx_device_memory * const mdev = (gx_device_memory *)dev;
71
    const byte *line;
72
    int first_bit;
73
    byte first_mask, b0, b1, bxor, left_mask, right_mask;
74
    static const byte btab[4] = {0, 0x55, 0xaa, 0xff};
75
    static const byte bmask[4] = {0xc0, 0x30, 0xc, 3};
76
    static const byte lmask[4] = {0, 0xc0, 0xf0, 0xfc};
77
 
78
    declare_scan_ptr(dest);
79
 
80
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
81
    setup_rect(dest);
82
    line = base + (sourcex >> 3);
83
    first_bit = 0x80 >> (sourcex & 7);
84
    first_mask = bmask[x & 3];
85
    left_mask = lmask[x & 3];
86
    right_mask = ~lmask[(x + w) & 3];
87
    if ((x & 3) + w <= 3)
88
	left_mask = right_mask = left_mask | right_mask;
89
    b0 = btab[zero & 3];
90
    b1 = btab[one & 3];
91
    bxor = b0 ^ b1;
92
    while (h-- > 0) {
93
	register byte *pptr = (byte *) dest;
94
	const byte *sptr = line;
95
	register int sbyte = *sptr++;
96
	register int bit = first_bit;
97
	register byte mask = first_mask;
98
	int count = w;
99
 
100
	/* We have 4 cases, of which only 2 really matter. */
101
	if (one != gx_no_color_index) {
102
	    if (zero != gx_no_color_index) {	/* Copying an opaque bitmap. */
103
		byte data = (*pptr & left_mask) | (b0 & ~left_mask);
104
 
105
		for ( ; ; ) {
106
		    if (sbyte & bit)
107
			data ^= bxor & mask;
108
		    if ((bit >>= 1) == 0)
109
			bit = 0x80, sbyte = *sptr++;
110
		    if ((mask >>= 2) == 0)
111
			mask = 0xc0, *pptr++ = data, data = b0;
112
		    if (--count <= 0)
113
			break;
114
		}
115
		if (mask != 0xc0)
116
		    *pptr =
117
			(*pptr & right_mask) | (data & ~right_mask);
118
	    } else {		/* Filling a mask. */
119
		for ( ; ; ) {
120
		    if (sbyte & bit)
121
			*pptr = (*pptr & ~mask) + (b1 & mask);
122
		    if (--count <= 0)
123
			break;
124
		    if ((bit >>= 1) == 0)
125
			bit = 0x80, sbyte = *sptr++;
126
		    if ((mask >>= 2) == 0)
127
			mask = 0xc0, pptr++;
128
		}
129
	    }
130
	} else {		/* Some other case. */
131
	    for ( ; ; ) {
132
		if (!(sbyte & bit)) {
133
		    if (zero != gx_no_color_index)
134
			*pptr = (*pptr & ~mask) + (b0 & mask);
135
		}
136
		if (--count <= 0)
137
		    break;
138
		if ((bit >>= 1) == 0)
139
		    bit = 0x80, sbyte = *sptr++;
140
		if ((mask >>= 2) == 0)
141
		    mask = 0xc0, pptr++;
142
	    }
143
	}
144
	line += sraster;
145
	inc_ptr(dest, draster);
146
    }
147
    return 0;
148
}
149
 
150
/* Copy a color bitmap. */
151
private int
152
mem_mapped2_copy_color(gx_device * dev,
153
		       const byte * base, int sourcex, int sraster,
154
		       gx_bitmap_id id, int x, int y, int w, int h)
155
{
156
    int code;
157
 
158
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
159
    /* Use monobit copy_mono. */
160
    /* Patch the width in the device temporarily. */
161
    dev->width <<= 1;
162
    code = (*dev_proc(&mem_mono_device, copy_mono))
163
	(dev, base, sourcex << 1, sraster, id,
164
	 x << 1, y, w << 1, h, (gx_color_index) 0, (gx_color_index) 1);
165
    /* Restore the correct width. */
166
    dev->width >>= 1;
167
    return code;
168
}
169
 
170
/* ================ "Word"-oriented device ================ */
171
 
172
/* Note that on a big-endian machine, this is the same as the */
173
/* standard byte-oriented-device. */
174
 
175
#if !arch_is_big_endian
176
 
177
/* Procedures */
178
declare_mem_procs(mem2_word_copy_mono, mem2_word_copy_color, mem2_word_fill_rectangle);
179
 
180
/* Here is the device descriptor. */
181
const gx_device_memory mem_mapped2_word_device =
182
mem_full_device("image2w", 2, 0, mem_open,
183
		mem_mapped_map_rgb_color, mem_mapped_map_color_rgb,
184
		mem2_word_copy_mono, mem2_word_copy_color,
185
		mem2_word_fill_rectangle, gx_default_map_cmyk_color,
186
		gx_default_strip_tile_rectangle, gx_no_strip_copy_rop,
187
		mem_word_get_bits_rectangle);
188
 
189
/* Fill a rectangle with a color. */
190
private int
191
mem2_word_fill_rectangle(gx_device * dev, int x, int y, int w, int h,
192
			 gx_color_index color)
193
{
194
    gx_device_memory * const mdev = (gx_device_memory *)dev;
195
    byte *base;
196
    uint raster;
197
 
198
    fit_fill(dev, x, y, w, h);
199
    base = scan_line_base(mdev, y);
200
    raster = mdev->raster;
201
    mem_swap_byte_rect(base, raster, x << 1, w << 1, h, true);
202
    bits_fill_rectangle(base, x << 1, raster,
203
			tile_patterns[color], w << 1, h);
204
    mem_swap_byte_rect(base, raster, x << 1, w << 1, h, true);
205
    return 0;
206
}
207
 
208
/* Copy a bitmap. */
209
private int
210
mem2_word_copy_mono(gx_device * dev,
211
		    const byte * base, int sourcex, int sraster,
212
		    gx_bitmap_id id, int x, int y, int w, int h,
213
		    gx_color_index zero, gx_color_index one)
214
{
215
    gx_device_memory * const mdev = (gx_device_memory *)dev;
216
    byte *row;
217
    uint raster;
218
    bool store;
219
 
220
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
221
    row = scan_line_base(mdev, y);
222
    raster = mdev->raster;
223
    store = (zero != gx_no_color_index && one != gx_no_color_index);
224
    mem_swap_byte_rect(row, raster, x << 1, w << 1, h, store);
225
    mem_mapped2_copy_mono(dev, base, sourcex, sraster, id,
226
			  x, y, w, h, zero, one);
227
    mem_swap_byte_rect(row, raster, x << 1, w << 1, h, false);
228
    return 0;
229
}
230
 
231
/* Copy a color bitmap. */
232
private int
233
mem2_word_copy_color(gx_device * dev,
234
		     const byte * base, int sourcex, int sraster,
235
		     gx_bitmap_id id, int x, int y, int w, int h)
236
{
237
    int code;
238
 
239
    fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
240
    /* Use monobit copy_mono. */
241
    /* Patch the width in the device temporarily. */
242
    dev->width <<= 1;
243
    code = (*dev_proc(&mem_mono_word_device, copy_mono))
244
	(dev, base, sourcex << 1, sraster, id,
245
	 x << 1, y, w << 1, h, (gx_color_index) 0, (gx_color_index) 1);
246
    /* Restore the correct width. */
247
    dev->width >>= 1;
248
    return code;
249
}
250
 
251
#endif /* !arch_is_big_endian */