Full_Name: Peter Kampstra
Version: 2.4.0
OS: Windows
Submission from: (NULL) (130.37.20.20)


Hi,

If you use win.metafile(), "Save as metafile...", or "Copy as metafile" on
Windows, the metafile is rendered at screen resolution. Therefore, the output of
curves like

win.metafile("resolution.emf")
x=seq(1,10,0.001)
y=1/x
plot(x,y,type="l")
dev.off()

does not look smooth. I tracked the problem down to
https://svn.r-project.org/R/trunk/src/gnuwin32/graphapp/metafile.c , to
    hDC = CreateEnhMetaFile(NULL, strlen(name) ? name : NULL, &wr, 
                            "GraphApp\0\0");
If NULL is passed as reference HDC to this function, the metafile will be at
screen resolution. If you use such a picture in Word/Powerpoint/etc, it is
visible that curved lines are not smooth...

Therefore, I suggest using a printer as the reference HDC instead. The following
function can be used:

/*
 *  Creates a HDC to the best printer to be used as a reference for
CreateEnhMetaFile
 */
HDC createbestmetafilehdc() {
        DWORD                           neededsize;
        DWORD                           noprinters;
        DWORD                           printer;
        LPPRINTER_INFO_5        printerinfo = NULL;
        int                                     bestres = 0;
        HDC                                     besthdc = 0;

        EnumPrinters(PRINTER_ENUM_CONNECTIONS|PRINTER_ENUM_LOCAL, NULL, 5, 
NULL, 0,
&neededsize, &noprinters);
        printerinfo = (LPPRINTER_INFO_5) malloc(neededsize);

        if (EnumPrinters(PRINTER_ENUM_CONNECTIONS|PRINTER_ENUM_LOCAL, NULL, 5,
(LPBYTE)printerinfo, neededsize, &neededsize, &noprinters)) {
                //init best resolution for hdc=0, which is screen resolution:   
 
                HDC curhdc = GetDC(NULL);
                if (curhdc) {
                        bestres = GetDeviceCaps(curhdc, LOGPIXELSX) + 
GetDeviceCaps(curhdc,
LOGPIXELSY);
                        bestres = ReleaseDC(NULL, curhdc); 
                }

                for (int i = 0; i < noprinters; i++) {
                        curhdc = CreateDC("WINSPOOL", 
printerinfo[i].pPrinterName, NULL, NULL);
                        if (curhdc) {
                                int curres = GetDeviceCaps(curhdc, LOGPIXELSX) 
+ GetDeviceCaps(curhdc,
LOGPIXELSY);
                                if (curres > bestres) {
                                        if (besthdc)
                                                DeleteDC(besthdc);
                                        bestres = curres;
                                        besthdc = curhdc;
                                } else {
                                        DeleteDC(curhdc);
                                }
                        }
                }
        }

        free(printerinfo);
        return besthdc;
}

This function can be used like:
        HDC refhdc=createbestmetafilehdc();

        hDC = CreateEnhMetaFile(refhdc, strlen(name) ? name : NULL, &wr, 
                            "GraphApp\0\0");
        if (refhdc)
                DeleteDC(refhdc);

And cppix,ppix, etc. can be calculated like (this is a workaround for buggy
drivers??):
        HDC forhdc=refhdc;
        if (!(forhdc))
                forhdc=GetDC(NULL);                   
        cppix = 25.40 * GetDeviceCaps(forhdc,HORZRES) /
GetDeviceCaps(forhdc,HORZSIZE);
        ppix  = 100 * GetDeviceCaps(forhdc, LOGPIXELSX);
        cppiy = 25.40 * GetDeviceCaps(forhdc, VERTRES) / GetDeviceCaps(forhdc,
VERTSIZE);
        ppiy  = 100 * GetDeviceCaps(forhdc, LOGPIXELSY);
        if (!(refhdc))
                ReleaseDC(NULL,forhdc);

And probably some other changes will be necessary...

Keep up the good work,

Peter Kampstra
[EMAIL PROTECTED] / http://peter.kampstra.net

______________________________________________
R-devel@r-project.org mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel

Reply via email to