⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gsprint.cpp

📁 GSview 4.6 PostScript previewer。Ghostscript在MS-Windows, OS/2 and Unix下的图形化接口
💻 CPP
📖 第 1 页 / 共 2 页
字号:
    }
    
    // Get the information needed for the DEVNAMES structure
    GetProfileString("Devices", device, "", driverbuf, sizeof(driverbuf));
    if (strlen(driverbuf) == 0)
	return FALSE;	// printer doesn't exist

    driver = strtok(driverbuf, ",");
    output = strtok(NULL, ",");

    // Build the DEVNAMES structure
    length = sizeof(DEVNAMES) + 
	strlen(device) + 1 + 
	strlen(driver) + 1 +
	strlen(output) + 2;
    if (length < 1024)
	length = 1024;
    hglobal = GlobalAlloc(GMEM_MOVEABLE, length);
    if (hglobal == NULL)
	return FALSE;
    lpdevnames = (LPDEVNAMES)GlobalLock(hglobal);
    memset(lpdevnames, 0, length);
    offset = sizeof(DEVNAMES);
    lpdevnames->wDriverOffset = offset;
    strcpy((char *)lpdevnames + offset, driver);
    offset += strlen(driver) + 1;
    lpdevnames->wDeviceOffset = offset;
    strcpy((char *)lpdevnames + offset, device);
    offset += strlen(device) + 1;
    lpdevnames->wOutputOffset = offset;
    strcpy((char *)lpdevnames + offset, output);
    GlobalUnlock(hglobal);
    lpdevnames = NULL;
    *hdevnames = hglobal;

    // here we should try to merge requests for page size,
    // duplex, orientation etc. by obtaining and modifying
    // DEVMODE.
    LPDEVMODE podevmode, pidevmode;
    HANDLE hprinter;

    if (!OpenPrinter(device, &hprinter, NULL))
	return FALSE;
    length = DocumentProperties(NULL, hprinter, device, NULL, NULL, 0);

    hglobal = GlobalAlloc(GMEM_MOVEABLE, length);
    if (hglobal == NULL) {
	ClosePrinter(hprinter);
	return FALSE;
    }
    podevmode = (LPDEVMODE)GlobalLock(hglobal);
    memset(podevmode, 0, length);
	    
    if ((pidevmode = (LPDEVMODE)malloc(length)) == (LPDEVMODE) NULL) {
	GlobalUnlock(hglobal);
	GlobalFree(hglobal);
	ClosePrinter(hprinter);
	return FALSE;
    }
    DocumentProperties(NULL, hprinter, device, podevmode, NULL, DM_OUT_BUFFER);

    memcpy(pidevmode, podevmode, length);

    pidevmode->dmFields = 0;

    if (opt->duplex) {
	pidevmode->dmFields |= DM_DUPLEX;
	pidevmode->dmDuplex = DMDUP_VERTICAL;
    }

    if (opt->copies) {
	pidevmode->dmFields |= DM_COPIES;
	pidevmode->dmCopies = opt->copies;
    }
    if (opt->orientation == PORTRAIT) {
	pidevmode->dmFields |= DM_ORIENTATION;
	pidevmode->dmOrientation = DMORIENT_PORTRAIT;
    } else if (opt->orientation == LANDSCAPE) {
	pidevmode->dmFields |= DM_ORIENTATION;
	pidevmode->dmOrientation = DMORIENT_LANDSCAPE;
    }

    // merge the entries
    DocumentProperties(NULL, hprinter, device, podevmode, pidevmode, 
	DM_IN_BUFFER | DM_OUT_BUFFER);
    ClosePrinter(hprinter);


    free(pidevmode);
    GlobalUnlock(hglobal);
    *hdevmode = hglobal;
    return TRUE;
}

void print_devmode(HANDLE hDevMode)
{
    DWORD dw;
    if ((hDevMode == NULL) || (hDevMode == INVALID_HANDLE_VALUE))
	return;
    LPDEVMODE dm = (LPDEVMODE)GlobalLock(hDevMode);
    fprintf(stdout, "DevMode:\n");
    fprintf(stdout, " dmDeviceName=\042%s\042\n", dm->dmDeviceName);
    fprintf(stdout, " dmFields=0x%x\n", dm->dmFields);
    dw = dm->dmFields;
    if (dw & DM_ORIENTATION)
	fprintf(stdout, "  DM_ORIENTATION\n");
    if (dw & DM_PAPERSIZE)
	fprintf(stdout, "  DM_PAPERSIZE\n");
    if (dw & DM_PAPERLENGTH)
	fprintf(stdout, "  DM_PAPERLENGTH\n");
    if (dw & DM_PAPERWIDTH)
	fprintf(stdout, "  DM_PAPERWIDTH\n");
    if (dw & DM_SCALE)
	fprintf(stdout, "  DM_SCALE\n");
    if (dw & DM_COPIES)
	fprintf(stdout, "  DM_COPIES\n");
    if (dw & DM_DEFAULTSOURCE)
	fprintf(stdout, "  DM_DEFAULTSOURCE\n");
    if (dw & DM_PRINTQUALITY)
	fprintf(stdout, "  DM_PRINTQUALITY\n");
    if (dw & DM_COLOR)
	fprintf(stdout, "  DM_COLOR\n");
    if (dw & DM_DUPLEX)
	fprintf(stdout, "  DM_DUPLEX\n");
    if (dw & DM_YRESOLUTION)
	fprintf(stdout, "  DM_YRESOLUTION\n");
    if (dw & DM_TTOPTION)
	fprintf(stdout, "  DM_TTOPTION\n");
    if (dw & DM_COLLATE)
	fprintf(stdout, "  DM_COLLATE\n");
    if (dw & DM_FORMNAME)
	fprintf(stdout, "  DM_FORMNAME\n");
    fprintf(stdout, " dmOrientation=%d\n", dm->dmOrientation);
    fprintf(stdout, " dmPaperSize=%d\n", dm->dmPaperSize);
    fprintf(stdout, " dmPaperLength=%d\n", dm->dmPaperLength);
    fprintf(stdout, " dmPaperWidth=%d\n", dm->dmPaperWidth);
    fprintf(stdout, " dmScale=%d\n", dm->dmScale);
    fprintf(stdout, " dmCopies=%d\n", dm->dmCopies);
    fprintf(stdout, " dmDefaultSource=%d\n", dm->dmDefaultSource);
    fprintf(stdout, " dmPrintQuality=%d\n", dm->dmPrintQuality);
    fprintf(stdout, " dmColor=%d\n", dm->dmColor);
    fprintf(stdout, " dmDuplex=%d\n", dm->dmDuplex);
    fprintf(stdout, " dmYResolution=%d\n", dm->dmYResolution);
    fprintf(stdout, " dmTTOption=%d\n", dm->dmTTOption);
    fprintf(stdout, " dmCollate=%d\n", dm->dmCollate);
    fprintf(stdout, " dmFormName=\042%s\042\n", dm->dmFormName);
    fprintf(stdout, " dmLogPixels=%d\n", dm->dmLogPixels);
    fprintf(stdout, " dmBitsPerPel=%d\n", dm->dmBitsPerPel);
    fprintf(stdout, " dmPelsWidth=%d\n", dm->dmPelsWidth);
    fprintf(stdout, " dmPelsHeight=%d\n", dm->dmPelsHeight);
    fprintf(stdout, " dmDisplayFlags=%d\n", dm->dmDisplayFlags);
    fprintf(stdout, " dmDisplayFrequency=%d\n", dm->dmDisplayFrequency);
    GlobalUnlock(hDevMode);
}

void print_devnames(HANDLE hDevNames)
{
    if ((hDevNames == NULL) || (hDevNames == INVALID_HANDLE_VALUE))
	return;
    LPDEVNAMES lpdevnames = (LPDEVNAMES)GlobalLock(hDevNames);
    fprintf(stdout, "DevNames:\n");
    fprintf(stdout, " Device=\042%s\042\n", 
	((char *)lpdevnames) + lpdevnames->wDeviceOffset);
    fprintf(stdout, " Driver=\042%s\042\n", 
	((char *)lpdevnames) + lpdevnames->wDriverOffset);
    fprintf(stdout, " Output=\042%s\042\n", 
	((char *)lpdevnames) + lpdevnames->wOutputOffset);
    GlobalUnlock(hDevNames);
}



HDC query_printer(GSPRINT_OPTION *opt)
{
    PRINTDLG pd;
    memset(&pd, 0, sizeof(pd));
    pd.lStructSize = sizeof(pd);
    pd.hwndOwner = HWND_DESKTOP;
    pd.Flags = PD_RETURNDC;
    if (!get_devmode(opt, &pd.hDevMode, &pd.hDevNames))
	return (HDC)NULL;
    pd.Flags |= PD_NOSELECTION;
    pd.nMinPage = 1;
    pd.nMaxPage = (unsigned int)-1;
    if (opt->from != 0) {
	pd.nFromPage = opt->from;
	pd.nToPage = 999;
	pd.Flags |= PD_PAGENUMS;
    }
    if (opt->to != 0) {
	if (pd.nFromPage == 0)
		pd.nFromPage = 1;
	pd.nToPage = opt->to;
	pd.Flags |= PD_PAGENUMS;
    }

    if (!PrintDlg(&pd))
	return (HDC)NULL;

    if (pd.Flags & PD_PAGENUMS) {
	opt->from = pd.nFromPage;
	opt->to = pd.nToPage;
    }
    if (opt->debug)
	print_devnames(pd.hDevNames);
    if (opt->debug)
	print_devmode(pd.hDevMode);
    GlobalFree(pd.hDevMode);
    GlobalFree(pd.hDevNames);
    pd.hDevMode = NULL;
    pd.hDevNames = NULL;
    return pd.hDC;
}

HDC open_printer(GSPRINT_OPTION *opt)
{
    char *device;
    char *driver;
    char *output;
    HANDLE hDevMode;
    HANDLE hDevNames;
    HDC hdc;

    if (!get_devmode(opt, &hDevMode, &hDevNames))
	    return (HDC)NULL;
    
    LPDEVNAMES lpdevnames = (LPDEVNAMES)GlobalLock(hDevNames);
    device = ((char *)lpdevnames) + lpdevnames->wDeviceOffset;
    driver = ((char *)lpdevnames) + lpdevnames->wDriverOffset;
    output = ((char *)lpdevnames) + lpdevnames->wOutputOffset;

    LPDEVMODE lpdevmode = (LPDEVMODE)GlobalLock(hDevMode);

    hdc = CreateDC(driver, device, NULL, lpdevmode);

    GlobalUnlock(hDevMode);
    GlobalUnlock(hDevNames);

    if (opt->debug)
	print_devnames(hDevNames);
    if (opt->debug)
	print_devmode(hDevMode);

    GlobalFree(hDevMode);
    GlobalFree(hDevNames);

    return hdc;
}


#ifdef NOTUSED
void CheckProcess( void *dummy )
{
    DWORD exit_status;

    while (GetExitCodeProcess(piProcInfo.hProcess, &exit_status)
    && (exit_status == STILL_ACTIVE)) {
	    Sleep(1000);
	    if (global_debug)
		fprintf(stderr, ".");
    }
    if (global_debug)
	fprintf(stderr, "CheckProcess exiting\n");
    CloseHandle(piProcInfo.hProcess);
    CloseHandle(piProcInfo.hThread);

    // We still have a handle to the write end of the pipe
    // Reading the read end of the pipe won't return EOF 
    // until both the child copy of the write handle and
    // our copy of the write handle are closed.
    CloseHandle(hPipeWr);
}
#endif

int main(int argc, char *argv[])
{
    GSPRINT_OPTION opt;

    print_id();
#ifdef BETA
    if (beta())
	return 1;
#endif

    memset(&opt, 0, sizeof(opt));
    opt.args_end = 0;
    opt.args[0] = '\0';
    opt.args[1] = '\0';

    find_gs(opt.gs, sizeof(opt.gs)-1, 600, FALSE);

    // try reading the default config file
    char buf[1024];
    if (!GetModuleFileName(NULL, buf, sizeof(buf)-1))
	return 1;
    char *s = strrchr(buf, '\\');
    if (s) {
	s++;
	strcpy(s, "gsprint.cfg");
    }
    FILE *f = fopen(buf, "r");
    if (f != (FILE *)NULL) {
	if (!read_config(&opt, f)) {
	    fclose(f);
	    return 1;
	}
	fclose(f);
    }

    if (!collect_args(&opt, argc, argv))
       return 1;
    if (!process_args(&opt))
       return 1;

    if (strlen(opt.gs) == 0) {
       fprintf(stdout, "You must use -ghostscript\n");
       return 1;
    }

    if (opt.debug) {
	fprintf(stdout, "Options:\n");
	fprintf(stdout, " Colour=%d\n", opt.colour);
	fprintf(stdout, " Orientation=%d\n", opt.orientation);
	fprintf(stdout, " Duplex=%d\n", opt.duplex);
	fprintf(stdout, " Copies=%d\n", opt.copies);
	fprintf(stdout, " From=%d\n", opt.from);
	fprintf(stdout, " To=%d\n", opt.to);
	fprintf(stdout, " Even/Odd=%d\n", opt.even_odd);
	fprintf(stdout, " Twoup=%d\n", opt.twoup);
	fprintf(stdout, " Query=%d\n", opt.query);
	fprintf(stdout, " Printer=%d\n", opt.printer);
	fprintf(stdout, " Printer Name=\042%s\042\n", opt.printer_name);
	fprintf(stdout, " Ghostscript=\042%s\042\n", opt.gs);
	fprintf(stdout, " Ghostscript Options=\042%s\042\n", opt.options);
	fprintf(stdout, " Document: \042%s\042\n", opt.document_name);
    }

    // Get a printer handle
    HDC hdc = NULL;
    if (opt.query) {
	hdc = query_printer(&opt);
    }
    else {
	hdc = open_printer(&opt);
    }
    if (hdc == (HDC)NULL) {
	fprintf(stderr, "Couldn't open Windows GDI printer driver\n");
	if (!opt.query)
	    fprintf(stderr, "Printer name: \042%s\042\n", opt.printer_name);
	return 1;
    }
    
    // create the pipe for capturing printer output
    /* Set the bInheritHandle flag so pipe handles are inherited. */
    SECURITY_ATTRIBUTES saAttr;
    saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
    saAttr.bInheritHandle = TRUE;
    saAttr.lpSecurityDescriptor = NULL;
    HANDLE hPipeTemp;
    if (!CreatePipe(&hPipeTemp, &hPipeWr, &saAttr, 0)) {
	fprintf(stderr, "failed to open printer pipe\n");
	    return 1;
    }
    /* make the read handle non-inherited */
    if (!DuplicateHandle(GetCurrentProcess(), hPipeTemp,
	    GetCurrentProcess(), &hPipeRd, 0,
	    FALSE,       /* not inherited */
	    DUPLICATE_SAME_ACCESS)) {
	return 1;
    }
    CloseHandle(hPipeTemp);

    // open printer, get size and resolution
    CPrintDIB printdib;
    LPBYTE p;
    LPBYTE pLine = NULL;
    int length;
    DWORD dwRead;
    DOCINFO di;
    memset(&di, 0, sizeof(DOCINFO));
    di.cbSize = sizeof(DOCINFO);
    di.lpszDocName = strlen(opt.document_name) ? opt.document_name : "gsprint";
    di.lpszOutput = NULL;
    if (StartDoc(hdc, &di) == SP_ERROR) {
	DWORD err = GetLastError();
	fprintf(stderr, "StartDoc failed, error code %ld\n", err);
	write_error(err);
	DeleteDC(hdc);
	return 1;
    }

    int width = GetDeviceCaps(hdc, PHYSICALWIDTH);
    int height = GetDeviceCaps(hdc, PHYSICALHEIGHT);
    int xdpi = GetDeviceCaps(hdc, LOGPIXELSX);
    int ydpi = GetDeviceCaps(hdc, LOGPIXELSY);
    int xoff = GetDeviceCaps(hdc, PHYSICALOFFSETX);
    int yoff = GetDeviceCaps(hdc, PHYSICALOFFSETY);
    int hres = GetDeviceCaps(hdc, HORZRES);
    int vres = GetDeviceCaps(hdc, VERTRES);

    if (opt.debug) {
	fprintf(stdout, "PHYSICALWIDTH=%d\n", width);
	fprintf(stdout, "PHYSICALHEIGHT=%d\n", height);
	fprintf(stdout, "PHYSICALOFFSETX=%d\n", xoff);
	fprintf(stdout, "PHYSICALOFFSETY=%d\n", yoff);
	fprintf(stdout, "HORZRES=%d\n", hres);
	fprintf(stdout, "VERTRES=%d\n", vres);
	fprintf(stdout, "LOGPIXELSX=%d\n", xdpi);
	fprintf(stdout, "LOGPIXELSY=%d\n", ydpi);
    }

    // copy all the command line arguments to a buffer
    char command[4096];
    int i;
    strcpy(command, opt.gs);
    switch (opt.colour) {
	case MONO:
	    strcat(command, " -sDEVICE=bmpmono");
	    break;
	case GREY:
	    strcat(command, " -sDEVICE=bmpgray");
	    break;
	case COLOUR:
	    strcat(command, " -sDEVICE=bmp16m");
	    break;
    }
    strcat(command, " -dNOPAUSE");
    sprintf(command + strlen(command), " -g%dx%d -r%dx%d",
	width, height, xdpi, ydpi);
    sprintf(command + strlen(command), " -sOutputFile=%%handle%%%08x", hPipeWr);

   { /* Set the margins so that PDFFitPAge and EPSFitPage work better.
      * This may cause problems here.  It would be better to place it
      * just before the filename, not before other the ghostscript
      * options.
      */
 	char margin[256];
   	sprintf(margin, 
	    " -c \042<< /.HWMargins [%lg %lg %lg %lg] >> setpagedevice\042 -f",
	    (double)xoff / xdpi * 72.0,  			/* left */
	    (double)yoff / ydpi * 72.0,				/* top */
	    (double)(width - xoff - hres) / xdpi * 72.0,	/* right */
	    (double)(height - yoff - vres) / ydpi * 72.0);	/* bottom */
	strcat(command, margin);
    }

    strcat(command, opt.options);

    if (opt.twoup) 	// add an extra showpage to eject last odd page
	strcat(command, " -c showpage -f");
    strcat(command, " -c quit");

    if (opt.twoup) {
	// page counts need to be halved for twoup
	if (opt.from)
	    opt.from = opt.from / 2;
	if (opt.to)
	    opt.to = (opt.to+1) / 2;
    }

    if (opt.debug) {
	fprintf(stdout, " Command: \042%s\042\n", command);
    }

    // start the program
    if (!exec_prog(command)) {
	fprintf(stderr, "Failed to exec program\n  %s\n",command);
	CloseHandle(hPipeWr);
	CloseHandle(hPipeRd);
	return 1;
    }

    global_debug = opt.debug;
#ifdef NOTUSED
    _beginthread(CheckProcess, 32768, NULL);
#endif

    GFile *pFile = gfile_open_handle((int)hPipeRd);

    // now that program is running, we can close our copy of
    // the pipe write handle
    CloseHandle(hPipeWr);
    hPipeWr = INVALID_HANDLE_VALUE;
  
    int page = 0;
    BOOL print_it;
    printdib.debug = opt.debug_gdi;

    while (printdib.ReadHeader(pFile)) {
	page++;
	print_it = TRUE;
	if ((opt.even_odd == EVEN_PAGES) && ((page & 1) == 1))
	    print_it = FALSE;
	else if ((opt.even_odd == ODD_PAGES) && ((page & 1) == 0))
	    print_it = FALSE;
	if ((opt.from > 0) && (page < opt.from))
	    print_it = FALSE;
	if ((opt.to > 0) && (page > opt.to))
	    print_it = FALSE;
	
	fprintf(stdout, "Page %d, %s\n", page, 
		print_it ? "PRINT" : "ignore");
	if (print_it)
	    StartPage(hdc);
	length = printdib.m_bytewidth;
	pLine = new BYTE[length];
	
	for (i=0; i < printdib.m_PageBmp.bmp2.biHeight; i++) {
	    // read a scan line
	    length = printdib.m_bytewidth;
	    p = pLine;
	    while (length && (dwRead = gfile_read(pFile, p, length)) != 0) {
		length -= dwRead;
		p += dwRead;
	    }
	    if (print_it)
		printdib.AddPrintLine(hdc, i, pLine);
	}
	if (print_it) {
	    printdib.FlushPrintBitmap(hdc);
	    EndPage(hdc);
	}
	delete pLine;
    }

    EndDoc(hdc);
    DeleteDC(hdc);
    gfile_close(pFile);
    Sleep(2000);

    return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -