The R Project SVN R

Rev

Rev 36017 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 36017 Rev 36167
Line 417... Line 417...
417
    }
417
    }
418
    return ans;
418
    return ans;
419
}
419
}
420
 
420
 
421
/* GetTextArg() : extract from call and possibly set text arguments
421
/* GetTextArg() : extract from call and possibly set text arguments
422
 *  ("label", col=, cex=, font=, vfont=)
422
 *  ("label", col=, cex=, font=)
423
 *
423
 *
424
 * Main purpose: Treat things like  title(main = list("This Title", font= 4))
424
 * Main purpose: Treat things like  title(main = list("This Title", font= 4))
425
 *
425
 *
426
 * Called from	do_title()  [only, currently]
426
 * Called from	do_title()  [only, currently]
427
 */
427
 */
428
static void
428
static void
429
GetTextArg(SEXP call, SEXP spec, SEXP *ptxt,
429
GetTextArg(SEXP call, SEXP spec, SEXP *ptxt,
430
	   int *pcol, double *pcex, int *pfont, SEXP *pvfont)
430
	   int *pcol, double *pcex, int *pfont)
431
{
431
{
432
    int i, n, col, font, colspecd;
432
    int i, n, col, font, colspecd;
433
    double cex;
433
    double cex;
434
    SEXP txt, vfont, nms;
434
    SEXP txt, nms;
435
 
435
 
436
    txt	  = R_NilValue;
436
    txt	  = R_NilValue;
437
    vfont = R_NilValue;
-
 
438
    cex	  = NA_REAL;
437
    cex	  = NA_REAL;
439
    col	  = R_TRANWHITE;
438
    col	  = R_TRANWHITE;
440
    colspecd = 0;
439
    colspecd = 0;
441
    font  = NA_INTEGER;
440
    font  = NA_INTEGER;
442
    PROTECT(txt);
441
    PROTECT(txt);
Line 477... Line 476...
477
		    }
476
		    }
478
		}
477
		}
479
		else if (!strcmp(CHAR(STRING_ELT(nms, i)), "font")) {
478
		else if (!strcmp(CHAR(STRING_ELT(nms, i)), "font")) {
480
		    font = asInteger(FixupFont(VECTOR_ELT(spec, i), NA_INTEGER));
479
		    font = asInteger(FixupFont(VECTOR_ELT(spec, i), NA_INTEGER));
481
		}
480
		}
482
		else if (!strcmp(CHAR(STRING_ELT(nms, i)), "vfont")) {
-
 
483
		    vfont = FixupVFont(VECTOR_ELT(spec, i));
-
 
484
		}
-
 
485
		else if (!strcmp(CHAR(STRING_ELT(nms, i)), "")) {
481
		else if (!strcmp(CHAR(STRING_ELT(nms, i)), "")) {
486
		    txt = VECTOR_ELT(spec, i);
482
		    txt = VECTOR_ELT(spec, i);
487
		    if (TYPEOF(txt) == LANGSXP || TYPEOF(txt)==SYMSXP) {
483
		    if (TYPEOF(txt) == LANGSXP || TYPEOF(txt)==SYMSXP) {
488
			UNPROTECT(1);
484
			UNPROTECT(1);
489
			PROTECT(txt = coerceVector(txt, EXPRSXP));
485
			PROTECT(txt = coerceVector(txt, EXPRSXP));
Line 510... Line 506...
510
    if (txt != R_NilValue) {
506
    if (txt != R_NilValue) {
511
	*ptxt = txt;
507
	*ptxt = txt;
512
	if (R_FINITE(cex))	 *pcex	 = cex;
508
	if (R_FINITE(cex))	 *pcex	 = cex;
513
	if (colspecd)	         *pcol	 = col;
509
	if (colspecd)	         *pcol	 = col;
514
	if (font != NA_INTEGER)	 *pfont	 = font;
510
	if (font != NA_INTEGER)	 *pfont	 = font;
515
	if (vfont != R_NilValue) *pvfont = vfont;
-
 
516
    }
511
    }
517
}/* GetTextArg */
512
}/* GetTextArg */
518
 
513
 
519
 
514
 
520
    /* GRAPHICS FUNCTION ENTRY POINTS */
515
    /* GRAPHICS FUNCTION ENTRY POINTS */
Line 585... Line 580...
585
    if (length(args) < 3)
580
    if (length(args) < 3)
586
	errorcall(call, _("at least 3 arguments required"));
581
	errorcall(call, _("at least 3 arguments required"));
587
 
582
 
588
    xlim = CAR(args);
583
    xlim = CAR(args);
589
    if (!isNumeric(xlim) || LENGTH(xlim) != 2)
584
    if (!isNumeric(xlim) || LENGTH(xlim) != 2)
590
	errorcall(call, _("invalid '%s' value"), "ylim");
585
	errorcall(call, _("invalid '%s' value"), "xlim");
591
    args = CDR(args);
586
    args = CDR(args);
592
 
587
 
593
    ylim = CAR(args);
588
    ylim = CAR(args);
594
    if (!isNumeric(ylim) || LENGTH(ylim) != 2)
589
    if (!isNumeric(ylim) || LENGTH(ylim) != 2)
595
	errorcall(call, _("invalid '%s' value"), "xlim");
590
	errorcall(call, _("invalid '%s' value"), "ylim");
596
    args = CDR(args);
591
    args = CDR(args);
597
 
592
 
598
    logscale = FALSE;
593
    logscale = FALSE;
599
    logarg = CAR(args);
594
    logarg = CAR(args);
600
    if (!isString(logarg))
595
    if (!isString(logarg))
Line 654... Line 649...
654
	pin1 = GConvertXUnits(1.0, NPC, INCHES, dd);
649
	pin1 = GConvertXUnits(1.0, NPC, INCHES, dd);
655
	pin2 = GConvertYUnits(1.0, NPC, INCHES, dd);
650
	pin2 = GConvertYUnits(1.0, NPC, INCHES, dd);
656
	xdelta = fabs(xmax - xmin) / asp;
651
	xdelta = fabs(xmax - xmin) / asp;
657
	ydelta = fabs(ymax - ymin);
652
	ydelta = fabs(ymax - ymin);
658
	if(xdelta == 0.0 && ydelta == 0.0) {
653
	if(xdelta == 0.0 && ydelta == 0.0) {
659
	    /* We really do mean zero: small non-zero values work
654
	    /* We really do mean zero: small non-zero values work.
660
	       Mimic the behaviour of GScale for the x axis. */
655
	       Mimic the behaviour of GScale for the x axis. */
661
	    xadd = yadd = ((xmin == 0.0) ? 1 : 0.4) * asp;
656
	    xadd = yadd = ((xmin == 0.0) ? 1 : 0.4) * asp;
662
	    xadd *= asp;
657
	    xadd *= asp;
663
	} else {
658
	} else {
664
	    xscale = pin1 / xdelta;
659
	    xscale = pin1 / xdelta;
Line 674... Line 669...
674
    }
669
    }
675
    else { /* asp <= 0 or not finite -- includes logscale ! */
670
    else { /* asp <= 0 or not finite -- includes logscale ! */
676
	GScale(xmin, xmax, 1, dd);
671
	GScale(xmin, xmax, 1, dd);
677
	GScale(ymin, ymax, 2, dd);
672
	GScale(ymin, ymax, 2, dd);
678
    }
673
    }
-
 
674
    /* GScale set the [xy]axp parameters */
679
    GMapWin2Fig(dd);
675
    GMapWin2Fig(dd);
680
    GRestorePars(dd);
676
    GRestorePars(dd);
-
 
677
    /* This has now clobbered the Rf_ggptr settings for coord system */
681
    /* NOTE: the operation is only recorded if there was no "error" */
678
    /* NOTE: the operation is only recorded if there was no "error" */
682
    if (GRecording(call, dd))
679
    if (GRecording(call, dd))
683
	recordGraphicOperation(op, originalArgs, dd);
680
	recordGraphicOperation(op, originalArgs, dd);
684
    return R_NilValue;
681
    return R_NilValue;
685
}
682
}
Line 956... Line 953...
956
}
953
}
957
 
954
 
958
SEXP do_axis(SEXP call, SEXP op, SEXP args, SEXP env)
955
SEXP do_axis(SEXP call, SEXP op, SEXP args, SEXP env)
959
{
956
{
960
    /* axis(side, at, labels, tick, line, pos,
957
    /* axis(side, at, labels, tick, line, pos,
961
     *	    outer, font, vfont, lty, lwd, col, padj, ...) */
958
     *	    outer, font, lty, lwd, col, padj, ...) */
962
 
959
 
963
    SEXP at, lab, vfont, padj;
960
    SEXP at, lab, padj;
964
    int col, font, lty, npadj;
961
    int col, font, lty, npadj;
965
    int i, n, nint = 0, ntmp, side, *ind, outer, lineoff = 0;
962
    int i, n, nint = 0, ntmp, side, *ind, outer, lineoff = 0;
966
    int istart, iend, incr;
963
    int istart, iend, incr;
967
    Rboolean dolabels, doticks, logflag = FALSE;
964
    Rboolean dolabels, doticks, logflag = FALSE;
968
    Rboolean create_at;
965
    Rboolean create_at;
Line 976... Line 973...
976
 
973
 
977
    /* Arity Check */
974
    /* Arity Check */
978
    /* This is a builtin function, so it should always have */
975
    /* This is a builtin function, so it should always have */
979
    /* the correct arity, but it doesn't hurt to be defensive. */
976
    /* the correct arity, but it doesn't hurt to be defensive. */
980
 
977
 
981
    if (length(args) < 9)
978
    if (length(args) < 12)
982
	errorcall(call, _("too few arguments"));
979
	errorcall(call, _("too few arguments"));
983
    GCheckState(dd);
980
    GCheckState(dd);
984
 
981
 
985
    /* Required argument: "side" */
982
    /* Required argument: "side" */
986
    /* Which side of the plot the axis is to appear on. */
983
    /* Which side of the plot the axis is to appear on. */
Line 1061... Line 1058...
1061
 
1058
 
1062
    /* Optional argument: "font" */
1059
    /* Optional argument: "font" */
1063
    font = asInteger(FixupFont(CAR(args), NA_INTEGER));
1060
    font = asInteger(FixupFont(CAR(args), NA_INTEGER));
1064
    args = CDR(args);
1061
    args = CDR(args);
1065
 
1062
 
1066
    /* Optional argument: "vfont" */
-
 
1067
    /* Allows Hershey vector fonts to be used */
-
 
1068
    PROTECT(vfont = FixupVFont(CAR(args)));
-
 
1069
    if (!isNull(vfont)) {
-
 
1070
      warning("vfont not supported for axis();  use par(family) instead");
-
 
1071
    }
-
 
1072
    args = CDR(args);
-
 
1073
 
-
 
1074
    /* Optional argument: "lty" */
1063
    /* Optional argument: "lty" */
1075
    lty = asInteger(FixupLty(CAR(args), NA_INTEGER));
1064
    lty = asInteger(FixupLty(CAR(args), NA_INTEGER));
1076
    args = CDR(args);
1065
    args = CDR(args);
1077
 
1066
 
1078
    /* Optional argument: "lwd" */
1067
    /* Optional argument: "lwd" */
1079
    lwd = asReal(FixupLwd(CAR(args), Rf_gpptr(dd)->lwd));
1068
    lwd = asReal(FixupLwd(CAR(args), 1));
1080
    args = CDR(args);
1069
    args = CDR(args);
1081
 
1070
 
1082
    /* Optional argument: "col" */
1071
    /* Optional argument: "col" */
1083
    col = asInteger(FixupCol(CAR(args), Rf_gpptr(dd)->fg));
1072
    col = asInteger(FixupCol(CAR(args), Rf_gpptr(dd)->fg));
1084
    args = CDR(args);
1073
    args = CDR(args);
Line 1094... Line 1083...
1094
    npadj = length(padj);
1083
    npadj = length(padj);
1095
    if (npadj <= 0) errorcall(call, _("zero length 'padj' specified"));
1084
    if (npadj <= 0) errorcall(call, _("zero length 'padj' specified"));
1096
 
1085
 
1097
    /* Now we process all the remaining inline par values:
1086
    /* Now we process all the remaining inline par values:
1098
       we need to do it now as x/yaxp are retrieved next.
1087
       we need to do it now as x/yaxp are retrieved next.
1099
       That will set Rf_gpptr, so we update that. */
1088
       That will set Rf_gpptr, so we update that first - do_plotwindow
-
 
1089
       clobbered the Rf_gpptr settings. */
1100
    GSavePars(dd);
1090
    GSavePars(dd);
1101
    Rf_gpptr(dd)->xaxp[0] = Rf_dpptr(dd)->xaxp[0];
1091
    Rf_gpptr(dd)->xaxp[0] = Rf_dpptr(dd)->xaxp[0];
1102
    Rf_gpptr(dd)->xaxp[1] = Rf_dpptr(dd)->xaxp[1];
1092
    Rf_gpptr(dd)->xaxp[1] = Rf_dpptr(dd)->xaxp[1];
1103
    Rf_gpptr(dd)->xaxp[2] = Rf_dpptr(dd)->xaxp[2];
1093
    Rf_gpptr(dd)->xaxp[2] = Rf_dpptr(dd)->xaxp[2];
1104
    Rf_gpptr(dd)->yaxp[0] = Rf_dpptr(dd)->yaxp[0];
1094
    Rf_gpptr(dd)->yaxp[0] = Rf_dpptr(dd)->yaxp[0];
Line 1183... Line 1173...
1183
     * If it is, we just bail out at this point. */
1173
     * If it is, we just bail out at this point. */
1184
 
1174
 
1185
    if (((side == 1 || side == 3) && Rf_gpptr(dd)->xaxt == 'n') ||
1175
    if (((side == 1 || side == 3) && Rf_gpptr(dd)->xaxt == 'n') ||
1186
	((side == 2 || side == 4) && Rf_gpptr(dd)->yaxt == 'n')) {
1176
	((side == 2 || side == 4) && Rf_gpptr(dd)->yaxt == 'n')) {
1187
	GRestorePars(dd);
1177
	GRestorePars(dd);
1188
	UNPROTECT(5);
1178
	UNPROTECT(4);
1189
	return R_NilValue;
1179
	return R_NilValue;
1190
    }
1180
    }
1191
 
1181
 
1192
 
1182
 
1193
    /* no! we do allow an `lty' argument -- will not be used often though
1183
    /* no! we do allow an `lty' argument -- will not be used often though
1194
     *	Rf_gpptr(dd)->lty = LTY_SOLID; */
1184
     *	Rf_gpptr(dd)->lty = LTY_SOLID; */
1195
    Rf_gpptr(dd)->lty = lty;
1185
    Rf_gpptr(dd)->lty = lty;
1196
    Rf_gpptr(dd)->lwd = lwd;
1186
    Rf_gpptr(dd)->lwd = lwd;
1197
 
1187
 
1198
    /* Override par("xpd") and force clipping to figure region.
1188
    /* Override par("xpd") and force clipping to device region. */
1199
     * NOTE: don't override to _reduce_ clipping region */
-
 
1200
 
-
 
1201
    Rf_gpptr(dd)->xpd = 2;
1189
    Rf_gpptr(dd)->xpd = 2;
1202
 
1190
 
1203
    Rf_gpptr(dd)->adj = R_FINITE(hadj) ? hadj : 0.5;
1191
    Rf_gpptr(dd)->adj = R_FINITE(hadj) ? hadj : 0.5;
1204
    Rf_gpptr(dd)->font = (font == NA_INTEGER)? Rf_gpptr(dd)->fontaxis : font;
1192
    Rf_gpptr(dd)->font = (font == NA_INTEGER)? Rf_gpptr(dd)->fontaxis : font;
1205
    Rf_gpptr(dd)->cex = Rf_gpptr(dd)->cexbase * Rf_gpptr(dd)->cexaxis;
1193
    Rf_gpptr(dd)->cex = Rf_gpptr(dd)->cexbase * Rf_gpptr(dd)->cexaxis;
Line 1472... Line 1460...
1472
    GMode(0, dd);
1460
    GMode(0, dd);
1473
    GRestorePars(dd);
1461
    GRestorePars(dd);
1474
    /* NOTE: only record operation if no "error"  */
1462
    /* NOTE: only record operation if no "error"  */
1475
    if (GRecording(call, dd))
1463
    if (GRecording(call, dd))
1476
	recordGraphicOperation(op, originalArgs, dd);
1464
	recordGraphicOperation(op, originalArgs, dd);
1477
    UNPROTECT(5); /* lab, vfont, at, lab, padj again */
1465
    UNPROTECT(4); /* lab, at, lab, padj again */
1478
    return at;
1466
    return at;
1479
}/* do_axis */
1467
}/* do_axis */
1480
 
1468
 
1481
 
1469
 
1482
SEXP do_plot_xy(SEXP call, SEXP op, SEXP args, SEXP env)
1470
SEXP do_plot_xy(SEXP call, SEXP op, SEXP args, SEXP env)
Line 1838... Line 1826...
1838
}
1826
}
1839
 
1827
 
1840
 
1828
 
1841
SEXP do_rect(SEXP call, SEXP op, SEXP args, SEXP env)
1829
SEXP do_rect(SEXP call, SEXP op, SEXP args, SEXP env)
1842
{
1830
{
1843
    /* rect(xl, yb, xr, yt, col, border, lty, lwd, xpd, ...) */
1831
    /* rect(xl, yb, xr, yt, col, border, lty, ...) */
1844
    SEXP sxl, sxr, syb, syt, sxpd, col, lty, lwd, border;
1832
    SEXP sxl, sxr, syb, syt, col, lty, lwd, border;
1845
    double *xl, *xr, *yb, *yt, x0, y0, x1, y1;
1833
    double *xl, *xr, *yb, *yt, x0, y0, x1, y1;
1846
    int i, n, nxl, nxr, nyb, nyt, ncol, nlty, nlwd, nborder, xpd;
1834
    int i, n, nxl, nxr, nyb, nyt, ncol, nlty, nlwd, nborder;
1847
    SEXP originalArgs = args;
1835
    SEXP originalArgs = args;
1848
    DevDesc *dd = CurrentDevice();
1836
    DevDesc *dd = CurrentDevice();
1849
 
1837
 
1850
    if (length(args) < 4) errorcall(call, _("too few arguments"));
1838
    if (length(args) < 4) errorcall(call, _("too few arguments"));
1851
    GCheckState(dd);
1839
    GCheckState(dd);
Line 1870... Line 1858...
1870
 
1858
 
1871
    PROTECT(lwd = FixupLwd(CAR(args), Rf_gpptr(dd)->lwd));
1859
    PROTECT(lwd = FixupLwd(CAR(args), Rf_gpptr(dd)->lwd));
1872
    nlwd = length(lwd);
1860
    nlwd = length(lwd);
1873
    args = CDR(args);
1861
    args = CDR(args);
1874
 
1862
 
1875
    sxpd = CAR(args);
-
 
1876
    if (sxpd != R_NilValue)
-
 
1877
	xpd = asInteger(sxpd);
-
 
1878
    else
-
 
1879
	xpd = Rf_gpptr(dd)->xpd;
-
 
1880
    args = CDR(args);
-
 
1881
 
-
 
1882
    GSavePars(dd);
1863
    GSavePars(dd);
1883
    ProcessInlinePars(args, dd, call);
1864
    ProcessInlinePars(args, dd, call);
1884
 
1865
 
1885
    if (xpd == NA_INTEGER)
-
 
1886
	Rf_gpptr(dd)->xpd = 2;
-
 
1887
    else
-
 
1888
	Rf_gpptr(dd)->xpd = xpd;
-
 
1889
 
-
 
1890
    xl = REAL(sxl);
1866
    xl = REAL(sxl);
1891
    xr = REAL(sxr);
1867
    xr = REAL(sxr);
1892
    yb = REAL(syb);
1868
    yb = REAL(syb);
1893
    yt = REAL(syt);
1869
    yt = REAL(syt);
1894
 
1870
 
Line 1923... Line 1899...
1923
}
1899
}
1924
 
1900
 
1925
 
1901
 
1926
SEXP do_arrows(SEXP call, SEXP op, SEXP args, SEXP env)
1902
SEXP do_arrows(SEXP call, SEXP op, SEXP args, SEXP env)
1927
{
1903
{
1928
    /* arrows(x0, y0, x1, y1, length, angle, code, col, lty, lwd, xpd) */
1904
    /* arrows(x0, y0, x1, y1, length, angle, code, col, lty, lwd, ...) */
1929
    SEXP sx0, sx1, sy0, sy1, sxpd, col, rawcol, lty, lwd;
1905
    SEXP sx0, sx1, sy0, sy1, col, lty, lwd;
1930
    double *x0, *x1, *y0, *y1;
1906
    double *x0, *x1, *y0, *y1;
1931
    double xx0, yy0, xx1, yy1;
1907
    double xx0, yy0, xx1, yy1;
1932
    double hlength, angle;
1908
    double hlength, angle;
1933
    int code;
1909
    int code;
1934
    int nx0, nx1, ny0, ny1, i, n, ncol, nlty, nlwd, xpd;
1910
    int nx0, nx1, ny0, ny1, i, n, ncol, nlty, nlwd;
1935
    SEXP originalArgs = args;
1911
    SEXP originalArgs = args;
1936
    DevDesc *dd = CurrentDevice();
1912
    DevDesc *dd = CurrentDevice();
1937
 
1913
 
1938
    if (length(args) < 4) errorcall(call, _("too few arguments"));
1914
    if (length(args) < 4) errorcall(call, _("too few arguments"));
1939
    GCheckState(dd);
1915
    GCheckState(dd);
Line 1958... Line 1934...
1958
    code = asInteger(CAR(args));
1934
    code = asInteger(CAR(args));
1959
    if (code == NA_INTEGER || code < 0 || code > 3)
1935
    if (code == NA_INTEGER || code < 0 || code > 3)
1960
	errorcall(call, _("invalid arrow head specification"));
1936
	errorcall(call, _("invalid arrow head specification"));
1961
    args = CDR(args);
1937
    args = CDR(args);
1962
 
1938
 
1963
    /*
-
 
1964
     * Need raw colours to be able to check for NAs
-
 
1965
     * FixupCol converts NAs to fully transparent
-
 
1966
     */
-
 
1967
    rawcol = CAR(args);
-
 
1968
    PROTECT(col = FixupCol(rawcol, R_TRANWHITE));
1939
    PROTECT(col = FixupCol(CAR(args), R_TRANWHITE));
1969
    ncol = LENGTH(col);
1940
    ncol = LENGTH(col);
1970
    args = CDR(args);
1941
    args = CDR(args);
1971
 
1942
 
1972
    PROTECT(lty = FixupLty(CAR(args), Rf_gpptr(dd)->lty));
1943
    PROTECT(lty = FixupLty(CAR(args), Rf_gpptr(dd)->lty));
1973
    nlty = length(lty);
1944
    nlty = length(lty);
1974
    args = CDR(args);
1945
    args = CDR(args);
1975
    /* use FixupLwd, as segments() does too! */
-
 
1976
#ifdef R_1_x_y
-
 
1977
    PROTECT(lwd = CAR(args));
-
 
1978
    nlwd = length(lwd);
-
 
1979
    if (nlwd == 0)
-
 
1980
	errorcall(call, _("'lwd' must be numeric of length >=1"));
-
 
1981
#else
1946
 
1982
    PROTECT(lwd = FixupLwd(CAR(args), Rf_gpptr(dd)->lwd));
1947
    PROTECT(lwd = FixupLwd(CAR(args), Rf_gpptr(dd)->lwd));
1983
    nlwd = length(lwd);
1948
    nlwd = length(lwd);
1984
#endif
-
 
1985
    args = CDR(args);
-
 
1986
 
-
 
1987
    sxpd = CAR(args);
-
 
1988
    if (sxpd != R_NilValue)
-
 
1989
	xpd = asInteger(sxpd);
-
 
1990
    else
-
 
1991
	xpd = Rf_gpptr(dd)->xpd;
-
 
1992
    args = CDR(args);
1949
    args = CDR(args);
1993
 
1950
 
1994
    GSavePars(dd);
1951
    GSavePars(dd);
1995
 
-
 
1996
    if (xpd == NA_INTEGER)
1952
    ProcessInlinePars(args, dd, call);
1997
	Rf_gpptr(dd)->xpd = 2;
-
 
1998
    else
-
 
1999
	Rf_gpptr(dd)->xpd = xpd;
-
 
2000
 
1953
 
2001
    x0 = REAL(sx0);
1954
    x0 = REAL(sx0);
2002
    y0 = REAL(sy0);
1955
    y0 = REAL(sy0);
2003
    x1 = REAL(sx1);
1956
    x1 = REAL(sx1);
2004
    y1 = REAL(sy1);
1957
    y1 = REAL(sy1);
Line 2010... Line 1963...
2010
	xx1 = x1[i%nx1];
1963
	xx1 = x1[i%nx1];
2011
	yy1 = y1[i%ny1];
1964
	yy1 = y1[i%ny1];
2012
	GConvert(&xx0, &yy0, USER, DEVICE, dd);
1965
	GConvert(&xx0, &yy0, USER, DEVICE, dd);
2013
	GConvert(&xx1, &yy1, USER, DEVICE, dd);
1966
	GConvert(&xx1, &yy1, USER, DEVICE, dd);
2014
	if (R_FINITE(xx0) && R_FINITE(yy0) && R_FINITE(xx1) && R_FINITE(yy1)) {
1967
	if (R_FINITE(xx0) && R_FINITE(yy0) && R_FINITE(xx1) && R_FINITE(yy1)) {
2015
	    if (isNAcol(rawcol, i, ncol))
-
 
2016
		Rf_gpptr(dd)->col = Rf_dpptr(dd)->col;
-
 
2017
	    else
-
 
2018
		Rf_gpptr(dd)->col = INTEGER(col)[i % ncol];
1968
	    Rf_gpptr(dd)->col = INTEGER(col)[i % ncol];
2019
	    if (nlty == 0 || INTEGER(lty)[i % nlty] == NA_INTEGER)
-
 
2020
		Rf_gpptr(dd)->lty = Rf_dpptr(dd)->lty;
-
 
2021
	    else
-
 
2022
		Rf_gpptr(dd)->lty = INTEGER(lty)[i % nlty];
1969
	    Rf_gpptr(dd)->lty = INTEGER(lty)[i % nlty];
2023
	    Rf_gpptr(dd)->lwd = REAL(lwd)[i % nlwd];
1970
	    Rf_gpptr(dd)->lwd = REAL(lwd)[i % nlwd];
2024
	    GArrow(xx0, yy0, xx1, yy1, DEVICE,
1971
	    GArrow(xx0, yy0, xx1, yy1, DEVICE,
2025
		   hlength, angle, code, dd);
1972
		   hlength, angle, code, dd);
2026
	}
1973
	}
2027
    }
1974
    }
Line 2046... Line 1993...
2046
    GPolygon(n, x, y, USER, fill, border, dd);
1993
    GPolygon(n, x, y, USER, fill, border, dd);
2047
}
1994
}
2048
 
1995
 
2049
SEXP do_polygon(SEXP call, SEXP op, SEXP args, SEXP env)
1996
SEXP do_polygon(SEXP call, SEXP op, SEXP args, SEXP env)
2050
{
1997
{
2051
    /* polygon(x, y, col, border, lty, xpd, ...) */
1998
    /* polygon(x, y, col, border, lty, ...) */
2052
    SEXP sx, sy, col, border, lty, sxpd;
1999
    SEXP sx, sy, col, border, lty;
2053
    int nx;
2000
    int nx;
2054
    int ncol, nborder, nlty, xpd, i, start=0;
2001
    int ncol, nborder, nlty, i, start=0;
2055
    int num = 0;
2002
    int num = 0;
2056
    double *x, *y, xx, yy, xold, yold;
2003
    double *x, *y, xx, yy, xold, yold;
2057
 
2004
 
2058
    SEXP originalArgs = args;
2005
    SEXP originalArgs = args;
2059
    DevDesc *dd = CurrentDevice();
2006
    DevDesc *dd = CurrentDevice();
Line 2067... Line 2014...
2067
    nx = LENGTH(sx);
2014
    nx = LENGTH(sx);
2068
 
2015
 
2069
    PROTECT(col = FixupCol(CAR(args), R_TRANWHITE));	args = CDR(args);
2016
    PROTECT(col = FixupCol(CAR(args), R_TRANWHITE));	args = CDR(args);
2070
    ncol = LENGTH(col);
2017
    ncol = LENGTH(col);
2071
 
2018
 
2072
    PROTECT(border = FixupCol(CAR(args), Rf_gpptr(dd)->fg));	args = CDR(args);
2019
    PROTECT(border = FixupCol(CAR(args), Rf_gpptr(dd)->fg)); args = CDR(args);
2073
    nborder = LENGTH(border);
2020
    nborder = LENGTH(border);
2074
 
2021
 
2075
    PROTECT(lty = FixupLty(CAR(args), Rf_gpptr(dd)->lty));	args = CDR(args);
2022
    PROTECT(lty = FixupLty(CAR(args), Rf_gpptr(dd)->lty)); args = CDR(args);
2076
    nlty = length(lty);
2023
    nlty = length(lty);
2077
 
2024
 
2078
    sxpd = CAR(args);
-
 
2079
    if (sxpd != R_NilValue)
-
 
2080
	xpd = asInteger(sxpd);
-
 
2081
    else
-
 
2082
	xpd = Rf_gpptr(dd)->xpd;
-
 
2083
    args = CDR(args);
-
 
2084
 
-
 
2085
    GSavePars(dd);
2025
    GSavePars(dd);
2086
    ProcessInlinePars(args, dd, call);
2026
    ProcessInlinePars(args, dd, call);
2087
 
2027
 
2088
    if (xpd == NA_INTEGER)
-
 
2089
	Rf_gpptr(dd)->xpd = 2;
-
 
2090
    else
-
 
2091
	Rf_gpptr(dd)->xpd = xpd;
-
 
2092
 
-
 
2093
    GMode(1, dd);
2028
    GMode(1, dd);
2094
 
2029
 
2095
    x = REAL(sx);
2030
    x = REAL(sx);
2096
    y = REAL(sy);
2031
    y = REAL(sy);
2097
    xold = NA_REAL;
2032
    xold = NA_REAL;
Line 2135... Line 2070...
2135
}
2070
}
2136
 
2071
 
2137
SEXP do_text(SEXP call, SEXP op, SEXP args, SEXP env)
2072
SEXP do_text(SEXP call, SEXP op, SEXP args, SEXP env)
2138
{
2073
{
2139
/* text(xy, labels, adj, pos, offset,
2074
/* text(xy, labels, adj, pos, offset,
2140
 *	vfont, cex, col, font, xpd, ...)
2075
 *	vfont, cex, col, font, ...)
2141
 */
2076
 */
2142
    SEXP sx, sy, sxy, sxpd, txt, adj, pos, cex, col, rawcol, font, vfont;
2077
    SEXP sx, sy, sxy, txt, adj, pos, cex, col, rawcol, font, vfont;
2143
    int i, n, npos, ncex, ncol, nfont, ntxt, xpd;
2078
    int i, n, npos, ncex, ncol, nfont, ntxt;
2144
    double adjx = 0, adjy = 0, offset = 0.5;
2079
    double adjx = 0, adjy = 0, offset = 0.5;
2145
    double *x, *y;
2080
    double *x, *y;
2146
    double xx, yy;
2081
    double xx, yy;
2147
    Rboolean vectorFonts = FALSE;
2082
    Rboolean vectorFonts = FALSE;
2148
    SEXP string, originalArgs = args;
2083
    SEXP string, originalArgs = args;
Line 2219... Line 2154...
2219
 
2154
 
2220
    PROTECT(font = FixupFont(CAR(args), NA_INTEGER));
2155
    PROTECT(font = FixupFont(CAR(args), NA_INTEGER));
2221
    nfont = LENGTH(font);
2156
    nfont = LENGTH(font);
2222
    args = CDR(args);
2157
    args = CDR(args);
2223
 
2158
 
2224
    sxpd = CAR(args); /* xpd: NULL -> par("xpd") */
-
 
2225
    if (sxpd != R_NilValue)
-
 
2226
	xpd = asInteger(sxpd);
-
 
2227
    else
-
 
2228
	xpd = Rf_gpptr(dd)->xpd;
-
 
2229
    args = CDR(args);
-
 
2230
 
-
 
2231
    x = REAL(sx);
2159
    x = REAL(sx);
2232
    y = REAL(sy);
2160
    y = REAL(sy);
2233
    /* n = LENGTH(sx) = LENGTH(sy) */
2161
    /* n = LENGTH(sx) = LENGTH(sy) */
2234
    ntxt = LENGTH(txt);
2162
    ntxt = LENGTH(txt);
2235
 
2163
 
2236
    GSavePars(dd);
2164
    GSavePars(dd);
2237
    ProcessInlinePars(args, dd, call);
2165
    ProcessInlinePars(args, dd, call);
2238
 
2166
 
2239
    Rf_gpptr(dd)->xpd = (xpd == NA_INTEGER)? 2 : xpd;
-
 
2240
 
-
 
2241
    GMode(1, dd);
2167
    GMode(1, dd);
2242
    if (n == 0 && ntxt > 0)
2168
    if (n == 0 && ntxt > 0)
2243
	errorcall(call, _("no coordinates were supplied"));
2169
	errorcall(call, _("no coordinates were supplied"));
2244
    for (i = 0; i < imax2(n,ntxt); i++) {
2170
    for (i = 0; i < imax2(n,ntxt); i++) {
2245
	xx = x[i % n];
2171
	xx = x[i % n];
Line 2420... Line 2346...
2420
	 adj = NA,
2346
	 adj = NA,
2421
	 padj = NA,
2347
	 padj = NA,
2422
	 cex = NA,
2348
	 cex = NA,
2423
	 col = NA,
2349
	 col = NA,
2424
	 font = NA,
2350
	 font = NA,
2425
	 vfont = NULL,
-
 
2426
	 ...) */
2351
	 ...) */
2427
 
2352
 
2428
SEXP do_mtext(SEXP call, SEXP op, SEXP args, SEXP env)
2353
SEXP do_mtext(SEXP call, SEXP op, SEXP args, SEXP env)
2429
{
2354
{
2430
    SEXP text, side, line, outer, at, adj, padj, cex, col, font, vfont, string;
2355
    SEXP text, side, line, outer, at, adj, padj, cex, col, font, string;
2431
    SEXP rawcol;
2356
    SEXP rawcol;
2432
    int ntext, nside, nline, nouter, nat, nadj, npadj, ncex, ncol, nfont;
2357
    int ntext, nside, nline, nouter, nat, nadj, npadj, ncex, ncol, nfont;
2433
    Rboolean dirtyplot = FALSE, gpnewsave = FALSE, dpnewsave = FALSE;
2358
    Rboolean dirtyplot = FALSE, gpnewsave = FALSE, dpnewsave = FALSE;
2434
    int i, n, fontsave, colsave;
2359
    int i, n, fontsave, colsave;
2435
    double cexsave;
2360
    double cexsave;
Line 2516... Line 2441...
2516
    nfont = length(font);
2441
    nfont = length(font);
2517
    if (nfont <= 0) errorcall(call, _("zero length 'font' specified"));
2442
    if (nfont <= 0) errorcall(call, _("zero length 'font' specified"));
2518
    if (n < nfont) n = nfont;
2443
    if (n < nfont) n = nfont;
2519
    args = CDR(args);
2444
    args = CDR(args);
2520
 
2445
 
2521
    /* Arg11 : vfont */
-
 
2522
    PROTECT(vfont = FixupVFont(CAR(args)));
-
 
2523
    if (!isNull(vfont)) {
-
 
2524
      warning("vfont not supported for mtext();  use par(family) instead");
-
 
2525
    }
-
 
2526
    args = CDR(args);
-
 
2527
 
-
 
2528
    GSavePars(dd);
2446
    GSavePars(dd);
2529
    ProcessInlinePars(args, dd, call);
2447
    ProcessInlinePars(args, dd, call);
2530
 
2448
 
2531
    /* If we only scribble in the outer margins, */
2449
    /* If we only scribble in the outer margins, */
2532
    /* we don't want to mark the plot as dirty. */
2450
    /* we don't want to mark the plot as dirty. */
Line 2596... Line 2514...
2596
    GRestorePars(dd);
2514
    GRestorePars(dd);
2597
    if (!dirtyplot) {
2515
    if (!dirtyplot) {
2598
	Rf_gpptr(dd)->new = gpnewsave;
2516
	Rf_gpptr(dd)->new = gpnewsave;
2599
	Rf_dpptr(dd)->new = dpnewsave;
2517
	Rf_dpptr(dd)->new = dpnewsave;
2600
    }
2518
    }
2601
    UNPROTECT(11);
2519
    UNPROTECT(10);
2602
 
2520
 
2603
    /* NOTE: only record operation if no "error"  */
2521
    /* NOTE: only record operation if no "error"  */
2604
    if (GRecording(call, dd))
2522
    if (GRecording(call, dd))
2605
	recordGraphicOperation(op, originalArgs, dd);
2523
	recordGraphicOperation(op, originalArgs, dd);
2606
    return R_NilValue;
2524
    return R_NilValue;
Line 2613... Line 2531...
2613
 
2531
 
2614
   title(main, sub, xlab, ylab,
2532
   title(main, sub, xlab, ylab,
2615
	 line, outer,
2533
	 line, outer,
2616
	 ...) */
2534
	 ...) */
2617
 
2535
 
2618
    SEXP Main, xlab, ylab, sub, vfont, string;
2536
    SEXP Main, xlab, ylab, sub, string;
2619
    double adj, adjy, cex, offset, line, hpos, vpos, where;
2537
    double adj, adjy, cex, offset, line, hpos, vpos, where;
2620
    int col, font, outer;
2538
    int col, font, outer;
2621
    int i, n;
2539
    int i, n;
2622
    SEXP originalArgs = args;
2540
    SEXP originalArgs = args;
2623
    DevDesc *dd = CurrentDevice();
2541
    DevDesc *dd = CurrentDevice();
Line 2665... Line 2583...
2665
    GMode(1, dd);
2583
    GMode(1, dd);
2666
    if (Main != R_NilValue) {
2584
    if (Main != R_NilValue) {
2667
	cex = Rf_gpptr(dd)->cexmain;
2585
	cex = Rf_gpptr(dd)->cexmain;
2668
	col = Rf_gpptr(dd)->colmain;
2586
	col = Rf_gpptr(dd)->colmain;
2669
	font = Rf_gpptr(dd)->fontmain;
2587
	font = Rf_gpptr(dd)->fontmain;
2670
	GetTextArg(call, Main, &Main, &col, &cex, &font, &vfont);
2588
	GetTextArg(call, Main, &Main, &col, &cex, &font);
2671
	Rf_gpptr(dd)->col = col;
2589
	Rf_gpptr(dd)->col = col;
2672
	Rf_gpptr(dd)->cex = Rf_gpptr(dd)->cexbase * cex;
2590
	Rf_gpptr(dd)->cex = Rf_gpptr(dd)->cexbase * cex;
2673
	Rf_gpptr(dd)->font = font;
2591
	Rf_gpptr(dd)->font = font;
2674
	if (outer) {
2592
	if (outer) {
2675
	    if (R_FINITE(line)) {
2593
	    if (R_FINITE(line)) {
Line 2712... Line 2630...
2712
    }
2630
    }
2713
    if (sub != R_NilValue) {
2631
    if (sub != R_NilValue) {
2714
	cex = Rf_gpptr(dd)->cexsub;
2632
	cex = Rf_gpptr(dd)->cexsub;
2715
	col = Rf_gpptr(dd)->colsub;
2633
	col = Rf_gpptr(dd)->colsub;
2716
	font = Rf_gpptr(dd)->fontsub;
2634
	font = Rf_gpptr(dd)->fontsub;
2717
	GetTextArg(call, sub, &sub, &col, &cex, &font, &vfont);
2635
	GetTextArg(call, sub, &sub, &col, &cex, &font);
2718
	Rf_gpptr(dd)->col = col;
2636
	Rf_gpptr(dd)->col = col;
2719
	Rf_gpptr(dd)->cex = Rf_gpptr(dd)->cexbase * cex;
2637
	Rf_gpptr(dd)->cex = Rf_gpptr(dd)->cexbase * cex;
2720
	Rf_gpptr(dd)->font = font;
2638
	Rf_gpptr(dd)->font = font;
2721
	if (R_FINITE(line))
2639
	if (R_FINITE(line))
2722
	    vpos = line;
2640
	    vpos = line;
Line 2744... Line 2662...
2744
    }
2662
    }
2745
    if (xlab != R_NilValue) {
2663
    if (xlab != R_NilValue) {
2746
	cex = Rf_gpptr(dd)->cexlab;
2664
	cex = Rf_gpptr(dd)->cexlab;
2747
	col = Rf_gpptr(dd)->collab;
2665
	col = Rf_gpptr(dd)->collab;
2748
	font = Rf_gpptr(dd)->fontlab;
2666
	font = Rf_gpptr(dd)->fontlab;
2749
	GetTextArg(call, xlab, &xlab, &col, &cex, &font, &vfont);
2667
	GetTextArg(call, xlab, &xlab, &col, &cex, &font);
2750
	Rf_gpptr(dd)->cex = Rf_gpptr(dd)->cexbase * cex;
2668
	Rf_gpptr(dd)->cex = Rf_gpptr(dd)->cexbase * cex;
2751
	Rf_gpptr(dd)->col = col;
2669
	Rf_gpptr(dd)->col = col;
2752
	Rf_gpptr(dd)->font = font;
2670
	Rf_gpptr(dd)->font = font;
2753
	if (R_FINITE(line))
2671
	if (R_FINITE(line))
2754
	    vpos = line;
2672
	    vpos = line;
Line 2776... Line 2694...
2776
    }
2694
    }
2777
    if (ylab != R_NilValue) {
2695
    if (ylab != R_NilValue) {
2778
	cex = Rf_gpptr(dd)->cexlab;
2696
	cex = Rf_gpptr(dd)->cexlab;
2779
	col = Rf_gpptr(dd)->collab;
2697
	col = Rf_gpptr(dd)->collab;
2780
	font = Rf_gpptr(dd)->fontlab;
2698
	font = Rf_gpptr(dd)->fontlab;
2781
	GetTextArg(call, ylab, &ylab, &col, &cex, &font, &vfont);
2699
	GetTextArg(call, ylab, &ylab, &col, &cex, &font);
2782
	Rf_gpptr(dd)->cex = Rf_gpptr(dd)->cexbase * cex;
2700
	Rf_gpptr(dd)->cex = Rf_gpptr(dd)->cexbase * cex;
2783
	Rf_gpptr(dd)->col = col;
2701
	Rf_gpptr(dd)->col = col;
2784
	Rf_gpptr(dd)->font = font;
2702
	Rf_gpptr(dd)->font = font;
2785
	if (R_FINITE(line))
2703
	if (R_FINITE(line))
2786
	    vpos = line;
2704
	    vpos = line;