diff options
author | Ralph Giles <ralph.giles@artifex.com> | 2008-08-29 18:46:21 +0000 |
---|---|---|
committer | Ralph Giles <ralph.giles@artifex.com> | 2008-08-29 18:46:21 +0000 |
commit | 6ff2582d038f99b79178082b200bdfe73f734456 (patch) | |
tree | 6db04fc72813760fdc6912a15875ad83d57943df /gs/base/gdevm2.c | |
parent | 9d36ee856e41244d3cf0469fc0004d21e6911994 (diff) | |
download | ghostpdl-6ff2582d038f99b79178082b200bdfe73f734456.tar.gz |
Split the source tree into two new directories.
PSSRC files are now in 'gs/psi'.
GLSRC files are now in 'gs/base'.
This is to facilitate build modularization and merging in the ghostpdl
tree.
NOTE: msvc32.mak is now in psi, not src.
git-svn-id: http://svn.ghostscript.com/ghostscript/trunk@9048 a1074d23-0009-0410-80fe-cf8c14f379e6
Diffstat (limited to 'gs/base/gdevm2.c')
-rw-r--r-- | gs/base/gdevm2.c | 247 |
1 files changed, 247 insertions, 0 deletions
diff --git a/gs/base/gdevm2.c b/gs/base/gdevm2.c new file mode 100644 index 000000000..85558bee2 --- /dev/null +++ b/gs/base/gdevm2.c @@ -0,0 +1,247 @@ +/* Copyright (C) 2001-2006 Artifex Software, Inc. + All Rights Reserved. + + This software is provided AS-IS with no warranty, either express or + implied. + + This software is distributed under license and may not be copied, modified + or distributed except as expressly authorized under the terms of that + license. Refer to licensing information at http://www.artifex.com/ + or contact Artifex Software, Inc., 7 Mt. Lassen Drive - Suite A-134, + San Rafael, CA 94903, U.S.A., +1(415)492-9861, for further information. +*/ +/* $Id$ */ +/* 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 */ + +/* ================ 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 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. */ +static int +mem_mapped2_fill_rectangle(gx_device * dev, + int x, int y, int w, int h, gx_color_index color) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + + 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. */ +static 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) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + 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 <= 3) + 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); + + for ( ; ; ) { + if (sbyte & bit) + data ^= bxor & mask; + if ((bit >>= 1) == 0) + bit = 0x80, sbyte = *sptr++; + if ((mask >>= 2) == 0) + mask = 0xc0, *pptr++ = data, data = b0; + if (--count <= 0) + break; + } + if (mask != 0xc0) + *pptr = + (*pptr & right_mask) | (data & ~right_mask); + } else { /* Filling a mask. */ + for ( ; ; ) { + if (sbyte & bit) + *pptr = (*pptr & ~mask) + (b1 & mask); + if (--count <= 0) + break; + if ((bit >>= 1) == 0) + bit = 0x80, sbyte = *sptr++; + if ((mask >>= 2) == 0) + mask = 0xc0, pptr++; + } + } + } else { /* Some other case. */ + for ( ; ; ) { + if (!(sbyte & bit)) { + if (zero != gx_no_color_index) + *pptr = (*pptr & ~mask) + (b0 & mask); + } + if (--count <= 0) + break; + if ((bit >>= 1) == 0) + bit = 0x80, sbyte = *sptr++; + if ((mask >>= 2) == 0) + mask = 0xc0, pptr++; + } + } + line += sraster; + inc_ptr(dest, draster); + } + return 0; +} + +/* Copy a color bitmap. */ +static 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 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, gx_default_map_cmyk_color, + gx_default_strip_tile_rectangle, gx_no_strip_copy_rop, + mem_word_get_bits_rectangle); + +/* Fill a rectangle with a color. */ +static int +mem2_word_fill_rectangle(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + 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. */ +static 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) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + 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. */ +static 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 */ |