/* Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999 artofcode LLC. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA, 02111-1307. */ /*$Id: gdevm32.c,v 1.2.6.1.2.1 2003/01/17 00:49:00 giles Exp $ */ /* 32-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 /* Procedures */ declare_mem_procs(mem_true32_copy_mono, mem_true32_copy_color, mem_true32_fill_rectangle); /* The device descriptor. */ const gx_device_memory mem_true32_device = mem_full_device("image32", 24, 8, mem_open, gx_default_map_rgb_color, gx_default_map_color_rgb, mem_true32_copy_mono, mem_true32_copy_color, mem_true32_fill_rectangle, gx_default_cmyk_map_cmyk_color, gx_default_strip_tile_rectangle, mem_default_strip_copy_rop, mem_get_bits_rectangle); /* Convert x coordinate to byte offset in scan line. */ #undef x_to_byte #define x_to_byte(x) ((x) << 2) /* Swap the bytes of a color if needed. */ #define color_swap_bytes(color)\ (((color) >> 24) + (((color) >> 8) & 0xff00) +\ (((color) & 0xff00) << 8) + ((color) << 24)) #if arch_is_big_endian # define arrange_bytes(color) (color) #else # define arrange_bytes(color) color_swap_bytes(color) #endif /* Fill a rectangle with a color. */ private int mem_true32_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; bits32 a_color; declare_scan_ptr(dest); fit_fill(dev, x, y, w, h); a_color = arrange_bytes(color); setup_rect(dest); if (w <= 4) switch (w) { /*case 0: *//* not possible */ #define dest32 ((bits32 *)dest) case 1: do { dest32[0] = a_color; inc_ptr(dest, draster); } while (--h > 0); break; case 2: do { dest32[1] = dest32[0] = a_color; inc_ptr(dest, draster); } while (--h > 0); break; case 3: do { dest32[2] = dest32[1] = dest32[0] = a_color; inc_ptr(dest, draster); } while (--h > 0); break; case 4: do { dest32[3] = dest32[2] = dest32[1] = dest32[0] = a_color; inc_ptr(dest, draster); } while (--h > 0); break; default: /* not possible */ ; } else if (a_color == 0) do { memset(dest, 0, w << 2); inc_ptr(dest, draster); } while (--h > 0); else do { bits32 *pptr = dest32; int cnt = w; do { pptr[3] = pptr[2] = pptr[1] = pptr[0] = a_color; pptr += 4; } while ((cnt -= 4) > 4); do { *pptr++ = a_color; } while (--cnt > 0); inc_ptr(dest, draster); } while (--h > 0); #undef dest32 return 0; } /* Copy a monochrome bitmap. */ private int mem_true32_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; bits32 a_zero = arrange_bytes(zero); bits32 a_one = arrange_bytes(one); const byte *line; declare_scan_ptr(dest); fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); setup_rect(dest); line = base + (sourcex >> 3); if (zero == gx_no_color_index) { int first_bit = sourcex & 7; int w_first = min(w, 8 - first_bit); int w_rest = w - w_first; if (one == gx_no_color_index) return 0; /* * There are no halftones, so this case -- characters -- * is the only common one. */ while (h-- > 0) { bits32 *pptr = (bits32 *) dest; const byte *sptr = line; int sbyte = (*sptr++ << first_bit) & 0xff; int count = w_first; if (sbyte) do { if (sbyte & 0x80) *pptr = a_one; sbyte <<= 1; pptr++; } while (--count > 0); else pptr += count; for (count = w_rest; count >= 8; count -= 8, pptr += 8) { sbyte = *sptr++; if (sbyte) { if (sbyte & 0x80) pptr[0] = a_one; if (sbyte & 0x40) pptr[1] = a_one; if (sbyte & 0x20) pptr[2] = a_one; if (sbyte & 0x10) pptr[3] = a_one; if (sbyte & 0x08) pptr[4] = a_one; if (sbyte & 0x04) pptr[5] = a_one; if (sbyte & 0x02) pptr[6] = a_one; if (sbyte & 0x01) pptr[7] = a_one; } } if (count) { sbyte = *sptr; do { if (sbyte & 0x80) *pptr = a_one; sbyte <<= 1; pptr++; } while (--count > 0); } line += sraster; inc_ptr(dest, draster); } } else { /* zero != gx_no_color_index */ int first_bit = 0x80 >> (sourcex & 7); while (h-- > 0) { bits32 *pptr = (bits32 *) dest; const byte *sptr = line; int sbyte = *sptr++; int bit = first_bit; int count = w; do { if (sbyte & bit) { if (one != gx_no_color_index) *pptr = a_one; } else *pptr = a_zero; if ((bit >>= 1) == 0) bit = 0x80, sbyte = *sptr++; pptr++; } while (--count > 0); line += sraster; inc_ptr(dest, draster); } } return 0; } /* Copy a color bitmap. */ private int mem_true32_copy_color(gx_device * dev, const byte * base, int sourcex, int sraster, gx_bitmap_id id, int x, int y, int w, int h) { gx_device_memory * const mdev = (gx_device_memory *)dev; fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h); return 0; } /* ================ "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(mem32_word_copy_mono, mem32_word_copy_color, mem32_word_fill_rectangle); /* Here is the device descriptor. */ const gx_device_memory mem_true32_word_device = mem_full_device("image32w", 24, 8, mem_open, gx_default_map_rgb_color, gx_default_map_color_rgb, mem32_word_copy_mono, mem32_word_copy_color, mem32_word_fill_rectangle, gx_default_cmyk_map_cmyk_color, gx_default_strip_tile_rectangle, gx_no_strip_copy_rop, mem_word_get_bits_rectangle); /* Fill a rectangle with a color. */ private int mem32_word_fill_rectangle(gx_device * dev, int x, int y, int w, int h, gx_color_index color) { return mem_true32_fill_rectangle(dev, x, y, w, h, color_swap_bytes(color)); } /* Copy a bitmap. */ private int mem32_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) { return mem_true32_copy_mono(dev, base, sourcex, sraster, id, x, y, w, h, color_swap_bytes(zero), color_swap_bytes(one)); } /* Copy a color bitmap. */ private int mem32_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) { gx_device_memory * const mdev = (gx_device_memory *)dev; byte *row; uint raster; fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); row = scan_line_base(mdev, y); raster = mdev->raster; bytes_copy_rectangle(row + (x << 2), raster, base + (sourcex << 2), sraster, w << 2, h); mem_swap_byte_rect(row, raster, x << 5, w << 5, h, false); return 0; } #endif /* !arch_is_big_endian */