baptiste.auguie at gmail.com
2009-Dec-11 14:15 UTC
[Rd] incorrect linetype with pdf device (PR#14128)
Full_Name: baptiste augui?
Version: 2.10.1 RC (2009-12-06 r50690)
OS: Mac OSX 10.5
Submission from: (NULL) (90.25.215.172)
The following code, run with a vanilla R session, produces different visual
output for the two devices,
library(grid)
pdf("test-pdf.pdf")
grid.newpage()
grid.lines(gp=gpar(lty="13", lineend = "butt"))
dev.off()
png("test-png.png")
grid.newpage()
grid.lines(gp=gpar(lty="13", lineend = "butt"))
dev.off()
The pdf output, opened with Acrobat, shows only extremely thin marks (artifacts)
at low zoom factor, and invisible line at higher zoom factor. The same file
opened with Adobe Illustrator reveals that the line pattern lty=13 has in fact
become 04 (0 solid length, 4 space). Similarly, lty=123456 would produce 032547,
pdf("test-123456.pdf")
grid.newpage()
grid.lines(gp=gpar(lty="123456", lineend = "butt"))
dev.off()
while the same command with quartz() gives the correct line pattern,
quartz(type="pdf", file="test2-123456.pdf")
grid.newpage()
grid.lines(gp=gpar(lty="123456", lineend = "butt"))
dev.off()
The same behavior is observed with R 2.11.0 (2009-12-09 r50690)
sessionInfo()
R version 2.10.1 RC (2009-12-06 r50690)
i386-apple-darwin9.8.0
locale:
[1] en_GB.UTF-8/en_GB.UTF-8/C/C/en_GB.UTF-8/en_GB.UTF-8
attached base packages:
[1] grid stats graphics grDevices utils datasets methods
[8] base
Dear list,
A small follow up on this issue. The same behavior is observed for
postscript() and pdf(), so I suspect the erroneous code is in
grDevices/src/devPS.c. In particular, this macro,
static void
PostScriptSetLineTexture(FILE *fp, const char *dashlist, int nlty, double lwd)
{
/* use same macro for Postscript and PDF */
#define PP_SetLineTexture(_CMD_) \
double dash; \
int i; \
fprintf(fp,"["); \
for (i = 0; i < nlty; i++) { \
dash = (lwd >= 1 ? lwd: 1) * \
((i % 2) ? dashlist[i] + 1 \
:((nlty == 1 && dashlist[i] == 1.) ? 1. : dashlist[i] - 1)); \
if (dash < 0) dash = 0; \
fprintf(fp," %.2f", dash); \
} \
fprintf(fp,"] 0 %s\n", _CMD_)
PP_SetLineTexture("setdash");
}
I think the dash pattern should be
dash = (lwd >= 1 ? lwd: 1) * \
((i % 2) ? dashlist[i] \
:((nlty == 1 && dashlist[i] == 1.) ? 1. : dashlist[i] ));
instead (but I don't know C well enough to be sure).
Best regards,
baptiste
Dear all,
Running this minimal example,
library(grid)
postscript("test-123456.eps")
grid.newpage()
grid.lines(gp=gpar(lty="123456", lineend = "butt"))
dev.off()
produces eps output with the following setdash description towards the
end of the file,
## [ 0.00 3.00 2.00 5.00 4.00 7.00] 0 setdash
I consulted the postscript reference manual (page 667 *), which
indicates that the array should rather be [1 2 3 4 5 6] as intended
(and as produced by, e.g., quartz())
(*): http://www.adobe.com/products/postscript/pdfs/PLRM.pdf
Regards,
baptiste