/* Copy a monochrome bitmap. */ static int mac_copy_mono (register gx_device *dev, const unsigned char *base, int data_x, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index color_0, gx_color_index color_1) { gx_device_macos * mdev = (gx_device_macos *)dev; int byteCount = raster * h; short copyMode; // this case doesn't change the picture -> return without wasting time if (color_0 == gx_no_color_index && color_1 == gx_no_color_index) return 0; fit_copy(dev, base, data_x, raster, id, x, y, w, h); CheckMem(10*1024 + byteCount*10, 100*1024 + byteCount*10); ResetPage(); if (color_0 == gx_no_color_index) copyMode = srcOr; else if (color_1 == gx_no_color_index) copyMode = notSrcBic; // this mode is untested ! (no file found which is using it) else copyMode = srcCopy; copyMode += ditherCopy; GSSetBkCol(dev, mdev->currPicPos, color_0); GSSetFgCol(dev, mdev->currPicPos, color_1); PICTWriteOpcode(mdev->currPicPos, 0x0098); PICTWriteInt(mdev->currPicPos, raster); PICTWriteRect(mdev->currPicPos, 0, 0, raster*8, h); PICTWriteRect(mdev->currPicPos, data_x, 0, w, h); PICTWriteRect(mdev->currPicPos, x, y, w, h); PICTWriteInt(mdev->currPicPos, copyMode); PICTWriteDataPackBits(mdev->currPicPos, base, raster, h); PICT_OpEndPicGoOn(mdev->currPicPos); return 0; }
/* Color = gx_no_color_index means transparent (no effect on the image). */ static int win_ddb_copy_mono(gx_device * dev, const byte * base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) { int endx; const byte *ptr_line; int width_bytes, height; DWORD rop = rop_write_at_1s; int color; BYTE aBit[bmWidthBytes * bmHeight]; BYTE *aptr = aBit; fit_copy(dev, base, sourcex, raster, id, x, y, w, h); if (sourcex & ~7) { base += sourcex >> 3; sourcex &= 7; }
int mem_gray8_rgb24_strip_copy_rop(gx_device * dev, const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, const gx_color_index * scolors, const gx_strip_bitmap * textures, const gx_color_index * tcolors, int x, int y, int width, int height, int phase_x, int phase_y, gs_logical_operation_t lop) { gx_device_memory *mdev = (gx_device_memory *) dev; gs_rop3_t rop = lop_rop(lop); gx_color_index const_source = gx_no_color_index; gx_color_index const_texture = gx_no_color_index; uint draster = mdev->raster; int line_count; byte *drow, *base; int depth = dev->color_info.depth; int bpp = depth >> 3; /* bytes per pixel, 1 or 3 */ gx_color_index all_ones = ((gx_color_index) 1 << depth) - 1; gx_color_index strans = (lop & lop_S_transparent ? all_ones : gx_no_color_index); gx_color_index ttrans = (lop & lop_T_transparent ? all_ones : gx_no_color_index); #ifdef USE_RUN_ROP rop_run_op ropper; #ifdef COMPARE_AND_CONTRAST static byte testbuffer[4096]; static byte *start; static int bytelen; #endif #endif /* Check for constant source. */ if (!rop3_uses_S(rop)) const_source = 0; /* arbitrary */ else if (scolors != 0 && scolors[0] == scolors[1]) { /* Constant source */ const_source = scolors[0]; if (const_source == gx_device_black(dev)) rop = rop3_know_S_0(rop); else if (const_source == gx_device_white(dev)) rop = rop3_know_S_1(rop); } /* Check for constant texture. */ if (!rop3_uses_T(rop)) const_texture = 0; /* arbitrary */ else if (tcolors != 0 && tcolors[0] == tcolors[1]) { /* Constant texture */ const_texture = tcolors[0]; if (const_texture == gx_device_black(dev)) rop = rop3_know_T_0(rop); else if (const_texture == gx_device_white(dev)) rop = rop3_know_T_1(rop); } if (bpp == 1 && (gx_device_has_color(dev) || (gx_device_black(dev) != 0 || gx_device_white(dev) != all_ones)) ) { /* * This is an 8-bit device but not gray-scale. Except in a few * simple cases, we have to use the slow algorithm that converts * values to and from RGB. */ gx_color_index bw_pixel; switch (rop) { case rop3_0: bw_pixel = gx_device_black(dev); goto bw; case rop3_1: bw_pixel = gx_device_white(dev); bw: if (bw_pixel == 0x00) rop = rop3_0; else if (bw_pixel == 0xff) rop = rop3_1; else goto df; break; case rop3_D: break; case rop3_S: if (lop & lop_S_transparent) goto df; break; case rop3_T: if (lop & lop_T_transparent) goto df; break; default: df: return mem_default_strip_copy_rop(dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop); } } /* Adjust coordinates to be in bounds. */ if (const_source == gx_no_color_index) { fit_copy(dev, sdata, sourcex, sraster, id, x, y, width, height); } else { fit_fill(dev, x, y, width, height); } /* Set up transfer parameters. */ line_count = height; base = scan_line_base(mdev, y); drow = base + x * bpp; /* * There are 18 cases depending on whether each of the source and * texture is constant, 1-bit, or multi-bit, and on whether the * depth is 8 or 24 bits. We divide first according to constant * vs. non-constant, and then according to 1- vs. multi-bit, and * finally according to pixel depth. This minimizes source code, * but not necessarily time, since we do some of the divisions * within 1 or 2 levels of loop. */ #ifdef USE_RUN_ROP #define dbit(base, i) ((base)[(i) >> 3] & (0x80 >> ((i) & 7))) /* 8-bit */ #define cbit8(base, i, colors)\ (dbit(base, i) ? (byte)colors[1] : (byte)colors[0]) #define rop_body_8(s_pixel, t_pixel)\ if ( (s_pixel) == strans || /* So = 0, s_tr = 1 */\ (t_pixel) == ttrans /* Po = 0, p_tr = 1 */\ )\ continue;\ *dptr = (*rop_proc_table[rop])(*dptr, s_pixel, t_pixel) /* 24-bit */ #define get24(ptr)\ (((gx_color_index)(ptr)[0] << 16) | ((gx_color_index)(ptr)[1] << 8) | (ptr)[2]) #define put24(ptr, pixel)\ (ptr)[0] = (byte)((pixel) >> 16),\ (ptr)[1] = (byte)((uint)(pixel) >> 8),\ (ptr)[2] = (byte)(pixel) #define cbit24(base, i, colors)\ (dbit(base, i) ? colors[1] : colors[0]) #define rop_body_24(s_pixel, t_pixel)\ if ( (s_pixel) == strans || /* So = 0, s_tr = 1 */\ (t_pixel) == ttrans /* Po = 0, p_tr = 1 */\ )\ continue;\ { gx_color_index d_pixel = get24(dptr);\ d_pixel = (*rop_proc_table[rop])(d_pixel, s_pixel, t_pixel);\ put24(dptr, d_pixel);\ } if (const_texture != gx_no_color_index) { /**** Constant texture ****/ if (const_source != gx_no_color_index) { /**** Constant source & texture ****/ rop_get_run_op(&ropper, lop, depth, rop_s_constant | rop_t_constant); rop_set_s_constant(&ropper, const_source); rop_set_t_constant(&ropper, const_texture); for (; line_count-- > 0; drow += draster) { #ifdef COMPARE_AND_CONTRAST byte *dptr = drow; int left = width; bytelen = left*bpp; start = dptr; memcpy(testbuffer, dptr, bytelen); rop_run(&ropper, testbuffer, left); if (bpp == 1) /**** 8-bit destination ****/ for (; left > 0; ++dptr, --left) { vd_pixel(int2fixed((dptr - base) % draster), int2fixed((dptr - base) / draster + y), const_texture); rop_body_8((byte)const_source, (byte)const_texture); } else /**** 24-bit destination ****/ for (; left > 0; dptr += 3, --left) { vd_pixel(int2fixed((dptr - base) % draster / 3), int2fixed((dptr - base) / draster + y), const_texture); rop_body_24(const_source, const_texture); } if (memcmp(testbuffer, start, bytelen) != 0) { eprintf("Failed!\n"); } #else rop_run(&ropper, drow, width); #endif } rop_release_run_op(&ropper); } else { /**** Data source, const texture ****/ if (scolors) { const byte *srow = sdata; rop_get_run_op(&ropper, lop, depth, rop_t_constant | rop_s_1bit); rop_set_t_constant(&ropper, const_texture); rop_set_s_colors(&ropper, scolors); for (; line_count-- > 0; drow += draster, srow += sraster) { #ifdef COMPARE_AND_CONTRAST byte *dptr = drow; int left = width; /**** 1-bit source ****/ int sx = sourcex; rop_set_s_bitmap_subbyte(&ropper, srow, sourcex); bytelen = left*bpp; start = dptr; memcpy(testbuffer, dptr, bytelen); rop_run(&ropper, testbuffer, width); if (bpp == 1) /**** 8-bit destination ****/ for (; left > 0; ++dptr, ++sx, --left) { byte s_pixel = cbit8(srow, sx, scolors); vd_pixel(int2fixed((dptr - base) % draster), int2fixed((dptr - base) / draster + y), const_texture); rop_body_8(s_pixel, (byte)const_texture); } else /**** 24-bit destination ****/ for (; left > 0; dptr += 3, ++sx, --left) { bits32 s_pixel = cbit24(srow, sx, scolors); vd_pixel(int2fixed((dptr - base) % draster / 3), int2fixed((dptr - base) / draster + y), const_texture); rop_body_24(s_pixel, const_texture); } if (memcmp(testbuffer, start, bytelen) != 0) { eprintf("Failed!\n"); } #else /**** 1-bit source ****/ /**** 8-bit destination ****/ /**** 24-bit destination ****/ rop_set_s_bitmap_subbyte(&ropper, srow, sourcex); rop_run(&ropper, drow, width); #endif } rop_release_run_op(&ropper); } else { const byte *srow = sdata; rop_get_run_op(&ropper, lop, depth, rop_t_constant); rop_set_t_constant(&ropper, const_texture); for (; line_count-- > 0; drow += draster, srow += sraster) { #ifdef COMPARE_AND_CONTRAST byte *dptr = drow; int left = width; bytelen = left*bpp; start = dptr; memcpy(testbuffer, dptr, bytelen); rop_set_s_bitmap(&ropper, srow + sourcex * bpp); rop_run(&ropper, testbuffer, left); /**** 8-bit source & dest ****/ if (bpp == 1) { const byte *sptr = srow + sourcex; for (; left > 0; ++dptr, ++sptr, --left) { byte s_pixel = *sptr; vd_pixel(int2fixed((dptr - base) % draster), int2fixed((dptr - base) / draster + y), const_texture); rop_body_8(s_pixel, (byte)const_texture); } } else { /**** 24-bit source & dest ****/ const byte *sptr = srow + sourcex * 3; bytelen = left*bpp; start = dptr; memcpy(testbuffer, dptr, bytelen); for (; left > 0; dptr += 3, sptr += 3, --left) { bits32 s_pixel = get24(sptr); vd_pixel(int2fixed((dptr - base) % draster / 3), int2fixed((dptr - base) / draster + y), const_texture); rop_body_24(s_pixel, const_texture); } } if (memcmp(testbuffer, start, bytelen) != 0) { eprintf("Failed!\n"); } #else /**** 8-bit source & dest ****/ /**** 24-bit source & dest ****/ rop_set_s_bitmap(&ropper, srow + sourcex * bpp); rop_run(&ropper, drow, width); #endif } rop_release_run_op(&ropper); } } } else if (const_source != gx_no_color_index) { /**** Const source, data texture ****/ if (tcolors) { uint traster = textures->raster; int ty = y + phase_y; rop_get_run_op(&ropper, lop, depth, rop_s_constant | rop_t_1bit); rop_set_s_constant(&ropper, const_source); for (; line_count-- > 0; drow += draster, ++ty) { /* Loop over copies of the tile. */ int dx = x, w = width, nw; byte *dptr = drow; const byte *trow = textures->data + (ty % textures->size.y) * traster; int xoff = x_offset(phase_x, ty, textures); for (; w > 0; dx += nw, w -= nw) { int tx = (dx + xoff) % textures->rep_width; int left = nw = min(w, textures->size.x - tx); const byte *tptr = trow; rop_set_t_bitmap_subbyte(&ropper, trow, tx); #ifdef COMPARE_AND_CONTRAST bytelen = left*bpp; start = dptr; memcpy(testbuffer, dptr, bytelen); rop_run(&ropper, testbuffer, left); /**** 1-bit texture ****/ if (bpp == 1) /**** 8-bit dest ****/ for (; left > 0; ++dptr, ++tx, --left) { byte t_pixel = cbit8(tptr, tx, tcolors); vd_pixel(int2fixed((dptr - base) % draster), int2fixed((dptr - base) / draster + y), t_pixel); rop_body_8((byte)const_source, t_pixel); } else /**** 24-bit dest ****/ for (; left > 0; dptr += 3, ++tx, --left) { bits32 t_pixel = cbit24(tptr, tx, tcolors); vd_pixel(int2fixed((dptr - base) % draster / 3), int2fixed((dptr - base) / draster + y), t_pixel); rop_body_24(const_source, t_pixel); } if (memcmp(testbuffer, start, bytelen) != 0) { eprintf("Failed!\n"); } #else rop_run(&ropper, dptr, left); dptr += left; #endif } } } else { uint traster = textures->raster; int ty = y + phase_y; rop_get_run_op(&ropper, lop, depth, rop_s_constant); rop_set_s_constant(&ropper, const_source); for (; line_count-- > 0; drow += draster, ++ty) { /* Loop over copies of the tile. */ int dx = x, w = width, nw; byte *dptr = drow; const byte *trow = textures->data + (ty % textures->size.y) * traster; int xoff = x_offset(phase_x, ty, textures); for (; w > 0; dx += nw, w -= nw) { int tx = (dx + xoff) % textures->rep_width; int left = nw = min(w, textures->size.x - tx); const byte *tptr = trow + tx*bpp; rop_set_t_bitmap(&ropper, tptr); #ifdef COMPARE_AND_CONTRAST bytelen = left*bpp; start = dptr; memcpy(testbuffer, dptr, bytelen); rop_run(&ropper, testbuffer, left); /**** 8-bit T & D ****/ if (bpp == 1) { for (; left > 0; ++dptr, ++tptr, --left) { byte t_pixel = *tptr; vd_pixel(int2fixed((dptr - base) % draster), int2fixed((dptr - base) / draster + y), t_pixel); rop_body_8((byte)const_source, t_pixel); } } else { /**** 24-bit T & D ****/ for (; left > 0; dptr += 3, tptr += 3, --left) { bits32 t_pixel = get24(tptr); vd_pixel(int2fixed((dptr - base) % draster / 3), int2fixed((dptr - base) / draster + y), t_pixel); rop_body_24(const_source, t_pixel); } } if (memcmp(testbuffer, start, bytelen) != 0) { eprintf("Failed!\n"); } #else /**** 8-bit T & D ****/ /**** 24-bit T & D ****/ rop_run(&ropper, dptr, left); dptr += left * bpp; #endif } } rop_release_run_op(&ropper); } } else { /**** Data source & texture ****/ if (scolors != NULL | tcolors != NULL) { uint traster = textures->raster; int ty = y + phase_y; const byte *srow = sdata; rop_get_run_op(&ropper, lop, depth, ((scolors == NULL ? 0 : rop_s_1bit) | (tcolors == NULL ? 0 : rop_t_1bit))); /* Loop over scan lines. */ for (; line_count-- > 0; drow += draster, srow += sraster, ++ty) { /* Loop over copies of the tile. */ int sx = sourcex; int dx = x; int w = width; int nw; byte *dptr = drow; const byte *trow = textures->data + (ty % textures->size.y) * traster; int xoff = x_offset(phase_x, ty, textures); for (; w > 0; dx += nw, w -= nw) { /* Loop over individual pixels. */ int tx = (dx + xoff) % textures->rep_width; int left = nw = min(w, textures->size.x - tx); const byte *sptr = srow + sx*bpp; const byte *tptr = trow + tx*bpp; /* * For maximum speed, we should split this loop * into 7 cases depending on source & texture * depth: (1,1), (1,8), (1,24), (8,1), (8,8), * (24,1), (24,24). But since we expect these * cases to be relatively uncommon, we just * divide on the destination depth. */ if (scolors) rop_set_s_bitmap_subbyte(&ropper, srow, sx); else rop_set_s_bitmap(&ropper, sptr); if (tcolors) rop_set_t_bitmap_subbyte(&ropper, trow, tx); else rop_set_t_bitmap(&ropper, tptr); #ifdef COMPARE_AND_CONTRAST bytelen = left*bpp; start = dptr; memcpy(testbuffer, dptr, bytelen); rop_run(&ropper, testbuffer, left); if (bpp == 1) { /**** 8-bit destination ****/ for (; left > 0; ++dptr, ++sptr, ++tptr, ++sx, ++tx, --left) { byte s_pixel = (scolors ? cbit8(srow, sx, scolors) : *sptr); byte t_pixel = (tcolors ? cbit8(trow, tx, tcolors) : *tptr); vd_pixel(int2fixed((dptr - base) % draster), int2fixed((dptr - base) / draster + y), t_pixel); rop_body_8(s_pixel, t_pixel); } } else { /**** 24-bit destination ****/ for (; left > 0; dptr += 3, sptr += 3, tptr += 3, ++sx, ++tx, --left) { bits32 s_pixel = (scolors ? cbit24(srow, sx, scolors) : get24(sptr)); bits32 t_pixel = (tcolors ? cbit24(tptr, tx, tcolors) : get24(tptr)); vd_pixel(int2fixed((dptr - base) % draster / 3), int2fixed((dptr - base) / draster + y), t_pixel); rop_body_24(s_pixel, t_pixel); } } if (memcmp(testbuffer, start, bytelen) != 0) { eprintf("Failed!\n"); } #else rop_run(&ropper, dptr, left); #endif } } } else { uint traster = textures->raster; int ty = y + phase_y; const byte *srow = sdata; /* Loop over scan lines. */ rop_get_run_op(&ropper, rop, depth, 0); for (; line_count-- > 0; drow += draster, srow += sraster, ++ty) { /* Loop over copies of the tile. */ int sx = sourcex; int dx = x; int w = width; int nw; byte *dptr = drow; const byte *trow = textures->data + (ty % textures->size.y) * traster; int xoff = x_offset(phase_x, ty, textures); for (; w > 0; dx += nw, w -= nw) { /* Loop over individual pixels. */ int tx = (dx + xoff) % textures->rep_width; int left = nw = min(w, textures->size.x - tx); const byte *tptr = trow + tx * bpp; const byte *sptr = srow + sx * bpp; rop_set_s_bitmap(&ropper, sptr); rop_set_t_bitmap(&ropper, tptr); #ifdef COMPARE_AND_CONTRAST if (bpp == 1) { rop_run(&ropper, testbuffer, left); /**** 8-bit destination ****/ for (; left > 0; ++dptr, ++sptr, ++tptr, ++sx, ++tx, --left) { rop_body_8(*sptr, *tptr); } } else { /**** 24-bit destination ****/ for (; left > 0; dptr += 3, sptr += 3, tptr += 3, ++sx, ++tx, --left) { bits32 s_pixel = get24(sptr); bits32 t_pixel = get24(tptr); rop_body_24(s_pixel, t_pixel); } } if (memcmp(testbuffer, start, bytelen) != 0) { eprintf("Failed!\n"); } #else /**** 8-bit destination ****/ /**** 24-bit destination ****/ rop_run(&ropper, dptr, left); #endif } } rop_release_run_op(&ropper); } } #undef rop_body_8 #undef rop_body_24 #undef dbit #undef cbit8 #undef cbit24 #else #define dbit(base, i) ((base)[(i) >> 3] & (0x80 >> ((i) & 7))) /* 8-bit */ #define cbit8(base, i, colors)\ (dbit(base, i) ? (byte)colors[1] : (byte)colors[0]) #define rop_body_8(s_pixel, t_pixel)\ if ( (s_pixel) == strans || /* So = 0, s_tr = 1 */\ (t_pixel) == ttrans /* Po = 0, p_tr = 1 */\ )\ continue;\ *dptr = (*rop_proc_table[rop])(*dptr, s_pixel, t_pixel) /* 24-bit */ #define get24(ptr)\ (((gx_color_index)(ptr)[0] << 16) | ((gx_color_index)(ptr)[1] << 8) | (ptr)[2]) #define put24(ptr, pixel)\ (ptr)[0] = (byte)((pixel) >> 16),\ (ptr)[1] = (byte)((uint)(pixel) >> 8),\ (ptr)[2] = (byte)(pixel) #define cbit24(base, i, colors)\ (dbit(base, i) ? colors[1] : colors[0]) #define rop_body_24(s_pixel, t_pixel)\ if ( (s_pixel) == strans || /* So = 0, s_tr = 1 */\ (t_pixel) == ttrans /* Po = 0, p_tr = 1 */\ )\ continue;\ { gx_color_index d_pixel = get24(dptr);\ d_pixel = (*rop_proc_table[rop])(d_pixel, s_pixel, t_pixel);\ put24(dptr, d_pixel);\ } if (const_texture != gx_no_color_index) { /**** Constant texture ****/ if (const_source != gx_no_color_index) { /**** Constant source & texture ****/ for (; line_count-- > 0; drow += draster) { byte *dptr = drow; int left = width; if (bpp == 1) /**** 8-bit destination ****/ for (; left > 0; ++dptr, --left) { vd_pixel(int2fixed((dptr - base) % draster), int2fixed((dptr - base) / draster + y), const_texture); rop_body_8((byte)const_source, (byte)const_texture); } else /**** 24-bit destination ****/ for (; left > 0; dptr += 3, --left) { vd_pixel(int2fixed((dptr - base) % draster / 3), int2fixed((dptr - base) / draster + y), const_texture); rop_body_24(const_source, const_texture); } } } else { /**** Data source, const texture ****/ const byte *srow = sdata; for (; line_count-- > 0; drow += draster, srow += sraster) { byte *dptr = drow; int left = width; if (scolors) { /**** 1-bit source ****/ int sx = sourcex; if (bpp == 1) /**** 8-bit destination ****/ for (; left > 0; ++dptr, ++sx, --left) { byte s_pixel = cbit8(srow, sx, scolors); vd_pixel(int2fixed((dptr - base) % draster), int2fixed((dptr - base) / draster + y), const_texture); rop_body_8(s_pixel, (byte)const_texture); } else /**** 24-bit destination ****/ for (; left > 0; dptr += 3, ++sx, --left) { bits32 s_pixel = cbit24(srow, sx, scolors); vd_pixel(int2fixed((dptr - base) % draster / 3), int2fixed((dptr - base) / draster + y), const_texture); rop_body_24(s_pixel, const_texture); } } else if (bpp == 1) { /**** 8-bit source & dest ****/ const byte *sptr = srow + sourcex; for (; left > 0; ++dptr, ++sptr, --left) { byte s_pixel = *sptr; vd_pixel(int2fixed((dptr - base) % draster), int2fixed((dptr - base) / draster + y), const_texture); rop_body_8(s_pixel, (byte)const_texture); } } else { /**** 24-bit source & dest ****/ const byte *sptr = srow + sourcex * 3; for (; left > 0; dptr += 3, sptr += 3, --left) { bits32 s_pixel = get24(sptr); vd_pixel(int2fixed((dptr - base) % draster / 3), int2fixed((dptr - base) / draster + y), const_texture); rop_body_24(s_pixel, const_texture); } } } } } else if (const_source != gx_no_color_index) { /**** Const source, data texture ****/ uint traster = textures->raster; int ty = y + phase_y; for (; line_count-- > 0; drow += draster, ++ty) { /* Loop over copies of the tile. */ int dx = x, w = width, nw; byte *dptr = drow; const byte *trow = textures->data + (ty % textures->size.y) * traster; int xoff = x_offset(phase_x, ty, textures); for (; w > 0; dx += nw, w -= nw) { int tx = (dx + xoff) % textures->rep_width; int left = nw = min(w, textures->size.x - tx); const byte *tptr = trow; if (tcolors) { /**** 1-bit texture ****/ if (bpp == 1) /**** 8-bit dest ****/ for (; left > 0; ++dptr, ++tx, --left) { byte t_pixel = cbit8(tptr, tx, tcolors); vd_pixel(int2fixed((dptr - base) % draster), int2fixed((dptr - base) / draster + y), t_pixel); rop_body_8((byte)const_source, t_pixel); } else /**** 24-bit dest ****/ for (; left > 0; dptr += 3, ++tx, --left) { bits32 t_pixel = cbit24(tptr, tx, tcolors); vd_pixel(int2fixed((dptr - base) % draster / 3), int2fixed((dptr - base) / draster + y), t_pixel); rop_body_24(const_source, t_pixel); } } else if (bpp == 1) { /**** 8-bit T & D ****/ tptr += tx; for (; left > 0; ++dptr, ++tptr, --left) { byte t_pixel = *tptr; vd_pixel(int2fixed((dptr - base) % draster), int2fixed((dptr - base) / draster + y), t_pixel); rop_body_8((byte)const_source, t_pixel); } } else { /**** 24-bit T & D ****/ tptr += tx * 3; for (; left > 0; dptr += 3, tptr += 3, --left) { bits32 t_pixel = get24(tptr); vd_pixel(int2fixed((dptr - base) % draster / 3), int2fixed((dptr - base) / draster + y), t_pixel); rop_body_24(const_source, t_pixel); } } } } } else { /**** Data source & texture ****/ uint traster = textures->raster; int ty = y + phase_y; const byte *srow = sdata; /* Loop over scan lines. */ for (; line_count-- > 0; drow += draster, srow += sraster, ++ty) { /* Loop over copies of the tile. */ int sx = sourcex; int dx = x; int w = width; int nw; byte *dptr = drow; const byte *trow = textures->data + (ty % textures->size.y) * traster; int xoff = x_offset(phase_x, ty, textures); for (; w > 0; dx += nw, w -= nw) { /* Loop over individual pixels. */ int tx = (dx + xoff) % textures->rep_width; int left = nw = min(w, textures->size.x - tx); const byte *tptr = trow; /* * For maximum speed, we should split this loop * into 7 cases depending on source & texture * depth: (1,1), (1,8), (1,24), (8,1), (8,8), * (24,1), (24,24). But since we expect these * cases to be relatively uncommon, we just * divide on the destination depth. */ if (bpp == 1) { /**** 8-bit destination ****/ const byte *sptr = srow + sx; tptr += tx; for (; left > 0; ++dptr, ++sptr, ++tptr, ++sx, ++tx, --left) { byte s_pixel = (scolors ? cbit8(srow, sx, scolors) : *sptr); byte t_pixel = (tcolors ? cbit8(tptr, tx, tcolors) : *tptr); vd_pixel(int2fixed((dptr - base) % draster), int2fixed((dptr - base) / draster + y), t_pixel); rop_body_8(s_pixel, t_pixel); } } else { /**** 24-bit destination ****/ const byte *sptr = srow + sx * 3; tptr += tx * 3; for (; left > 0; dptr += 3, sptr += 3, tptr += 3, ++sx, ++tx, --left) { bits32 s_pixel = (scolors ? cbit24(srow, sx, scolors) : get24(sptr)); bits32 t_pixel = (tcolors ? cbit24(tptr, tx, tcolors) : get24(tptr)); vd_pixel(int2fixed((dptr - base) % draster / 3), int2fixed((dptr - base) / draster + y), t_pixel); rop_body_24(s_pixel, t_pixel); } } } } } #undef rop_body_8 #undef rop_body_24 #undef dbit #undef cbit8 #undef cbit24 #endif return 0; }
/* Copy a color bitmap. */ static int mac_copy_color (register gx_device *dev, const unsigned char *base, int data_x, int raster, gx_bitmap_id id, int x, int y, int w, int h) { gx_device_macos * mdev = (gx_device_macos *)dev; int byteCount = raster * h, color; gx_color_value rgb[3]; fit_copy(dev, base, data_x, raster, id, x, y, w, h); CheckMem(10*1024 + byteCount*4, 100*1024 + byteCount*4); ResetPage(); GSSetStdCol(mdev->currPicPos); // Sets FgCol to Black and BkCol to White if (mdev->color_info.depth == 24) { PICTWriteOpcode(mdev->currPicPos, 0x009A); PICTWriteLong(mdev->currPicPos, 0x000000FF); PICTWritePixMap(mdev->currPicPos, 0, 0, raster/4, h, raster, 2, 0, X2Fix(mdev->x_pixels_per_inch), X2Fix(mdev->y_pixels_per_inch), 32); PICTWriteRect(mdev->currPicPos, data_x, 0, w, h); PICTWriteRect(mdev->currPicPos, x, y, w, h); PICTWriteInt(mdev->currPicPos, srcCopy); /* memcpy(mdev->currPicPos, base, byteCount); (char*)(mdev->currPicPos) += byteCount;*/ { short i; byteCount = 0; for (i=0; i<raster/4*h; i++) { // PICTWriteByte(mdev->currPicPos, 0x00); PICTWriteByte(mdev->currPicPos, 0x00); PICTWriteByte(mdev->currPicPos, 0x00); PICTWriteByte(mdev->currPicPos, 0x00); byteCount += 3; } } if (byteCount % 2) PICTWriteFillByte(mdev->currPicPos); } else if (mdev->color_info.depth <= 8) { ColorSpec *colorTable; colorTable = (ColorSpec*) malloc(sizeof(ColorSpec) * (1 << mdev->color_info.depth)); for (color=0; color < (1 << mdev->color_info.depth); color++) { (*dev_proc(dev, map_color_rgb))(dev, color, rgb); colorTable[color].value = color; colorTable[color].rgb.red = rgb[0]; colorTable[color].rgb.green = rgb[1]; colorTable[color].rgb.blue = rgb[2]; } PICTWriteOpcode(mdev->currPicPos, 0x0098); PICTWritePixMap(mdev->currPicPos, 0, 0, raster*8/mdev->color_info.depth, h, raster, 1, 0, X2Fix(mdev->x_pixels_per_inch), X2Fix(mdev->y_pixels_per_inch), mdev->color_info.depth); PICTWriteColorTable(mdev->currPicPos, 0, (1 << mdev->color_info.depth), colorTable); PICTWriteRect(mdev->currPicPos, data_x, 0, w, h); PICTWriteRect(mdev->currPicPos, x, y, w, h); PICTWriteInt(mdev->currPicPos, srcCopy); PICTWriteDataPackBits(mdev->currPicPos, base, raster, h); free(colorTable); } else { gx_default_copy_color( dev, base, data_x, raster, id, x, y, w, h ); } PICT_OpEndPicGoOn(mdev->currPicPos); return 0; }
/* that's why this will only work on a fully white background!!!! */ static int mac_copy_alpha(gx_device *dev, const unsigned char *base, int data_x, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index color, int depth) { gx_device_macos * mdev = (gx_device_macos *)dev; ColorSpec *colorTable; short copyMode, shade, maxShade = (1 << depth) - 1, byteCount = raster * h; gx_color_value rgb[3]; colorHSV colHSV; colorRGB colRGB; float saturation, value; fit_copy(dev, base, data_x, raster, id, x, y, w, h); CheckMem( byteCount*4 + 200*1024, byteCount*4 + 500*1024 ); ResetPage(); colorTable = (ColorSpec*) malloc(sizeof(ColorSpec) * (maxShade+1)); if (colorTable == NULL) return gs_error_VMerror; (*dev_proc(dev, map_color_rgb))(dev, color, rgb); colRGB.red = rgb[0]; colRGB.green = rgb[1]; colRGB.blue = rgb[2]; mac_convert_rgb_hsv(&colRGB, &colHSV); saturation = colHSV.s; value = colHSV.v; for (shade=0; shade <= maxShade; shade++) { colorTable[shade].value = maxShade - shade; colHSV.s = saturation * (1.0 - (float)shade/(float)maxShade); colHSV.v = value + ((1.0 - value) * (float)shade/(float)maxShade); mac_convert_hsv_rgb(&colHSV, &colRGB); colorTable[shade].rgb.red = colRGB.red; colorTable[shade].rgb.green = colRGB.green; colorTable[shade].rgb.blue = colRGB.blue; } copyMode = srcCopy + ditherCopy; GSSetStdCol(mdev->currPicPos); if (raster < 8) { PICTWriteOpcode(mdev->currPicPos, 0x0090); } else { PICTWriteOpcode(mdev->currPicPos, 0x0098); } PICTWritePixMap(mdev->currPicPos, 0, 0, raster*8/depth, h, raster, 0, 0, X2Fix(mdev->x_pixels_per_inch), X2Fix(mdev->y_pixels_per_inch), depth); PICTWriteColorTable(mdev->currPicPos, 0, maxShade+1, colorTable); PICTWriteRect(mdev->currPicPos, data_x, 0, w, h); PICTWriteRect(mdev->currPicPos, x, y, w, h); PICTWriteInt(mdev->currPicPos, copyMode); PICTWriteDataPackBits(mdev->currPicPos, base, raster, h); PICT_OpEndPicGoOn(mdev->currPicPos); free(colorTable); return 0; }
/* Copy a monochrome bitmap. */ static int x_copy_mono(gx_device * dev, const byte * base, int sourcex, int raster, gx_bitmap_id id, int x, int y, int w, int h, gx_color_index zero, gx_color_index one) /* * X doesn't directly support the simple operation of writing a color * through a mask specified by an image. The plot is the following: * If neither color is gx_no_color_index ("transparent"), * use XPutImage with the "copy" function as usual. * If the color either bitwise-includes or is bitwise-included-in * every color written to date * (a special optimization for writing black/white on color displays), * use XPutImage with an appropriate Boolean function. * Otherwise, do the following complicated stuff: * Create pixmap of depth 1 if necessary. * If foreground color is "transparent" then * invert the raster data. * Use XPutImage to copy the raster image to the newly * created Pixmap. * Install the Pixmap as the clip_mask in the X GC and * tweak the clip origin. * Do an XFillRectangle, fill style=solid, specifying a * rectangle the same size as the original raster data. * De-install the clip_mask. */ { gx_device_X *xdev = (gx_device_X *) dev; int function = GXcopy; unsigned long lzero = zero, lone = one; x_pixel bc = lzero, fc = lone; fit_copy(dev, base, sourcex, raster, id, x, y, w, h); flush_text(xdev); xdev->image.width = sourcex + w; xdev->image.height = h; xdev->image.data = (char *)base; xdev->image.bytes_per_line = raster; X_SET_FILL_STYLE(xdev, FillSolid); /* Check for null, easy 1-color, hard 1-color, and 2-color cases. */ if (zero != gx_no_color_index) { if (one != gx_no_color_index) { /* 2-color case. */ /* Simply replace existing bits with what's in the image. */ } else if (!(~xdev->colors_and & bc)) { function = GXand; fc = ~(x_pixel) 0; } else if (!(~bc & xdev->colors_or)) { function = GXor; fc = 0; } else { goto hard; } } else { if (one == gx_no_color_index) { /* no-op */ return 0; } else if (!(~xdev->colors_and & fc)) { function = GXand; bc = ~(x_pixel) 0; } else if (!(~fc & xdev->colors_or)) { function = GXor; bc = 0; } else { goto hard; } } xdev->image.format = XYBitmap; X_SET_FUNCTION(xdev, function); if (bc != xdev->back_color) { XSetBackground(xdev->dpy, xdev->gc, (xdev->back_color = bc)); } if (fc != xdev->fore_color) { XSetForeground(xdev->dpy, xdev->gc, (xdev->fore_color = fc)); } if (zero != gx_no_color_index) NOTE_COLOR(xdev, lzero); if (one != gx_no_color_index) NOTE_COLOR(xdev, lone); put_image(xdev->dpy, xdev->dest, xdev->gc, &xdev->image, sourcex, 0, x, y, w, h); goto out; hard: /* Handle the hard 1-color case. */ if (raster > xdev->cp.raster || h > xdev->cp.height) { /* Must allocate a new pixmap and GC. */ /* Release the old ones first. */ free_cp(dev); /* Create the clipping pixmap, depth must be 1. */ xdev->cp.pixmap = XCreatePixmap(xdev->dpy, xdev->win, raster << 3, h, 1); if (xdev->cp.pixmap == (Pixmap) 0) { lprintf("x_copy_mono: can't allocate pixmap\n"); return_error(gs_error_VMerror); } xdev->cp.gc = XCreateGC(xdev->dpy, xdev->cp.pixmap, 0, 0); if (xdev->cp.gc == (GC) 0) { lprintf("x_copy_mono: can't allocate GC\n"); return_error(gs_error_VMerror); } xdev->cp.raster = raster; xdev->cp.height = h; } /* Initialize static mask image params */ xdev->image.format = XYBitmap; X_SET_FUNCTION(xdev, GXcopy); /* Select polarity based on fg/bg transparency. */ if (one == gx_no_color_index) { /* invert */ XSetBackground(xdev->dpy, xdev->cp.gc, (x_pixel) 1); XSetForeground(xdev->dpy, xdev->cp.gc, (x_pixel) 0); X_SET_FORE_COLOR(xdev, lzero); } else { XSetBackground(xdev->dpy, xdev->cp.gc, (x_pixel) 0); XSetForeground(xdev->dpy, xdev->cp.gc, (x_pixel) 1); X_SET_FORE_COLOR(xdev, lone); } put_image(xdev->dpy, xdev->cp.pixmap, xdev->cp.gc, &xdev->image, sourcex, 0, 0, 0, w, h); /* Install as clipmask. */ XSetClipMask(xdev->dpy, xdev->gc, xdev->cp.pixmap); XSetClipOrigin(xdev->dpy, xdev->gc, x, y); /* * Draw a solid rectangle through the raster clip mask. * Note fill style is guaranteed to be solid from above. */ XFillRectangle(xdev->dpy, xdev->dest, xdev->gc, x, y, w, h); /* Tidy up. Free the pixmap if it's big. */ XSetClipMask(xdev->dpy, xdev->gc, None); if (raster * h > xdev->MaxTempPixmap) free_cp(dev); out:if (xdev->bpixmap != (Pixmap) 0) { /* We wrote to the pixmap, so update the display now. */ x_update_add(xdev, x, y, w, h); } return 0; }
/* * The default implementation for non-memory devices uses get_bits_rectangle * to read out the pixels, the memory device implementation to do the * operation, and copy_color to write the pixels back. */ int gx_default_strip_copy_rop(gx_device * dev, const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, const gx_color_index * scolors, const gx_strip_bitmap * textures, const gx_color_index * tcolors, int x, int y, int width, int height, int phase_x, int phase_y, gs_logical_operation_t lop) { int depth = dev->color_info.depth; gs_memory_t *mem = dev->memory; const gx_device_memory *mdproto = gdev_mem_device_for_bits(depth); gx_device_memory mdev; uint draster; byte *row = 0; gs_int_rect rect; int max_height; int block_height; int code; int py; #ifdef DEBUG if (gs_debug_c('b')) trace_copy_rop("gx_default_strip_copy_rop", dev, sdata, sourcex, sraster, id, scolors, textures, tcolors, x, y, width, height, phase_x, phase_y, lop); #endif if (mdproto == 0) return_error(gs_error_rangecheck); if (sdata == 0) { fit_fill(dev, x, y, width, height); } else { fit_copy(dev, sdata, sourcex, sraster, id, x, y, width, height); } draster = bitmap_raster(width * depth); max_height = max_rop_bitmap / draster; if (max_height == 0) max_height = 1; block_height = min(height, max_height); gs_make_mem_device(&mdev, mdproto, mem, -1, dev); gx_device_retain((gx_device *)&mdev, true); /* prevent freeing */ mdev.width = width; mdev.height = block_height; mdev.bitmap_memory = mem; mdev.color_info = dev->color_info; code = (*dev_proc(&mdev, open_device))((gx_device *)&mdev); if (code < 0) return code; if (rop3_uses_D(gs_transparent_rop(lop))) { row = gs_alloc_bytes(mem, draster * block_height, "copy_rop row"); if (row == 0) { code = gs_note_error(gs_error_VMerror); goto out; } } rect.p.x = x; rect.q.x = x + width; for (py = y; py < y + height; py += block_height) { if (block_height > y + height - py) block_height = y + height - py; rect.p.y = py; rect.q.y = py + block_height; if (row /*uses_d*/) { gs_get_bits_params_t bit_params; bit_params.options = GB_COLORS_NATIVE | GB_ALPHA_NONE | GB_DEPTH_ALL | GB_PACKING_CHUNKY | GB_RETURN_ALL | GB_ALIGN_STANDARD | GB_OFFSET_0 | GB_OFFSET_ANY | GB_RASTER_STANDARD; bit_params.data[0] = row; bit_params.x_offset = 0; code = (*dev_proc(dev, get_bits_rectangle)) (dev, &rect, &bit_params, NULL); if (code < 0) break; code = (*dev_proc(&mdev, copy_color)) ((gx_device *)&mdev, bit_params.data[0], bit_params.x_offset, draster, gx_no_bitmap_id, 0, 0, width, block_height); if (code < 0) return code; } code = (*dev_proc(&mdev, strip_copy_rop)) ((gx_device *)&mdev, sdata + (py - y) * sraster, sourcex, sraster, gx_no_bitmap_id, scolors, textures, tcolors, 0, 0, width, block_height, phase_x + x, phase_y + py, lop); if (code < 0) break; code = (*dev_proc(dev, copy_color)) (dev, scan_line_base(&mdev, 0), 0, draster, gx_no_bitmap_id, x, py, width, block_height); if (code < 0) break; } out: gs_free_object(mem, row, "copy_rop row"); (*dev_proc(&mdev, close_device))((gx_device *)&mdev); return code; }