[Rd] GCircle(): fails for non-clippable devices under certain circumstances (see below) (PR#940)
thoffman@zappa.sax.de
thoffman@zappa.sax.de
Tue, 15 May 2001 23:36:37 +0200 (MET DST)
The following code snippet from graphics.c: GCircle() (around line 3100) fails for devices which
can not clip (dd->dp.canClip==0) and try to plot a circle that does not fit into the plot region, but
fits into the device region, see inserted comments:
....
result = clipCircleCode(x, y, coords, ir, dd);
// result>0, because circle does not fit into plot region (for dd->gp.xpd=0)
switch (result) {
case -2: /* No clipping; draw all of circle */
dd->dp.circle(x, y, coords, ir, bg, fg, dd);
break;
case -1: /* Total clipping; draw nothing */
break;
default: /* Partial clipping; draw poly[line|gon] */
// we proceed here:
dd->gp.xpd = 2;
// check clipping for the device region:
result = clipCircleCode(x, y, coords, ir, dd);
// ...if it fits, result=-2: ouch, we have thrown away the result from the 1st check!
dd->gp.xpd = xpdsaved;
if (dd->dp.canClip && result == -2) {
// ...but it does not matter if we can clip!
GClip(dd);
dd->dp.circle(x, y, coords, ir, bg, fg, dd);
}
else {
//...BUT if we can not clip, then we call for trouble:
vmax = vmaxget();$
....
default: /* Partial clipping; draw poly[line|gon] */
if (dd->dp.canClip) {
dd->gp.xpd = 2;
result = clipCircleCode(x, y, coords, ir, dd);
dd->gp.xpd = xpdsaved;
if (result == -2) {
GClip(dd);
dd->dp.circle(x, y, coords, ir, bg, fg, dd);
break;
}
}
vmax = vmaxget();
xc = (double*)R_alloc(result+1, sizeof(double));
yc = (double*)R_alloc(result+1, sizeof(double));
GConvert(&x, &y, coords, DEVICE, dd);
convertCircle(x, y, ir, result, xc, yc, dd);
if (bg == NA_INTEGER) {
dd->gp.col = fg;
GPolyline(result+1, xc, yc, DEVICE, dd);
}
else {
int npts;
double *xcc, *ycc;
xcc = ycc = 0; /* -Wall */
npts = GClipPolygon(xc, yc, result, DEVICE, 0, xcc, ycc, dd);
if (npts > 1) {
xcc = (double*)R_alloc(npts, sizeof(double));
ycc = (double*)R_alloc(npts, sizeof(double));
npts = GClipPolygon(xc, yc, result, DEVICE, 1,
xcc, ycc, dd);
dd->dp.polygon(npts, xcc, ycc, DEVICE, bg, fg, dd);
}
}
vmaxset(vmax);
}
}
This works at least in my test case at
> version
_
platform i386-pc-os2_emx
arch i386
os os2_emx
system i386, os2_emx
status
major 1
minor 2.2
year 2001
month 02
day 26
language R
Thomas Hoffmann.
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._