home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mega Top 1
/
os2_top1.zip
/
os2_top1
/
APPS
/
TEKST
/
GSPMSRC
/
SRC
/
GDEVPM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-20
|
29KB
|
932 lines
/* 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);
}