1 /*
2 * R : A Computer Language for Statistical Data Analysis
3 * Copyright (C) 1999, 2000 Guido Masarotto
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, a copy is available at
17 * https://www.R-project.org/Licenses/
18 */
19
20 /* Support for printer
21 * printer newprinter() - return a printer object - to draw to the
22 * printer use drawto(...) and the drawXXX
23 * functions + nextpage(printer)
24 * printers can be deleted by 'del(printer)'
25 */
26
27 #include "win-nls.h"
28 #include "internal.h"
29 #include "rui.h"
30
31
32 /*
33 * Internal printer deletion function.
34 */
private_delprinter(printer obj)35 static void private_delprinter(printer obj)
36 {
37 HDC h = (HDC) obj->handle;
38 if (!obj || !h || (obj->kind != PrinterObject)) return;
39 EndPage(h);
40 EndDoc(h);
41 DeleteDC(h);
42 return;
43 }
44
45 /*
46 * Create/return the base printer object.
47 */
get_printer_base(void)48 static object get_printer_base(void)
49 {
50 static object printer_base = NULL;
51
52 if (! printer_base)
53 printer_base = new_object(BaseObject, 0, NULL);
54 return printer_base;
55 }
56
chooseprinter(void)57 static HDC chooseprinter(void)
58 {
59 PRINTDLG pd;
60 HDC dc;
61 DWORD rc;
62 char cwd[MAX_PATH];
63
64 GetCurrentDirectory(MAX_PATH,cwd);
65
66 pd.lStructSize = sizeof( PRINTDLG );
67 pd.hwndOwner = NULL;
68 pd.hDevMode = (HANDLE)NULL;
69 pd.hDevNames = (HANDLE)NULL;
70 pd.Flags = PD_RETURNDC | PD_NOSELECTION | PD_NOPAGENUMS |
71 PD_USEDEVMODECOPIES;
72 pd.nFromPage = 0;
73 pd.nToPage = 0;
74 pd.nMinPage = 0;
75 pd.nMaxPage = 0;
76 pd.nCopies = 1;
77 pd.hInstance = (HINSTANCE)NULL;
78 pd.lCustData = (LPARAM)0;
79 pd.lpfnPrintHook = 0;
80 pd.lpfnSetupHook = 0;
81 pd.lpPrintTemplateName = (LPCSTR) 0;
82 pd.lpSetupTemplateName = (LPCSTR) 0;
83 pd.hPrintTemplate = (HGLOBAL)0;
84 pd.hSetupTemplate = (HGLOBAL)0;
85
86 dc = PrintDlg( &pd ) ? pd.hDC : NULL;
87 SetCurrentDirectory(cwd);
88 if (!dc) {
89 rc = CommDlgExtendedError(); /* 0 means user cancelled */
90 if (rc) R_ShowMessage(_("Unable to choose printer"));
91 }
92 return dc;
93 }
94
95
newprinter(double width,double height,const char * name)96 printer newprinter(double width, double height, const char *name)
97 {
98 DOCINFO docinfo;
99 printer obj;
100 HDC hDC;
101 double dd,AL;
102 int ww,hh,x0,y0;
103
104 if(strlen(name)) {
105 OSVERSIONINFO verinfo;
106 verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
107 GetVersionEx(&verinfo);
108 switch(verinfo.dwPlatformId) {
109 case VER_PLATFORM_WIN32_NT:
110 hDC = CreateDC("WINSPOOL", name, NULL, NULL);
111 default:
112 hDC = CreateDC(NULL, name, NULL, NULL);
113 }
114 } else hDC = chooseprinter();
115 if ( !hDC ) return NULL;
116 obj = new_object(PrinterObject, (HANDLE) hDC, get_printer_base());
117 if ( !obj ) {
118 R_ShowMessage(_("Insufficient memory for new printer"));
119 DeleteDC(hDC);
120 return NULL;
121 }
122 if ((width == 0.0) && (height == 0.0)) {
123 ww = GetDeviceCaps(hDC, HORZRES);
124 hh = GetDeviceCaps(hDC, VERTRES);
125 }
126 else {
127 if (width < 0.1) width = 0.1;
128 if (height < 0.1) height = 0.1;
129 dd = GetDeviceCaps(hDC, HORZSIZE) / width;
130 AL = (dd < 1.0) ? dd : 1.0;
131 dd = GetDeviceCaps(hDC, VERTSIZE) / height;
132 AL = (dd < AL) ? dd : AL;
133 ww = (AL * width) * GetDeviceCaps(hDC, LOGPIXELSX) / 25.4;
134 hh = (AL * height) * GetDeviceCaps(hDC, LOGPIXELSY) / 25.4;
135 }
136 x0 = (GetDeviceCaps(hDC, HORZRES) - ww) / 2;
137 y0 = (GetDeviceCaps(hDC, VERTRES) - hh) / 2;
138 obj->rect = rect(x0, y0, ww, hh);
139 obj->depth = GetDeviceCaps(hDC, BITSPIXEL)* GetDeviceCaps(hDC, PLANES);
140 obj->die = private_delprinter;
141 obj->drawstate = copydrawstate();
142 obj->drawstate->dest = obj;
143
144 docinfo.cbSize = sizeof(DOCINFO); /* set this size... */
145 docinfo.lpszDocName = "GraphAppPrintJob";
146 docinfo.lpszOutput = 0; /* no file output... */
147 docinfo.lpszDatatype = 0;
148 docinfo.fwType = 0;
149
150 if (StartDoc(hDC, &docinfo) <= 0) {
151 R_ShowMessage(_("Unable to start the print job"));
152 del(obj);
153 return NULL;
154 }
155
156 StartPage(hDC);
157 return obj;
158 }
159
160
nextpage(printer p)161 void nextpage(printer p)
162 {
163 if (!p || (p->kind != PrinterObject)) return;
164 EndPage((HDC) p->handle);
165 StartPage((HDC) p->handle);
166 }
167