blob: 5686ded09d2331a648151bcd0535b51932a540cb [file] [log] [blame]
/*
* R : A Computer Language for Statistical Data Analysis
* Copyright (C) 1999-2001 Guido Masarotto and Brian Ripley
*
* 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/
*/
/*
* metafile newmetafile(char *name,rect r)
* return a metafile object of 'nominal' size (r.width)x(r.height)
* in 0.01mm. Use drawto(...)/drawXXX/gdrawXXX to draw to the
* metafile. If "name"=="" metafile is in memory.
*
* del(metafile) finalizes/closes the metafile. Closed in memory
* metafile are saved to the clipboard.
*
*/
#define ENABLE_NLS 1
#include "win-nls.h"
#include "internal.h"
#include "rui.h"
/*
* Internal metafile deletion function.
*/
static void private_delmetafile(metafile obj)
{
HENHMETAFILE hm;
if (!obj || (obj->kind != MetafileObject)) return;
hm = (HENHMETAFILE) CloseEnhMetaFile((HDC) obj->handle);
if (strlen(GA_gettext(obj))) { /* real file*/
DeleteEnhMetaFile(hm);
return;
}
if (OpenClipboard(NULL) && EmptyClipboard() && /* try to save to the*/
SetClipboardData(CF_ENHMETAFILE, hm) && /*clipboard */
CloseClipboard())
return;
else {
R_ShowMessage(G_("Unable to save metafile to the clipboard"));
DeleteEnhMetaFile(hm);
return;
}
}
/*
* Create/return the base printer object.
*/
static object get_metafile_base(void)
{
static object metafile_base = NULL;
if (! metafile_base)
metafile_base = new_object(BaseObject, 0, NULL);
return metafile_base;
}
/* width and height are in mm */
metafile newmetafile(const char *name, double width, double height,
double xpinch, double ypinch)
{
metafile obj;
HDC hDC;
RECT wr;
static double cppix=-1, ppix, cppiy, ppiy;
/* If user has overridden, do not query Windows for device info */
if (xpinch > 0.0 && ypinch > 0.0) {
cppix = xpinch;
ppix = 100 * xpinch;
cppiy = ypinch;
ppiy = 100 * ypinch;
} else {
/*
* In theory, (cppix=ppix) and (cppiy=ppiy). However, we
* use the ratio to adjust the 'reference dimension'
* in case.... ("Importing graph in MsWord" thread)
*/
if (cppix < 0) {
cppix = 25.40 * devicewidth(NULL) / devicewidthmm(NULL);
ppix = 100 * devicepixelsx(NULL);
cppiy = 25.40 * deviceheight(NULL) / deviceheightmm(NULL);
ppiy = 100 * devicepixelsy(NULL);
}
}
/* This is all very peculiar. We would really like to create
a metafile measured in some sensible units, but it seems
we get it in units of 0.01mm *on the current screen* with
horizontal and vertical resolution set for that screen.
And of course Windows is famous for getting screen sizes wrong.
*/
wr.left = 0;
wr.top = 0 ;
wr.right = (ppix * width) / cppix ;
wr.bottom = (ppiy * height) / cppiy ;
/* Here the size is in 0.01mm units */
hDC = CreateEnhMetaFile(NULL, strlen(name) ? name : NULL, &wr,
"GraphApp\0\0");
if ( !hDC ) {
R_ShowMessage(G_("Unable to create metafile"));
return NULL;
}
obj = new_object(MetafileObject, (HANDLE) hDC, get_metafile_base());
if ( !obj ) {
R_ShowMessage(G_("Insufficient memory to create metafile"));
DeleteEnhMetaFile(CloseEnhMetaFile(hDC));
return NULL;
}
/* In looks like Windows rounds up the width and height, so we
do too. 1 out is common, but 2 out has been seen.
This is needed to get complete painting of the background.
*/
obj->rect = rect(0, 0, 2+(ppix * width)/2540, 2+(ppiy * height)/2540);
obj->depth = GetDeviceCaps(hDC, BITSPIXEL) * GetDeviceCaps(hDC, PLANES);
obj->die = private_delmetafile;
obj->drawstate = copydrawstate();
obj->drawstate->dest = obj;
settext(obj, name ? name : "");
return obj;
}