summaryrefslogtreecommitdiff
path: root/Build/source/texk/windvi/winprint.c
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/texk/windvi/winprint.c')
-rw-r--r--Build/source/texk/windvi/winprint.c1779
1 files changed, 0 insertions, 1779 deletions
diff --git a/Build/source/texk/windvi/winprint.c b/Build/source/texk/windvi/winprint.c
deleted file mode 100644
index 88426999de1..00000000000
--- a/Build/source/texk/windvi/winprint.c
+++ /dev/null
@@ -1,1779 +0,0 @@
-/*
- winprint.c : implementation file
- Time-stamp: "01/01/12 10:50:56 popineau"
-
- Copyright (C) 1999
- Fabrice Popineau <Fabrice.Popineau@supelec.fr>
-
- This file is part of Windvi.
-
- Windvi is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2, or (at your option)
- any later version.
-
- Windvi is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
- License for more details.
-
- You should have received a copy of the GNU General Public License
- along with Windvi; if not, write to the Free Software Foundation, 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
-
-/*
- Supports 'print setup' and 'print' functions.
-
- Not so easy to implement color printing.
- Some remarks :
- - it seems no possible to use rasterops
- to do tramsparent blt
- - a part from doing banding which might be
- very expensive
- - maybe we could build a list of affected rectangles
- (rules and specials)
- - and redraw the needed parts using the appropriate mode
-
- */
-
-#include "wingui.h"
-#include "xdvi-config.h"
-#include <commdlg.h>
-#include "gsdll.h"
-
-#define DEBUG_PRINT 0
-
-HWND hDlgPrint = 0, hWndParent = 0;
-CHAR *msgFormat = "file %s (page %d in [%d - %d])";
-CHAR msgBuffer[256];
-BOOL isPrinting = FALSE, isPrintingDvips = FALSE;
-int iFirstPage, iLastPage;
-HDC hMemBandDC;
-HBITMAP oldprintDIB, printDIB;
-void *lpMemBandData;
-struct BITMAPINFO_256 bmiMemBand;
-BOOL bPrintError = FALSE;
-BOOL bUserAbort = FALSE;
-
-/*
-
- Variables to save display configuration
-
- */
-
-HDC save_maneDC;
-int save_page, save_shrink;
-struct WindowRec save_mane;
-Pixel save_fore, save_back;
-Boolean save_grey;
-POINT saveScroll;
-BOOL savedPS;
-int save_maneRC;
-int saveBitsPixel;
-int save_u_paper_w, save_u_paper_h;
-int save_offset_x, save_offset_y;
-
-/*
- Printercapabilities
- */
-
-unsigned int iPrintBitsPixel, iPrintSizePal, iPrintColorRes, iPrintRasterCaps;
-unsigned int iPrintOffsetX, iPrintOffsetY;
-unsigned int nBandHeight, current_band, nBandNumbers;
-unsigned int nBandMBSize = 2;
-
-/*
- extern definitions
- */
-extern void redraw(struct WindowRec *);
-extern BOOL IsOpenedDviFile();
-extern void ReopenDviFile();
-extern void prescan();
-
-BOOL CALLBACK AbortProc(HDC hdc, int nCode)
-{
- MSG msg;
-
- /* Retrieve and remove messages from the thread's message queue. */
- while (!bUserAbort && PeekMessage(&msg, (HWND) NULL, 0, 0, PM_REMOVE)) {
- /* Process any messages for the Cancel dialog box. */
- if (!hDlgPrint || !IsDialogMessage(hDlgPrint, &msg)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
-
- /* Return the global isPrinting flag (which is set to FALSE if the
- user presses the Cancel button). */
- return !bUserAbort;
-
- UNREFERENCED_PARAMETER(hdc);
- UNREFERENCED_PARAMETER(nCode);
-}
-
-LRESULT CALLBACK PrintDlgProc(HWND hwndDlg, UINT message,
- WPARAM wParam, LPARAM lParam)
-{
- switch (message) {
-
- case WM_INITDIALOG: /* message: initialize dialog box */
- /* Initialize the static text control. */
- SetDlgItemText(hwndDlg, IDD_FILE, xbasename(dvi_name));
-
- /* Initialize the progress bars. */
- SendDlgItemMessage(hwndDlg, IDC_PRINT_PROGRESS_PAGE,
- PBM_SETRANGE, (WPARAM) 0, MAKELPARAM(1, total_pages));
- SendDlgItemMessage(hwndDlg, IDC_PRINT_PROGRESS_PAGE,
- PBM_SETPOS, (WPARAM) 1, (LPARAM) 0);
- SendDlgItemMessage(hwndDlg, IDC_PRINT_PROGRESS_PAGE,
- PBM_SETBARCOLOR,
- (WPARAM) 0, (LPARAM) (COLORREF) MYRGB(0, 255, 40));
-
- SendDlgItemMessage(hwndDlg, IDC_PRINT_PROGRESS_BAND,
- PBM_SETRANGE, (WPARAM) 0, MAKELPARAM(1, 100));
- SendDlgItemMessage(hwndDlg, IDC_PRINT_PROGRESS_BAND,
- PBM_SETPOS, (WPARAM) 1, (LPARAM) 0);
- SendDlgItemMessage(hwndDlg, IDC_PRINT_PROGRESS_PAGE,
- PBM_SETBARCOLOR,
- (WPARAM) 0, (LPARAM) (COLORREF) MYRGB(0, 40, 255));
-
- SetFocus(GetDlgItem(hwndDlg, IDD_CANCEL));
- return 0; /* Because it is setting focus */
-
- case WM_COMMAND: /* message: received a command */
- /* User pressed "Cancel" button--stop print job. */
- bUserAbort = TRUE;
- EnableWindow(hWndParent, TRUE);
- DestroyWindow(hwndDlg);
- hDlgPrint = 0;
- return 1;
- }
-
- return 0;
- UNREFERENCED_PARAMETER(lParam);
- UNREFERENCED_PARAMETER(wParam);
- UNREFERENCED_PARAMETER(message);
-}
-
-/****************************************************************************
- * *
- * FUNCTION : InitPrinting(HDC hDC, HWND hWnd, HANDLE hInst, LPSTR msg) *
- * *
- * PURPOSE : Makes preliminary driver calls to set up print job. *
- * *
- * RETURNS : TRUE - if successful. *
- * FALSE - otherwise. *
- * *
- ****************************************************************************/
-BOOL InitPrinting(HDC hDC, HWND hWnd, HANDLE hInst, LPSTR msg)
-{
- DOCINFO DocInfo;
-
- bPrintError = FALSE; /* no errors yet */
- bUserAbort = FALSE; /* user hasn't aborted */
-
- hWndParent = hWnd; /* save for Enable at Term time */
-
- hDlgPrint = CreateDialog (hInst, "ABORTPRINTDLG", hWndParent,
- (DLGPROC)PrintDlgProc);
-
- if (!hDlgPrint)
- return FALSE;
-
- EnableWindow (hWndParent, FALSE); /* disable parent */
-
- /*
- Use new printing APIs...Petrus Wong 12-May-1993
- */
- if (SetAbortProc(hDC, (ABORTPROC)AbortProc) <= 0) {
- bPrintError = TRUE;
- return FALSE;
- }
-
- ZeroMemory(&DocInfo, sizeof(DocInfo));
- DocInfo.cbSize = sizeof(DOCINFO);
- DocInfo.lpszDocName = (LPTSTR) msg;
- DocInfo.lpszOutput = NULL;
-
- if (StartDoc(hDC, &DocInfo) <= 0) {
- bPrintError = TRUE;
- return FALSE;
- }
- bPrintError = FALSE;
-
- /* might want to call the abort proc here to allow the user to
- * abort just before printing begins */
- return TRUE;
-}
-
-/****************************************************************************
- * *
- * FUNCTION : TermPrinting(HDC hDC) *
- * *
- * PURPOSE : Terminates print job. *
- * *
- ****************************************************************************/
-VOID TermPrinting(HDC hDC)
-{
- /*
- Use new printing APIs...Petrus Wong 12-May-1993
- */
- if (!bPrintError)
- EndDoc(hDC);
-
- if (bUserAbort)
- AbortDoc(hDC);
- else {
- EnableWindow(hWndParent, TRUE);
- DestroyWindow(hDlgPrint);
- hDlgPrint = 0;
- }
-
-}
-
-LRESULT CmdFilePrSetup (HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
-{
- PAGESETUPDLG pgsdlg;
- return 0;
-}
-
-/***********************************************************************
- *
- * GetPrinterDC()
- *
- * Uses PrinDlg common dialog for printer selection and creates a dc.
- * Returns NULL on error.
- *
- ***********************************************************************/
-
-HDC GetPrinterDC(HWND hWnd)
-{
- PRINTDLG pd;
- char gszDevice[256];
- char gszOutput[256];
-
- ZeroMemory(&pd, sizeof(pd));
-
- pd.lStructSize = sizeof(PRINTDLG);
- pd.hwndOwner = hWnd;
- pd.Flags = PD_ALLPAGES | PD_RETURNDC /* | PD_PRINTSETUP */;
- pd.nFromPage = 1;
- pd.nToPage = total_pages;
- pd.nMinPage = 1;
- pd.nMaxPage = total_pages;
- pd.nCopies = 1;
-
- iFirstPage = 0;
- iLastPage = total_pages - 1;
-
- if (PrintDlg(&pd) == TRUE) {
- DEVNAMES *pDevNames;
- DEVMODE *pDevMode;
-
- pDevNames = GlobalLock(pd.hDevNames);
- pDevMode = GlobalLock(pd.hDevMode);
-
- lstrcpy((LPSTR)gszDevice,
- (LPSTR)((char *)pDevNames+pDevNames->wDeviceOffset));
-
- if(!lstrcmpi((LPSTR)((char *)pDevNames+pDevNames->wDeviceOffset),
- (LPSTR)((char *)pDevNames+pDevNames->wOutputOffset)))
- lstrcpy((LPSTR)gszOutput, "net:");
- else
- lstrcpy((LPSTR)gszOutput,
- (LPSTR)((char *)pDevNames+pDevNames->wOutputOffset));
-
-
-#if DEBUG_PRINT
- if (pDevMode = pd.hDevMode) {
- fprintf(stderr, "devmode: name = %s, colors = %s\n",
- pDevMode->dmDeviceName,
- pDevMode->dmColor == DMCOLOR_COLOR ? "color" : "mono");
- }
- fprintf(stderr, "gszDevice = %s\ngszOutput = %s\n",
- gszDevice, gszOutput);
-#endif
-
- iFirstPage = pd.nFromPage - 1;
- iLastPage = pd.nToPage - 1;
-
- GlobalUnlock(pd.hDevNames);
- GlobalUnlock(pd.hDevMode);
-
- return pd.hDC;
- }
- else {
- CommDlgExtendedError();
- iFirstPage = iLastPage = 0;
- return NULL;
- }
-}
-
-BOOL SetupPageForPrinting(HDC hDC) {
-
- int cxPage, cyPage, cxInch, cyInch;
-
- /* Should we bother about the number of colors the printer
- will support ?
- Answer : YES !!!
- */
-
- iPrintRasterCaps = GetDeviceCaps(hDC, RASTERCAPS);
-
- /* Examine the raster capabilities of the device identified by hDC
- to verify that it supports the BitBlt function. */
-
- if (!(iPrintRasterCaps & RC_STRETCHDIB)) {
- DeleteDC(hDC);
- MessageBox(hWndParent,
- "Printer cannot display bitmaps.",
- "Device Error",
- MB_OK);
- return FALSE;
- }
-
- if (!(iPrintRasterCaps & RC_BITMAP64)) {
- DeleteDC(hDC);
- MessageBox(hWndParent,
- "Printer cannot cope with bitmaps > 64k.",
- "Device Error",
- MB_OK);
- return FALSE;
- }
-
- /* FIXME: there is a problem if Bits per Pixel is 1 !
- Check with the dib palette.
- */
- iPrintBitsPixel = GetDeviceCaps(hDC, BITSPIXEL);
- iPrintSizePal = GetDeviceCaps(hDC, SIZEPALETTE);
- iPrintColorRes = GetDeviceCaps(hDC, COLORRES);
- iPrintOffsetX = GetDeviceCaps(hDC, PHYSICALOFFSETX);
- iPrintOffsetY = GetDeviceCaps(hDC, PHYSICALOFFSETY);
- /* There is a mess there with device not reporting colors ! */
- iPrintBitsPixel = 24;
-
- cxPage = GetDeviceCaps(hDC, HORZRES); /* Width of printr page - pixels */
- cyPage = GetDeviceCaps(hDC, VERTRES); /* Height of printr page - pixels */
- cxInch = GetDeviceCaps(hDC, LOGPIXELSX);/* Printer pixels per inch - X */
- cyInch = GetDeviceCaps(hDC, LOGPIXELSY);/* Printer pixels per inch - Y */
-
- SetStretchBltMode(hDC, COLORONCOLOR);
-
- save_mane = mane;
- save_shrink = shrink_factor;
- save_fore = fore_Pixel;
- save_back = back_Pixel;
- save_grey = use_grey;
- saveScroll.x = xCurrentScroll;
- saveScroll.y = yCurrentScroll;
- save_page = current_page;
- save_maneDC = maneDC;
- savedPS = resource._postscript;
- save_maneRC = maneRasterCaps;
- saveBitsPixel = maneBitsPixel;
- save_u_paper_w = unshrunk_paper_w;
- save_u_paper_h = unshrunk_paper_h;
- save_offset_x = offset_x;
- save_offset_y = offset_y;
- offset_x -= iPrintOffsetX;
- offset_y -= iPrintOffsetY;
- xCurrentScroll = yCurrentScroll = 0;
- shrink_factor = 1;
- use_grey = False;
- maneRasterCaps = iPrintRasterCaps;
- maneBitsPixel = iPrintBitsPixel;
-
- unshrunk_paper_w = cxPage;
- unshrunk_paper_h = cyPage;
- unshrunk_page_w = unshrunk_dvifile_page_w;
- unshrunk_page_h = unshrunk_dvifile_page_h;
- if (unshrunk_page_h < unshrunk_paper_h)
- unshrunk_page_h = unshrunk_paper_h;
- if (unshrunk_page_w < unshrunk_paper_w)
- unshrunk_page_w = unshrunk_paper_w;
-
- mane.shrinkfactor = 1;
- mane.base_x = 0;
- mane.base_y = 0;
- mane.min_x = 0;
- mane.min_y = 0;
- mane.max_x = unshrunk_paper_w;
- mane.max_y = unshrunk_paper_h;
- mane.width = mane.max_x - mane.min_x;
- mane.height = mane.max_y - mane.min_y;
-
- init_page();
-
-#if DEBUG_PRINT
- fprintf(stderr, "printer page (%d x %d), cx = %d, cy = %d\n",
- cxPage, cyPage, cxInch, cyInch);
- fprintf(stderr, "bits/pixel = %d, colorres = %d, size pal = %d\n",
- iPrintBitsPixel, iPrintColorRes, iPrintSizePal);
- fprintf(stderr, "dvi paper (%d x %d)\n", unshrunk_paper_w, unshrunk_paper_h);
- fprintf(stderr, "dvi unshrunk page (%d x %d)\n",
- unshrunk_page_w, unshrunk_page_h);
- fprintf(stderr, "dvi shrunk page (%d x %d)\n", page_w, page_h);
- fprintf(stderr, "offset printer (%d , %d)\n", iPrintOffsetX, iPrintOffsetY);
-#endif
-
-#if 0
- /* FIXME: change mode and dpi */
- resource._pixels_per_inch = cxInch;
- resource.mfmode = ?;
-#endif
-
- if (!IsOpenedDviFile())
- ReopenDviFile();
-
- scanned_page_bak = scanned_page = -1;
-
- initcolor();
- reset_fonts();
-#ifdef XFORM
- reset_xform_stack();
-#endif
-
- return TRUE;
-}
-
-BOOL RestorePageForDisplay()
-{
- fprintf(stderr, "Restoring for display...\n");
-
- mane = save_mane;
- shrink_factor = save_shrink;
- current_page = save_page;
- use_grey = save_grey;
- xCurrentScroll = saveScroll.x;
- yCurrentScroll = saveScroll.y;
- fore_Pixel = save_fore;
- back_Pixel = save_back;
-
- offset_x = save_offset_x;
- offset_y = save_offset_y;
-
- unshrunk_paper_w = save_u_paper_w;
- unshrunk_paper_h = save_u_paper_h;
- unshrunk_page_w = unshrunk_dvifile_page_w;
- unshrunk_page_h = unshrunk_dvifile_page_h;
- if (unshrunk_page_h < unshrunk_paper_h)
- unshrunk_page_h = unshrunk_paper_h;
- if (unshrunk_page_w < unshrunk_paper_w)
- unshrunk_page_w = unshrunk_paper_w;
- init_page();
-
- /*
- User might abort before config has been changed
- */
- maneBitsPixel = saveBitsPixel;
- maneRasterCaps = save_maneRC;
-
- foreGC = ruleGC = highGC = maneDC = save_maneDC;
-
- scanned_page = scanned_page_reset = -1;
-#ifdef XFORM
- reset_xform_stack();
-#endif
-
- initcolor();
- reset_fonts();
-
- resource._postscript = savedPS;
-
-
- return TRUE;
-}
-
-void PrepareForBanding(HDC hDC)
-{
-
- RGBQUAD QuadWhite = { 255, 255, 255, 0};
- RGBQUAD QuadBlack = { 0, 0, 0, 0};
-
- /* Create a memory DC that is compatible with the printer DC */
- hMemBandDC = CreateCompatibleDC(hDC);
-
- SetStretchBltMode(hMemBandDC, COLORONCOLOR);
-
-#ifdef TRANSFORM
- if (IS_WIN98 || IS_NT)
- SetGraphicsMode(hMemBandDC, GM_ADVANCED);
-#endif
-
- /*
- Do banding. We can't afford more than say 6Mb at a time.
- Calculate the number of rows at the current dpi.
- Print as many bands as needed.
- */
-
- nBandNumbers = ROUNDUP(unshrunk_paper_w * unshrunk_paper_h * iPrintBitsPixel,
- nBandMBSize * 1024 * 1024 * 8) + 1;
- nBandHeight = ROUNDUP(unshrunk_paper_h, nBandNumbers);
-
- SendDlgItemMessage(hDlgPrint, IDC_PRINT_PROGRESS_BAND,
- PBM_SETRANGE,
- (WPARAM) 0, (LPARAM) MAKELPARAM(1, nBandNumbers));
- SendDlgItemMessage(hDlgPrint, IDC_PRINT_PROGRESS_BAND,
- PBM_SETPOS,
- (WPARAM) 1, (LPARAM) 0);
-
- mane.base_y = 0;
- mane.max_y = nBandHeight;
- mane.height = mane.max_y - mane.min_y;
-
-#if DEBUG_PRINT
- fprintf(stderr, "Band numbers = %d, Band height = %d, page_h = %d\n",
- nBandNumbers, nBandHeight, unshrunk_paper_h);
-#endif
-
- /* Create a DIB for printing into it. We might need maneDIB to do redraw
- while printing */
- printDIB = CreateDIB(hMemBandDC, unshrunk_paper_w + 1, nBandHeight + 1,
- iPrintBitsPixel,
- &bmiMemBand, &lpMemBandData);
-
- /* FIXME : there is a problem with monochrome printing. */
- if (iPrintBitsPixel == 1) {
- bmiMemBand.bmiColors[1] = QuadWhite;
- bmiMemBand.bmiColors[0] = QuadBlack;
- }
-
- /* Put the DIB into the memory DC */
- oldprintDIB = SelectObject(hMemBandDC, printDIB);
-
- if (resource._postscript) {
- ps_destroy();
- initGS();
- }
-
-}
-
-static BOOL bBandInit = FALSE;
-
-void FreeBandingRc()
-{
- SelectObject(hMemBandDC, oldprintDIB);
- DeleteObject(printDIB);
-
- DeleteObject(hMemBandDC);
-
- if (resource._postscript) {
- ps_destroy();
- initGS();
- }
- bBandInit = FALSE;
-}
-
-void DrawPage(HDC hPrinterDC, int page)
-{
- if (!IsOpenedDviFile())
- ReopenDviFile();
-
- current_page = page;
-
- bColorPage = psToDisplay = FALSE;
-
-#if 1
- /* FIXME: really needed ? */
- init_colors();
-#endif
-
-#ifdef TRANSFORM
- /* FIXME : there should be a global stack in case
- such transformations would span over several pages. */
- if (resource.use_xform)
- reset_xfrm_stack();
-#endif
-
- if (!bBandInit) {
- bBandInit = TRUE;
- PrepareForBanding(hPrinterDC);
- }
-
- if (scanned_page < current_page)
- prescan();
-
-#if DEBUG_PRINT
- fprintf(stderr, "page %d, bColorPage = %d psToDisplay = %d\n",
- page, bColorPage, psToDisplay);
-#endif
-
- if (bColorPage || psToDisplay) {
-
- /* Specials, do banding */
- maneDC = foreGC = ruleGC = highGC = hMemBandDC;
-
- for (current_band = 0; current_band < nBandNumbers; current_band++) {
-#if DEBUG_PRINT
- fprintf(stderr, "Printing page %d band %d\n",
- page, current_band);
-#endif
- mane.base_y = current_band*nBandHeight;
- mane.max_y = min(nBandHeight, unshrunk_paper_h - current_band * nBandHeight) + 1;
- mane.height = mane.max_y - mane.min_y;
-
- if (resource._postscript && psToDisplay && gs_device) {
- extern void
- init_ps_page(int llx, int lly, int urx, int ury, int height);
- extern void gs_io(char *);
- gs_io("H initgraphics\n");
- init_ps_page(0,0,
- mane.max_x - mane.min_x,
- mane.max_y - mane.min_y,
- mane.base_y + mane.max_y);
- gs_io("\nstop\n%%xdvimark\n");
- }
-
- /* FIXME : paint background color */
- if (get_back_color(current_page) != MYRGB(255,255,255))
- fprintf(stderr, "this page is white, but should be %-8x\n",
- get_back_color(current_page));
-
- /* FIXME: check about the + 1 on each dimension ! */
- if (PatBlt(foreGC, 0, 0, unshrunk_paper_w + 1, nBandHeight + 1,
- WHITENESS) == 0)
- Win32Error("Redraw Page background");
-
- /* First pass for specials */
- allowDrawingChars = FALSE;
- redraw(&mane);
-
-#if DEBUG_PRINT
- fprintf(stderr, "PS state: resource._postscript = %d, psToDisplay = %d, gs_device = %d\n",
- resource._postscript, psToDisplay, gs_device);
-#endif
-
- if (resource._postscript && psToDisplay && gs_device) {
- /* if gs is active, try to make it paint its picture */
- BITMAPINFO_256 bmih;
- LPBYTE ppbyte;
- (*pgsdll_lock_device)(gs_device, 1);
- /* Get a pointer to the bitmap in gs interpreter */
- (*pgsdll_get_bitmap_row)(gs_device, &(bmih.bmiHeader), bmih.bmiColors, &ppbyte, 0);
-#if DEBUG_PRINT
- fprintf(stderr,
- "bmih : %d x %d x %d at %x (colors : used %d at %x)\n",
- bmih.bmiHeader.biWidth,
- bmih.bmiHeader.biHeight,
- bmih.bmiHeader.biBitCount,
- ppbyte,
- bmih.bmiHeader.biClrUsed,
- bmih.bmiColors);
-#endif
- if (StretchDIBits(foreGC,
- mane.min_x,
- mane.min_y,
- mane.max_x - mane.min_x,
- mane.max_y - mane.min_y,
- 0,
- 0,
- mane.max_x - mane.min_x,
- mane.max_y - mane.min_y,
- ppbyte, (LPBITMAPINFO)&bmih,
- (bmih.bmiHeader.biClrUsed ? DIB_PAL_COLORS : DIB_RGB_COLORS),
- SRCCOPY) == GDI_ERROR)
- Win32Error("Print/GS/StretchDIBits");
- (*pgsdll_lock_device)(gs_device, 0);
- }
-
- /* Second pass for glyphs */
- allowDrawingChars = TRUE;
- redraw(&mane);
-#if 0
- fprintf(stderr, "before bitblt ...");
-#endif
-
-#if DEBUG_PRINT
- fprintf(stderr, "Printing band to (%d, %d) - (%d x %d)\n",
- mane.base_x + mane.min_x,
- mane.base_y + mane.min_y,
- mane.max_x - mane.min_x,
- mane.max_y - mane.min_y);
-
-#endif
-
-#if 0
- SelectObject(hMemBandDC, oldPrintDIB);
-#endif
- if (StretchDIBits(hPrinterDC,
- mane.base_x + mane.min_x,
- mane.base_y + mane.min_y,
- mane.max_x - mane.min_x,
- mane.max_y - mane.min_y,
- 0, 0,
- mane.max_x - mane.min_x,
- mane.max_y - mane.min_y,
- lpMemBandData, (LPBITMAPINFO)&bmiMemBand,
- (bmiMemBand.bmiHeader.biClrUsed ? DIB_PAL_COLORS : DIB_RGB_COLORS),
- SRCCOPY) == GDI_ERROR)
- Win32Error("WinPrint/StretchDIBits()");
-
- if (hDlgPrint)
- SendDlgItemMessage(hDlgPrint, IDC_PRINT_PROGRESS_BAND,
- PBM_SETPOS, (WPARAM) current_band, (LPARAM) 0);
-
- }
- }
- else {
- /* No color or PS specials on this page,
- draw directly onto the hPrinterDC */
- mane.base_x = 0; mane.base_y = 0;
- mane.min_x = 0; mane.max_x = unshrunk_paper_w;
- mane.min_y = 0; mane.max_y = unshrunk_paper_h;
- maneDC = foreGC = ruleGC = highGC = hPrinterDC;
- allowDrawingChars = TRUE;
- redraw(&mane);
- }
-
- if (hDlgPrint)
- SendDlgItemMessage(hDlgPrint, IDC_PRINT_PROGRESS_PAGE,
- PBM_SETPOS, (WPARAM) page, (LPARAM) 0);
-
-}
-
-LRESULT CmdFilePrint (HWND hwnd, WORD wCommand, WORD wNotify, HWND hwndCtrl)
-{
- HDC hPrinterDC;
- int page;
-
- if (!(hPrinterDC = GetPrinterDC(hwnd)))
- return 0;
-
-#if 0
- __asm int 3;
-#endif
-
- /* Set the flag used by the AbortPrintJob dialog procedure. */
-
- if (InitPrinting(hPrinterDC, hwnd, hInst, dvi_name)) {
-
- /* Reset pre-scanning */
- scanned_page = scanned_page_reset = -1;
-
- SendDlgItemMessage(hDlgPrint, IDC_PRINT_PROGRESS_PAGE,
- PBM_SETRANGE,
- (WPARAM) 0, (LPARAM) MAKELPARAM(iFirstPage, iLastPage));
- SendDlgItemMessage(hDlgPrint, IDC_PRINT_PROGRESS_PAGE,
- PBM_SETSTEP,
- (WPARAM) 1, (LPARAM) 0);
-
- isPrinting = TRUE;
- if (!SetupPageForPrinting(hPrinterDC))
- goto Abort;
-
-
- for (page = iFirstPage; page <= iLastPage; page++) {
-
- if (StartPage(hPrinterDC) <= 0) {
- Win32Error("CmdFilePrint/StartPage");
- break;
- }
-
- if (bUserAbort) {
- break;
- }
- else {
- DrawPage(hPrinterDC, page);
- }
-
- if (EndPage(hPrinterDC) <= 0) {
- Win32Error("CmdFilePrint/StartPage");
- break;
- }
-
- }
-
- Abort:
- RestorePageForDisplay();
- if (bBandInit)
- FreeBandingRc();
- isPrinting = FALSE;
-
- TermPrinting(hPrinterDC);
- }
-
- DeleteDC(hPrinterDC);
- return 0;
-}
-
-#if 0
-
-BOOL GuessPostScriptPrinter()
-{
- bFound = FALSE;
- for (each device in [Devices] section of win.ini) {
- /* extract the necessary fields from the ini line */
- szDriverName = driver name extracted from ini line
- szModelName = left side of ini line (the key)
- szPort = port name extracted from ini line.
-
- hIC = CreateIC(szDriverName, szModelName, szPort, NULL);
- if (hIC) {
- /* see if driver supports GETTECHNOLOGY escape */
- wEscape = GETTECHNOLOGY;
- if (Escape(hIC, QUERYESCSUPPORT, sizeof(WORD), &wEscape, NULL))
- {
- Escape(hIC, GETTECHNOLOGY, 0, NULL,
-
- &szTechnology);
-
- /* Check that the string starts with PostScript
- * by doing a case-insensitive search. Allow
- * for the possibility that the string could be
- * longer, like "PostScript level 2" or some other
- * extension.
- */
- if (beginning of string is "PostScript")
- bFound = TRUE;
- }
- DeleteDC(hIC);
- }
-
- /* if the driver has been found break out */
- if (bFound)
- break;
- }
-
- if (bFound) {
- PostScript driver is szDriverName, model is szModelName, port is
- szPort.
-
- }
-}
-NOTE: In the event that GETTECHNOLOGY is not supported by some printer drivers, another method need to be used to determine if the printer is a PostScript printer. One possible method is to use QUERYESCSUPPORT on escapes that are only implemented by PostScript printers. For example:
-
-EPSPRINTING
-SETLINEJOIN
-SETMITERLIMIT
-SET_POLY_MODE
-
-
-Similarly, you can determine a PCL printer by calling QUERYESCSUPPORT on the following escape:
-
-DRAWPATTERNRECT
-
-============================================================================================================
-
-This will print a file on a PS printer for example.
-
-/* FILE: spool.c */
-
-#include <windows.h>
-#include <print.h>
-#include <commdlg.h>
-#include <string.h>
-
-// Function prototypes
-BOOL FAR PASCAL PrintFile(LPSTR, HDC, HGLOBAL, HGLOBAL);
-VOID SendFile(HDC, LPSTR);
-HDC GetPrinterDC(HGLOBAL, HGLOBAL);
-BOOL CALLBACK __export PrintAbortProc(HDC, int);
-
- // Play with this number
-#define BUFSIZE 2048
-
-// Convenient structure for use with PASSTHROUGH escape
-typedef struct
-{
- WORD wSize;
- BYTE bData[2]; // placeholder
-} PASSTHROUGHSTRUCT, FAR *LPPTS;
-
-
-BOOL bAbort; // Global printing abort flag
-
-
- //*************************************************************
- //
- // PrintFile()
- //
- // Purpose:
- // Reads a file and copies it to a printer using the
- // PASSTHROUGH escape.
- //
- // Parameters:
- // LPSTR szFile - Pointer to path/filename to print
- // HDC hPrnDC - Handle to printer DC or NULL
- // HGLOBAL hDevNames - Handle to DEVNAMES struct or NULL
- // HGLOBAL hDevMode - Handle to DEVMODE struct or NULL
- //
- // Return:
- // Returns nonzero for success or zero for failure.
- //
- // Comments:
- // hDevNames and hDevMode are only used if hPrnDC is NULL.
- // If both hPrnDC and hDevNames are NULL, the default
- // printer is used.
- //
- // History: Date Author Comment
- // 6/03/93 JMS Created
- //
- //*************************************************************
-
-BOOL FAR PASCAL PrintFile ( LPSTR szFile,
- HDC hPrnDC,
- HGLOBAL hDevNames,
- HGLOBAL hDevMode )
-{
- int iEsc;
- BOOL bLocalDC = TRUE; // Assume we must create a DC (hPrnDC == NULL)
-
- bAbort = FALSE; // Haven't aborted yet
-
-
- // Make sure we have a printer DC
-
- if (!hPrnDC)
- hPrnDC = GetPrinterDC(hDevNames, hDevMode);
- else
- bLocalDC = FALSE; // Use passed in hPrnDC
-
- if (!hPrnDC)
- return FALSE;
-
-
- // PASSTHROUGH is required. If driver doesn't support it, bail out.
-
- iEsc = PASSTHROUGH;
- if (!Escape(hPrnDC, QUERYESCSUPPORT, sizeof(int), (LPSTR)&iEsc, NULL))
- {
- bAbort = TRUE;
- goto MSFCleanUp;
- }
-
- // If we created the DC, install an abort procedure. We don't have
- // a Cancel dialog box, but the abort proc enables multitasking.
- // (Use __export and compile with -GA or -GD so we don't need
- // a MakeProcInstance.)
-
- if (bLocalDC)
- Escape (hPrnDC, SETABORTPROC, 0, (LPSTR) PrintAbortProc, NULL);
-
- // Call EPSPRINTING if it is supported (that is, if we're on a
- // PostScript printer) to suppress downloading the pscript header.
-
- iEsc = EPSPRINTING;
- if (Escape(hPrnDC, QUERYESCSUPPORT, sizeof(int), (LPSTR)&iEsc, NULL))
- {
- iEsc = 1; // 1 == enable PASSTHROUGH (disable pscript header)
- Escape(hPrnDC, EPSPRINTING, sizeof(int), (LPSTR)&iEsc, NULL);
- }
-
- SendFile(hPrnDC, szFile); // Send file to printer (could do multiple
- // files)
-
- MSFCleanUp: // Done
-
- if (bLocalDC) // Only delete DC if we created it
- DeleteDC(hPrnDC);
-
- return !bAbort;
-
-} /* PrintFile() */
-
-
-VOID SendFile(HDC hPrnDC, LPSTR szFile)
-{
- static LPPTS lpPTS=NULL; // Pointer to PASSTHROUGHSTRUCT
- OFSTRUCT ofs;
- HFILE hFile;
-
- hFile = OpenFile((LPSTR) szFile, &ofs, OF_READ);
- if (hFile == HFILE_ERROR)
- {
- bAbort = TRUE; // Can't open file!
- return;
- }
-
- if (!lpPTS &&
- !(lpPTS = (LPPTS)GlobalLock(GlobalAlloc(GPTR, sizeof(WORD) +
- BUFSIZE))))
- {
- bAbort = TRUE; // Can't allocate memory for buffer!
- return;
- }
-
- Escape (hPrnDC, STARTDOC, 0, "", NULL);
-
- // Loop through the file, reading a chunk at a time and passing
- // it to the printer. QueryAbort calls the abort procedure, which
- // processes messages so we don't tie up the whole system.
- // We could skip the QueryAbort, in which case we wouldn't need
- // to set an abort proc at all.
-
- do {
- if ((lpPTS->wSize=_lread(hFile, lpPTS->bData, BUFSIZE)) ==
- HFILE_ERROR)
- {
- bAbort = TRUE; // error reading file
- break;
- }
-
- Escape(hPrnDC, PASSTHROUGH, NULL, (LPSTR)lpPTS, NULL);
- }
- while ((lpPTS->wSize == BUFSIZE) && QueryAbort(hPrnDC, 0));
-
- if (!bAbort)
- Escape(hPrnDC, ENDDOC, NULL, NULL, NULL);
-
- _lclose(hFile);
-
-} /* SendFile() */
-
-HDC GetPrinterDC(HGLOBAL hDevNames, HGLOBAL hDevMode)
-{
- HDC hdc;
- char szPrinter[64];
- LPSTR szDevice=NULL, szDriver=NULL, szOutput=NULL;
- LPDEVMODE lpdm;
-
- if (hDevNames)
- {
- LPDEVNAMES lpdn = (LPDEVNAMES) GlobalLock(hDevNames);
-
- szDriver = (LPSTR) lpdn + lpdn->wDriverOffset;
- szDevice = (LPSTR) lpdn + lpdn->wDeviceOffset;
- szOutput = (LPSTR) lpdn + lpdn->wOutputOffset;
-
- if (hDevMode)
- lpdm = (LPDEVMODE) GlobalLock(hDevMode);
- }
- else
- { // Get default printer info
- GetProfileString ("windows", "device", "", szPrinter, 64);
-
- if (!((szDevice = strtok (szPrinter, "," )) &&
- (szDriver = strtok (NULL, ", ")) &&
- (szOutput = strtok (NULL, ", "))))
- return NULL; // No default printer
-
- lpdm = NULL; // Don't use DEVMODE with default printer
- }
-
- hdc = CreateDC(szDriver, szDevice, szOutput, lpdm);
-
- if (hDevMode && lpdm)
- GlobalUnlock(hDevMode);
- if (hDevNames)
- GlobalUnlock(hDevNames);
-
- return hdc;
-
-} /* GetPrinterDC() */
-
-
-BOOL CALLBACK __export PrintAbortProc(HDC hdc, int code)
-{
- MSG msg;
-
- while (!bAbort && PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- return (!bAbort);
-
-} /* PrintAbortProc() */
-
-/*** EOF: spool.c ***/
-=============================================================================================================
-To identify the printer as a PostScript printer, use this code:
-
-
-int gPrCode = 0; // Set according to platform.
-
-if( Win32s ) // Using the Win16 driver.
-{
- gPrCode = PASSTHROUGH;
- if((Escape(printerIC, GETTECHNOLOGY, NULL, NULL, (LPSTR)szTech) &&
- !lstrcmp(szTech, "PostScript")) &&
- Escape(printerIC, QUERYESCSUPPORT, sizeof(int),
- (LPSTR)gPrCode, NULL )
- {
- // The printer is PostScript.
- ...
- }
- }
- else // Using Win32 driver under Windows NT.
- {
- gPrCode = POSTSCRIPT_PASSTHROUGH; // Fails with Win16 driver
- if( Escape(printerIC, QUERYESCSUPPORT, sizeof(int), (LPSTR)gPrCode,
- NULL))
- {
- // The printer is PostScript.
- ...
- }
- }
-
-
- Printing
- To send PostScript data to the printer on either platform, use this code:
-
-
-// Assuming a buffer, szPSBuf, of max size MAX_PSBUF containing
-// nPSData bytes of PostScript data.
-
- char szBuf[MAX_PSBUF+sizeof(short)];
-
- // Store length in buffer.
- *((short *)szBuf) = nPSData;
-
- // Store data in buffer.
- memcpy( (char *)szBuf + sizeof(short), szPSBuf, nPSData );
-
- // Note that gPrCode (set when identifying the printer) depends on
- // the platform.
- Escape( printerDC, gPrCode, (int) nPSData, szBuf, NULL );
-
-
- However, your output may appear scaled or translated incorrectly or data may be transformed off the page under Win32s.
- The origin and scale for Windows printer drivers is not the PostScript default (bottom left/72 dpi) but is instead at the upper left and at the device scale(300 dpi). Therefore, before sending data to the printer, you may need to send a couple of PostScript commands to scale or translate the matrix. For example, for scaling, send the following escape to scale the PostScript transform to 72 dpi:
-
-
- xres = GetDeviceCaps(printerDC, LOGPIXELSX);
- yres = GetDeviceCaps(printerDC, LOGPIXELSY);
-
-// Two leading spaces for the following operation.
- wsprintf(szBuf, " %d 72 div %d 72 div scale\n", xres, yres);
-
- // Put actual size into buffer
- *((short *)szBuf) = strlen(szBuf)-2;
- Escape( printerDC, gPrCode, strlen(szBuf)-2, szBuf, NULL );
-
-
-
-#endif
-
-#if 0
- /* ******************************************************************** */
- /* */
- /* print.c */
- /* */
- /* Source file for Device-Independent Bitmap (DIB) API. Provides */
- /* the following functions: */
- /* */
- /* PrintWindow() - Prints all or part of a window */
- /* PrintScreen() - Prints the entire screen */
- /* PrintDIB() - Prints the specified DIB */
- /* */
- /* Written by Microsoft Product Support Services, Developer Support. */
- /* Copyright 1991-1998 Microsoft Corporation. All rights reserved. */
- /* ******************************************************************** */
-
-#define STRICT /* enable strict type checking */
-
-#include <windows.h>
-#include <string.h>
-#include "dibdll.h" /* Header for printing dialog & DLL instance handle */
-#include "dibapi.h" /* Header for DIB functions */
-#include "dibutil.h" /* Auxiliary functions */
-
-
- extern HANDLE ghDLLInst; /* Global handle to DLL's instance */
-
-/***************************************************************
- * Typedefs
- **************************************************************/
-
-/* Structure used for Banding */
-
- typedef struct
- {
- BOOL bGraphics;
- BOOL bText;
- RECT GraphicsRect;
- } BANDINFOSTRUCT;
-
-
- /****************************************************************
- * Variables
- ***************************************************************/
-
- HWND hDlgAbort; /* Handle to Abort Dialog */
- char szPrintDlg[] = "PRINTING"; /* Name of Print dialog from .RC */
- BOOL bAbort = FALSE; /* Abort a print operation? */
- char gszDevice[50]; /* Keeps track out device (e.g. "HP LaserJet") */
- char gszOutput[50]; /* Output device (e.g. "LPT1:") */
-
- /***************************************************************
- * Function prototypes for functions local to this module
- **************************************************************/
-
- BOOL CALLBACK PrintAbortProc(HDC, int);
- int CALLBACK PrintAbortDlg(HWND, UINT, WPARAM, LPARAM);
- WORD PrintBand(HDC, LPRECT, LPRECT, BOOL, BOOL, LPBITMAPINFOHEADER, LPSTR);
- HDC GetPrinterDC(void);
- void CalculatePrintRect(HDC, LPRECT, WORD, DWORD, DWORD);
-
-
- /**********************************************************************
- *
- * PrintDIB()
- *
- * Description:
- *
- * This routine prints the specified DIB. The actual printing is done
- * in the PrintBand() routine (see below), this procedure drives the
- * printing operation. PrintDIB() has the code to handle both banding
- * and non-banding printers. A banding printer can be distinguished by
- * the GetDeviceCaps() API (see the code below). On banding devices,
- * must repeatedly call the NEXTBAND escape to get the next banding
- * rectangle to print into. If the device supports the BANDINFO escape,
- * it should be used to determine whether the band "wants" text or
- * graphics (or both). On non-banding devices, we can ignore all this
- * and call PrintBand() on the entire page.
- *
- * Parameters:
- *
- * HDIB hDib - Handle to dib to be printed
- *
- * WORD fPrintOpt - tells which print option to use (PW_BESTFIT,
- * PW_STRETCHTOPAGE, OR PW_SCALE)
- *
- * WORD wXScale, wYScale - X and Y scaling factors (integers) for
- * printed output if the PW_SCALE option is used.
- *
- * LPSTR szJobName - Name that you would like to give to this print job (this
- * name shows up in the Print Manager as well as the
- * "Now Printing..." dialog box).
- *
- * Return Value: (see errors.h for description)
- *
- * One of: ERR_INVALIDHANDLE
- * ERR_LOCK
- * ERR_SETABORTPROC
- * ERR_STARTDOC
- * ERR_NEWFRAME
- * ERR_ENDDOC
- * ERR_GETDC
- * ERR_STRETCHDIBITS
- *
- ********************************************************************/
-
- WORD PrintDIB(HDIB hDib, WORD fPrintOpt, WORD wXScale, WORD wYScale,
- LPSTR szJobName)
- {
- HDC hPrnDC; /* DC to the printer */
- RECT rect; /* Rect structure used for banding */
- LPSTR lpBits; /* pointer to the DIB bits */
- LPBITMAPINFOHEADER lpDIBHdr; /* Pointer to DIB header */
- int nBandCount = 0; /* used for print dialog box to count bands */
- WORD wErrorCode = 0; /* Error code to return */
- RECT rPrintRect; /* specifies the area on the printer */
- /* (in printer coordinates) which we */
- /* want the DIB to go to */
- char szBuffer[70]; /* Buffer to hold message for "Printing" dlg box */
- char szJobNameTrunc[35]; /* szJobName truncated to 31 */
- /* characters, since STARTDOC can't */
- /* accept a string longer than 31 */
- DOCINFO DocInfo; /* structure for StartDoc */
- int nTemp; /* used to check banding capability */
- CHAR lpBuffer[128]; /* Buffer for strings retrieved from resources */
-
-
- /* Paramter validation */
-
- if (!hDib)
- return ERR_INVALIDHANDLE;
-
- /* Get pointer to DIB header */
-
- lpDIBHdr = (LPBITMAPINFOHEADER)GlobalLock(hDib);
- if (!lpDIBHdr) /* Check that we have a valid pointer */
- return ERR_LOCK;
- lpBits = FindDIBBits((LPSTR)lpDIBHdr); /* Find pointer to DIB bits */
-
- if (hPrnDC = GetPrinterDC())
- {
- SetStretchBltMode(hPrnDC, COLORONCOLOR);
-
- /* Determine rPrintRect (printer area to print to) from the */
- /* fPrintOpt. Fill in rPrintRect.left and .top from wXScale and */
- /* wYScale just in case we use PW_SCALE (see the function */
- /* CalculatePrintRect). */
-
- rPrintRect.left = wXScale;
- rPrintRect.top = wYScale;
- CalculatePrintRect(hPrnDC, &rPrintRect, fPrintOpt, lpDIBHdr->biWidth,
- lpDIBHdr->biHeight);
-
- /* Initialize the abort procedure. */
-
- hDlgAbort = CreateDialog(ghDLLInst, szPrintDlg, GetFocus(),
- (DLGPROC)PrintAbortDlg);
-
- /* ISet the text inside the dialog to the name of our print job */
-
- lstrcpy(szJobNameTrunc, szJobName);
- szJobNameTrunc[31] = '\0'; /* Truncate string to 31 chars */
- LoadString(ghDLLInst, IDS_PRINTMSG, lpBuffer, sizeof(lpBuffer));
- wsprintf(szBuffer, lpBuffer, (LPSTR)szJobNameTrunc);
- SetDlgItemText(hDlgAbort, IDC_PRINTTEXT1, (LPSTR)szBuffer);
-
- /* Set global variable bAbort to FALSE. This will get set to TRUE */
- /* in our PrintAbortDlg() procedure if the user selects the */
- /* CANCEL button in our dialog box */
-
- bAbort = FALSE;
-
- /* set up the Abort Procedure */
-
- if (SetAbortProc(hPrnDC, (ABORTPROC)PrintAbortProc) < 0)
- return ERR_SETABORTPROC;
-
- /* start print job */
-
- ZeroMemory(&DocInfo, sizeof(DOCINFO));
- DocInfo.cbSize = sizeof(DOCINFO);
- DocInfo.lpszDocName = (LPTSTR)szJobNameTrunc;
- DocInfo.lpszOutput = NULL;
-
- if (StartDoc(hPrnDC, &DocInfo) <= 0)
- {
- /* Oops, something happened, let's clean up here and return */
-
- DestroyWindow(hDlgAbort); /* Remove abort dialog box */
- DeleteDC(hPrnDC);
- GlobalUnlock(hDib);
- return ERR_STARTDOC;
- }
-
- /* Note: the following banding code applies to Windows 3.1. With the new */
- /* printing architecture of Win32, send out both the graphics and */
- /* text in one band (like a non-banding device). This code is used */
- /* for Win32s since Win32s depends on Windows 3.1 printing architecture. */
- /* */
- /* Check if need to do banding. If we do, loop through */
- /* each band in the page, calling NEXTBAND and BANDINFO */
- /* (if supported) calling PrintBand() on the band. Else, */
- /* call PrintBand() with the entire page as our clipping */
- /* rectangle! */
-
- /* If Wincap32 is running on Win32s, then use banding */
-
- nTemp = NEXTBAND;
- if (Escape(hPrnDC, QUERYESCSUPPORT, sizeof(int), (LPSTR)&nTemp, NULL) &&
- (GetVersion() & 0x80000000) && (LOWORD(GetVersion()) == 3))
- {
- BOOL bBandInfoDevice;
- BANDINFOSTRUCT biBandInfo; /* Used for banding */
-
- /* Fill in initial values for our BandInfo Structure to */
- /* tell driver we can want to do graphics and text, and */
- /* also which area we want the graphics to go in. */
-
- biBandInfo.bGraphics = TRUE;
- biBandInfo.bText = TRUE;
- biBandInfo.GraphicsRect = rPrintRect;
-
- /* Check if device supports the BANDINFO escape. */
-
- nTemp = BANDINFO;
- bBandInfoDevice = Escape(hPrnDC, QUERYESCSUPPORT, sizeof(int),
- (LPSTR)&nTemp, NULL);
-
- /* Do each band -- Call Escape() with NEXTBAND, then the */
- /* rect structure returned is the area where we are to */
- /* print in. This loop exits when the rect area is empty. */
-
- while (Escape(hPrnDC, NEXTBAND, 0, NULL, (LPSTR)&rect) && !
- IsRectEmpty(&rect))
- {
- char szTmpBuf[100];
-
-
- /* Do the BANDINFO, if needed. */
-
- if (bBandInfoDevice)
- Escape(hPrnDC, BANDINFO, sizeof(BANDINFOSTRUCT), (LPSTR)&
- biBandInfo, (LPSTR)&biBandInfo);
- LoadString(ghDLLInst, IDS_BANDNMBR, lpBuffer, sizeof(lpBuffer));
- wsprintf(szTmpBuf, lpBuffer, ++nBandCount);
- SetDlgItemText(hDlgAbort, IDC_PERCENTAGE, (LPSTR)szTmpBuf);
-
- /* Call PrintBand() to do actual output into band. */
- /* Pass in our band-info flags to tell what sort */
- /* of data to output into the band. Note that on */
- /* non-banding devices, we pass in the default bandinfo */
- /* stuff set above (i.e. bText=TRUE, bGraphics=TRUE). */
-
- wErrorCode = PrintBand(hPrnDC, &rPrintRect, &rect,
- biBandInfo.bText, biBandInfo.bGraphics, lpDIBHdr,
- lpBits);
- }
- }
- else
- {
- /* Print the whole page -- non-banding device. */
-
- if (StartPage(hPrnDC) <= 0)
- return ERR_STARTPAGE;
-
- rect = rPrintRect;
- LoadString(ghDLLInst, IDS_SENDINGBAND, lpBuffer, sizeof(lpBuffer));
- SetDlgItemText(hDlgAbort, IDC_PERCENTAGE, lpBuffer);
- wErrorCode = PrintBand(hPrnDC, &rPrintRect, &rect, TRUE, TRUE,
- lpDIBHdr, lpBits);
-
- /* Non-banding devices need a NEWFRAME */
-
- if (EndPage(hPrnDC) <= 0)
- return ERR_ENDPAGE;
- }
-
-
- /* End the print operation. Only send the ENDDOC if */
- /* we didn't abort or error. */
-
- if (!bAbort)
- {
- /* We errored out on ENDDOC, but don't return here - we still */
- /* need to close the dialog box, free proc instances, etc. */
-
- if (EndDoc(hPrnDC) <= 0)
- wErrorCode = ERR_ENDDOC;
-
- DestroyWindow(hDlgAbort);
- }
-
- /* All done, clean up. */
-
- DeleteDC(hPrnDC);
- }
- else
- wErrorCode = ERR_GETDC; /* Couldn't get Printer DC! */
-
- GlobalUnlock(hDib);
- return wErrorCode;
- }
-
-
-
-
- /* ******************************************************************* */
- /* Auxiliary Functions */
- /* -- Local to this module only */
- /* ******************************************************************* */
-
-
- /*********************************************************************
- *
- * CalculatePrintRect()
- *
- * Given fPrintOpt and a size of the DIB, return the area on the
- * printer where the image should go (in printer coordinates). If
- * fPrintOpt is PW_SCALE, then lpPrintRect.left and .top should
- * contain WORDs which specify the scaling factor for the X and
- * Y directions, respecively.
- *
- ********************************************************************/
-
- void CalculatePrintRect(HDC hDC, LPRECT lpPrintRect, WORD fPrintOpt,
- DWORD cxDIB, DWORD cyDIB)
- {
- int cxPage, cyPage, cxInch, cyInch;
-
- if (!hDC)
- return;
-
- /* Get some info from printer driver */
-
- cxPage = GetDeviceCaps(hDC, HORZRES); /* Width of printr page - pixels */
- cyPage = GetDeviceCaps(hDC, VERTRES); /* Height of printr page - pixels */
- cxInch = GetDeviceCaps(hDC, LOGPIXELSX);/* Printer pixels per inch - X */
- cyInch = GetDeviceCaps(hDC, LOGPIXELSY);/* Printer pixels per inch - Y */
-
- switch (fPrintOpt)
- {
-
- /* Best Fit case -- create a rectangle which preserves */
- /* the DIB's aspect ratio, and fills the page horizontally. */
-
- /* The formula in the "->bottom" field below calculates the Y */
- /* position of the printed bitmap, based on the size of the */
- /* bitmap, the width of the page, and the relative size of */
- /* a printed pixel (cyInch / cxInch). */
-
- case PW_BESTFIT:
- lpPrintRect->top = 0;
- lpPrintRect->left = 0;
- lpPrintRect->bottom = (int)(((double)cyDIB * cxPage * cyInch) /
- ((double)cxDIB * cxInch));
- lpPrintRect->right = cxPage;
- break;
-
- /* Scaling option -- lpPrintRect's top/left contain */
- /* multipliers to multiply the DIB's height/width by. */
-
- case PW_SCALE:
- {
- int cxMult, cyMult;
-
- cxMult = lpPrintRect->left;
- cyMult = lpPrintRect->top;
- lpPrintRect->top = 0;
- lpPrintRect->left = 0;
- lpPrintRect->bottom = (int)(cyDIB * cyMult);
- lpPrintRect->right = (int)(cxDIB * cxMult);
- break;
- }
-
- /* Stretch To Page case -- create a rectangle */
- /* which covers the entire printing page (note that this */
- /* is also the default). */
-
- case PW_STRETCHTOPAGE:
-
- default:
- lpPrintRect->top = 0;
- lpPrintRect->left = 0;
- lpPrintRect->bottom = cyPage;
- lpPrintRect->right = cxPage;
- break;
- }
- }
-
-
- /*********************************************************************
- *
- * PrintBand()
- *
- * This routine does ALL output to the printer. It is called from
- * the PrintDIB() routine. It is called for both banding and non-
- * banding printing devices. lpRectClip contains the rectangular
- * area we should do our output into (i.e. we should clip our output
- * to this area). The flags fDoText and fDoGraphics should be set
- * appropriately (if we want any text output to the rectangle, set
- * fDoText to true). Normally these flags are returned on banding
- * devices which support the BANDINFO escape.
- *
- ********************************************************************/
-
- WORD PrintBand(HDC hDC, LPRECT lpRectOut, LPRECT lpRectClip, BOOL fDoText,
- BOOL fDoGraphics, LPBITMAPINFOHEADER lpDIBHdr, LPSTR lpDIBBits)
- {
- RECT rect; /* Temporary rectangle */
- double dblXScaling, /* X and Y scaling factors */
- dblYScaling;
- WORD wReturn = 0; /* Return code */
-
- if (fDoGraphics)
- {
- dblXScaling = ((double)lpRectOut->right - lpRectOut->left) / (double)
- lpDIBHdr->biWidth;
- dblYScaling = ((double)lpRectOut->bottom - lpRectOut->top) / (double)
- lpDIBHdr->biHeight;
-
- /* Now we set up a temporary rectangle -- this rectangle */
- /* holds the coordinates on the paper where our bitmap */
- /* WILL be output. We can intersect this rectangle with */
- /* the lpClipRect to see what we NEED to output to this */
- /* band. Then, we determine the coordinates in the DIB */
- /* to which this rectangle corresponds (using dbl?Scaling). */
-
- IntersectRect(&rect, lpRectOut, lpRectClip);
- if (!IsRectEmpty(&rect))
- {
- RECT rectIn;
-
- rectIn.left = (int)((rect.left - lpRectOut->left) / dblXScaling +
- 0.5
- );
- rectIn.top = (int)((rect.top - lpRectOut->top) / dblYScaling + 0.5);
- rectIn.right = (int)(rectIn.left + (rect.right - rect.left) /
- dblXScaling + 0.5);
- rectIn.bottom = (int)(rectIn.top + (rect.bottom - rect.top) /
- dblYScaling + 0.5);
- if (!StretchDIBits(hDC, rect.left, rect.top,
- rect.right - rect.left, rect.bottom - rect.top,
- rectIn.left, (int)(lpDIBHdr->biHeight) -
- rectIn.top - (rectIn.bottom - rectIn.top),
- rectIn.right - rectIn.left, rectIn.bottom - rectIn.top,
- lpDIBBits, (LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS,
- SRCCOPY))
- wReturn = ERR_STRETCHDIBITS; /* StretchDIBits() failed! */
- }
- }
-
- return wReturn;
- }
-
-
- /***********************************************************************
- *
- * GetPrinterDC()
- *
- * Uses PrinDlg common dialog for printer selection and creates a dc.
- * Returns NULL on error.
- *
- ***********************************************************************/
-
- HDC GetPrinterDC() {
-
- PRINTDLG pd;
-
- ZeroMemory(&pd, sizeof(pd));
-
- pd.lStructSize = sizeof(PRINTDLG);
- pd.Flags = PD_RETURNDC;
-
- if (PrintDlg(&pd) == TRUE)
- {
- DEVNAMES *pDevNames = GlobalLock(pd.hDevNames);
-
- lstrcpy((LPSTR)gszDevice,
- (LPSTR)((char *)pDevNames+pDevNames->wDeviceOffset));
-
- if(!lstrcmpi((LPSTR)((char *)pDevNames+pDevNames->wDeviceOffset),
- (LPSTR)((char *)pDevNames+pDevNames->wOutputOffset)))
- lstrcpy((LPSTR)gszOutput, "net:");
- else
- lstrcpy((LPSTR)gszOutput,
- (LPSTR)((char *)pDevNames+pDevNames->wOutputOffset));
-
- GlobalUnlock(pd.hDevNames);
- return pd.hDC;
- }
-
- else
- return NULL;
- }
-
-
- /**********************************************************************
- * PrintAbortProc()
- *
- * Abort procedure - contains the message loop while printing is
- * in progress. By using a PeekMessage() loop, multitasking
- * can occur during printing.
- *
- **********************************************************************/
-
- BOOL CALLBACK PrintAbortProc(HDC hDC, int code)
- {
- MSG msg;
-
- while (!bAbort && PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
- if (!IsDialogMessage(hDlgAbort, &msg))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- return !bAbort;
- }
-
- /***********************************************************************
- *
- * PrintAbortDlg()
- *
- *
- * This is the Dialog Procedure which will handle the "Now Printing"
- * dialog box. When the user presses the "Cancel" button, the
- * global variable bAbort is set to TRUE, which causes the
- * PrintAbortProc to exit, which in turn causes the printing
- * operation to terminate.
- *
- ***********************************************************************/
-
- int CALLBACK PrintAbortDlg(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
- {
- switch (msg)
- {
- case WM_INITDIALOG:
- {
- char szBuffer[100];
-
- /* Fill in the text which specifies where this bitmap */
- /* is going ("on HP LaserJet on LPT1", for example) */
- LoadString(ghDLLInst, IDS_ABORTSTRING, msgBuffer, sizeof(msgBuffer));
- wsprintf(szBuffer, msgBuffer, (LPSTR)gszDevice,
- (LPSTR)gszOutput);
- SetDlgItemText(hWnd, IDC_PRINTTEXT2, (LPSTR)szBuffer);
- SetFocus(GetDlgItem(hWnd, IDCANCEL));
- return TRUE; /* Return TRUE because we called SetFocus() */
- }
-
- case WM_COMMAND:
- bAbort = TRUE;
- DestroyWindow(hWnd);
- return TRUE;
- break;
- }
-
- return FALSE;
- }
-
-#endif
-
-#define NEW_DIB_FORMAT(lpbih) (lpbih->biSize != sizeof(BITMAPCOREHEADER))
-
- /******************************************************************************
- * *
- * FUNCTION : DIBNumColors(LPVOID lpv) *
- * *
- * PURPOSE : Determines the number of colors in the DIB by looking at *
- * the BitCount and ClrUsed fields in the info block. *
- * *
- * RETURNS : The number of colors in the DIB. With DIBS with more than *
- * 8-bits-per-pixel that have a color table table included, *
- * then the return value will be the number of colors in the *
- * color table rather than the number of colors in the DIB. *
- * *
- * *
- *****************************************************************************/
- WORD DIBNumColors (LPVOID lpv)
- {
- INT bits;
- LPBITMAPINFOHEADER lpbih = (LPBITMAPINFOHEADER)lpv;
- LPBITMAPCOREHEADER lpbch = (LPBITMAPCOREHEADER)lpv;
-
- /* With the BITMAPINFO format headers, the size of the palette
- * is in biClrUsed, whereas in the BITMAPCORE - style headers, it
- * is dependent on the bits per pixel ( = 2 raised to the power of
- * bits/pixel).
- */
- if (NEW_DIB_FORMAT(lpbih)) {
- if (lpbih->biClrUsed != 0)
- return (WORD)lpbih->biClrUsed;
- bits = lpbih->biBitCount;
- }
- else
- bits = lpbch->bcBitCount;
-
- if (bits > 8)
- return 0; /* Since biClrUsed is 0, we dont have a an optimal palette */
- else
- return (1 << bits);
- }
-
- /******************************************************************************
- * *
- * FUNCTION : ColorTableSize(LPVOID lpv) *
- * *
- * PURPOSE : Calculates the palette size in bytes. If the info. block *
- * is of the BITMAPCOREHEADER type, the number of colors is *
- * multiplied by 3 to give the palette size, otherwise the *
- * number of colors is multiplied by 4. *
- * *
- * RETURNS : Color table size in number of bytes. *
- * *
- *****************************************************************************/
- WORD ColorTableSize (LPVOID lpv)
- {
- LPBITMAPINFOHEADER lpbih = (LPBITMAPINFOHEADER)lpv;
-
- if (NEW_DIB_FORMAT(lpbih))
- {
- if (((LPBITMAPINFOHEADER)(lpbih))->biCompression == BI_BITFIELDS)
- /* Remember that 16/32bpp dibs can still have a color table */
- return (sizeof(DWORD) * 3) + (DIBNumColors (lpbih) * sizeof (RGBQUAD));
- else
- return (DIBNumColors (lpbih) * sizeof (RGBQUAD));
- }
- else
- return (DIBNumColors (lpbih) * sizeof (RGBTRIPLE));
- }
-
-