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