diff options
Diffstat (limited to 'gs/base/gdevmac.c')
-rw-r--r-- | gs/base/gdevmac.c | 842 |
1 files changed, 842 insertions, 0 deletions
diff --git a/gs/base/gdevmac.c b/gs/base/gdevmac.c new file mode 100644 index 000000000..2366bc928 --- /dev/null +++ b/gs/base/gdevmac.c @@ -0,0 +1,842 @@ +/* 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$ */ +/* MacOS bitmap output device. This code is superceeded by + the newer gsapi_* interface and the DISPLAY device. Please + use that instead. See doc/API.htm for more information */ + +#include "gdevmac.h" +#include "gsparam.h" +#include "gsdll.h" + + + +/* The device descriptor */ + +gx_device_procs gs_mac_procs = { + mac_open, /* open_device */ + mac_get_initial_matrix, /* get_initial_matrix */ + mac_sync_output, /* sync_output */ + mac_output_page, /* output_page */ + mac_close, /* close_device */ + gx_default_rgb_map_rgb_color, /* map_rgb_color */ + gx_default_rgb_map_color_rgb, /* map_color_rgb */ + mac_fill_rectangle, /* fill_rectangle */ + NULL, /* tile_rectangle */ + mac_copy_mono, /* copy_mono */ + NULL,// mac_copy_color, /* copy_color */ + mac_draw_line, /* draw_line */ + NULL, /* get_bits */ + mac_get_params, /* get_params */ + mac_put_params, /* put_params */ + NULL, /* map_cmyk_color */ + mac_get_xfont_procs, /* get_xfont_procs */ + NULL, /* get_xfont_device */ + NULL, /* map_rgb_alpha_color */ + gx_page_device_get_page_device, /* get_page_device */ + gx_default_get_alpha_bits, /* get_alpha_bits */ + mac_copy_alpha, /* copy_alpha */ + NULL, /* get_band */ + NULL, /* copy_rop */ + NULL, /* fill_path */ + NULL, /* stroke_path */ + NULL, /* fill_mask */ + NULL, /* fill_trapezoid */ + NULL, /* fill_parallelogram */ + NULL, /* fill_triangle */ + NULL, /* draw_thin_line */ + NULL, /* begin_image */ + NULL, /* image_data */ + NULL, /* end_image */ + NULL //mac_strip_tile_rectangle /* strip_tile_rectangle */ +}; + + + +/* The instance is public. */ + +gx_device_macos gs_macos_device = { + std_device_color_body(gx_device_macos, + &gs_mac_procs, + DEV_MAC_NAME, + DEFAULT_DEV_WIDTH, /* x and y extent (nominal) */ + DEFAULT_DEV_HEIGHT, + DEFAULT_DEV_DPI, /* x and y density (nominal) */ + DEFAULT_DEV_DPI, + /*dci_color(*/8, 255, 256/*)*/), + { 0 }, /* std_procs */ + "", /* Output Filename */ + NULL, /* Output File */ + NULL, /* PicHandle to "draw" into */ + NULL, /* PicPtr */ + false, /* outputPage */ + false, /* use XFont interface (render with local TrueType fonts) */ + -1, /* lastFontFace */ + -1, /* lastFontSize */ + -1, /* lastFontID */ + 0 /* numUsedFonts */ +}; + + + + + +static int +mac_open(register gx_device *dev) +{ + gx_device_macos * mdev = (gx_device_macos *)dev; + + static short picHeader[42] = { 0x0000, // picture size + 0x0000, 0x0000, 0x0318, 0x0264, // bounding rect at 72dpi + 0x0011, 0x02ff, 0x0c00, 0xfffe, 0x0000, // version/header opcodes + 0x0048, 0x0000, // best x resolution + 0x0048, 0x0000, // best y resolution + 0x0000, 0x0000, 0x0318, 0x0264, // optimal src rect at 72dpi + 0x0000, // reserved + + 0x0000, 0x001e, // DefHilite + 0x0008, 0x0048, // PenMode + 0x001a, 0x0000, 0x0000, 0x0000, // RGBFgCol = Black + 0x001b, 0xFFFF, 0xFFFF, 0xFFFF, // RGBBkCol = White + + 0x0001, 0x000A, // set clipping + 0x0000, 0x0000, 0x0318, 0x0264, // clipping rect + 0x0032, 0x0000, 0x0000, 0x0318, 0x0264 // erase rect + }; + + + mac_set_colordepth(dev, mdev->color_info.depth); + + mdev->numUsedFonts = 0; + mdev->lastFontFace = -1; + mdev->lastFontSize = -1; + mdev->lastFontID = -1; + + mdev->pic = (PicHandle) NewHandle(500000); + if (mdev->pic == 0) // error, not enough memory + return gs_error_VMerror; + + HLockHi((Handle) mdev->pic); // move handle high and lock it + + mdev->currPicPos = (short*) *mdev->pic; + memcpy(mdev->currPicPos, picHeader, 42*2); + mdev->currPicPos += 42; + + // enter correct dimensions and resolutions + ((short*)(*mdev->pic))[ 3] = mdev->MediaSize[1]; + ((short*)(*mdev->pic))[ 4] = mdev->MediaSize[0]; + + ((short*)(*mdev->pic))[16] = ((short*)(*mdev->pic))[35] = ((short*)(*mdev->pic))[40] = mdev->height; + ((short*)(*mdev->pic))[17] = ((short*)(*mdev->pic))[36] = ((short*)(*mdev->pic))[41] = mdev->width; + + ((short*)(*mdev->pic))[10] = (((long) X2Fix( mdev->x_pixels_per_inch )) & 0xFFFF0000) >> 16; + ((short*)(*mdev->pic))[11] = ((long) X2Fix( mdev->x_pixels_per_inch )) & 0x0000FFFF; + ((short*)(*mdev->pic))[12] = (((long) X2Fix( mdev->y_pixels_per_inch )) & 0xFFFF0000) >> 16; + ((short*)(*mdev->pic))[13] = ((long) X2Fix( mdev->y_pixels_per_inch )) & 0x0000FFFF; + + // finish picture, but dont increment pointer, we want to go on drawing + *mdev->currPicPos = 0x00ff; + + // notify the caller that a new device was opened + if (pgsdll_callback) + (*pgsdll_callback) (GSDLL_DEVICE, (char *)mdev, 1); + + return 0; +} + + + +static void +mac_get_initial_matrix(register gx_device *dev, register gs_matrix *pmat) +{ + pmat->xx = dev->x_pixels_per_inch / 72.0; + pmat->xy = 0; + pmat->yx = 0; + pmat->yy = dev->y_pixels_per_inch / -72.0; + pmat->tx = 0; + pmat->ty = dev->height; +} + + + +/* Make the output appear on the screen. */ +int +mac_sync_output(gx_device * dev) +{ + gx_device_macos * mdev = (gx_device_macos *)dev; + + // finish picture, but dont increment pointer, we want to go on drawing + *mdev->currPicPos = 0x00ff; + + // tell the caller to sync + if (pgsdll_callback) + (*pgsdll_callback) (GSDLL_SYNC, (char *)mdev, 0); + + return (0); +} + + + +int +mac_output_page(gx_device * dev, int copies, int flush) +{ + gx_device_macos * mdev = (gx_device_macos *)dev; + int code = 0; + + mdev->outputPage = true; + + if (strcmp(mdev->outputFileName, "")) { + // save file + code = mac_save_pict(dev); + } + + // tell the caller that the page is done + if (pgsdll_callback) + (*pgsdll_callback) (GSDLL_PAGE, (char *)mdev, 0); + + gx_finish_output_page(dev, copies, flush); + + return code; +} + + +static int +mac_save_pict(gx_device * dev) +{ + gx_device_macos * mdev = (gx_device_macos *)dev; + int code = 0; + int i; + + if (mdev->outputFile == NULL) { + code = gx_device_open_output_file(dev, mdev->outputFileName, true, true, &(mdev->outputFile)); + if (code < 0) return code; + } + + for (i=0; i<512; i++) fputc(0, mdev->outputFile); + fwrite(*(mdev->pic), sizeof(char), ((long) mdev->currPicPos - (long) *mdev->pic + 2), mdev->outputFile); + + gx_device_close_output_file(dev, mdev->outputFileName, mdev->outputFile); + mdev->outputFile = NULL; + + return code; +} + + +/* Close the device. */ +static int +mac_close(register gx_device *dev) +{ + gx_device_macos * mdev = (gx_device_macos *)dev; + + long len; + + HUnlock((Handle) mdev->pic); // no more changes in the pict -> unlock handle + if (strcmp(mdev->outputFileName, "")) { + DisposeHandle((Handle) mdev->pic); + gx_device_close_output_file(dev, mdev->outputFileName, mdev->outputFile); + mdev->outputFile = 0; + } else { + len = (long)mdev->currPicPos - (long)*mdev->pic; + SetHandleSize((Handle) mdev->pic, len + 10); // +10 just for the case + } + + // notify the caller that the device was closed + // it has to dispose the PICT handle when it is ready! + if (pgsdll_callback) + (*pgsdll_callback) (GSDLL_DEVICE, (char *)mdev, 0); + + return 0; +} + + + +/* Fill a rectangle with a color. */ +static int +mac_fill_rectangle(register gx_device *dev, + int x, int y, int w, int h, + gx_color_index color) +{ + gx_device_macos * mdev = (gx_device_macos *)dev; + + /* ignore a fullpage rect directly after an output_page, this would clear the pict */ + if (mdev->outputPage && + (x == 0) && (y == 0) && (w == mdev->width) && (h == mdev->height)) { + return 0; + } + + CheckMem(1024, 100*1024); + ResetPage(); + + GSSetFgCol(dev, mdev->currPicPos, color); + PICT_fillRect(mdev->currPicPos, x, y, w, h); + + PICT_OpEndPicGoOn(mdev->currPicPos); + + return 0; +} + + + +/* Draw a line */ +static int +mac_draw_line (register gx_device *dev, + int x0, int y0, + int x1, int y1, + gx_color_index color) +{ + gx_device_macos * mdev = (gx_device_macos *)dev; + + CheckMem(1024, 100*1024); + ResetPage(); + + GSSetFgCol(dev, mdev->currPicPos, color); + PICT_Line(mdev->currPicPos, x0, y0, x1, y1); + + PICT_OpEndPicGoOn(mdev->currPicPos); + + return 0; +} + + + +/* 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; +} + + + +/* Fill a region with a color and apply a per-pixel alpha-value */ +/* alpha value is simulated by changed the value to white. Full transparency means white color */ +/* 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; +} + + + +void +mac_convert_rgb_hsv(colorRGB *inRGB, colorHSV *HSV) +{ +#define NORMALIZE_RGB(col) ((float)col/(float)0xFFFF) + + float min = 1.0, temp; + float r = NORMALIZE_RGB(inRGB->red), + g = NORMALIZE_RGB(inRGB->green), + b = NORMALIZE_RGB(inRGB->blue); + + HSV->h = 0; + + HSV->v = r; + if (g > HSV->v) HSV->v = g; + if (b > HSV->v) HSV->v = b; + + min = r; + if (g < min) min = g; + if (b < min) min = b; + + temp = HSV->v - min; + + if (HSV->v > 0) + HSV->s = temp / HSV->v; + else + HSV->s = 0; + + if (HSV->s > 0) { + float rd = (HSV->v - r) / temp, + gd = (HSV->v - g) / temp, + bd = (HSV->v - b) / temp; + + if (HSV->v == r) { + if (min == g) HSV->h = 5 + bd; + else HSV->h = 1 - gd; + } else if (HSV->v == g) { + if (min == b) HSV->h = 1 + rd; + else HSV->h = 3 - bd; + } else { + if (min == r) HSV->h = 3 + gd; + else HSV->h = 5 - rd; + } + + if (HSV->h < 6) HSV->h *= 60; + else HSV->h = 0; + } +} + + +void +mac_convert_hsv_rgb(colorHSV *inHSV, colorRGB *RGB) +{ + if (inHSV->s == 0) { + RGB->red = RGB->green = RGB->blue = inHSV->v * 0xFFFF; + } else { + float h = inHSV->h / 60; + int i = trunc(h); + float fract = h - i; + unsigned short t1 = (inHSV->v * (1 - inHSV->s)) * 0xFFFF, + t2 = (inHSV->v * (1 - inHSV->s * fract)) * 0xFFFF, + t3 = (inHSV->v * (1 - inHSV->s * (1 - fract))) * 0xFFFF, + v = inHSV->v * 0xFFFF; + + switch(i) { + case 0: RGB->red = v; + RGB->green = t3; + RGB->blue = t1; + break; + + case 1: RGB->red = t2; + RGB->green = v; + RGB->blue = t1; + break; + + case 2: RGB->red = t1; + RGB->green = v; + RGB->blue = t3; + break; + + case 3: RGB->red = t1; + RGB->green = t2; + RGB->blue = v; + break; + + case 4: RGB->red = t3; + RGB->green = t1; + RGB->blue = v; + break; + + case 5: RGB->red = v; + RGB->green = t1; + RGB->blue = t2; + break; + } + } +} + + + +// set color info and procedures according to pixeldepth +static int +mac_set_colordepth(gx_device *dev, int depth) +{ + gx_device_macos * mdev = (gx_device_macos *)dev; + gx_device_color_info * ci = &mdev->color_info; + + if (depth != 1 && depth != 4 && depth != 7 && depth != 8 && depth != 24) + return gs_error_rangecheck; + + mdev->color_info.depth = depth; + switch (depth) + { + case 1: // Black/White + ci->num_components = 1; + ci->max_gray = 1; ci->max_color = 0; + ci->dither_grays = 2; ci->dither_colors = 0; + set_dev_proc(dev, map_rgb_color, gx_default_b_w_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gx_default_b_w_map_color_rgb); + break; + + case 4: // 4Bit-Gray + ci->num_components = 1; + ci->max_gray = 15; ci->max_color = 0; + ci->dither_grays = 16; ci->dither_colors = 0; + set_dev_proc(dev, map_rgb_color, gx_default_gray_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gx_default_gray_map_color_rgb); + break; + + case 7: // 8Bit-Gray + ci->depth = 7; + ci->num_components = 1; + ci->max_gray = 255; ci->max_color = 0; + ci->dither_grays = 256; ci->dither_colors = 0; + set_dev_proc(dev, map_rgb_color, gx_default_gray_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gx_default_gray_map_color_rgb); + break; + + case 8: // 8Bit-Color + ci->num_components = 3; + ci->max_gray = 15; ci->max_color = 5; + ci->dither_grays = 16; ci->dither_colors = 6; + set_dev_proc(dev, map_rgb_color, gx_default_rgb_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gx_default_rgb_map_color_rgb); + break; + +/* case 16: // 16Bit-Color + ci->num_components = 3; + ci->max_gray = 255; ci->max_color = 65535; + ci->dither_grays = 256; ci->dither_colors = 65536; + set_dev_proc(dev, map_rgb_color, gx_default_rgb_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gx_default_rgb_map_color_rgb); + break; +*/ + case 24: // 24Bit-Color + ci->num_components = 3; + ci->max_gray = 255; ci->max_color = 16777215; + ci->dither_grays = 256; ci->dither_colors = 16777216; + set_dev_proc(dev, map_rgb_color, gx_default_rgb_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gx_default_rgb_map_color_rgb); + break; + } + + return 0; +} + + +static int +mac_put_params(gx_device *dev, gs_param_list *plist) +{ + gx_device_macos *mdev = (gx_device_macos *)dev; + + int isOpen = mdev->is_open; + int code; + bool useXFonts; + int depth; + gs_param_string outputFile; + + // Get the UseExternalFonts Parameter + code = param_read_bool(plist, "UseExternalFonts", &useXFonts); + if (!code) + mdev->useXFonts = useXFonts; + + // Get the BitsPerPixel Parameter + code = param_read_int(plist, "BitsPerPixel", &depth); + if (!code) { + code = mac_set_colordepth(dev, depth); + if (code) + param_return_error(plist, "BitsPerPixel", gs_error_rangecheck); + } + + // Get OutputFile + code = param_read_string(plist, "OutputFile", &outputFile); + if (code < 0) { + param_signal_error(plist, "OutputFile", code); + return code; + } else if (code == 0) { + + if (dev->LockSafetyParams && + bytes_compare(outputFile.data, outputFile.size, + (const byte *)mdev->outputFileName, strlen(mdev->outputFileName))) { + param_signal_error(plist, "OutputFile", gs_error_invalidaccess); + return gs_error_invalidaccess; + } + if (outputFile.size > (gp_file_name_sizeof - 1)) { + param_signal_error(plist, "OutputFile", gs_error_limitcheck); + return gs_error_limitcheck; + } + + /* If filename changed, close file. */ + if (outputFile.data != 0 && + bytes_compare(outputFile.data, outputFile.size, + (const byte *)mdev->outputFileName, strlen(mdev->outputFileName))) { + /* Close the file if it's open. */ + if (mdev->outputFile != NULL) { + gx_device_close_output_file(dev, mdev->outputFileName, mdev->outputFile); + memcpy(mdev->outputFileName, outputFile.data, outputFile.size); + mdev->outputFileName[outputFile.size] = 0; + gx_device_open_output_file(dev, mdev->outputFileName, true, true, &(mdev->outputFile)); + } else { + memcpy(mdev->outputFileName, outputFile.data, outputFile.size); + mdev->outputFileName[outputFile.size] = 0; + } + } + } + + // Get the Default Parameters + mdev->is_open = 0; + code = gx_default_put_params( dev, plist ); + mdev->is_open = isOpen; + + return code; +} + + +static int +mac_get_params(gx_device *dev, gs_param_list *plist) +{ + gx_device_macos *mdev = (gx_device_macos *)dev; + + int code; + gs_param_string outputFile; + + code = gx_default_get_params(dev, plist); + if (code < 0) + return code; + + // UseExternalFonts + code = param_write_bool(plist, "UseExternalFonts", &(mdev->useXFonts)); + + // color depth + code = param_write_int(plist, "BitsPerPixel", &(mdev->color_info.depth)); + + // output file name + outputFile.data = (const byte *) mdev->outputFileName; + outputFile.size = strlen(mdev->outputFileName); + outputFile.persistent = false; + code = param_write_string(plist, "OutputFile", &outputFile); + + return code; +} + + + +/* let the caller get the device PictHandle, he has to draw it to screen */ +int GSDLLAPI +gsdll_get_pict(unsigned char *dev, PicHandle *thePict) +{ + gx_device_macos * mdev = (gx_device_macos *)dev; + + *thePict = mdev->pic; + + return 0; +} + + + + + + +/*************************************************************************************/ +/*************************************************************************************/ +/** Experimental functions! **/ +/*************************************************************************************/ +/*************************************************************************************/ + + + + +#if 0 +/* NOT FUNCTIONAL !!! */ +/* 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; +} +#endif + + + +#if 0 +/* tile a rectangle with a bitmap or pixmap */ +static int +mac_strip_tile_rectangle(register gx_device *dev, const gx_strip_bitmap *tile, + int x, int y, int w, int h, + gx_color_index color_0, gx_color_index color_1, + int phase_x, int phase_y) +{ + gx_device_macos * mdev = (gx_device_macos *)dev; + + int byteCount = tile->raster * tile->size.y; +/* + // tile is a pixmap + if (color_0 == gx_no_color_index && color_1 == gx_no_color_index) + return 0;// gx_default_strip_tile_rectangle(dev, tile, x, y, w, h, color_0, color_1, phase_x, phase_y); + + if (color_0 != gx_no_color_index && color_1 != gx_no_color_index) { + // monochrome tiles + if (phase_x != 0 ||Ęphase_y != 0 || tile->shift != 0 || + tile->strip_height != 0 ||Ętile->strip_shift != 0) { + return gx_default_strip_tile_rectangle(dev, tile, x, y, w, h, color_0, color_1, phase_x, phase_y); + } + + } else { + return 0;//gx_default_strip_tile_rectangle(dev, tile, x, y, w, h, color_0, color_1, phase_x, phase_y); + } +*/ +} +#endif + + + + + + + + + + |