home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 10 Tools
/
10-Tools.zip
/
gbmos2pm.zip
/
gbmv2
/
bmputils.c
next >
Wrap
C/C++ Source or Header
|
1996-11-16
|
12KB
|
470 lines
/*
bmputils.c - PM Bitmap Utilities
*/
/*...sincludes:0:*/
#define INCL_DOS
#define INCL_WIN
#define INCL_GPI
#define INCL_DEV
#define INCL_SPL
#define INCL_SPLDOSPRINT
#define INCL_BITMAPFILEFORMAT
#include <os2.h>
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <memory.h>
#define _BMPUTILS_
#include "bmputils.h"
/*...vbmputils\46\h:0:*/
/*...e*/
/*...sBmpBlitter \45\ blit one part of one bitmap to part of another:0:*/
BMP_ERR BmpBlitter(
HAB hab,
HBITMAP hbmSrc, RECTL rclSrc,
HBITMAP hbmDst, RECTL rclDst
)
{
HDC hdcSrc, hdcDst;
HPS hpsSrc, hpsDst;
BITMAPINFOHEADER2 bmp;
SIZEL sizl;
POINTL aptl[4];
if ( (hdcSrc = DevOpenDC(hab, OD_MEMORY, "*", 0L, (PDEVOPENDATA) NULL, (HDC) NULL)) == (HDC) NULL )
return BMP_ERR_RES;
bmp.cbFix = sizeof(BITMAPINFOHEADER2);
GpiQueryBitmapInfoHeader(hbmSrc, &bmp);
sizl.cx = bmp.cx; sizl.cy = bmp.cy;
if ( (hpsSrc = GpiCreatePS(hab, hdcSrc, &sizl, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC)) == (HPS) NULL )
{
DevCloseDC(hdcSrc);
return BMP_ERR_RES;
}
if ( (hdcDst = DevOpenDC(hab, OD_MEMORY, "*", 0L, (PDEVOPENDATA) NULL, (HDC) NULL)) == (HDC) NULL )
{
GpiDestroyPS(hpsSrc); DevCloseDC(hdcSrc);
return BMP_ERR_RES;
}
bmp.cbFix = sizeof(BITMAPINFOHEADER2);
GpiQueryBitmapInfoHeader(hbmDst, &bmp);
sizl.cx = bmp.cx; sizl.cy = bmp.cy;
if ( (hpsDst = GpiCreatePS(hab, hdcDst, &sizl, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC)) == (HPS) NULL )
{
DevCloseDC(hdcDst);
GpiDestroyPS(hpsSrc); DevCloseDC(hdcSrc);
return BMP_ERR_RES;
}
GpiSetBitmap(hpsSrc, hbmSrc);
GpiSetBitmap(hpsDst, hbmDst);
aptl[0].x = rclDst.xLeft;
aptl[0].y = rclDst.yBottom;
aptl[1].x = rclDst.xRight;
aptl[1].y = rclDst.yTop;
aptl[2].x = rclSrc.xLeft;
aptl[2].y = rclSrc.yBottom;
aptl[3].x = rclSrc.xRight;
aptl[3].y = rclSrc.yTop;
if ( aptl[1].x - aptl[0].x == aptl[3].x - aptl[2].x &&
aptl[1].y - aptl[0].y == aptl[3].y - aptl[2].y )
GpiBitBlt(hpsDst, hpsSrc, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE);
else
GpiBitBlt(hpsDst, hpsSrc, 4L, aptl, ROP_SRCCOPY, BBO_IGNORE);
GpiSetBitmap(hpsDst, (HBITMAP) NULL); GpiDestroyPS(hpsDst); DevCloseDC(hdcDst);
GpiSetBitmap(hpsSrc, (HBITMAP) NULL); GpiDestroyPS(hpsSrc); DevCloseDC(hdcSrc);
return BMP_ERR_OK;
}
/*...e*/
/*...sBmpCopySubrectangle \45\ make a new bitmap from a bit of the first:0:*/
BMP_ERR BmpCopySubrectangle(HAB hab, HBITMAP hbmSrc, RECTL rclSrc, HBITMAP *phbmDst)
{
BITMAPINFOHEADER2 bmp;
HBITMAP hbmDst;
RECTL rclDst;
SIZEL sizl;
USHORT rc;
HDC hdc;
HPS hps;
bmp.cbFix = sizeof(BITMAPINFOHEADER2);
GpiQueryBitmapInfoHeader(hbmSrc, &bmp);
bmp.cx = (USHORT) (rclSrc.xRight - rclSrc.xLeft);
bmp.cy = (USHORT) (rclSrc.yTop - rclSrc.yBottom);
if ( (hdc = DevOpenDC(hab, OD_MEMORY, "*", 0L, (PDEVOPENDATA) NULL, (HDC) NULL)) == (HDC) NULL )
return BMP_ERR_RES;
sizl.cx = bmp.cx; sizl.cy = bmp.cy;
if ( (hps = GpiCreatePS(hab, hdc, &sizl, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC)) == (HPS) NULL )
{
DevCloseDC(hdc);
return BMP_ERR_RES;
}
if ( (hbmDst = GpiCreateBitmap(hps, &bmp, 0L, NULL, NULL)) == (HBITMAP) NULL )
{
GpiDestroyPS(hps);
DevCloseDC(hdc);
return BMP_ERR_MEM;
}
GpiDestroyPS(hps);
DevCloseDC(hdc);
rclDst.xLeft = 0; rclDst.xRight = bmp.cx;
rclDst.yBottom = 0; rclDst.yTop = bmp.cy;
if ( (rc = BmpBlitter(hab, hbmSrc, rclSrc, hbmDst, rclDst)) != BMP_ERR_OK )
{
GpiDeleteBitmap(hbmDst);
return rc;
}
*phbmDst = hbmDst;
return BMP_ERR_OK;
}
/*...e*/
/*...sBmpCopy \45\ make a new bitmap from all of the first:0:*/
BMP_ERR BmpCopy(HAB hab, HBITMAP hbmSrc, HBITMAP *phbmDst)
{
BITMAPINFOHEADER2 bmp;
RECTL rclSrc;
bmp.cbFix = sizeof(BITMAPINFOHEADER2);
GpiQueryBitmapInfoHeader(hbmSrc, &bmp);
rclSrc.xLeft = 0; rclSrc.xRight = bmp.cx;
rclSrc.yBottom = 0; rclSrc.yTop = bmp.cy;
return BmpCopySubrectangle(hab, hbmSrc, rclSrc, phbmDst);
}
/*...e*/
/*...sBmpPrint \45\ print a bitmap:0:*/
/*...sEnquireQueueDetails:0:*/
static BOOL EnquireQueueDetails(
CHAR *szQueue,
CHAR *szLogAddress,
CHAR *szDriverName,
CHAR *szNameWPS,
DRIVDATA **ppdriv
)
{
ULONG cb; PRQINFO3 *ppq3;
SplQueryQueue(NULL, szQueue, 3, NULL, 0, &cb);
if ( cb < sizeof(PRQINFO3) )
return FALSE;
if ( (ppq3 = (PRQINFO3 *) malloc(cb)) == (PRQINFO3 *) NULL )
return FALSE;
SplQueryQueue(NULL, szQueue, 3, ppq3, cb, &cb);
strcpy(szNameWPS, ppq3 -> pszComment);
strcpy(szLogAddress, szQueue);
sscanf(ppq3 -> pszDriverName, "%[^.,;]", szDriverName);
*ppdriv = ppq3 -> pDriverData;
free(ppq3);
return TRUE;
}
/*...e*/
/*...sPrinterInfo:0:*/
static BOOL PrinterInfo(HPS hpsPrinter, const CHAR *szNameWPS)
{
HDC hdcPrinter = GpiQueryDevice(hpsPrinter);
LONG lBitCount, lPlanes, lColors, lPhysColors;
SIZEL sizlPrinter;
CHAR sz[100+1];
GpiQueryPS(hpsPrinter, &sizlPrinter);
DevQueryCaps(hdcPrinter, CAPS_COLOR_BITCOUNT, 1L, &lBitCount );
DevQueryCaps(hdcPrinter, CAPS_COLOR_PLANES , 1L, &lPlanes );
DevQueryCaps(hdcPrinter, CAPS_COLORS , 1L, &lColors );
DevQueryCaps(hdcPrinter, CAPS_PHYS_COLORS , 1L, &lPhysColors);
sprintf(sz, "%s: %ldx%ld, %ld bits, %ld planes, %ld colors, %ld physical colors?",
szNameWPS, sizlPrinter.cx, sizlPrinter.cy, lBitCount, lPlanes, lColors, lPhysColors);
return WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, sz, "GbmV2 - Confirm Printer", 0, MB_OKCANCEL | MB_QUERY | MB_MOVEABLE) == MBID_OK;
}
/*...e*/
/*...sTransferBitmapData:0:*/
/*
Put the largest possible copy of the bitmap onto the printer presentation
space. Preserve aspect ratio and correct for printer aspect ratio.
*/
/*...sMonoPrint:0:*/
static BOOL MonoPrint(HPS hpsPrinter)
{
HDC hdcPrinter = GpiQueryDevice(hpsPrinter);
LONG lBitCount, lPlanes;
DevQueryCaps(hdcPrinter, CAPS_COLOR_BITCOUNT, 1L, &lBitCount);
DevQueryCaps(hdcPrinter, CAPS_COLOR_PLANES , 1L, &lPlanes );
return lBitCount == 1 && lPlanes == 1;
}
/*...e*/
static BMP_ERR TransferBitmapData(
HAB hab,
HBITMAP hbm, LONG lColorFg, LONG lColorBg,
HDC hdcPrinter, HPS hpsPrinter
)
{
SIZEL sizlMemory, sizlPrinter, sizlImage;
SIZEL sizlMmPrinter, sizlMmImage; /* Sizes in mm */
HDC hdcMemory;
HPS hpsMemory;
POINTL aptl[4];
BITMAPINFOHEADER2 bmp;
LONG xRes, yRes, xCentre, yCentre;
/* Query printer size */
GpiQueryPS(hpsPrinter, &sizlPrinter);
/* Query bitmap size */
bmp.cbFix = sizeof(BITMAPINFOHEADER2);
GpiQueryBitmapInfoHeader(hbm, &bmp);
sizlMemory.cx = (LONG) bmp.cx;
sizlMemory.cy = (LONG) bmp.cy;
/* Make a memory device context for the bitmap */
if ( (hdcMemory = DevOpenDC(hab, OD_MEMORY, "*", 0L, NULL, hdcPrinter)) == (HPS) NULL )
return BMP_ERR_RES;
if ( (hpsMemory = GpiCreatePS(hab, hdcMemory, &sizlMemory, PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC)) == (HPS) NULL )
{
DevCloseDC(hdcMemory);
return BMP_ERR_RES;
}
GpiSetBitmap(hpsMemory, hbm);
/* Set colours ready for blitting into printer ps */
if ( bmp.cBitCount == 1 )
{
GpiSetBackColor(hpsPrinter, GpiQueryColorIndex(hpsPrinter, 0, lColorBg));
GpiSetColor (hpsPrinter, GpiQueryColorIndex(hpsPrinter, 0, lColorFg));
}
/*...sscale to fit page:8:*/
/* Query printer aspect ratio */
DevQueryCaps(hdcPrinter, CAPS_HORIZONTAL_RESOLUTION, 1L, &xRes);
DevQueryCaps(hdcPrinter, CAPS_VERTICAL_RESOLUTION , 1L, &yRes);
/* Get size of page in mm */
sizlMmPrinter.cx = (1000L * sizlPrinter.cx) / xRes;
sizlMmPrinter.cy = (1000L * sizlPrinter.cy) / yRes;
/* Get largest image size in mm */
if ( sizlMemory.cx * sizlMmPrinter.cy > sizlMemory.cy * sizlMmPrinter.cx )
/* Stretch to fill width */
{
sizlMmImage.cx = sizlMmPrinter.cx;
sizlMmImage.cy = (sizlMmImage.cx * sizlMemory.cy) / sizlMemory.cx;
}
else
/* Stretch to fill height */
{
sizlMmImage.cy = sizlMmPrinter.cy;
sizlMmImage.cx = (sizlMmImage.cy * sizlMemory.cx) / sizlMemory.cy;
}
sizlImage.cx = (xRes * sizlMmImage.cx) / 1000L;
sizlImage.cy = (yRes * sizlMmImage.cy) / 1000L;
xCentre = ((sizlPrinter.cx - sizlImage.cx) >> 1);
yCentre = ((sizlPrinter.cy - sizlImage.cy) >> 1);
aptl[0].x = xCentre;
aptl[0].y = yCentre;
aptl[1].x = xCentre + sizlImage.cx;
aptl[1].y = yCentre + sizlImage.cy;
aptl[2].x = 0;
aptl[2].y = 0;
aptl[3].x = sizlMemory.cx;
aptl[3].y = sizlMemory.cy;
GpiBitBlt(hpsPrinter, hpsMemory, 4L, aptl, ROP_SRCCOPY,
MonoPrint(hpsPrinter) ? BBO_AND : BBO_IGNORE);
/*...e*/
#if 0
/*...sposition in the middle if room:8:*/
if ( sizlMemory.cx < sizlPrinter.cx &&
sizlMemory.cy < sizlPrinter.cy )
{
xCentre = ((sizlPrinter.cx - sizlMemory.cx) >> 1);
yCentre = ((sizlPrinter.cy - sizlMemory.cy) >> 1);
aptl[0].x = xCentre;
aptl[0].y = yCentre;
aptl[1].x = xCentre + sizlMemory.cx;
aptl[1].y = yCentre + sizlMemory.cy;
aptl[2].x = 0;
aptl[2].y = 0;
GpiBitBlt(hpsPrinter, hpsMemory, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE);
}
/*...e*/
#endif
GpiSetBitmap(hpsMemory, (HBITMAP) NULL);
GpiDestroyPS(hpsMemory);
DevCloseDC(hdcMemory);
return BMP_ERR_OK;
}
/*...e*/
BMP_ERR BmpPrint(
HAB hab,
HBITMAP hbm, LONG lColorFg, LONG lColorBg,
const CHAR *szDocName,
const CHAR *szComment,
CHAR *szQueueToUse
)
{
static SIZEL sizl = { 0, 0 };
HDC hdcPrinter;
HPS hpsPrinter;
CHAR szLogAddress[256];
CHAR szDriverName[256];
CHAR szNameWPS[256];
DEVOPENSTRUC dop;
USHORT cb, usJobId;
CHAR szQueue[256];
BMP_ERR rc;
LONG lOutCount;
BOOL fQueried = FALSE;
/* Set defaults, in case can't query information about printer */
dop.pszLogAddress = szLogAddress;
dop.pszDriverName = szDriverName;
dop.pdriv = NULL;
dop.pszDataType = "PM_Q_STD";
dop.pszComment = (PSZ) szComment;
dop.pszQueueProcName = NULL;
dop.pszQueueProcParams = NULL;
dop.pszSpoolerParams = NULL;
dop.pszNetworkParams = NULL;
if ( szQueueToUse != NULL )
/* Use the queue we have been told to use */
fQueried = EnquireQueueDetails(szQueueToUse, szLogAddress, szDriverName, szNameWPS, &dop.pdriv);
else if ( (cb = (USHORT) PrfQueryProfileString(HINI_PROFILE, "PM_SPOOLER",
"QUEUE", NULL, szQueue, (LONG) sizeof(szQueue))) > 0 )
/* Use application default queue */
{
szQueue[cb - 2] = '\0'; /* Remove semicolon at end */
fQueried = EnquireQueueDetails(szQueue, szLogAddress, szDriverName, szNameWPS, &dop.pdriv);
}
if ( !fQueried )
return BMP_ERR_QUERY;
/* Try to create printer device context */
if ( (hdcPrinter = DevOpenDC(hab, OD_QUEUED, "*", 5L, (PDEVOPENDATA) &dop, (HDC) NULL)) == (HDC) NULL )
/* Failed to open printer device context */
return BMP_ERR_PRINTER;
/* Create a presentation space of default size (size of page) */
if ( (hpsPrinter = GpiCreatePS(hab, hdcPrinter, &sizl, PU_PELS | GPIF_DEFAULT | GPIA_ASSOC)) == (HPS) NULL )
/* Could not make presentation space */
{
DevCloseDC(hdcPrinter);
return BMP_ERR_PRINTER;
}
/* Tell user about printer, and give chance to abort job */
if ( !PrinterInfo(hpsPrinter, szNameWPS) )
{
GpiAssociate(hpsPrinter, (HDC) NULL);
GpiDestroyPS(hpsPrinter);
DevCloseDC(hdcPrinter);
return BMP_ERR_OK;
}
/* Indicate a new print job is starting */
if ( !DevEscape(hdcPrinter, DEVESC_STARTDOC, (LONG) strlen(szDocName),
(BYTE *) szDocName, &lOutCount, (BYTE *) NULL) )
{
GpiAssociate(hpsPrinter, (HDC) NULL);
GpiDestroyPS(hpsPrinter);
DevCloseDC(hdcPrinter);
return BMP_ERR_PRINT;
}
GpiErase(hpsPrinter); /* Blank the page to CLR_BACKGROUND */
if ( (rc = TransferBitmapData(hab, hbm, lColorFg, lColorBg, hdcPrinter, hpsPrinter)) != BMP_ERR_OK )
{
DevEscape(hdcPrinter, DEVESC_ABORTDOC, 0L, NULL, 0L, NULL);
GpiAssociate(hpsPrinter, (HDC) NULL);
GpiDestroyPS(hpsPrinter);
DevCloseDC(hdcPrinter);
return rc;
}
/* Indicate the job is done */
if ( !DevEscape(hdcPrinter, DEVESC_ENDDOC, 0L, (BYTE *) NULL, &lOutCount, (BYTE *) &usJobId) )
{
GpiAssociate(hpsPrinter, (HDC) NULL);
GpiDestroyPS(hpsPrinter);
DevCloseDC(hdcPrinter);
return BMP_ERR_PRINT;
}
GpiAssociate(hpsPrinter, (HDC) NULL);
GpiDestroyPS(hpsPrinter);
DevCloseDC(hdcPrinter);
return BMP_ERR_OK;
}
/*...e*/
/*...sBmpErrorMessage \45\ get error message from error return code:0:*/
CHAR *BmpErrorMessage(BMP_ERR rc, CHAR *sz)
{
static CHAR *aszBitmapErrors[] =
{
"",
"out of memory",
"out of resources",
"can't query printer/queue details",
"can't locate printer/queue",
"error sending data to printer/queue",
};
return strcpy(sz, aszBitmapErrors[rc]);
}
/*...e*/