home *** CD-ROM | disk | FTP | other *** search
- /* gdevpm.c */
- /* Ghostscript driver for OS2 2.x Presentation Manager. */
- /* Version 2.6a by Jim Yang, 1992, 1993. */
-
- #define INCL_PM
- #define INCL_DOS
- #define INCL_WIN
- #define INCL_GPI
-
- #include <stdlib.h>
- #include "gx.h"
- #include "memory_.h"
- #include "gserrors.h"
- #include "gsprops.h"
- #include "gsutil.h"
- #include "gxdevice.h"
- #include "gsos2.h"
- #include "gxdevmem.h"
- #include <os2.h>
-
- #define TILE_CACHE_WIDTH 160
- #define TILE_CACHE_HEIGHT 32
-
- #define MAX_PALETTE_COLORS 224
- #define COLORS_STATIC 64
-
- #define DEFAULT_WIDTH 442
- #define DEFAULT_HEIGHT 572
- #define DEFAULT_XDPI 52.0
- #define DEFAULT_YDPI 52.0
-
- #define DRV_PALETTE_MANAGER 0x02
-
- /*-------------------------------------------------------------------------*/
- /* Variables and procedures shared with gsos2b.exe. */
- HPAL hpal;
- HWND hwndClient;
- ULONG DrawingMode;
- LONG CXImage, CYImage;
- HEV hevWaitClient;
- float Xdpi, Ydpi;
- int repaint_window (int x0, int y0, int x1, int y1,
- int x2, int y2, int x3, int y3);
- /*-------------------------------------------------------------------------*/
-
- extern HAB habGS; /* declared in gp_os2.c */
- extern int pm_draw_line_called; /* declared in gxdraw.c */
-
- /* See gxdevice.h for the definitions of the procedures. */
-
- dev_proc_open_device (pm_open);
- dev_proc_get_initial_matrix (pm_get_initial_matrix);
- dev_proc_output_page (pm_output_page);
- dev_proc_close_device (pm_close);
- dev_proc_fill_rectangle (pm_fill_rectangle);
- dev_proc_tile_rectangle (pm_tile_rectangle);
- dev_proc_copy_mono (pm_copy_mono);
- dev_proc_copy_color (pm_copy_color);
- dev_proc_draw_line (pm_draw_line);
- dev_proc_map_rgb_color (pm_map_rgb_color);
- dev_proc_map_color_rgb (pm_map_color_rgb);
- dev_proc_sync_output (pm_sync_output);
-
- int alloc_backing_bitmap (gx_device *dev);
- VOID APIENTRY close_pm_driver ();
-
- /* The device descriptor */
- typedef struct gx_device_pm_s gx_device_pm;
- struct gx_device_pm_s
- {
- gx_device_common;
- HWND hwndClient;
- HPS hpsWin;
- HDC hdcTile;
- HPS hpsTile;
- HBITMAP hbmTile;
- BITMAPINFOHEADER2 bmpTile;
- BITMAPINFO2 *pbmiTile;
- BYTE *TileCache;
- gx_bitmap_id last_bitmap_id;
- HDC hdcBackingBitmap;
- HPS hpsBackingBitmap;
- HBITMAP hbmBackingBitmap;
- BITMAPINFOHEADER2 bmpBackingBitmap;
- BITMAPINFO2 *pbmiBackingBitmap;
- ULONG DriverCaps;
- ULONG HighestColorIndex;
- HPAL hpal;
- ULONG aulColorTable [MAX_PALETTE_COLORS];
- gx_device_memory mdev;
- BYTE *BackingBitmapPtr;
- ULONG DrawBitsflOptions;
- };
-
- #define pmdev ((gx_device_pm *)dev)
- #define pmmdev ((gx_device *) &pmdev->mdev)
- #define pmmproc(proc) (*pmdev->mdev.procs->proc)
-
- private gx_device_procs pm_procs =
- {
- pm_open,
- pm_get_initial_matrix,
- pm_sync_output,
- pm_output_page,
- pm_close,
- pm_map_rgb_color,
- pm_map_color_rgb,
- pm_fill_rectangle,
- pm_tile_rectangle,
- pm_copy_mono,
- pm_copy_color,
- pm_draw_line,
- gx_default_get_bits,
- gx_default_get_props,
- gx_default_put_props,
- gx_default_map_cmyk_color,
- NULL /* No support for external fonts */
- };
-
- gx_device_pm gs_os2pm_device =
- {
- sizeof(gx_device_pm),
- &pm_procs,
- "os2pm",
- DEFAULT_WIDTH, DEFAULT_HEIGHT,
- DEFAULT_XDPI, DEFAULT_YDPI,
- no_margins,
- {1, 2, 3, 0, 4, 0}, /* 4 shades of gray */
- 0 /* not opened yet */
- };
-
- gx_device_pm *CurrentDev;
-
-
- /* Create a color palette and realize it. */
- MakeColorPalette (gx_device *dev)
- {
- static const gx_device_color_info info_256 = dci_color (8, 63, 4);
- ULONG *pulTable, aulTable [256], r, g, b, i, clr;
- HPAL hpalOld;
- BITMAPINFO2 *pbmiBackingBitmap;
-
- pbmiBackingBitmap = pmdev->pbmiBackingBitmap;
-
- pmdev->DrawBitsflOptions = BBO_IGNORE | BBO_PAL_COLORS;
- dev->color_info = info_256;
-
- for (i = 0; i < 256; i++)
- {
- pbmiBackingBitmap->argbColor[i].bBlue = i;
- pbmiBackingBitmap->argbColor[i].bGreen = 0;
- pbmiBackingBitmap->argbColor[i].bRed = 0;
- pbmiBackingBitmap->argbColor[i].fcOptions = 0;
- }
-
- pulTable = pmdev->aulColorTable;
-
- for (i = 0, r = 0; r < 256; r += 85)
- for (g = 0; g < 256; g += 85)
- for (b = 0; b < 256; b += 85, i++, pulTable++)
- {
- *pulTable = (r << 16) + (g << 8) + b;
- aulTable [i] = *pulTable;
- }
-
- for (; i < MAX_PALETTE_COLORS; i++)
- aulTable [i] = PC_RESERVED << 24;
-
- hpal = GpiCreatePalette (habGS, LCOL_PURECOLOR, LCOLF_CONSECRGB,
- MAX_PALETTE_COLORS, aulTable);
-
- if (hpal == GPI_ERROR)
- {
- fprintf (stdout, "Error creating palette!\n");
- return (0);
- }
-
- pmdev->hpal = hpal;
-
- hpalOld = GpiSelectPalette (pmdev->hpsWin, hpal);
- if (hpalOld == PAL_ERROR)
- fprintf (stdout, "Error setting palette of drawing window!\n");
-
- WinRealizePalette (hwndClient, pmdev->hpsWin, &clr);
-
- pmdev->HighestColorIndex = COLORS_STATIC;
-
- DosSleep (250L); /* Sleep for 1/4 second for PM to change palette. */
-
- return (0);
- }
-
-
- /* Create a logical color table with 16 or 4 gray scales. */
- MakeGrayTable (gx_device *dev, int GrayScales)
- {
- static const gx_device_color_info info_16 = {1, 4, 15, 0, 16, 0};
- static const gx_device_color_info info_4 = {1, 2, 3, 0, 4, 0};
- static const gx_device_color_info info_2 = dci_black_and_white;
- LONG alTable [16], i;
- BITMAPINFO2 *pbmiBackingBitmap;
-
- pbmiBackingBitmap = pmdev->pbmiBackingBitmap;
- pmdev->DrawBitsflOptions = BBO_IGNORE;
-
- if (GrayScales == 16)
- {
- dev->color_info = info_16;
- for (i = 0; i < 16; i++)
- {
- alTable [i] = 0x111111 * i;
- pbmiBackingBitmap->argbColor[i].bBlue = 0x11 * i;
- pbmiBackingBitmap->argbColor[i].bGreen = 0x11 * i;
- pbmiBackingBitmap->argbColor[i].bRed = 0x11 * i;
- pbmiBackingBitmap->argbColor[i].fcOptions = 0;
- }
- GpiCreateLogColorTable (pmdev->hpsWin, LCOL_PURECOLOR, LCOLF_CONSECRGB,
- 0L, 16L, alTable);
- }
- else if (GrayScales == 4)
- {
- dev->color_info = info_4;
- for (i = 0; i < 4; i++)
- {
- alTable [i] = 0x555555 * i;
- pbmiBackingBitmap->argbColor[i].bBlue = 0x55 * i;
- pbmiBackingBitmap->argbColor[i].bGreen = 0x55 * i;
- pbmiBackingBitmap->argbColor[i].bRed = 0x55 * i;
- pbmiBackingBitmap->argbColor[i].fcOptions = 0;
- }
- GpiCreateLogColorTable (pmdev->hpsWin, LCOL_PURECOLOR, LCOLF_CONSECRGB,
- 0L, 4L, alTable);
- if (pmdev->pbmiBackingBitmap->cBitCount == 4)
- {
- GpiCreateLogColorTable (pmdev->hpsBackingBitmap, LCOL_PURECOLOR,
- LCOLF_CONSECRGB, 0L, 4L, alTable);
- }
- }
- else /* Black and white */
- {
- dev->color_info = info_2;
- for (i = 0; i < 2; i++)
- {
- alTable [i] = 0xffffff * i;
- pbmiBackingBitmap->argbColor[i].bBlue = 0xff * i;
- pbmiBackingBitmap->argbColor[i].bGreen = 0xff * i;
- pbmiBackingBitmap->argbColor[i].bRed = 0xff * i;
- pbmiBackingBitmap->argbColor[i].fcOptions = 0;
- }
- GpiCreateLogColorTable (pmdev->hpsWin, LCOL_PURECOLOR, LCOLF_CONSECRGB,
- 0L, 2L, alTable);
- if (pmdev->pbmiBackingBitmap->cBitCount == 4)
- {
- GpiCreateLogColorTable (pmdev->hpsBackingBitmap, LCOL_PURECOLOR,
- LCOLF_CONSECRGB, 0L, 2L, alTable);
- }
- }
-
- return (0);
- }
-
-
- /* Open the PM driver. */
- int pm_open (register gx_device *dev)
- {
- LONG alBmpFormats [2], lCaps;
- BOOL fSuccess;
- SIZEL sizl;
- BITMAPINFO2 *pbmiBackingBitmap, *pbmiTile;
- HDC hdcWin;
- static DEVOPENSTRUC dop = {NULL, "DISPLAY", NULL, NULL, NULL};
- static LONG TimesOpened;
- ULONG ulMode, ulPostCt;
-
- CurrentDev = pmdev;
-
- pmdev->hwndClient = hwndClient;
- pmdev->hpsWin = WinGetPS (hwndClient);
-
- /* Bring the drawing window to the top and activate it so that it has */
- /* the input focus - having input focus is necessary in order to */
- /* realize the palette absolutely. Use the event semaphore */
- /* hevWaitClient to wait until the drawing window has been moved to */
- /* the top before continuing. */
- DosResetEventSem (hevWaitClient, &ulPostCt);
- WinPostMsg (hwndClient, WM_USER, (MPARAM) WM_USER_WINTOTOP, 0L);
- DosWaitEventSem (hevWaitClient, SEM_INDEFINITE_WAIT);
-
- /* Tell the window's client procedure to call WinShowWindow and */
- /* make the window visible. */
- DosResetEventSem (hevWaitClient, &ulPostCt);
- WinPostMsg (hwndClient, WM_USER, (MPARAM) WM_USER_SHOWWIN, 0L);
- DosWaitEventSem (hevWaitClient, SEM_INDEFINITE_WAIT);
-
- dev->width = CXImage;
- dev->height = CYImage;
- dev->x_pixels_per_inch = Xdpi;
- dev->y_pixels_per_inch = Ydpi;
-
- hdcWin = GpiQueryDevice (pmdev->hpsWin);
-
- if (hdcWin == NULLHANDLE || hdcWin == HDC_ERROR)
- fprintf (stdout, "Error getting hdcWin!\n");
-
- fSuccess = DevQueryCaps (hdcWin, CAPS_ADDITIONAL_GRAPHICS, 1L, &lCaps);
- if (!fSuccess)
- fprintf (stdout, "DevQueryCaps failed: CAPS_ADDITIONAL_GRAPHICS.\n");
-
- pmdev->DriverCaps = 0;
-
- if (lCaps & CAPS_PALETTE_MANAGER)
- pmdev->DriverCaps |= DRV_PALETTE_MANAGER;
-
- sizl.cx = sizl.cy = 0;
-
- pmdev->hdcTile = DevOpenDC (habGS, OD_MEMORY, "*", 5L, (PDEVOPENDATA) &dop,
- NULLHANDLE);
-
- pmdev->hpsTile = GpiCreatePS (habGS, pmdev->hdcTile, &sizl, PU_PELS |
- GPIA_ASSOC | GPIT_MICRO | GPIF_DEFAULT);
-
- pmdev->TileCache = (BYTE *) calloc ((TILE_CACHE_WIDTH / (sizeof(ULONG) * 8))
- * TILE_CACHE_HEIGHT, sizeof (ULONG));
- if (pmdev->TileCache == NULL)
- fprintf (stdout, "Error allocating memory for TileCache!\n");
-
- pbmiTile = malloc (sizeof (BITMAPINFO2) + sizeof (RGB2));
- if (pbmiTile == NULL)
- fprintf (stdout, "Error allocating memory for BITMAPINFO2 for Tile!\n");
- pmdev->pbmiTile = pbmiTile;
-
- memset (pbmiTile, 0, sizeof (BITMAPINFOHEADER2));
- memset (&(pmdev->bmpTile), 0, sizeof (BITMAPINFOHEADER2));
- pbmiTile->cbFix = pmdev->bmpTile.cbFix = sizeof (BITMAPINFOHEADER2);
- pbmiTile->cPlanes = pmdev->bmpTile.cPlanes = 1;
- pbmiTile->cBitCount = pmdev->bmpTile.cBitCount = 1;
-
- pbmiTile->argbColor[0].bBlue = 0;
- pbmiTile->argbColor[0].bGreen = 0;
- pbmiTile->argbColor[0].bRed = 0;
- pbmiTile->argbColor[0].fcOptions = 0;
-
- pbmiTile->argbColor[1].bBlue = 0xff;
- pbmiTile->argbColor[1].bGreen = 0xff;
- pbmiTile->argbColor[1].bRed = 0xff;
- pbmiTile->argbColor[1].fcOptions = 0;
-
- pbmiTile->cx = pmdev->bmpTile.cx = TILE_CACHE_WIDTH;
- pbmiTile->cy = pmdev->bmpTile.cy = TILE_CACHE_HEIGHT;
-
- pmdev->hbmTile = GpiCreateBitmap (pmdev->hpsTile, &(pmdev->bmpTile),
- 0L, NULL, NULL);
-
- GpiSetBitmap (pmdev->hpsTile, pmdev->hbmTile);
-
- GpiQueryDeviceBitmapFormats (pmdev->hpsWin, 2L, alBmpFormats);
-
- pbmiBackingBitmap = malloc (sizeof (BITMAPINFO2) + 256 * sizeof (RGB2));
- if (pbmiBackingBitmap == NULL)
- fprintf (stdout, "Error allocating memory for BITMAPINFO2 for Mono!\n");
- pmdev->pbmiBackingBitmap = pbmiBackingBitmap;
-
- memset (pbmiBackingBitmap, 0, sizeof (BITMAPINFOHEADER2));
- pbmiBackingBitmap->cbFix = sizeof (BITMAPINFOHEADER2);
- pbmiBackingBitmap->cPlanes = 1;
- pbmiBackingBitmap->cBitCount = (USHORT) alBmpFormats [1];
- pbmiBackingBitmap->cx = dev->width;
- pbmiBackingBitmap->cy = dev->height;
-
- if ((DrawingMode & MODE_256_COLOR) && !(pmdev->DriverCaps & DRV_PALETTE_MANAGER))
- {
- fprintf (stdout, "You cannot use the 256 color mode because your"
- " display driver is not capable of palette"
- " management!\n");
- return_error (gs_error_rangecheck);
- }
-
- if (pbmiBackingBitmap->cBitCount < 8 && ((DrawingMode & MODE_256_COLOR) ||
- (DrawingMode & MODE_16_GRAY)))
- {
- fprintf (stdout, "You cannot use the 256 color mode or the 16 gray mode"
- " because you are using a 16 color display!\n");
- return_error (gs_error_rangecheck);
- }
-
- if (pbmiBackingBitmap->cBitCount > 8)
- pbmiBackingBitmap->cBitCount = 8;
-
- if (DrawingMode & MODE_2_GRAY)
- pbmiBackingBitmap->cBitCount = 1;
-
- if (pbmiBackingBitmap->cBitCount == 4)
- {
- pmdev->hdcBackingBitmap = DevOpenDC (habGS, OD_MEMORY, "*", 5L, (PDEVOPENDATA) &dop,
- NULLHANDLE);
-
- pmdev->hpsBackingBitmap = GpiCreatePS (habGS, pmdev->hdcBackingBitmap, &sizl, PU_PELS |
- GPIA_ASSOC | GPIT_MICRO | GPIF_DEFAULT);
-
- pmdev->bmpBackingBitmap.cbFix = sizeof (BITMAPINFOHEADER2);
- pmdev->bmpBackingBitmap.cPlanes = 1;
- pmdev->bmpBackingBitmap.cBitCount = 4;
-
- pmdev->bmpBackingBitmap.cx = dev->width;
- pmdev->bmpBackingBitmap.cy = dev->height;
-
- pmdev->hbmBackingBitmap = GpiCreateBitmap (pmdev->hpsBackingBitmap, &(pmdev->bmpBackingBitmap),
- 0L, NULL, NULL);
-
- GpiSetBitmap (pmdev->hpsBackingBitmap, pmdev->hbmBackingBitmap);
- }
-
- if (DrawingMode & MODE_256_COLOR)
- MakeColorPalette (dev);
- else if (DrawingMode & MODE_16_GRAY)
- MakeGrayTable (dev, 16);
- else if (DrawingMode & MODE_4_GRAY)
- MakeGrayTable (dev, 4);
- else
- MakeGrayTable (dev, 2);
-
- pmdev->last_bitmap_id = gx_no_bitmap_id;
-
- alloc_backing_bitmap (dev);
-
- /* Add the cleanup routines for the PM driver to the exit list. */
- DosExitList (EXLST_ADD | 0x0000, close_pm_driver);
-
- return (0);
- }
-
-
- /* Synchronize the device. If any output to the device has been buffered, */
- /* send / write it now. */
- int pm_sync_output (gx_device *dev)
- {
- POINTL *paptl;
- ULONG ulPostCt;
-
- if (DrawingMode & MODE_DRAW_BITMAP_ONLY)
- {
- DosResetEventSem (hevWaitClient, &ulPostCt);
- WinPostMsg (hwndClient, WM_USER, (MPARAM) WM_USER_SYNCOUTPUT, 0L);
- DosWaitEventSem (hevWaitClient, SEM_INDEFINITE_WAIT);
- }
-
- return (0);
- }
-
-
- /* Output a fully composed page to the device. */
- int pm_output_page (gx_device *dev, int num_copies, int flush)
- {
- ULONG ulPostCt;
-
- pm_sync_output (dev);
-
- if (DrawingMode & MODE_256_COLOR)
- pmdev->HighestColorIndex = COLORS_STATIC;
-
- DosResetEventSem (hevWaitClient, &ulPostCt);
- WinPostMsg (hwndClient, WM_USER, (MPARAM) WM_USER_SHOWPAGE, 0L);
- DosWaitEventSem (hevWaitClient, SEM_INDEFINITE_WAIT);
- return (0);
- }
-
-
- /* Close the PM driver. */
- int pm_close (register gx_device *dev)
- {
- if (DrawingMode & MODE_256_COLOR)
- {
- GpiSelectPalette (pmdev->hpsWin, NULLHANDLE);
- GpiDeletePalette (pmdev->hpal);
- }
-
- WinReleasePS (pmdev->hpsWin);
-
- free (pmdev->pbmiTile);
- free (pmdev->TileCache);
- free (pmdev->pbmiBackingBitmap);
- free (pmdev->BackingBitmapPtr);
-
- GpiSetBitmap (pmdev->hpsTile, NULLHANDLE);
- GpiDeleteBitmap (pmdev->hbmTile);
- GpiDestroyPS (pmdev->hpsTile);
- DevCloseDC (pmdev->hdcTile);
-
- CurrentDev = NULL;
-
- return (0);
- }
-
-
- /* Construct the initial transformation matrix mapping user coordinates */
- /* (nominally 1/72" per unit) to device coordinates. */
- void pm_get_initial_matrix (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 = 0;
- }
-
-
- #define MAP64(z) ((((z) >> (gx_color_value_bits - 6)) << 2) +\
- ((z) >> (gx_color_value_bits - 2)))
- /* Map a RGB color to a device color. */
- gx_color_index pm_map_rgb_color (gx_device *dev,
- gx_color_value red,
- gx_color_value green,
- gx_color_value blue)
- {
- gx_color_index radius;
- ULONG r, g, b, i, index, ulTable, *pulTable, rgb;
-
- if (DrawingMode & MODE_256_COLOR)
- {
- r = MAP64 (red); /* Map r to 0->255 in 64 steps. */
- g = MAP64 (green);
- b = MAP64 (blue);
-
- pulTable = pmdev->aulColorTable;
- index = pmdev->HighestColorIndex;
- rgb = (r << 16) + (g << 8) + b;
-
- for (i = 0; i < index; i++, pulTable++)
- if (*pulTable == rgb)
- return (i);
-
- if (index < MAX_PALETTE_COLORS)
- {
- ulTable = (PC_RESERVED << 24) + rgb;
- *pulTable = rgb;
- GpiAnimatePalette (pmdev->hpal, LCOLF_CONSECRGB, index, 1, &ulTable);
- pmdev->HighestColorIndex += 1;
- return (index);
- }
- else
- return (gx_no_color_index);
- }
- else if (DrawingMode & MODE_16_GRAY)
- {
- radius = (gx_color_index) max (red, max (green, blue));
- return (min ((radius * 16) / gx_max_color_value, 15));
- }
- else if (DrawingMode & MODE_4_GRAY)
- {
- radius = (gx_color_index) max (red, max (green, blue));
- return (min ((radius * 4) / gx_max_color_value, 3));
- }
- else
- {
- radius = (gx_color_index) max (red, max (green, blue));
- return (min ((radius * 2) / gx_max_color_value, 1));
- }
- }
-
-
- /* Map a device color code to RGB values. */
- int pm_map_color_rgb (gx_device *dev, gx_color_index color,
- gx_color_value rgb[3])
- {
- gx_color_value clr;
- ULONG *pulTable;
-
- if (DrawingMode & MODE_256_COLOR)
- {
- pulTable = pmdev->aulColorTable + color;
- rgb [2] = (*pulTable >> 16) * (gx_max_color_value / 255);
- rgb [1] = ((*pulTable >> 8) & 0xff) * (gx_max_color_value / 255);
- rgb [0] = (*pulTable & 0xff) * (gx_max_color_value / 255);
- }
- else if (DrawingMode & MODE_16_GRAY)
- {
- clr = (gx_max_color_value / 15) * color;
- rgb[2] = rgb[1] = rgb[0] = clr;
- }
- else if (DrawingMode & MODE_4_GRAY)
- {
- clr = (gx_max_color_value / 3) * color;
- rgb[2] = rgb[1] = rgb[0] = clr;
- }
- else
- {
- clr = gx_max_color_value * color;
- rgb[2] = rgb[1] = rgb[0] = clr;
- }
-
- return (0);
- }
-
-
- /* Fill a rectangle with a color. */
- int pm_fill_rectangle (gx_device *dev, int x, int y, int width, int height,
- gx_color_index color)
- {
- POINTL *paptl;
- RECTL rcl;
-
- if (width <= 0 || height <= 0)
- return (0);
-
- rcl.xLeft = x;
- rcl.yBottom = y;
- rcl.xRight = x + width;
- rcl.yTop = y + height;
-
- pmmproc (fill_rectangle) (pmmdev, x, y, width, height, color);
-
- if (DrawingMode & MODE_DRAW_BITMAP_ONLY || pm_draw_line_called)
- return (0);
-
- WinFillRect (pmdev->hpsWin, &rcl, color);
-
- return(0);
- }
-
-
- /* Tile a rectangle. Tiling consists of doing multiple copy_mono */
- /* operations to fill the rectangle with copies of the tile. */
- int pm_tile_rectangle (gx_device *dev, register const gx_bitmap *tile,
- int x, int y, int width, int height,
- gx_color_index color0, gx_color_index color1,
- int phase_x, int phase_y)
- {
- int data_x, data_y, cw, ch, cx, cy, h, w, dx;
- int raster, g, i, j, k;
- int TileSizeX, TileSizeY, TilesX, TilesY, BytesInTile;
- gx_bitmap_id id;
- BYTE *data, *TileCache;
- HPS hpsTile, hpsWin;
- POINTL aptl[3];
-
- if (width <= 0 || height <= 0)
- return (0);
-
- if (color0 == gx_no_color_index || color1 == gx_no_color_index)
- return (gx_default_tile_rectangle (dev, tile, x, y, width, height,
- color0, color1, phase_x, phase_y));
-
- gx_default_tile_rectangle (pmmdev, tile, x, y, width, height, color0,
- color1, phase_x, phase_y);
-
- if (DrawingMode & MODE_DRAW_BITMAP_ONLY || pm_draw_line_called)
- return (0);
-
- id = tile->id;
-
- raster = tile->raster;
- data = tile->data;
- TileSizeX = tile->size.x;
- TileSizeY = tile->size.y;
- hpsTile = pmdev->hpsTile;
- hpsWin = pmdev->hpsWin;
- TileCache = pmdev->TileCache;
-
- BytesInTile = TileSizeX / 8;
- TilesX = TILE_CACHE_WIDTH / TileSizeX;
- TilesY = TILE_CACHE_HEIGHT / TileSizeY;
-
- data_x = (x + phase_x) % tile->rep_width;
- data_y = (y + phase_y) % tile->rep_height;
-
- cw = min (TILE_CACHE_WIDTH - data_x, width);
- ch = min (TILE_CACHE_HEIGHT - data_y, height);
-
- if (id != pmdev->last_bitmap_id)
- {
- if (TILE_CACHE_HEIGHT < TileSizeY || TILE_CACHE_WIDTH < TileSizeX)
- {
- fprintf (stdout, "Unexpected tile size: size.x = %d, size.y = %d.\n",
- TileSizeX, TileSizeY);
- return (0);
- }
-
- for (g = 0; g < TilesY; g++, data = tile->data)
- for (i = 0; i < TileSizeY; i++, data += raster)
- for (j = 0; j < TilesX; j++)
- for (k = 0; k < BytesInTile; k++, TileCache++)
- *(TileCache) = *(data + k);
-
- GpiSetBitmapBits (hpsTile, 0L, TILE_CACHE_HEIGHT, pmdev->TileCache,
- pmdev->pbmiTile);
-
- pmdev->last_bitmap_id = id;
- }
-
- GpiSetColor (hpsWin, color1);
- GpiSetBackColor (hpsWin, color0);
-
- for (cy = 0, h = ch; cy < height; )
- {
- aptl[0].y = y + cy;
- aptl[1].y = y + cy + h;
- aptl[2].y = data_y;
-
- for (cx = 0, w = cw, dx = data_x; cx < width; )
- {
- aptl[0].x = x + cx;
- aptl[1].x = x + cx + w;
- aptl[2].x = dx;
-
- GpiBitBlt (hpsWin, hpsTile, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE);
-
- dx = 0;
- cx += w;
- w = min (width - cx, TILE_CACHE_WIDTH);
- }
- data_y = 0;
- cy += h;
- h = min (height - cy, TILE_CACHE_HEIGHT);
- }
-
- return (0);
- }
-
-
- /* Copy a monochrome bitmap. Color = gx_no_color_index means transparent */
- /* (no effect on the image). */
- int pm_copy_mono (gx_device *dev, const unsigned char *data,
- int data_x, int raster, gx_bitmap_id id,
- int x, int y, int width, int height,
- gx_color_index color0, gx_color_index color1)
- {
- POINTL aptl[4];
- HPS hpsWin;
-
- if (width <= 0 || height <= 0)
- return (0);
-
- pmmproc (copy_mono) (pmmdev, data, data_x, raster, id,
- x, y, width, height, color0, color1);
-
- if (DrawingMode & MODE_DRAW_BITMAP_ONLY)
- return (0);
-
- hpsWin = pmdev->hpsWin;
-
- aptl[0].x = x;
- aptl[0].y = y;
-
- aptl[1].x = x + width - 1;
- aptl[1].y = y + height - 1;
-
- aptl[2].x = x;
- aptl[2].y = y;
-
- aptl[3].x = aptl[1].x + 1;
- aptl[3].y = aptl[1].y + 1;
-
- GpiDrawBits (hpsWin, (PVOID) pmdev->BackingBitmapPtr,
- pmdev->pbmiBackingBitmap, 4L, aptl, ROP_SRCCOPY,
- pmdev->DrawBitsflOptions);
-
- return (0);
- }
-
-
- /* Copy a color image with multiple bits per pixel. Not yet implemented. */
- int pm_copy_color (gx_device *dev, const unsigned char *data,
- int data_x, int raster, gx_bitmap_id id,
- int x, int y, int width, int height)
- {
- int h, bits_shifted, pixels_drawn, bits_offset;
- const BYTE *pdata;
- BYTE clr, bucket;
- POINTL ptl, *aptl;
- HPS hpsMemory;
- LONG *plColor;
-
- if (width <= 0 || height <= 0)
- return (0);
-
- puts ("pm_copy_color called!");
-
- /* Normally not used by GhostScript 2.6.1 */
-
- return (0);
- }
-
-
- /* Draw a minimum-thickness line from (x0,y0) to (x1,y1). */
- int pm_draw_line (gx_device *dev, int x0, int y0, int x1, int y1,
- gx_color_index color)
- {
- POINTL ptl;
- HPS hpsWin;
-
- /* Always return -1 instead of 0 so that GS will use the default */
- /* algorithm to draw lines in the backing bitmap. */
-
- if (x0 == x1 && y0 == y1)
- return (-1);
-
- if (DrawingMode & MODE_DRAW_BITMAP_ONLY)
- return (-1);
-
- hpsWin = pmdev->hpsWin;
-
- GpiSetColor (hpsWin, color);
-
- ptl.x = x0;
- ptl.y = y0;
- GpiMove (hpsWin, &ptl);
-
- ptl.x = x1;
- ptl.y = y1;
- GpiLine (hpsWin, &ptl);
-
- return (-1);
- }
-
- /* In case the process is terminated without calling pm_close, free all */
- /* the resources allocated by the PM driver. This routine is one of */
- /* the functions called by DosExitList. */
- VOID APIENTRY close_pm_driver ()
- {
- gx_device_pm *PMdev;
-
- if (CurrentDev)
- pm_close (CurrentDev);
-
- DosExitList (EXLST_EXIT, NULL);
- }
-
-
- int alloc_backing_bitmap (gx_device *dev)
- {
- gx_device_memory mdev, *mdevp;
- ulong bitmap_size;
- byte *base;
-
- mdevp = gdev_mem_device_for_bits (pmdev->pbmiBackingBitmap->cBitCount);
- if (mdevp == 0)
- fprintf (stdout, "Error determining the appropriate memory device!\n");
- mdev = *mdevp;
- mdev.width = dev->width;
- mdev.height = dev->height;
- mdev.target = (gx_device *) dev;
-
- bitmap_size = gdev_mem_bitmap_size ((gx_device_memory *) &mdev);
- base = (byte *) calloc (bitmap_size / sizeof (long), sizeof (long));
- if (base == NULL)
- fprintf (stdout, "Error allocating backing bitmap memory!\n");
-
- pmdev->mdev = mdev;
- pmdev->mdev.base = base;
- pmdev->BackingBitmapPtr = (byte *) base;
-
- (*pmdev->mdev.procs->open_device)((gx_device *) &pmdev->mdev);
-
- return (0);
- }
-
-
- int repaint_window (int x0, int y0, int x1, int y1,
- int x2, int y2, int x3, int y3)
- {
- POINTL aptl [4];
- HWND hwnd;
- HPS hps, hpsBitmap;
- ULONG ulclr;
- RECTL rcl;
- gx_device *dev;
-
- dev = CurrentDev;
- hwnd = pmdev->hwndClient;
- hps = pmdev->hpsWin;
-
- if (pmdev->BackingBitmapPtr == NULL || x2 < 0 || y2 < 0 ||
- x3 > dev->width || y3 > dev->height)
- {
- rcl.xLeft = x0;
- rcl.yBottom = y0;
-
- rcl.xRight = x1 +1;
- rcl.yTop = y1 + 1;
-
- WinFillRect (hps, &rcl, CLR_WHITE);
- return (0);
- }
-
- aptl[0].x = x0;
- aptl[0].y = y0;
-
- aptl[1].x = x1;
- aptl[1].y = y1;
-
- aptl[2].x = x2;
- aptl[2].y = y2;
-
- aptl[3].x = x3;
- aptl[3].y = y3;
-
- if (DrawingMode & MODE_2_GRAY)
- {
- GpiSetColor (hps, 1);
- GpiSetBackColor (hps, 0);
- }
- else if (pmdev->pbmiBackingBitmap->cBitCount == 4)
- {
- hpsBitmap = pmdev->hpsBackingBitmap;
- GpiSetBitmapBits (hpsBitmap, y2, y3 - y2, pmdev->BackingBitmapPtr +
- pmdev->mdev.raster * y2, pmdev->pbmiBackingBitmap);
-
- if (DrawingMode & MODE_2_GRAY)
- {
- GpiSetColor (hps, 1);
- GpiSetBackColor (hps, 0);
- }
-
- aptl[1].x += 1;
- aptl[1].y += 1;
-
- GpiBitBlt (hps, hpsBitmap, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE);
- return (0);
- }
-
- if (DrawingMode & MODE_256_COLOR)
- WinRealizePalette (hwnd, hps, &ulclr);
-
- GpiDrawBits (hps, (PVOID) pmdev->BackingBitmapPtr,
- pmdev->pbmiBackingBitmap, 4L, aptl, ROP_SRCCOPY,
- pmdev->DrawBitsflOptions);
-
- return (0);
- }
-
-