The R Project SVN R

Rev

Rev 83775 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4394 ripley 1
/*
2
 *  R : A Computer Language for Statistical Data Analysis
9237 ripley 3
 *  Copyright (C) 1999, 2000  Guido Masarotto
4394 ripley 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
42300 ripley 16
 *  along with this program; if not, a copy is available at
68956 ripley 17
 *  https://www.R-project.org/Licenses/
4394 ripley 18
 */
19
 
83775 kalibera 20
/* Copyright (C) 2023      The R Core Team
21
   Path length limitations
22
 */
23
 
4394 ripley 24
/* Support for printer
25
 *  printer newprinter()  - return a printer object - to draw to the
26
 *                          printer use drawto(...) and the drawXXX
27
 *                          functions + nextpage(printer)
28
 *                          printers can be deleted by 'del(printer)'
29
 */
30
 
42521 ripley 31
#include "win-nls.h"
4394 ripley 32
#include "internal.h"
4649 ripley 33
#include "rui.h"
4394 ripley 34
 
83775 kalibera 35
#include <stdlib.h>
4394 ripley 36
 
83775 kalibera 37
 
4394 ripley 38
/*
39
 *  Internal printer deletion function.
40
 */
41
static void private_delprinter(printer obj)
42
{
4649 ripley 43
    HDC h = (HDC) obj->handle;
44
    if (!obj || !h || (obj->kind != PrinterObject)) return;
45
    EndPage(h);
46
    EndDoc(h);
47
    DeleteDC(h);
48
    return;
4394 ripley 49
}
50
 
51
/*
52
 *  Create/return the base printer object.
53
 */
54
static object get_printer_base(void)
55
{
4649 ripley 56
    static object printer_base = NULL;
4394 ripley 57
 
4649 ripley 58
    if (! printer_base)
59
	printer_base = new_object(BaseObject, 0, NULL);
60
    return printer_base;
4394 ripley 61
}
62
 
44201 ripley 63
static HDC chooseprinter(void)
4649 ripley 64
{
4394 ripley 65
    PRINTDLG pd;
66
    HDC dc;
6098 pd 67
    DWORD rc;
83775 kalibera 68
    char *cwd = NULL;
4394 ripley 69
 
83775 kalibera 70
    /* FIXME: can PrintDlg change the current directory? */
71
    rc = GetCurrentDirectory(0, NULL);
72
    if (rc) {
73
	cwd = (char *)malloc(rc);
74
	if (cwd) {
75
	    DWORD rc1 = GetCurrentDirectory(rc, cwd);
76
	    if (rc1 <= 0 || rc1 >= rc) {
77
		free(cwd);
78
		cwd = NULL;
79
	    }
80
	}
81
    }
4394 ripley 82
 
83
    pd.lStructSize = sizeof( PRINTDLG );
4649 ripley 84
    pd.hwndOwner = NULL;
85
    pd.hDevMode = (HANDLE)NULL;
86
    pd.hDevNames = (HANDLE)NULL;
4394 ripley 87
    pd.Flags = PD_RETURNDC | PD_NOSELECTION | PD_NOPAGENUMS |
4649 ripley 88
	PD_USEDEVMODECOPIES;
89
    pd.nFromPage = 0;
90
    pd.nToPage = 0;
91
    pd.nMinPage = 0;
92
    pd.nMaxPage = 0;
93
    pd.nCopies = 1;
94
    pd.hInstance = (HINSTANCE)NULL;
4394 ripley 95
    pd.lCustData = (LPARAM)0;
96
    pd.lpfnPrintHook = 0;
97
    pd.lpfnSetupHook = 0;
98
    pd.lpPrintTemplateName = (LPCSTR) 0;
99
    pd.lpSetupTemplateName = (LPCSTR) 0;
100
    pd.hPrintTemplate = (HGLOBAL)0;
101
    pd.hSetupTemplate = (HGLOBAL)0;
102
 
83775 kalibera 103
    /* FIXME: use PrintDlgEx? */
4394 ripley 104
    dc = PrintDlg( &pd ) ? pd.hDC : NULL;
83775 kalibera 105
    if (cwd) {
106
	SetCurrentDirectory(cwd);
107
	free(cwd);
108
    }
6098 pd 109
    if (!dc) {
110
	rc = CommDlgExtendedError(); /* 0 means user cancelled */
80542 maechler 111
	if (rc) R_ShowMessage(G_("Unable to choose printer"));
6098 pd 112
    }
4394 ripley 113
    return dc;
114
}
115
 
116
 
41793 ripley 117
printer newprinter(double width, double height, const char *name)
4394 ripley 118
{
119
    DOCINFO docinfo;
120
    printer obj;
19110 ripley 121
    HDC hDC;
4394 ripley 122
    double dd,AL;
123
    int ww,hh,x0,y0;
4649 ripley 124
 
19110 ripley 125
    if(strlen(name)) {
126
	OSVERSIONINFO verinfo;
127
	verinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
128
	GetVersionEx(&verinfo);
129
	switch(verinfo.dwPlatformId) {
130
	case VER_PLATFORM_WIN32_NT:
131
	    hDC = CreateDC("WINSPOOL", name, NULL, NULL);
132
	default:
133
	    hDC = CreateDC(NULL, name, NULL, NULL);
134
	}
135
    } else hDC = chooseprinter();
6098 pd 136
    if ( !hDC ) return NULL;
137
    obj = new_object(PrinterObject, (HANDLE) hDC, get_printer_base());
4394 ripley 138
    if ( !obj ) {
80542 maechler 139
	R_ShowMessage(G_("Insufficient memory for new printer"));
4649 ripley 140
	DeleteDC(hDC);
141
	return NULL;
4394 ripley 142
    }
4649 ripley 143
    if ((width == 0.0) && (height == 0.0)) {
144
	ww = GetDeviceCaps(hDC, HORZRES);
145
	hh = GetDeviceCaps(hDC, VERTRES);
4394 ripley 146
    }
147
    else {
4649 ripley 148
	if (width < 0.1) width = 0.1;
149
	if (height < 0.1) height = 0.1;
150
	dd =  GetDeviceCaps(hDC, HORZSIZE) / width;
151
	AL = (dd < 1.0) ? dd : 1.0;
152
	dd = GetDeviceCaps(hDC, VERTSIZE) / height;
153
	AL = (dd < AL) ? dd : AL;
6098 pd 154
	ww = (AL * width) * GetDeviceCaps(hDC, LOGPIXELSX) / 25.4;
155
	hh = (AL * height) * GetDeviceCaps(hDC, LOGPIXELSY) / 25.4;
4394 ripley 156
    }
6098 pd 157
    x0 = (GetDeviceCaps(hDC, HORZRES) - ww) / 2;
158
    y0 = (GetDeviceCaps(hDC, VERTRES) - hh) / 2;
159
    obj->rect = rect(x0, y0, ww, hh);
160
    obj->depth = GetDeviceCaps(hDC, BITSPIXEL)* GetDeviceCaps(hDC, PLANES);
4394 ripley 161
    obj->die = private_delprinter;
162
    obj->drawstate = copydrawstate();
163
    obj->drawstate->dest = obj;
164
 
165
    docinfo.cbSize = sizeof(DOCINFO);	/* set this size... */
166
    docinfo.lpszDocName = "GraphAppPrintJob";
167
    docinfo.lpszOutput = 0;		/* no file output... */
168
    docinfo.lpszDatatype = 0;
169
    docinfo.fwType = 0;
170
 
83779 kalibera 171
    /* Note: this fails when trying to print to a file using a long path,
172
       seen on Windows 10 19045, "Microsoft Print to PDF". However, this is
173
       the same as with other applications, seems to be a Windows issue. */
4394 ripley 174
    if (StartDoc(hDC, &docinfo) <= 0) {
80542 maechler 175
	R_ShowMessage(G_("Unable to start the print job"));
4649 ripley 176
	del(obj);
177
	return NULL;
4394 ripley 178
    }
179
 
180
    StartPage(hDC);
181
    return obj;
182
}
183
 
184
 
4649 ripley 185
void nextpage(printer p)
186
{
187
    if (!p || (p->kind != PrinterObject)) return;
188
    EndPage((HDC) p->handle);
189
    StartPage((HDC) p->handle);
4394 ripley 190
}