Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1062 lines
37 KiB

/****************************Module*Header******************************\
* Copyright (c) 1987 - 1991 Microsoft Corporation *
\***********************************************************************/
/********************************************************
* *
* file: PrintImg.c *
* system: Publisher's Paintbrush for MS-Windows *
* descr: prints image from image buffer *
* date: 06/27/87 MSZ *
* *
********************************************************/
// #define DEBUG
#define STATIC static
#include <windows.h>
#include <port1632.h>
//#define NOEXTERN
#include "pbrush.h"
//#include "fixedpt.h"
extern TCHAR pgmTitle[];
extern TCHAR fileName[];
extern TCHAR noFile[];
extern TCHAR winIniAppName[];
extern HPALETTE hPalette;
extern HWND pbrushWnd[];
extern int imagePlanes, imagePixels;
#define SETDIBSCALING 32
#define SET_BOUNDS 4109
#define BUFSIZE 140
#define MEMFACTORNUM 1
#define MEMFACTORDEN 6
#define MEMMAX 63000
#define NOSTART 10
#define NOMESG 20
#define STARTOK 30
#define INITOK 40
#define BiToByAl(bi,al) (((bi)+(al)*8-1)/((al)*8)*(al))
#define PollPrint() (*lpfnAbortPrt)((HDC)NULL, 0)
/*------------------------------------------------*/
/* nSizeFactor is available for setting the size */
/* of the printed image. It is the percent of */
/* scaling and can be set from another module. */
/*------------------------------------------------*/
int nSizeNum = 100, nSizeDen = 100;
HWND hDlgPrint = NULL;
BOOL bUserAbort;
extern int hResPrt, vResPrt; /* HORZRES, VERTRES */
extern int xPelsPrt, yPelsPrt; /* LOGPIXELSX, LOGPIXELSY */
extern TCHAR szHeader[], szFooter[]; /* Header/Footer strings */
extern BOOL fStretch;
STATIC BOOL bError;
STATIC BOOL fDIBScaling;
STATIC WNDPROC lpfnAbortDlg;
STATIC ABORTPROC lpfnAbortPrt;
STATIC long xLogPrint, yLogPrint, xLogImage, yLogImage; /* stretching factors */
STATIC POINT sFactor;
STATIC RECT rImage;
STATIC unsigned int nBitsPix, nScanLines;
STATIC unsigned long dwBitmapSize;
STATIC HDC hMemDC;
STATIC HANDLE hDIBInfo;
STATIC HPALETTE hPrtPalette, hMemPalette;
STATIC int CharPrintHeight;
STATIC unsigned long lIncArea, lTotArea;
STATIC int nPage, nPages;
STATIC int xImage, yImage;
STATIC LPTSTR szDay[] = { TEXT("Sun"), TEXT("Mon"), TEXT("Tue"), TEXT("Wed"), TEXT("Thu"), TEXT("Fri"), TEXT("Sat") };
STATIC LPTSTR szMonth[] = { TEXT(""), TEXT("Jan"), TEXT("Feb"), TEXT("Mar"), TEXT("Apr"), TEXT("May"), TEXT("Jun"),
TEXT("Jul"), TEXT("Aug"), TEXT("Sep"), TEXT("Oct"), TEXT("Nov"), TEXT("Dec") };
typedef struct tagDIBSCALE {
short ScaleMode;
short dx;
short dy;
} DIBSCALE;
DWORD TotalMemoryAvailable(void);
/*------------------------------------------------*/
/* Try to set the number of copies and the print */
/* quality; return the number of copies */
/*------------------------------------------------*/
STATIC int NEAR PASCAL SetPrintOptions(HDC hPrtDC, BOOL fDraft, int copies)
{
LONG lHolder, lParam;
/*------------------------------------------------*/
/* Tell the driver how many copies we want */
/*------------------------------------------------*/
lHolder = SETCOPYCOUNT;
if (Escape(hPrtDC, QUERYESCSUPPORT, sizeof(lHolder), (LPSTR) &lHolder, NULL)) {
Escape(hPrtDC, SETCOPYCOUNT, sizeof(copies), (LPSTR) &copies, (LPVOID) &copies);
} else {
copies = 1;
}
/*------------------------------------------------*/
/* Set the print quality if the driver allows */
/*------------------------------------------------*/
lHolder = DRAFTMODE;
lParam = fDraft ? 1 : 0;
if(Escape(hPrtDC, QUERYESCSUPPORT, sizeof(lHolder), (LPSTR) &lHolder, NULL))
Escape(hPrtDC, DRAFTMODE, sizeof(lParam), (LPSTR) &lParam, NULL);
/*------------------------------------------------*/
/* Return the # of copies that will actually be */
/* printed */
/*------------------------------------------------*/
return copies;
}
/*------------------------------------------------*/
/* Given a file name which may or may not include */
/* a path specification, return a pointer to the */
/* file name without the path */
/*------------------------------------------------*/
LPTSTR PFileInPath(LPTSTR sz)
{
LPTSTR pch;
/*------------------------------------------------*/
/* Strip path/drive specification from file name */
/*------------------------------------------------*/
pch = CharPrev(sz, sz + lstrlen(sz));
while (pch > sz) {
pch = CharPrev(sz,pch);
if (*pch == TEXT('\\') || *pch == TEXT(':')) {
pch = CharNext(pch);
break;
}
}
return(pch);
}
/*------------------------------------------------*/
/* Transform a rect in the image to a rect on the */
/* printer. */
/*------------------------------------------------*/
STATIC void NEAR PASCAL ImageToPrint(NPRECT nprDest, NPRECT nprImage, NPRECT nprPrint)
{
nprDest->left = (int)(nprPrint->left +
(nprDest->left - nprImage->left)* xLogPrint/xLogImage);
nprDest->top = (int)(nprPrint->top +
(nprDest->top - nprImage->top) * yLogPrint/yLogImage);
nprDest->right = (int)(nprPrint->left +
(nprDest->right - nprImage->left)* xLogPrint/xLogImage);
nprDest->bottom = (int)(nprPrint->top +
(nprDest->bottom - nprImage->top) * yLogPrint/yLogImage);
}
/*------------------------------------------------*/
/* Transform a rect on the printer to a rect in */
/* the image. */
/*------------------------------------------------*/
STATIC void NEAR PASCAL PrintToImage(NPRECT nprDest, NPRECT nprImage, NPRECT nprPrint)
{
nprDest->left = (int)(nprImage->left +
(nprDest->left - nprPrint->left)*xLogImage/xLogPrint);
nprDest->top = (int)(nprImage->top +
(nprDest->top - nprPrint->top )*yLogImage/yLogPrint);
nprDest->right = (int)(nprImage->left +
((nprDest->right - nprPrint->left)*xLogImage+xLogPrint-1)/xLogPrint);
nprDest->bottom = (int)(nprImage->top +
((nprDest->bottom - nprPrint->top )*yLogImage+yLogPrint-1)/yLogPrint);
}
/*------------------------------------------------*/
/* Initialize variables for printing */
/*------------------------------------------------*/
STATIC BOOL NEAR PASCAL InitPrinting(HDC hPrintDC, NPRECT nprImage,
NPRECT nprPrint, LPTSTR npFileName)
{
HDC hImageDC;
RECT rPrint;
TEXTMETRIC Metrics;
TCHAR msg[BUFSIZE], buf[BUFSIZE];
LPBITMAPINFO lpDIBInfo;
WORD nPaletteSize;
HANDLE hLogPalette;
LPLOGPALETTE lpLogPalette;
int holder;
int retVal;
DOCINFO DocInfo;
/*------------------------------------------------*/
/* Set memory to NULL and print flags */
/*------------------------------------------------*/
hMemDC = NULL;
hPrtPalette = hMemPalette = NULL;
hDIBInfo = NULL;
bError = bUserAbort = FALSE;
/*------------------------------------------------*/
/* Get a DC for the image and a memory DC */
/*------------------------------------------------*/
if(!(hImageDC = GetDisplayDC(pbrushWnd[PARENTid])))
return(NOSTART);
if(!(hMemDC = CreateCompatibleDC(hImageDC))) {
ReleaseDC(pbrushWnd[PARENTid], hImageDC);
return(NOSTART);
}
/*------------------------------------------------*/
/* These are the scaling factors used in */
/* PrintToImage and ImageToPrint */
/* nSizeNum and nSizeDen may be used to scale the */
/* image on the printer */
/*------------------------------------------------*/
if(Escape(hPrintDC, GETSCALINGFACTOR, 0, NULL, (LPVOID)&sFactor) <= 0)
sFactor.x = sFactor.y = 0;
sFactor.x = 1 << sFactor.x;
sFactor.y = 1 << sFactor.y;
if (fStretch) {
xLogPrint = (long)nSizeNum * xPelsPrt;
yLogPrint = (long)nSizeNum * yPelsPrt;
xLogImage = (long)nSizeDen * GetDeviceCaps(hImageDC, LOGPIXELSX);
yLogImage = (long)nSizeDen * GetDeviceCaps(hImageDC, LOGPIXELSY);
} else {
xLogPrint = nSizeNum * sFactor.x;
yLogPrint = nSizeNum * sFactor.y;
xLogImage = nSizeDen;
yLogImage = nSizeDen;
}
ReleaseDC(pbrushWnd[PARENTid], hImageDC);
/*------------------------------------------------*/
/* Compute the rect of the image that will */
/* actually be printed, the printing rectangle, */
/* and set the variables for calculating the */
/* percentage that has been printed */
/*------------------------------------------------*/
rImage = *nprPrint;
PrintToImage(&rImage, nprImage, nprPrint);
IntersectRect(&rImage, &rImage, nprImage);
xImage = rImage.right - rImage.left;
yImage = rImage.bottom - rImage.top;
nPages = (nprImage->right - nprImage->left + xImage - 1)/xImage;
nPages *= (nprImage->bottom - nprImage->top + yImage - 1)/yImage;
rPrint = *nprImage;
ImageToPrint(&rPrint, nprImage, nprPrint);
lIncArea = 0;
lTotArea = (long)(rPrint.right - rPrint.left)*(rPrint.bottom - rPrint.top);
IntersectRect(&rPrint, &rPrint, nprPrint);
/*------------------------------------------------*/
/* Make string to send to spooler, set the abort */
/* procedure, set the bounding rectangle of the */
/* printed image, and start printing the document */
/*------------------------------------------------*/
LoadString(hInst, IDSPrintSpool, buf, CharSizeOf(buf));
wsprintf(msg, buf, winIniAppName, npFileName);
if(SetAbortProc(hPrintDC, lpfnAbortPrt) == SP_ERROR)
return(NOSTART);
holder = SET_BOUNDS;
if(Escape(hPrintDC, QUERYESCSUPPORT, sizeof(holder), (LPSTR) &holder, NULL))
Escape(hPrintDC, SET_BOUNDS, sizeof(rPrint), (LPSTR)&rPrint, NULL);
DocInfo.cbSize = sizeof (DOCINFO);
DocInfo.lpszDocName = msg;
DocInfo.lpszOutput = NULL;
DocInfo.lpszDatatype = NULL;
DocInfo.fwType = 0;
if ((retVal = StartDoc(hPrintDC, &DocInfo)) <= 0)
{
if(!bUserAbort)
return(NOSTART);
else
return(NOMESG);
}
/*------------------------------------------------*/
/* Get printer font height */
/*------------------------------------------------*/
if (GetTextMetrics(hPrintDC, (LPTEXTMETRIC)(&Metrics)))
CharPrintHeight = Metrics.tmHeight + Metrics.tmExternalLeading;
else
CharPrintHeight = 12;
/*------------------------------------------------*/
/* Create two copies of the */
/* palette and select them into hMemDC and */
/* hPrintDC */
/*------------------------------------------------*/
if (hPalette) {
if(!GetObject(hPalette, sizeof(nPaletteSize), (LPVOID)&nPaletteSize)
|| !(hLogPalette = GlobalAlloc(GMEM_MOVEABLE,
(long)(sizeof(LOGPALETTE)+(nPaletteSize-1)*sizeof(PALETTEENTRY)))))
return(STARTOK);
if(!(lpLogPalette = (LPLOGPALETTE)GlobalLock(hLogPalette)))
goto NoLock;
lpLogPalette->palVersion = 0x0300;
lpLogPalette->palNumEntries = (WORD)nPaletteSize;
if(!GetPaletteEntries(hPalette, 0, nPaletteSize,
lpLogPalette->palPalEntry))
goto NoEntries;
hPrtPalette = CreatePalette(lpLogPalette);
hMemPalette = CreatePalette(lpLogPalette);
NoEntries:
GlobalUnlock(hLogPalette);
NoLock:
GlobalFree(hLogPalette);
if(!hPrtPalette || !hMemPalette
|| !SelectPalette(hPrintDC, hPrtPalette, FALSE)
|| !SelectPalette(hMemDC, hMemPalette, FALSE))
return(STARTOK);
}
nBitsPix = fDIBScaling ? imagePixels * (imagePlanes==3 ? 4 : imagePlanes):8;
/*------------------------------------------------*/
/* Set up memory for the DIB */
/*------------------------------------------------*/
if(!(hDIBInfo = GlobalAlloc(GMEM_MOVEABLE, sizeof(BITMAPINFO) +
(long)((1<<nBitsPix) - 1) * sizeof(RGBQUAD)))
|| !(lpDIBInfo = (LPBITMAPINFO)GlobalLock(hDIBInfo)))
return(STARTOK);
lpDIBInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
lpDIBInfo->bmiHeader.biWidth = 1;
lpDIBInfo->bmiHeader.biHeight = 1;
lpDIBInfo->bmiHeader.biPlanes = 1;
lpDIBInfo->bmiHeader.biBitCount = (WORD)nBitsPix;
lpDIBInfo->bmiHeader.biCompression = BI_RGB;
lpDIBInfo->bmiHeader.biSizeImage = 0;
lpDIBInfo->bmiHeader.biXPelsPerMeter = 0;
lpDIBInfo->bmiHeader.biYPelsPerMeter = 0;
lpDIBInfo->bmiHeader.biClrUsed = 0;
lpDIBInfo->bmiHeader.biClrImportant = 0;
GlobalUnlock(hDIBInfo);
LoadString(hInst, IDSPrintPercent, buf, CharSizeOf(buf));
wsprintf(msg, buf, 1, nPages, 0);
SetDlgItemText(hDlgPrint, IDPERCENT, msg);
return(INITOK);
}
/*------------------------------------------------*/
/* Main function for printing a band on the */
/* printer */
/*------------------------------------------------*/
STATIC void NEAR PASCAL PrintBand (HDC hPrintDC,
NPRECT nprBandPrint, NPRECT nprImage, NPRECT nprPrint)
{
int top;
int xIntImage, yIntImage, xIntPrint, yIntPrint;
RECT rBandImage, rBandPrint;
RECT rIntPrint, rIntImage;
HANDLE hDIBitmap;
LPBYTE lpDIBitmap;
LPBITMAPINFO lpDIBInfo;
HBITMAP hBitmap, hOldBitmap;
TCHAR szPercent[BUFSIZE], buf[BUFSIZE];
unsigned int yMax;
unsigned int xBitmap, yBitmap;
int LowMem = -1;
HBRUSH hBrush[256], hOldBrush;
WORD crColor, nextColor;
int i, j, dstI, endI, dstJ, dstWid, dstHgt;
BYTE far *hpDIBitmap;
/*------------------------------------------------*/
/* Find the rect of the band on the image and */
/* return if nothing to print in this band */
/*------------------------------------------------*/
rBandImage = *nprBandPrint;
PrintToImage(&rBandImage, nprImage, nprPrint);
if(!IntersectRect(&rBandImage, &rBandImage, nprImage))
return;
/*------------------------------------------------*/
/* Find the inverse rect of the band on the image */
/* and check if the current bitmap is large enough*/
/* for our purposes; xBitmap and yBitmap are the */
/* dimensions of the bitmap, and are only allowed */
/* to increase, except the total memory has a cap */
/* of dwBitmapSize */
/*------------------------------------------------*/
rBandPrint = rBandImage;
ImageToPrint(&rBandPrint, nprImage, nprPrint);
if(IsRectEmpty(&rBandPrint))
return;
/* For now, we are always going to create a new bitmap
that is exactly the right width */
xBitmap = rBandImage.right - rBandImage.left;
bError = TRUE; /* this will be set to FALSE if we print OK */
TryAgain:
++LowMem;
/*------------------------------------------------*/
/* Use MEMFACTOR*available memory or MEMMAX bytes */
/* for a bitmap that is compatible with the image */
/*------------------------------------------------*/
dwBitmapSize = ((DWORD)TotalMemoryAvailable() * MEMFACTORNUM / MEMFACTORDEN);
if(dwBitmapSize > MEMMAX)
dwBitmapSize = MEMMAX;
yMax = (int)((dwBitmapSize*8)/(xBitmap*nBitsPix));
yBitmap = rBandImage.bottom - rBandImage.top;
if(yBitmap > yMax)
yBitmap = yMax;
yBitmap >>= LowMem;
/*------------------------------------------------*/
/* Create a new bitmap, a new DIB, and */
/* recompute nScanLines (the number of image scan */
/* lines we may print at a time) */
/*------------------------------------------------*/
nScanLines = yBitmap;
if(!nScanLines)
return;
if(!(hBitmap = CreateBitmap(xBitmap, yBitmap,
(UINT)imagePlanes, (UINT)imagePixels, NULL))) {
DB_OUTF((acDbgBfr, TEXT("LowMem = %d; CreateBitmap\n\r"), LowMem));
goto Error1;
}
if(!(hOldBitmap = SelectObject(hMemDC, hBitmap))) {
DB_OUTF((acDbgBfr, TEXT("LowMem = %d; SelectObject1\n\r"), LowMem));
goto Error2;
}
if(!(hDIBitmap = GlobalAlloc(GMEM_MOVEABLE,
yBitmap * BiToByAl((long)nBitsPix * xBitmap, 4)))) {
DB_OUTF((acDbgBfr, TEXT("LowMem = %d; GlobalAlloc\n\r"), LowMem));
goto Error3;
}
/*------------------------------------------------*/
/* Repeat with successive hBitmap sized memory */
/* bands; we use PollPrint to get messages */
/*------------------------------------------------*/
for(top = rBandImage.top;
top < rBandImage.bottom && !bUserAbort;
top += nScanLines) {
bError = TRUE;
PollPrint();
/*------------------------------------------------*/
/* Start with an hBitmap sized rect, then */
/* intersect with the printer band and the image */
/* and continue if nothing to print */
/*------------------------------------------------*/
rIntImage.left = nprImage->left;
rIntImage.top = top;
rIntImage.right = nprImage->right;
rIntImage.bottom = top + nScanLines;
IntersectRect(&rIntImage, &rIntImage, nprImage);
if(!IntersectRect(&rIntImage, &rIntImage, &rBandImage)) {
continue ;
}
PollPrint();
/*------------------------------------------------*/
/* Transform to a printer rect, get the dimensions*/
/* of the image and printer rects, and page into */
/* memory */
/*------------------------------------------------*/
rIntPrint = rIntImage;
ImageToPrint(&rIntPrint, nprImage, nprPrint);
if(IsRectEmpty(&rIntPrint))
continue;
xIntPrint = rIntPrint.right - rIntPrint.left;
yIntPrint = rIntPrint.bottom - rIntPrint.top;
xIntImage = rIntImage.right - rIntImage.left;
yIntImage = rIntImage.bottom - rIntImage.top;
if(hPalette)
RealizePalette(hMemDC);
if(!(SelectObject(hMemDC, hBitmap))) {
DB_OUTF((acDbgBfr, TEXT("LowMem = %d; SelectObject2\n\r"), LowMem));
goto Error4;
}
if(!(BitBlt(hMemDC, 0, 0, xIntImage, yIntImage,
hdcWork, rIntImage.left, rIntImage.top, SRCCOPY))) {
DB_OUTF((acDbgBfr, TEXT("LowMem = %d; BitBlt\n\r"), LowMem));
goto Error4;
}
PollPrint();
SelectObject(hMemDC, hOldBitmap);
/*------------------------------------------------*/
/* Lock the DIB memory for use */
/*------------------------------------------------*/
if(!(lpDIBitmap = GlobalLock(hDIBitmap)))
goto Error4;
if(!(lpDIBInfo = (LPBITMAPINFO)GlobalLock(hDIBInfo)))
goto Error5;
/*------------------------------------------------*/
/* Set the size of the DIB to xBitmap,yIntImage */
/*------------------------------------------------*/
lpDIBInfo->bmiHeader.biWidth = xBitmap;
lpDIBInfo->bmiHeader.biHeight = yIntImage;
/*------------------------------------------------*/
/* Transform a bitmap to a DIB */
/*------------------------------------------------*/
if(!(GetDIBits(hMemDC, hBitmap, 0, yIntImage,
lpDIBitmap, lpDIBInfo, DIB_RGB_COLORS)))
goto Error6;
PollPrint();
/*------------------------------------------------*/
/* Send the portion of the image to the printer */
/*------------------------------------------------*/
if(hPalette)
RealizePalette(hPrintDC);
if(fDIBScaling) {
if(!StretchDIBits(hPrintDC, rIntPrint.left, rIntPrint.top,
xIntPrint, yIntPrint, 0, 0, xIntImage, yIntImage,
lpDIBitmap, lpDIBInfo, DIB_RGB_COLORS, SRCCOPY))
goto Error6;
bError = FALSE;
} else {
if(!(hOldBrush = SelectObject(hPrintDC, GetStockObject(WHITE_BRUSH))))
goto Error6;
SelectObject(hPrintDC, hOldBrush);
for(j=0; j<256; ++j)
hBrush[j] = NULL;
for(j=0, dstJ=0; j<yIntImage && !bUserAbort; ++j, dstJ+=dstHgt) {
PollPrint();
if(!(dstHgt = (WORD)(((DWORD)(j+1)*yIntPrint + yIntImage/2)
/yIntImage - dstJ)))
continue;
hpDIBitmap = lpDIBitmap + BiToByAl(xBitmap*8, 4)*(yIntImage-j-1);
nextColor = (WORD)*hpDIBitmap;
for(i=0, dstI=0; i<xIntImage; i=endI, dstI+=dstWid) {
crColor = nextColor;
if(!hBrush[crColor]) {
nextColor = 0;
while(!(hBrush[crColor] = CreateSolidBrush(
RGB(lpDIBInfo->bmiColors[crColor].rgbRed,
lpDIBInfo->bmiColors[crColor].rgbGreen,
lpDIBInfo->bmiColors[crColor].rgbBlue)))) {
for( ; nextColor<256 && !hBrush[nextColor];
++nextColor) ;
if(nextColor == 256)
goto Error7;
DeleteObject(hBrush[nextColor]);
hBrush[nextColor] = NULL;
}
}
for(endI=i+1; endI<xIntImage; ++endI) {
++hpDIBitmap;
if((nextColor = (WORD)*hpDIBitmap) != crColor)
break;
}
if(!(dstWid = (WORD)(((DWORD)endI*xIntPrint + xIntImage/2)
/xIntImage - dstI)))
continue;
if(!SelectObject(hPrintDC, hBrush[crColor]))
goto Error7;
PatBlt(hPrintDC, dstI+rIntPrint.left, dstJ+rIntPrint.top,
dstWid, dstHgt, PATCOPY);
SelectObject(hPrintDC, hOldBrush);
}
}
bError = FALSE;
Error7:
for(nextColor=0; nextColor<256; ++nextColor)
if(hBrush[nextColor])
DeleteObject(hBrush[nextColor]);
}
/*------------------------------------------------*/
/* Unlock DIB memory until we need it again */
/*------------------------------------------------*/
Error6:
GlobalUnlock(hDIBInfo);
Error5:
GlobalUnlock(hDIBitmap);
if(bError)
goto Error4;
PollPrint();
/*------------------------------------------------*/
/* Update the percentage display */
/*------------------------------------------------*/
if(hDlgPrint) {
IntersectRect(&rIntPrint, &rIntPrint, nprBandPrint);
lIncArea += (long)(rIntPrint.right - rIntPrint.left) *
(rIntPrint.bottom - rIntPrint.top);
if(lIncArea > lTotArea)
lIncArea = lTotArea;
LoadString(hInst, IDSPrintPercent, buf, CharSizeOf(buf));
wsprintf(szPercent, buf, nPage, nPages, (int)(100*lIncArea/lTotArea));
SetDlgItemText(hDlgPrint, IDPERCENT, szPercent);
}
PollPrint();
}
bError = FALSE;
Error4:
GlobalFree(hDIBitmap);
Error3:
SelectObject(hMemDC, hOldBitmap);
Error2:
DeleteObject(hBitmap);
Error1:
if(bError)
goto TryAgain;
}
/*------------------------------------------------*/
/* Delete global memory objects that are still */
/* around */
/*------------------------------------------------*/
STATIC void NEAR PASCAL TermPrinting(HDC hPrintDC, int DelTo)
{
/*------------------------------------------------*/
/* If there were no printing errors */
/*------------------------------------------------*/
if (DelTo >= STARTOK)
{
if (DelTo == INITOK && !bUserAbort && !bError)
EndDoc(hPrintDC);
else
AbortDoc(hPrintDC);
}
/*------------------------------------------------*/
/* Free up memory that is still being used */
/*------------------------------------------------*/
if(hMemDC ) DeleteDC(hMemDC);
if(hPrtPalette ) DeleteObject(hPrtPalette);
if(hMemPalette ) DeleteObject(hMemPalette);
if(hDIBInfo ) GlobalFree(hDIBInfo);
}
STATIC void NEAR PASCAL TranslateString(TCHAR chBuff[3][80], int nIndex[3],
TCHAR * src, TCHAR * szFilename)
{
TCHAR buf[80];
TCHAR letters[15];
TCHAR *dst = buf, *save_src = src;
int temp;
short nAlign = 1;
SYSTEMTIME systime;
nIndex[0] = nIndex[1] = nIndex[2] = 0;
LoadString (hInst, IDSLetters, letters, CharSizeOf(letters));
/*------------------------------------------------*/
/* Get the date/time in case we need it */
/*------------------------------------------------*/
GetSystemTime (&systime);
while (*src) {
/*------------------------------------------------*/
/* Copy all "ordinary" characters to their aligned*/
/* strings */
/*------------------------------------------------*/
while(*src && *src != TEXT('&')) {
chBuff[nAlign][nIndex[nAlign]] = *src++;
nIndex[nAlign] += 1;
}
/*------------------------------------------------*/
/* If we have come to the escape character */
/*------------------------------------------------*/
if (*src == TEXT('&')) {
src++;
/*------------------------------------------------*/
/* Copy the file name over */
/*------------------------------------------------*/
if (*src == letters[0] || *src == letters[1])
{
lstrcpy(chBuff[nAlign]+nIndex[nAlign], szFilename);
nIndex[nAlign] += lstrlen(szFilename);
}
/*------------------------------------------------*/
/* Print the page number (plus a constant) */
/*------------------------------------------------*/
else if (*src == letters[2] || *src == letters[3])
{
temp = 0;
/*------------------------------------------------*/
/* If a constant, convert to int before printing */
/*------------------------------------------------*/
if (*++src == TEXT('+')) {
src++;
while (_istdigit(*src)) {
temp = (10*temp) + *src - TEXT('0');
src++;
}
}
wsprintf (buf, TEXT("%d"), nPage + temp);
lstrcpy (chBuff[nAlign]+nIndex[nAlign], buf);
nIndex[nAlign] += lstrlen(buf);
src--;
} else if (*src == letters[4] || *src == letters[5]) {
/*------------------------------------------------*/
/* Print the time */
/*------------------------------------------------*/
WCHAR szWide[2];
GetLocaleInfoW (GetUserDefaultLCID (), LOCALE_STIME,
szWide, CharSizeOf(szWide));
#ifdef UNICODE
lstrcpy (buf, szWide);
#else
{ BOOL fDefCharUsed;
WideCharToMultiByte (CP_OEMCP, 0, szWide, -1, buf,
CharSizeOf(buf), NULL, &fDefCharUsed);
}
#endif
wsprintf (chBuff[nAlign]+nIndex[nAlign],
TEXT("%02d%c%02d%c%02d"), systime.wHour,
buf[0], systime.wMinute, buf[0], systime.wSecond);
nIndex[nAlign] += 8;
} else if (*src == letters[6] || *src == letters[7]) {
/*------------------------------------------------*/
/* Print the date */
/*------------------------------------------------*/
wsprintf (chBuff[nAlign]+nIndex[nAlign],
TEXT("%3s %3s %02d %4d"),
szDay[systime.wDayOfWeek],
szMonth[systime.wMonth],
systime.wDay, systime.wYear);
nIndex[nAlign] += 15;
} else if (*src == TEXT('&')) {
/*------------------------------------------------*/
/* Print a single & */
/*------------------------------------------------*/
chBuff[nAlign][nIndex[nAlign]] = TEXT('&');
nIndex[nAlign] += 1;
} else if (*src == letters[8] || *src == letters[9]) /* left */ {
/*------------------------------------------------*/
/* Set the alignment for the following characters */
/*------------------------------------------------*/
nAlign = 0;
} else if (*src == letters[10] || *src == letters[11]) /* center */
nAlign = 1;
else if (*src == letters[12] || *src == letters[13]) /* right */
nAlign = 2;
src++;
}
}
/*------------------------------------------------*/
/* Null-terminate all strings */
/*------------------------------------------------*/
for (nAlign = 0; nAlign < 3; nAlign++)
chBuff[nAlign][nIndex[nAlign]] = (TCHAR) 0;
}
/*
* print out the translated header/footer string in proper position.
*
* uses global stuff like CharPrintWidth, dyHeadFoot...
*
*/
STATIC void NEAR PASCAL PrintHeaderFooter (
HDC hPrintDC,
NPRECT nprHeader,
NPRECT nprFooter,
LPTSTR szFileName)
{
TCHAR buf[3][80];
int len[3];
TranslateString (buf, len, szHeader, szFileName);
SetTextAlign (hPrintDC, TA_LEFT | TA_BOTTOM | TA_NOUPDATECP);
if (len[0])
TextOut(hPrintDC, nprHeader->left,
nprHeader->bottom - CharPrintHeight, buf[0], len[0]);
SetTextAlign(hPrintDC, TA_CENTER | TA_BOTTOM | TA_NOUPDATECP);
if (len[1])
TextOut(hPrintDC, (nprHeader->left + nprHeader->right)/2,
nprHeader->bottom - CharPrintHeight, buf[1], len[1]);
SetTextAlign(hPrintDC, TA_RIGHT | TA_BOTTOM | TA_NOUPDATECP);
if (len[2])
TextOut(hPrintDC, nprHeader->right,
nprHeader->bottom - CharPrintHeight, buf[2], len[2]);
TranslateString(buf, len, szFooter, szFileName);
SetTextAlign(hPrintDC, TA_LEFT | TA_TOP | TA_NOUPDATECP);
if (len[0])
TextOut(hPrintDC, nprFooter->left,
nprFooter->top + CharPrintHeight, buf[0], len[0]);
SetTextAlign(hPrintDC, TA_CENTER | TA_TOP | TA_NOUPDATECP);
if (len[1])
TextOut(hPrintDC, (nprFooter->left + nprFooter->right)/2,
nprFooter->top + CharPrintHeight, buf[1], len[1]);
SetTextAlign(hPrintDC, TA_RIGHT | TA_TOP | TA_NOUPDATECP);
if (len[2])
TextOut(hPrintDC, nprFooter->right,
nprFooter->top + CharPrintHeight, buf[2], len[2]);
}
STATIC void PRIVATE ActualPrintImg(HDC hPrtDC, NPRECT nprImage, BOOL draft)
{
BOOL fBandingDevice;
RECT bandRect, tempRect, fullPageRect;
RECT rPrint, rHeader, rFooter;
#ifndef NT
BANDINFOSTRUCT BandInfo;
BOOL fBandInfo;
int holder;
#endif
int nInitReturn;
TCHAR szMsg[BUFSIZE], buf[BUFSIZE];
ComputePrintRect(nprImage, &rPrint, &rHeader, &rFooter);
fullPageRect.left = fullPageRect.top = 0;
fullPageRect.right = hResPrt;
fullPageRect.bottom = vResPrt;
#ifndef NT
holder = BANDINFO;
fBandInfo = Escape(hPrtDC, QUERYESCSUPPORT, sizeof(holder), (LPSTR) &holder, NULL);
#endif
fBandingDevice = GetDeviceCaps(hPrtDC, RASTERCAPS) & RC_BANDING;
fDIBScaling = draft || (imagePlanes * imagePixels) == 1
|| (GetDeviceCaps(hPrtDC, RASTERCAPS) & RC_STRETCHDIB);
if ((nInitReturn = InitPrinting(hPrtDC, nprImage, &rPrint,
fileName[0] ? fileName : noFile)) != INITOK) {
bUserAbort = TRUE;
if(nInitReturn != NOMESG)
SimpleMessage(IDSPrintInitErr, NULL, MB_OK | MB_ICONHAND);
goto Error2;
}
for (nPage = 1, rImage.top = nprImage->top;
rImage.top < nprImage->bottom;
rImage.top += yImage) {
for (rImage.left = nprImage->left;
rImage.left < nprImage->right && !bUserAbort && !bError;
rImage.left += xImage, ++nPage) {
DB_OUT("NextPage\n\r");
StartPage(hPrtDC);
LoadString(hInst, IDSPrintPercent, buf, CharSizeOf(buf));
wsprintf(szMsg, buf, nPage, nPages, (int)(100*lIncArea/lTotArea));
SetDlgItemText(hDlgPrint, IDPERCENT, szMsg);
rImage.right = rImage.left + xImage;
rImage.bottom = rImage.top + yImage;
IntersectRect(&rImage, &rImage, nprImage);
do {
/* set fields to defaults */
bandRect = fullPageRect;
#ifndef NT
BandInfo.rcGraphics = rPrint;
BandInfo.fText = BandInfo.fGraphics = TRUE;
#endif
if (fBandingDevice) {
/* tell the printer driver we're ready for the next band */
Escape(hPrtDC, NEXTBAND, 0, NULL, (LPVOID) &bandRect);
/* done page if band is empty */
if (IsRectEmpty(&bandRect))
break;
#ifndef NT
/* find out what type of band we are dealing with */
if (fBandInfo) {
BandInfo.fText = FALSE;
#ifndef WIN32
Escape(hPrtDC, BANDINFO, sizeof(BandInfo), (LPCSTR) &BandInfo,
(LPVOID) &BandInfo);
#endif
}
#endif
}
if(
#ifndef NT
BandInfo.fText &&
#endif
(IntersectRect(&tempRect, &rHeader, &bandRect)
|| IntersectRect(&tempRect, &rFooter, &bandRect))) {
/* print header and footer */
PrintHeaderFooter (hPrtDC, &rHeader, &rFooter,
fileName[0] ? fileName : noFile);
}
#ifndef NT
if (BandInfo.fGraphics) {
#endif
/* do graphics stuff */
PrintBand(hPrtDC, &bandRect, &rImage, &rPrint);
#ifndef NT
}
#endif
} while (fBandingDevice && !bUserAbort && !bError);
if (!fBandingDevice)
EndPage(hPrtDC);
}
}
if(fBandingDevice)
while(!IsRectEmpty(&bandRect))
Escape(hPrtDC, NEXTBAND, 0, NULL, (LPVOID) &bandRect);
Error2:
TermPrinting(hPrtDC, nInitReturn);
}
void PrintImg(NPRECT nprImage, BOOL draft, int copies)
{
BOOL result = FALSE;
HCURSOR oldcsr;
TCHAR msg[80], buf[80];
LPDEVNAMES lpDevNames;
LPTSTR portName,deviceName;
TCHAR nodefault[] = TEXT("NODEFAULT");
extern HDC printDC;
if (!printDC)
goto Error0;
oldcsr = SetCursor(LoadCursor(NULL, IDC_WAIT));
bUserAbort = bError = FALSE;
lpfnAbortDlg = NULL;
lpfnAbortPrt = NULL;
hDlgPrint = NULL;
if(!(lpfnAbortPrt = (ABORTPROC)MakeProcInstance((FARPROC)AbortPrt, hInst)))
goto Error1;
if(!(lpfnAbortDlg = (WNDPROC)MakeProcInstance((FARPROC)AbortDlg, hInst)))
goto Error2;
#ifdef BOGUS
SendMessage(pbrushWnd[PARENTid], WM_SYSCOMMAND, SC_MINIMIZE, 0L);
#endif
if(!(hDlgPrint = CreateDialog(hInst, (LPTSTR) MAKEINTRESOURCE(ABORTBOX),
pbrushWnd[PARENTid], (WNDPROC)lpfnAbortDlg)))
goto Error3;
EnableWindow(pbrushWnd[PARENTid], FALSE);
LoadString(hInst, IDSPrintFile, buf, CharSizeOf(buf));
wsprintf(msg, buf, PFileInPath(fileName[0] ? fileName : noFile));
SetDlgItemText(hDlgPrint, IDFILENAME, msg);
if (PD.hDevNames && (lpDevNames = (LPDEVNAMES)GlobalLock(PD.hDevNames))) {
portName = (LPTSTR)lpDevNames+lpDevNames->wOutputOffset;
deviceName = (LPTSTR)lpDevNames+lpDevNames->wDeviceOffset;
GlobalUnlock(PD.hDevNames);
}else{
if(!GetDefaultPort())
goto Error4;
if(PD.hDevNames && (lpDevNames = (LPDEVNAMES)GlobalLock(PD.hDevNames))){
portName = (LPTSTR)lpDevNames+lpDevNames->wOutputOffset;
deviceName = (LPTSTR)lpDevNames+lpDevNames->wDeviceOffset;
GlobalUnlock(PD.hDevNames);
}else
portName = deviceName = nodefault;
}
LoadString(hInst, IDSPrintDevice, buf, CharSizeOf(buf));
wsprintf(msg, buf, deviceName, portName);
SetDlgItemText(hDlgPrint, IDDEVICEPORT, msg);
for( ; copies>0 && !bUserAbort && !bError; )
{
copies -= SetPrintOptions(printDC, FALSE, copies);
ActualPrintImg(printDC, nprImage, draft);
}
result = !bError;
Error4:
if(hDlgPrint)
SendMessage(hDlgPrint, WM_COMMAND, IDOK, 0L);
Error3:
#ifdef BOGUS
SendMessage(pbrushWnd[PARENTid], WM_SYSCOMMAND, SC_RESTORE, 0L);
#endif
UpdateWindow(pbrushWnd[PAINTid]);
FreeProcInstance(lpfnAbortPrt);
Error2:
FreeProcInstance(lpfnAbortDlg);
Error1:
SetCursor(oldcsr);
DeleteDC(printDC);
printDC = NULL;
Error0:
if(!result)
SimpleMessage(IDSPrintInitErr, NULL, MB_OK);
}