| /* |
| * R : A Computer Language for Statistical Data Analysis |
| * Copyright (C) 1999, 2000 Guido Masarotto |
| * |
| * This program 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 of the License, or |
| * (at your option) any later version. |
| * |
| * This program 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 this program; if not, a copy is available at |
| * https://www.R-project.org/Licenses/ |
| */ |
| |
| /* Support for printer |
| * printer newprinter() - return a printer object - to draw to the |
| * printer use drawto(...) and the drawXXX |
| * functions + nextpage(printer) |
| * printers can be deleted by 'del(printer)' |
| */ |
| |
| #include "win-nls.h" |
| #include "internal.h" |
| #include "rui.h" |
| |
| |
| /* |
| * Internal printer deletion function. |
| */ |
| static void private_delprinter(printer obj) |
| { |
| HDC h = (HDC) obj->handle; |
| if (!obj || !h || (obj->kind != PrinterObject)) return; |
| EndPage(h); |
| EndDoc(h); |
| DeleteDC(h); |
| return; |
| } |
| |
| /* |
| * Create/return the base printer object. |
| */ |
| static object get_printer_base(void) |
| { |
| static object printer_base = NULL; |
| |
| if (! printer_base) |
| printer_base = new_object(BaseObject, 0, NULL); |
| return printer_base; |
| } |
| |
| static HDC chooseprinter(void) |
| { |
| PRINTDLG pd; |
| HDC dc; |
| DWORD rc; |
| char cwd[MAX_PATH]; |
| |
| GetCurrentDirectory(MAX_PATH,cwd); |
| |
| pd.lStructSize = sizeof( PRINTDLG ); |
| pd.hwndOwner = NULL; |
| pd.hDevMode = (HANDLE)NULL; |
| pd.hDevNames = (HANDLE)NULL; |
| pd.Flags = PD_RETURNDC | PD_NOSELECTION | PD_NOPAGENUMS | |
| PD_USEDEVMODECOPIES; |
| pd.nFromPage = 0; |
| pd.nToPage = 0; |
| pd.nMinPage = 0; |
| pd.nMaxPage = 0; |
| pd.nCopies = 1; |
| pd.hInstance = (HINSTANCE)NULL; |
| pd.lCustData = (LPARAM)0; |
| pd.lpfnPrintHook = 0; |
| pd.lpfnSetupHook = 0; |
| pd.lpPrintTemplateName = (LPCSTR) 0; |
| pd.lpSetupTemplateName = (LPCSTR) 0; |
| pd.hPrintTemplate = (HGLOBAL)0; |
| pd.hSetupTemplate = (HGLOBAL)0; |
| |
| dc = PrintDlg( &pd ) ? pd.hDC : NULL; |
| SetCurrentDirectory(cwd); |
| if (!dc) { |
| rc = CommDlgExtendedError(); /* 0 means user cancelled */ |
| if (rc) R_ShowMessage(_("Unable to choose printer")); |
| } |
| return dc; |
| } |
| |
| |
| printer newprinter(double width, double height, const char *name) |
| { |
| DOCINFO docinfo; |
| printer obj; |
| HDC hDC; |
| double dd,AL; |
| int ww,hh,x0,y0; |
| |
| if(strlen(name)) { |
| OSVERSIONINFO verinfo; |
| verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); |
| GetVersionEx(&verinfo); |
| switch(verinfo.dwPlatformId) { |
| case VER_PLATFORM_WIN32_NT: |
| hDC = CreateDC("WINSPOOL", name, NULL, NULL); |
| default: |
| hDC = CreateDC(NULL, name, NULL, NULL); |
| } |
| } else hDC = chooseprinter(); |
| if ( !hDC ) return NULL; |
| obj = new_object(PrinterObject, (HANDLE) hDC, get_printer_base()); |
| if ( !obj ) { |
| R_ShowMessage(_("Insufficient memory for new printer")); |
| DeleteDC(hDC); |
| return NULL; |
| } |
| if ((width == 0.0) && (height == 0.0)) { |
| ww = GetDeviceCaps(hDC, HORZRES); |
| hh = GetDeviceCaps(hDC, VERTRES); |
| } |
| else { |
| if (width < 0.1) width = 0.1; |
| if (height < 0.1) height = 0.1; |
| dd = GetDeviceCaps(hDC, HORZSIZE) / width; |
| AL = (dd < 1.0) ? dd : 1.0; |
| dd = GetDeviceCaps(hDC, VERTSIZE) / height; |
| AL = (dd < AL) ? dd : AL; |
| ww = (AL * width) * GetDeviceCaps(hDC, LOGPIXELSX) / 25.4; |
| hh = (AL * height) * GetDeviceCaps(hDC, LOGPIXELSY) / 25.4; |
| } |
| x0 = (GetDeviceCaps(hDC, HORZRES) - ww) / 2; |
| y0 = (GetDeviceCaps(hDC, VERTRES) - hh) / 2; |
| obj->rect = rect(x0, y0, ww, hh); |
| obj->depth = GetDeviceCaps(hDC, BITSPIXEL)* GetDeviceCaps(hDC, PLANES); |
| obj->die = private_delprinter; |
| obj->drawstate = copydrawstate(); |
| obj->drawstate->dest = obj; |
| |
| docinfo.cbSize = sizeof(DOCINFO); /* set this size... */ |
| docinfo.lpszDocName = "GraphAppPrintJob"; |
| docinfo.lpszOutput = 0; /* no file output... */ |
| docinfo.lpszDatatype = 0; |
| docinfo.fwType = 0; |
| |
| if (StartDoc(hDC, &docinfo) <= 0) { |
| R_ShowMessage(_("Unable to start the print job")); |
| del(obj); |
| return NULL; |
| } |
| |
| StartPage(hDC); |
| return obj; |
| } |
| |
| |
| void nextpage(printer p) |
| { |
| if (!p || (p->kind != PrinterObject)) return; |
| EndPage((HDC) p->handle); |
| StartPage((HDC) p->handle); |
| } |