summaryrefslogtreecommitdiff
path: root/gs/src/gdevm2.c
diff options
context:
space:
mode:
Diffstat (limited to 'gs/src/gdevm2.c')
-rw-r--r--gs/src/gdevm2.c239
1 files changed, 239 insertions, 0 deletions
diff --git a/gs/src/gdevm2.c b/gs/src/gdevm2.c
new file mode 100644
index 000000000..a3b2957a6
--- /dev/null
+++ b/gs/src/gdevm2.c
@@ -0,0 +1,239 @@
+/* Copyright (C) 1994, 1995, 1996 Aladdin Enterprises. All rights reserved.
+
+ This file is part of Aladdin Ghostscript.
+
+ Aladdin Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author
+ or distributor accepts any responsibility for the consequences of using it,
+ or for whether it serves any particular purpose or works at all, unless he
+ or she says so in writing. Refer to the Aladdin Ghostscript Free Public
+ License (the "License") for full details.
+
+ Every copy of Aladdin Ghostscript must include a copy of the License,
+ normally in a plain ASCII text file named PUBLIC. The License grants you
+ the right to copy, modify and redistribute Aladdin Ghostscript, but only
+ under certain conditions described in the License. Among other things, the
+ License requires that the copyright notice and this notice be preserved on
+ all copies.
+*/
+
+/* gdevm2.c */
+/* 2-bit-per-pixel "memory" (stored bitmap) device */
+#include "memory_.h"
+#include "gx.h"
+#include "gxdevice.h"
+#include "gxdevmem.h" /* semi-public definitions */
+#include "gdevmem.h" /* private definitions */
+
+/**************** NOTE: copy_rop only works for gray scale ****************/
+extern dev_proc_strip_copy_rop(mem_gray_strip_copy_rop);
+
+/* ================ Standard (byte-oriented) device ================ */
+
+#undef chunk
+#define chunk byte
+#define fpat(byt) mono_fill_make_pattern(byt)
+
+/* Procedures */
+declare_mem_procs(mem_mapped2_copy_mono, mem_mapped2_copy_color, mem_mapped2_fill_rectangle);
+
+/* The device descriptor. */
+const gx_device_memory far_data mem_mapped2_device =
+ mem_device("image2", 2, 0,
+ mem_mapped_map_rgb_color, mem_mapped_map_color_rgb,
+ mem_mapped2_copy_mono, mem_mapped2_copy_color, mem_mapped2_fill_rectangle,
+ mem_gray_strip_copy_rop);
+
+/* Convert x coordinate to byte offset in scan line. */
+#undef x_to_byte
+#define x_to_byte(x) ((x) >> 2)
+
+/* Define the 2-bit fill patterns. */
+static const mono_fill_chunk tile_patterns[4] =
+{ fpat(0x00), fpat(0x55), fpat(0xaa), fpat(0xff)
+};
+
+/* Fill a rectangle with a color. */
+private int
+mem_mapped2_fill_rectangle(gx_device *dev,
+ int x, int y, int w, int h, gx_color_index color)
+{ fit_fill(dev, x, y, w, h);
+ bits_fill_rectangle(scan_line_base(mdev, y), x << 1, mdev->raster,
+ tile_patterns[color], w << 1, h);
+ return 0;
+}
+
+/* Copy a bitmap. */
+private int
+mem_mapped2_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)
+{ const byte *line;
+ int first_bit;
+ byte first_mask, b0, b1, bxor, left_mask, right_mask;
+ static const byte btab[4] = { 0, 0x55, 0xaa, 0xff };
+ static const byte bmask[4] = { 0xc0, 0x30, 0xc, 3 };
+ static const byte lmask[4] = { 0, 0xc0, 0xf0, 0xfc };
+ declare_scan_ptr(dest);
+
+ fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
+ setup_rect(dest);
+ line = base + (sourcex >> 3);
+ first_bit = 0x80 >> (sourcex & 7);
+ first_mask = bmask[x & 3];
+ left_mask = lmask[x & 3];
+ right_mask = ~lmask[(x + w) & 3];
+ if ( (x & 3) + w <= 4 )
+ left_mask = right_mask = left_mask | right_mask;
+ b0 = btab[zero & 3];
+ b1 = btab[one & 3];
+ bxor = b0 ^ b1;
+ while ( h-- > 0 )
+ { register byte *pptr = (byte *)dest;
+ const byte *sptr = line;
+ register int sbyte = *sptr++;
+ register int bit = first_bit;
+ register byte mask = first_mask;
+ int count = w;
+
+ /* We have 4 cases, of which only 2 really matter. */
+ if ( one != gx_no_color_index )
+ { if ( zero != gx_no_color_index )
+ { /* Copying an opaque bitmap. */
+ byte data =
+ (*pptr & left_mask) | (b0 & ~left_mask);
+ do
+ { if ( sbyte & bit )
+ data ^= bxor & mask;
+ if ( (bit >>= 1) == 0 )
+ bit = 0x80, sbyte = *sptr++;
+ if ( (mask >>= 2) == 0 )
+ mask = 0xc0, *pptr++ = data, data = b0;
+ }
+ while ( --count > 0 );
+ if ( mask != 0xc0 )
+ *pptr =
+ (*pptr & right_mask) | (data & ~right_mask);
+ }
+ else
+ { /* Filling a mask. */
+ do
+ { if ( sbyte & bit )
+ *pptr = (*pptr & ~mask) + (b1 & mask);
+ if ( (bit >>= 1) == 0 )
+ bit = 0x80, sbyte = *sptr++;
+ if ( (mask >>= 2) == 0 )
+ mask = 0xc0, pptr++;
+ }
+ while ( --count > 0 );
+ }
+ }
+ else
+ { /* Some other case. */
+ do
+ { if ( !(sbyte & bit) )
+ { if ( zero != gx_no_color_index )
+ *pptr = (*pptr & ~mask) + (b0 & mask);
+ }
+ if ( (bit >>= 1) == 0 )
+ bit = 0x80, sbyte = *sptr++;
+ if ( (mask >>= 2) == 0 )
+ mask = 0xc0, pptr++;
+ }
+ while ( --count > 0 );
+ }
+ line += sraster;
+ inc_ptr(dest, draster);
+ }
+ return 0;
+}
+
+/* Copy a color bitmap. */
+private int
+mem_mapped2_copy_color(gx_device *dev,
+ const byte *base, int sourcex, int sraster, gx_bitmap_id id,
+ int x, int y, int w, int h)
+{ int code;
+ fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
+ /* Use monobit copy_mono. */
+ /* Patch the width in the device temporarily. */
+ dev->width <<= 1;
+ code = (*dev_proc(&mem_mono_device, copy_mono))
+ (dev, base, sourcex << 1, sraster, id,
+ x << 1, y, w << 1, h, (gx_color_index)0, (gx_color_index)1);
+ /* Restore the correct width. */
+ dev->width >>= 1;
+ return code;
+}
+
+/* ================ "Word"-oriented device ================ */
+
+/* Note that on a big-endian machine, this is the same as the */
+/* standard byte-oriented-device. */
+
+#if !arch_is_big_endian
+
+/* Procedures */
+declare_mem_procs(mem2_word_copy_mono, mem2_word_copy_color, mem2_word_fill_rectangle);
+
+/* Here is the device descriptor. */
+const gx_device_memory far_data mem_mapped2_word_device =
+ mem_full_device("image2w", 2, 0, mem_open,
+ mem_mapped_map_rgb_color, mem_mapped_map_color_rgb,
+ mem2_word_copy_mono, mem2_word_copy_color, mem2_word_fill_rectangle,
+ mem_word_get_bits, gx_default_map_cmyk_color,
+ gx_default_strip_tile_rectangle, gx_no_strip_copy_rop);
+
+/* Fill a rectangle with a color. */
+private int
+mem2_word_fill_rectangle(gx_device *dev, int x, int y, int w, int h,
+ gx_color_index color)
+{ byte *base;
+ uint raster;
+ fit_fill(dev, x, y, w, h);
+ base = scan_line_base(mdev, y);
+ raster = mdev->raster;
+ mem_swap_byte_rect(base, raster, x << 1, w << 1, h, true);
+ bits_fill_rectangle(base, x << 1, raster,
+ tile_patterns[color], w << 1, h);
+ mem_swap_byte_rect(base, raster, x << 1, w << 1, h, true);
+ return 0;
+}
+
+/* Copy a bitmap. */
+private int
+mem2_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)
+{ byte *row;
+ uint raster;
+ bool store;
+ fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
+ row = scan_line_base(mdev, y);
+ raster = mdev->raster;
+ store = (zero != gx_no_color_index && one != gx_no_color_index);
+ mem_swap_byte_rect(row, raster, x << 1, w << 1, h, store);
+ mem_mapped2_copy_mono(dev, base, sourcex, sraster, id,
+ x, y, w, h, zero, one);
+ mem_swap_byte_rect(row, raster, x << 1, w << 1, h, false);
+ return 0;
+}
+
+/* Copy a color bitmap. */
+private int
+mem2_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)
+{ int code;
+ fit_copy(dev, base, sourcex, sraster, id, x, y, w, h);
+ /* Use monobit copy_mono. */
+ /* Patch the width in the device temporarily. */
+ dev->width <<= 1;
+ code = (*dev_proc(&mem_mono_word_device, copy_mono))
+ (dev, base, sourcex << 1, sraster, id,
+ x << 1, y, w << 1, h, (gx_color_index)0, (gx_color_index)1);
+ /* Restore the correct width. */
+ dev->width >>= 1;
+ return code;
+}
+
+#endif /* !arch_is_big_endian */