The R Project SVN R

Rev

Rev 26787 | Rev 29450 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 26787 Rev 27236
Line 621... Line 621...
621
 ****************************************************************
621
 ****************************************************************
622
 */
622
 */
623
/* If the device canClip, R clips line to device extent and
623
/* If the device canClip, R clips line to device extent and
624
   device does all other clipping. */
624
   device does all other clipping. */
625
void GELine(double x1, double y1, double x2, double y2,
625
void GELine(double x1, double y1, double x2, double y2,
626
	    int col, double gamma, int lty, double lwd,
-
 
627
	    GEDevDesc *dd)
626
	    R_GE_gcontext *gc, GEDevDesc *dd)
628
{
627
{
629
    Rboolean clip_ok;
628
    Rboolean clip_ok;
630
    if (lty == LTY_BLANK) return;
629
    if (gc->lty == LTY_BLANK) return;
631
    if (dd->dev->canClip) {
630
    if (dd->dev->canClip) {
632
	clip_ok = clipLine(&x1, &y1, &x2, &y2, 1, dd);
631
	clip_ok = clipLine(&x1, &y1, &x2, &y2, 1, dd);
633
    }
632
    }
634
    else {
633
    else {
635
	clip_ok = clipLine(&x1, &y1, &x2, &y2, 0, dd);
634
	clip_ok = clipLine(&x1, &y1, &x2, &y2, 0, dd);
636
    }
635
    }
637
    if (clip_ok)
636
    if (clip_ok)
638
	dd->dev->line(x1, y1, x2, y2, col, gamma, lty, lwd, dd->dev);
637
	dd->dev->line(x1, y1, x2, y2, gc, dd->dev);
639
}
638
}
640
 
639
 
641
/****************************************************************
640
/****************************************************************
642
 * R code for clipping polylines
641
 * R code for clipping polylines
643
 ****************************************************************
642
 ****************************************************************
644
 */
643
 */
645
 
644
 
646
static void CScliplines(int n, double *x, double *y,
645
static void CScliplines(int n, double *x, double *y,
647
			int col, double gamma, int lty, double lwd,
-
 
648
			int toDevice, GEDevDesc *dd)
646
			R_GE_gcontext *gc, int toDevice, GEDevDesc *dd)
649
{
647
{
650
    int ind1, ind2;
648
    int ind1, ind2;
651
    /*int firstPoint = 1;*/
649
    /*int firstPoint = 1;*/
652
    int count = 0;
650
    int count = 0;
653
    int i = 0;
651
    int i = 0;
Line 677... Line 675...
677
	    if (ind1 && ind2) {
675
	    if (ind1 && ind2) {
678
		xx[0] = x1;
676
		xx[0] = x1;
679
		yy[0] = y1;
677
		yy[0] = y1;
680
		xx[1] = x2;
678
		xx[1] = x2;
681
		yy[1] = y2;
679
		yy[1] = y2;
682
		dd->dev->polyline(2, xx, yy, col, gamma, lty, lwd, dd->dev);
680
		dd->dev->polyline(2, xx, yy, gc, dd->dev);
683
	    }
681
	    }
684
	    else if (ind1) {
682
	    else if (ind1) {
685
		xx[0] = x1;
683
		xx[0] = x1;
686
		yy[0] = y1;
684
		yy[0] = y1;
687
		xx[1] = x2;
685
		xx[1] = x2;
688
		yy[1] = y2;
686
		yy[1] = y2;
689
		count = 2;
687
		count = 2;
690
		if (i == n - 1)
688
		if (i == n - 1)
691
		    dd->dev->polyline(count, xx, yy, col, gamma, 
689
		    dd->dev->polyline(count, xx, yy, gc, dd->dev);
692
				      lty, lwd, dd->dev);
-
 
693
	    }
690
	    }
694
	    else if (ind2) {
691
	    else if (ind2) {
695
		xx[count] = x2;
692
		xx[count] = x2;
696
		yy[count] = y2;
693
		yy[count] = y2;
697
		count++;
694
		count++;
698
		if (count > 1)
695
		if (count > 1)
699
		    dd->dev->polyline(count, xx, yy, col, gamma, 
696
		    dd->dev->polyline(count, xx, yy, gc, dd->dev);
700
				      lty, lwd, dd->dev);
-
 
701
	    }
697
	    }
702
	    else {
698
	    else {
703
		xx[count] = x2;
699
		xx[count] = x2;
704
		yy[count] = y2;
700
		yy[count] = y2;
705
		count++;
701
		count++;
706
		if (i == n - 1 && count > 1)
702
		if (i == n - 1 && count > 1)
707
		    dd->dev->polyline(count, xx, yy, col, gamma, 
703
		    dd->dev->polyline(count, xx, yy, gc, dd->dev);
708
				      lty, lwd, dd->dev);
-
 
709
	    }
704
	    }
710
	}
705
	}
711
	x1 = x[i];
706
	x1 = x[i];
712
	y1 = y[i];
707
	y1 = y[i];
713
    }
708
    }
Line 721... Line 716...
721
 */
716
 */
722
/* Clip and draw the polyline.
717
/* Clip and draw the polyline.
723
   If clipToDevice = 0, clip according to dd->dev->gp.xpd
718
   If clipToDevice = 0, clip according to dd->dev->gp.xpd
724
   If clipToDevice = 1, clip to the device extent */
719
   If clipToDevice = 1, clip to the device extent */
725
static void clipPolyline(int n, double *x, double *y,
720
static void clipPolyline(int n, double *x, double *y,
726
			 int col, double gamma, int lty, double lwd,
721
			 R_GE_gcontext *gc,
727
			 int clipToDevice, GEDevDesc *dd)
722
			 int clipToDevice, GEDevDesc *dd)
728
{
723
{
729
    CScliplines(n, x, y, col, gamma, lty, lwd, clipToDevice, dd);
724
    CScliplines(n, x, y, gc, clipToDevice, dd);
730
}
725
}
731
 
726
 
732
/* Draw a series of line segments. */
727
/* Draw a series of line segments. */
733
/* If the device canClip, R clips to the device extent and the device
728
/* If the device canClip, R clips to the device extent and the device
734
   does all other clipping */
729
   does all other clipping */
735
void GEPolyline(int n, double *x, double *y,
730
void GEPolyline(int n, double *x, double *y,
736
		int col, double gamma, int lty, double lwd,
731
		R_GE_gcontext *gc,
737
		GEDevDesc *dd)
732
		GEDevDesc *dd)
738
{
733
{
739
    if (lty == LTY_BLANK) return;
734
    if (gc->lty == LTY_BLANK) return;
740
    if (dd->dev->canClip) {
735
    if (dd->dev->canClip) {
741
	clipPolyline(n, x, y, col, gamma, 
-
 
742
		     lty, lwd, 1, dd);  /* clips to device extent
736
	clipPolyline(n, x, y, gc, 1, dd);  /* clips to device extent
743
						  then draws */
737
						  then draws */
744
    }
738
    }
745
    else
739
    else
746
	clipPolyline(n, x, y, col, gamma, lty, lwd, 0, dd);
740
	clipPolyline(n, x, y, gc, 0, dd);
747
}
741
}
748
 
742
 
749
/****************************************************************
743
/****************************************************************
750
 * R code for clipping polygons
744
 * R code for clipping polygons
751
 ****************************************************************
745
 ****************************************************************
Line 921... Line 915...
921
    closeClip (xout, yout, &cnt, store, &clip, cs);
915
    closeClip (xout, yout, &cnt, store, &clip, cs);
922
    return (cnt);
916
    return (cnt);
923
}
917
}
924
 
918
 
925
static void clipPolygon(int n, double *x, double *y,
919
static void clipPolygon(int n, double *x, double *y,
926
			int col, int fill, double gamma, int lty, double lwd,
920
			R_GE_gcontext *gc,
927
                        int toDevice, GEDevDesc *dd)
921
                        int toDevice, GEDevDesc *dd)
928
{
922
{
929
    double *xc = NULL, *yc = NULL;
923
    double *xc = NULL, *yc = NULL;
930
    /* if bg not specified then draw as polyline rather than polygon
924
    /* if bg not specified then draw as polyline rather than polygon
931
     * to avoid drawing line along border of clipping region */
925
     * to avoid drawing line along border of clipping region */
932
    if (fill == NA_INTEGER) {
926
    if (gc->fill == NA_INTEGER) {
933
	int i;
927
	int i;
934
	xc = (double*) R_alloc(n + 1, sizeof(double));
928
	xc = (double*) R_alloc(n + 1, sizeof(double));
935
	yc = (double*) R_alloc(n + 1, sizeof(double));
929
	yc = (double*) R_alloc(n + 1, sizeof(double));
936
	for (i=0; i<n; i++) {
930
	for (i=0; i<n; i++) {
937
	    xc[i] = x[i];
931
	    xc[i] = x[i];
938
	    yc[i] = y[i];
932
	    yc[i] = y[i];
939
	}
933
	}
940
	xc[n] = x[0];
934
	xc[n] = x[0];
941
	yc[n] = y[0];
935
	yc[n] = y[0];
942
	GEPolyline(n+1, xc, yc, col, gamma, lty, lwd, dd);
936
	GEPolyline(n+1, xc, yc, gc, dd);
943
    }
937
    }
944
    else {
938
    else {
945
	int npts;
939
	int npts;
946
	xc = yc = 0;		/* -Wall */
940
	xc = yc = 0;		/* -Wall */
947
	npts = clipPoly(x, y, n, 0, toDevice, xc, yc, dd);
941
	npts = clipPoly(x, y, n, 0, toDevice, xc, yc, dd);
948
	if (npts > 1) {
942
	if (npts > 1) {
949
	    xc = (double*) R_alloc(npts, sizeof(double));
943
	    xc = (double*) R_alloc(npts, sizeof(double));
950
	    yc = (double*) R_alloc(npts, sizeof(double));
944
	    yc = (double*) R_alloc(npts, sizeof(double));
951
	    npts = clipPoly(x, y, n, 1, toDevice, xc, yc, dd);
945
	    npts = clipPoly(x, y, n, 1, toDevice, xc, yc, dd);
952
	    dd->dev->polygon(npts, xc, yc, col, fill, gamma, 
946
	    dd->dev->polygon(npts, xc, yc, gc, dd->dev);
953
			     lty, lwd, dd->dev);
-
 
954
	}
947
	}
955
    }
948
    }
956
}
949
}
957
 
950
 
958
/****************************************************************
951
/****************************************************************
959
 * GEPolygon
952
 * GEPolygon
960
 ****************************************************************
953
 ****************************************************************
961
 */
954
 */
962
void GEPolygon(int n, double *x, double *y,
955
void GEPolygon(int n, double *x, double *y,
963
	       int col, int fill, double gamma, int lty, double lwd,
956
	       R_GE_gcontext *gc,
964
	       GEDevDesc *dd)
957
	       GEDevDesc *dd)
965
{
958
{
966
    /* 
959
    /* 
967
     * Save (and reset below) the heap pointer to clean up
960
     * Save (and reset below) the heap pointer to clean up
968
     * after any R_alloc's done by functions I call.
961
     * after any R_alloc's done by functions I call.
969
     */
962
     */
970
    char *vmaxsave = vmaxget();
963
    char *vmaxsave = vmaxget();
971
    if (lty == LTY_BLANK)
964
    if (gc->lty == LTY_BLANK)
972
	/* "transparent" border */
965
	/* "transparent" border */
973
	col = NA_INTEGER;
966
	gc->col = NA_INTEGER;
974
    if (dd->dev->canClip) {
967
    if (dd->dev->canClip) {
975
	/* 
968
	/* 
976
	 * If the device can clip, then we just clip to the device
969
	 * If the device can clip, then we just clip to the device
977
	 * boundary and let the device do clipping within that.
970
	 * boundary and let the device do clipping within that.
978
	 * We do this to avoid problems where writing WAY off the
971
	 * We do this to avoid problems where writing WAY off the
979
	 * device can cause problems for, e.g., ghostview
972
	 * device can cause problems for, e.g., ghostview
980
	 */
973
	 */
981
	clipPolygon(n, x, y, col, fill, gamma, lty, lwd, 1, dd);
974
	clipPolygon(n, x, y, gc, 1, dd);
982
    }
975
    }
983
    else
976
    else
984
	/*
977
	/*
985
	 * If the device can't clip, we have to do all the clipping
978
	 * If the device can't clip, we have to do all the clipping
986
	 * ourselves.
979
	 * ourselves.
987
	 */
980
	 */
988
	clipPolygon(n, x, y, col, fill, gamma, lty, lwd, 0, dd);
981
	clipPolygon(n, x, y, gc, 0, dd);
989
    vmaxset(vmaxsave);
982
    vmaxset(vmaxsave);
990
}
983
}
991
 
984
 
992
 
985
 
993
/****************************************************************
986
/****************************************************************
Line 1063... Line 1056...
1063
/****************************************************************
1056
/****************************************************************
1064
 * GECircle
1057
 * GECircle
1065
 ****************************************************************
1058
 ****************************************************************
1066
 */
1059
 */
1067
void GECircle(double x, double y, double radius,
1060
void GECircle(double x, double y, double radius,
1068
	     int col, int fill, double gamma, int lty, double lwd,
1061
	      R_GE_gcontext *gc,
1069
	     GEDevDesc *dd)
1062
	      GEDevDesc *dd)
1070
{
1063
{
1071
    char *vmax;
1064
    char *vmax;
1072
    double *xc, *yc;
1065
    double *xc, *yc;
1073
    int result;
1066
    int result;
1074
 
1067
 
Line 1091... Line 1084...
1091
	 *
1084
	 *
1092
	 * If the device can clip then we just clipped to the device
1085
	 * If the device can clip then we just clipped to the device
1093
	 * boundary so the circle is entirely within the device; the
1086
	 * boundary so the circle is entirely within the device; the
1094
	 * device will perform the clipping to the current clipping rect.
1087
	 * device will perform the clipping to the current clipping rect.
1095
	 */
1088
	 */
1096
	dd->dev->circle(x, y, radius, col, fill, gamma, lty, lwd, dd->dev);
1089
	dd->dev->circle(x, y, radius, gc, dd->dev);
1097
	break;
1090
	break;
1098
    case -1: /* Total clipping; draw nothing */
1091
    case -1: /* Total clipping; draw nothing */
1099
	/* 
1092
	/* 
1100
	 * If we did the clipping, then the circle is entirely outside
1093
	 * If we did the clipping, then the circle is entirely outside
1101
	 * the current clipping rect, so there is nothing to draw.
1094
	 * the current clipping rect, so there is nothing to draw.
Line 1115... Line 1108...
1115
	 * circle intersects the device boundary.  We assume that the
1108
	 * circle intersects the device boundary.  We assume that the
1116
	 * circle is not so big that other parts may be WAY off the
1109
	 * circle is not so big that other parts may be WAY off the
1117
	 * device and just draw a circle.
1110
	 * device and just draw a circle.
1118
	 */
1111
	 */
1119
	if (dd->dev->canClip) {
1112
	if (dd->dev->canClip) {
1120
	    dd->dev->circle(x, y, radius, col, fill, gamma, lty, lwd, dd->dev);
1113
	    dd->dev->circle(x, y, radius, gc, dd->dev);
1121
	}
1114
	}
1122
	else {
1115
	else {
1123
	    vmax = vmaxget();
1116
	    vmax = vmaxget();
1124
	    xc = (double*)R_alloc(result+1, sizeof(double));
1117
	    xc = (double*)R_alloc(result+1, sizeof(double));
1125
	    yc = (double*)R_alloc(result+1, sizeof(double));
1118
	    yc = (double*)R_alloc(result+1, sizeof(double));
1126
	    convertCircle(x, y, radius, result, xc, yc);
1119
	    convertCircle(x, y, radius, result, xc, yc);
1127
	    if (fill == NA_INTEGER) {
1120
	    if (gc->fill == NA_INTEGER) {
1128
		GEPolyline(result+1, xc, yc, col, gamma, lty, lwd, dd);
1121
		GEPolyline(result+1, xc, yc, gc, dd);
1129
	    }
1122
	    }
1130
	    else {
1123
	    else {
1131
		int npts;
1124
		int npts;
1132
		double *xcc, *ycc;
1125
		double *xcc, *ycc;
1133
		xcc = ycc = 0;	/* -Wall */
1126
		xcc = ycc = 0;	/* -Wall */
Line 1136... Line 1129...
1136
		if (npts > 1) {
1129
		if (npts > 1) {
1137
		    xcc = (double*)R_alloc(npts, sizeof(double));
1130
		    xcc = (double*)R_alloc(npts, sizeof(double));
1138
		    ycc = (double*)R_alloc(npts, sizeof(double));
1131
		    ycc = (double*)R_alloc(npts, sizeof(double));
1139
		    npts = clipPoly(xc, yc, result, 1, !dd->dev->canClip,
1132
		    npts = clipPoly(xc, yc, result, 1, !dd->dev->canClip,
1140
					xcc, ycc, dd);
1133
					xcc, ycc, dd);
1141
		    dd->dev->polygon(npts, xcc, ycc, col, fill, gamma, 
1134
		    dd->dev->polygon(npts, xcc, ycc, gc, dd->dev);
1142
				     lty, lwd, dd->dev);
-
 
1143
		}
1135
		}
1144
	    }
1136
	    }
1145
	    vmaxset(vmax);
1137
	    vmaxset(vmax);
1146
	}
1138
	}
1147
    }
1139
    }
Line 1183... Line 1175...
1183
 ****************************************************************
1175
 ****************************************************************
1184
 */
1176
 */
1185
/* Filled with color fill and outlined with color col  */
1177
/* Filled with color fill and outlined with color col  */
1186
/* These may both be NA_INTEGER	 */
1178
/* These may both be NA_INTEGER	 */
1187
void GERect(double x0, double y0, double x1, double y1,
1179
void GERect(double x0, double y0, double x1, double y1,
1188
	    int col, int fill, double gamma, int lty, double lwd,
1180
	    R_GE_gcontext *gc,
1189
	    GEDevDesc *dd)
1181
	    GEDevDesc *dd)
1190
{
1182
{
1191
    char *vmax;
1183
    char *vmax;
1192
    double *xc, *yc;
1184
    double *xc, *yc;
1193
    int result;
1185
    int result;
Line 1198... Line 1190...
1198
    result = clipRectCode(x0, y0, x1, y1, dd->dev->canClip, dd);
1190
    result = clipRectCode(x0, y0, x1, y1, dd->dev->canClip, dd);
1199
    switch (result) {
1191
    switch (result) {
1200
    case 0:  /* rectangle totally clipped; draw nothing */
1192
    case 0:  /* rectangle totally clipped; draw nothing */
1201
	break;
1193
	break;
1202
    case 1:  /* rectangle totally inside;  draw all */
1194
    case 1:  /* rectangle totally inside;  draw all */
1203
	dd->dev->rect(x0, y0, x1, y1, col, fill, gamma, 
1195
	dd->dev->rect(x0, y0, x1, y1, gc, dd->dev);
1204
		      lty, lwd, dd->dev);
-
 
1205
	break;
1196
	break;
1206
    case 2:  /* rectangle intersects clip region;  use polygon clipping */
1197
    case 2:  /* rectangle intersects clip region;  use polygon clipping */
1207
	if (dd->dev->canClip)
1198
	if (dd->dev->canClip)
1208
	    dd->dev->rect(x0, y0, x1, y1, col, fill, gamma, lty, lwd, dd->dev);
1199
	    dd->dev->rect(x0, y0, x1, y1, gc, dd->dev);
1209
	else {
1200
	else {
1210
	    vmax = vmaxget();
1201
	    vmax = vmaxget();
1211
	    xc = (double*)R_alloc(5, sizeof(double));
1202
	    xc = (double*)R_alloc(5, sizeof(double));
1212
	    yc = (double*)R_alloc(5, sizeof(double));
1203
	    yc = (double*)R_alloc(5, sizeof(double));
1213
	    xc[0] = x0; yc[0] = y0;
1204
	    xc[0] = x0; yc[0] = y0;
1214
	    xc[1] = x0; yc[1] = y1;
1205
	    xc[1] = x0; yc[1] = y1;
1215
	    xc[2] = x1; yc[2] = y1;
1206
	    xc[2] = x1; yc[2] = y1;
1216
	    xc[3] = x1; yc[3] = y0;
1207
	    xc[3] = x1; yc[3] = y0;
1217
	    xc[4] = x0; yc[4] = y0;
1208
	    xc[4] = x0; yc[4] = y0;
1218
	    if (fill == NA_INTEGER) {
1209
	    if (gc->fill == NA_INTEGER) {
1219
		GEPolyline(5, xc, yc, col, gamma, lty, lwd, dd);
1210
		GEPolyline(5, xc, yc, gc, dd);
1220
	    }
1211
	    }
1221
	    else { /* filled rectangle */
1212
	    else { /* filled rectangle */
1222
		int npts;
1213
		int npts;
1223
		double *xcc, *ycc;
1214
		double *xcc, *ycc;
1224
		xcc = ycc = 0;		/* -Wall */
1215
		xcc = ycc = 0;		/* -Wall */
1225
		npts = clipPoly(xc, yc, 4, 0, !dd->dev->canClip, xcc, ycc, dd);
1216
		npts = clipPoly(xc, yc, 4, 0, !dd->dev->canClip, xcc, ycc, dd);
1226
		if (npts > 1) {
1217
		if (npts > 1) {
1227
		    xcc = (double*)R_alloc(npts, sizeof(double));
1218
		    xcc = (double*)R_alloc(npts, sizeof(double));
1228
		    ycc = (double*)R_alloc(npts, sizeof(double));
1219
		    ycc = (double*)R_alloc(npts, sizeof(double));
1229
		    npts = clipPoly(xc, yc, 4, 1, !dd->dev->canClip, xcc, ycc, dd);
1220
		    npts = clipPoly(xc, yc, 4, 1, !dd->dev->canClip, xcc, ycc, dd);
1230
		    dd->dev->polygon(npts, xcc, ycc, col, fill, gamma, 
1221
		    dd->dev->polygon(npts, xcc, ycc, gc, dd->dev);
1231
				     lty, lwd, dd->dev);
-
 
1232
		}
1222
		}
1233
	    }
1223
	    }
1234
	    vmaxset(vmax);
1224
	    vmaxset(vmax);
1235
	}
1225
	}
1236
    }
1226
    }
Line 1252... Line 1242...
1252
   0 means totally outside clip region
1242
   0 means totally outside clip region
1253
   1 means totally inside clip region
1243
   1 means totally inside clip region
1254
   2 means intersects clip region */
1244
   2 means intersects clip region */
1255
static int clipTextCode(double x, double y, char *str,
1245
static int clipTextCode(double x, double y, char *str,
1256
			double rot, double hadj,
1246
			double rot, double hadj,
1257
			char *fontfamily, int fontface, double lineheight,
-
 
1258
			double cex, double ps,
1247
			R_GE_gcontext *gc,
1259
			int toDevice, GEDevDesc *dd)
1248
			int toDevice, GEDevDesc *dd)
1260
{
1249
{
1261
    double x0, x1, x2, x3, y0, y1, y2, y3, left, right, bottom, top;
1250
    double x0, x1, x2, x3, y0, y1, y2, y3, left, right, bottom, top;
1262
    double angle = DEG2RAD * rot;
1251
    double angle = DEG2RAD * rot;
1263
    double theta1 = M_PI/2 - angle;
1252
    double theta1 = M_PI/2 - angle;
1264
    double width = GEStrWidth(str, 
1253
    double width = GEStrWidth(str, gc, dd);
1265
			      fontfamily, fontface, lineheight,
-
 
1266
			      cex, ps, dd);
-
 
1267
    double height = GEStrHeight(str, 
1254
    double height = GEStrHeight(str, gc, dd);
1268
				fontfamily, fontface, 
-
 
1269
				lineheight,
-
 
1270
				cex, ps, dd);
-
 
1271
#ifdef HAVE_HYPOT
1255
#ifdef HAVE_HYPOT
1272
    double length = hypot(width, height);
1256
    double length = hypot(width, height);
1273
#else
1257
#else
1274
    double length = pythag(width, height);
1258
    double length = pythag(width, height);
1275
#endif
1259
#endif
Line 1290... Line 1274...
1290
    top = fmax2(fmax2(y0, y1), fmax2(y2, y3));
1274
    top = fmax2(fmax2(y0, y1), fmax2(y2, y3));
1291
    return clipRectCode(left, bottom, right, top, toDevice, dd);
1275
    return clipRectCode(left, bottom, right, top, toDevice, dd);
1292
}
1276
}
1293
 
1277
 
1294
static void clipText(double x, double y, char *str, double rot, double hadj,
1278
static void clipText(double x, double y, char *str, double rot, double hadj,
1295
		     int col, double gamma, 
1279
		     R_GE_gcontext *gc,
1296
		     char *fontfamily, int fontface, double lineheight,
-
 
1297
		     double cex, double ps,
-
 
1298
		     int toDevice, GEDevDesc *dd)
1280
		     int toDevice, GEDevDesc *dd)
1299
{
1281
{
1300
    int result = clipTextCode(x, y, str, rot, hadj, 
1282
    int result = clipTextCode(x, y, str, rot, hadj, gc,
1301
			      fontfamily, fontface, lineheight, cex, ps,
-
 
1302
			      toDevice, dd);
1283
			      toDevice, dd);
1303
    switch (result) {
1284
    switch (result) {
1304
    case 0:  /* text totally clipped; draw nothing */
1285
    case 0:  /* text totally clipped; draw nothing */
1305
	break;
1286
	break;
1306
    case 1:  /* text totally inside;  draw all */
1287
    case 1:  /* text totally inside;  draw all */
Line 1308... Line 1289...
1308
	 * FIXME:  Pass on the fontfamily, fontface, and
1289
	 * FIXME:  Pass on the fontfamily, fontface, and
1309
	 * lineheight so that the device can use them
1290
	 * lineheight so that the device can use them
1310
	 * if it wants to.
1291
	 * if it wants to.
1311
	 * NOTE: fontface corresponds to old "font"
1292
	 * NOTE: fontface corresponds to old "font"
1312
	 */
1293
	 */
1313
	dd->dev->text(x, y, str, rot, hadj, col, gamma, 
1294
	dd->dev->text(x, y, str, rot, hadj, gc, dd->dev);
1314
		      fontface, cex, ps, dd->dev);
-
 
1315
	break;
1295
	break;
1316
    case 2:  /* text intersects clip region
1296
    case 2:  /* text intersects clip region
1317
		act according to value of clipToDevice */
1297
		act according to value of clipToDevice */
1318
	if (toDevice) /* Device will do clipping */
1298
	if (toDevice) /* Device will do clipping */
1319
	    /*
1299
	    /*
1320
	     * FIXME:  Pass on the fontfamily, fontface, and
1300
	     * FIXME:  Pass on the fontfamily, fontface, and
1321
	     * lineheight so that the device can use them
1301
	     * lineheight so that the device can use them
1322
	     * if it wants to.
1302
	     * if it wants to.
1323
	     * NOTE: fontface corresponds to old "font"
1303
	     * NOTE: fontface corresponds to old "font"
1324
	     */
1304
	     */
1325
	    dd->dev->text(x, y, str, rot, hadj, col, gamma, 
1305
	    dd->dev->text(x, y, str, rot, hadj, gc, dd->dev);
1326
			  fontface, cex, ps, dd->dev);
-
 
1327
	else /* don't draw anything; this could be made less crude :) */
1306
	else /* don't draw anything; this could be made less crude :) */
1328
	    ;
1307
	    ;
1329
    }
1308
    }
1330
}
1309
}
1331
 
1310
 
Line 1401... Line 1380...
1401
 */
1380
 */
1402
/* If you want EXACT centering of text (e.g., like in GSymbol) */
1381
/* If you want EXACT centering of text (e.g., like in GSymbol) */
1403
/* then pass NA_REAL for xc and yc */
1382
/* then pass NA_REAL for xc and yc */
1404
void GEText(double x, double y, char *str,
1383
void GEText(double x, double y, char *str,
1405
	    double xc, double yc, double rot,
1384
	    double xc, double yc, double rot,
1406
	    int col, double gamma, 
1385
	    R_GE_gcontext *gc,
1407
	    char *fontfamily, int fontface, double lineheight,
-
 
1408
	    double cex, double ps,
-
 
1409
	    GEDevDesc *dd)
1386
	    GEDevDesc *dd)
1410
{
1387
{
1411
    /* 
1388
    /* 
1412
     * If the fontfamily is a Hershey font family, call R_GE_VText
1389
     * If the fontfamily is a Hershey font family, call R_GE_VText
1413
     */
1390
     */
1414
    int vfontcode = VFontFamilyCode(fontfamily);
1391
    int vfontcode = VFontFamilyCode(gc->fontfamily);
1415
    if (vfontcode >= 0) {
1392
    if (vfontcode >= 0) {
-
 
1393
	gc->fontfamily[0] = vfontcode;
1416
	/* 
1394
	/* 
1417
	 * R's "font" par has historically made 2=bold and 3=italic
1395
	 * R's "font" par has historically made 2=bold and 3=italic
1418
	 * These must be switched to correspond to Hershey fontfaces
1396
	 * These must be switched to correspond to Hershey fontfaces
1419
	 */
1397
	 */
1420
	if (fontface == 2)
1398
	if (gc->fontface == 2)
1421
	    fontface = 3;
1399
	    gc->fontface = 3;
1422
	else if (fontface == 3)
1400
	else if (gc->fontface == 3)
1423
	    fontface = 2;
1401
	    gc->fontface = 2;
1424
	R_GE_VText(x, y, str, vfontcode, fontface,
1402
	R_GE_VText(x, y, str, xc, yc, rot, gc, dd);
1425
		   xc, yc, rot, col, gamma, lineheight, cex, ps, dd);
-
 
1426
 
1403
 
1427
    } else {
1404
    } else {
1428
    char *sbuf = NULL;
1405
    char *sbuf = NULL;
1429
    if(str && *str) {
1406
    if(str && *str) {
1430
        char *s, *sb;
1407
        char *s, *sb;
Line 1462... Line 1439...
1462
		     * Adjust for potentially different current pointsize.
1439
		     * Adjust for potentially different current pointsize.
1463
		     * This is a crude calculation that might be better
1440
		     * This is a crude calculation that might be better
1464
		     * performed using a device call that responds with
1441
		     * performed using a device call that responds with
1465
		     * the current font pointsize in device coordinates.
1442
		     * the current font pointsize in device coordinates.
1466
		     */
1443
		     */
1467
		    yoff = fromDeviceHeight(yoff * cex * dd->dev->cra[1] *
1444
		    yoff = fromDeviceHeight(yoff * gc->lineheight * 
-
 
1445
					    gc->cex * dd->dev->cra[1] *
1468
					    ps/dd->dev->startps,
1446
					    gc->ps/dd->dev->startps,
1469
					    GE_INCHES, dd);
1447
					    GE_INCHES, dd);
1470
		    xoff = - yoff*sin_rot;
1448
		    xoff = - yoff*sin_rot;
1471
		    yoff = yoff*cos_rot;
1449
		    yoff = yoff*cos_rot;
1472
		    xoff = x + xoff;
1450
		    xoff = x + xoff;
1473
		    yoff = y + yoff;
1451
		    yoff = y + yoff;
Line 1476... Line 1454...
1476
		    yoff = y;
1454
		    yoff = y;
1477
		}
1455
		}
1478
		/* now determine bottom-left for THIS line */
1456
		/* now determine bottom-left for THIS line */
1479
		if(xc != 0.0 || yc != 0) {
1457
		if(xc != 0.0 || yc != 0) {
1480
		    double width, height;
1458
		    double width, height;
1481
		    width = fromDeviceWidth(GEStrWidth(sbuf, 
1459
		    width = fromDeviceWidth(GEStrWidth(sbuf, gc, dd),
1482
						       fontfamily,
-
 
1483
						       fontface,
-
 
1484
						       lineheight,
-
 
1485
						       cex, ps, dd),
-
 
1486
					    GE_INCHES, dd);
1460
					    GE_INCHES, dd);
1487
		    if (!R_FINITE(xc))
1461
		    if (!R_FINITE(xc))
1488
			xc = 0.5;
1462
			xc = 0.5;
1489
		    if (!R_FINITE(yc)) {
1463
		    if (!R_FINITE(yc)) {
1490
			/* "exact" vertical centering */
1464
			/* "exact" vertical centering */
1491
			/* If font metric info is available AND */
1465
			/* If font metric info is available AND */
1492
			/* there is only one line, use GMetricInfo & yc=0.5 */
1466
			/* there is only one line, use GMetricInfo & yc=0.5 */
1493
			/* Otherwise use GEStrHeight and fiddle yc */
1467
			/* Otherwise use GEStrHeight and fiddle yc */
1494
			double h, d, w;
1468
			double h, d, w;
1495
			/* 
-
 
1496
			 * FIXME:  Need to pass fontfamily to 
-
 
1497
			 * GEMetricInfo too
-
 
1498
			 */
-
 
1499
			GEMetricInfo(0, fontface, cex, ps, &h, &d, &w, dd);
1469
			GEMetricInfo(0, gc, &h, &d, &w, dd);
1500
			if (n>1 || (h==0 && d==0 && w==0)) {
1470
			if (n>1 || (h==0 && d==0 && w==0)) {
1501
			    height = fromDeviceHeight(GEStrHeight(sbuf, 
1471
			    height = fromDeviceHeight(GEStrHeight(sbuf, gc, 
1502
								  fontfamily,
-
 
1503
								  fontface,
1472
								  dd),
1504
								  lineheight,
-
 
1505
								  cex, ps, dd),
-
 
1506
						      GE_INCHES, dd);
1473
						      GE_INCHES, dd);
1507
			    yc = dd->dev->yCharOffset;
1474
			    yc = dd->dev->yCharOffset;
1508
			} else {
1475
			} else {
1509
			    double maxHeight = 0.0;
1476
			    double maxHeight = 0.0;
1510
			    double maxDepth = 0.0;
1477
			    double maxDepth = 0.0;
1511
			    char *ss;
1478
			    char *ss;
1512
			    int charNum = 0;
1479
			    int charNum = 0;
1513
			    for (ss=sbuf; *ss; ss++) {
1480
			    for (ss=sbuf; *ss; ss++) {
1514
				/* 
-
 
1515
				 * FIXME:  Need to pass fontfamily to 
-
 
1516
				 * GEMetricInfo too
-
 
1517
				 */
-
 
1518
				GEMetricInfo((unsigned char) *ss,
1481
				GEMetricInfo((unsigned char) *ss, gc,
1519
					     fontface, cex, ps, &h, &d, &w, dd);
1482
					     &h, &d, &w, dd);
1520
				h = fromDeviceHeight(h, GE_INCHES, dd);
1483
				h = fromDeviceHeight(h, GE_INCHES, dd);
1521
				d = fromDeviceHeight(d, GE_INCHES, dd);
1484
				d = fromDeviceHeight(d, GE_INCHES, dd);
1522
				/* Set maxHeight and maxDepth from height
1485
				/* Set maxHeight and maxDepth from height
1523
				   and depth of first char.
1486
				   and depth of first char.
1524
				   Must NOT set to 0 in case there is
1487
				   Must NOT set to 0 in case there is
Line 1535... Line 1498...
1535
			    }
1498
			    }
1536
			    height = maxHeight - maxDepth;
1499
			    height = maxHeight - maxDepth;
1537
			    yc = 0.5;
1500
			    yc = 0.5;
1538
			}
1501
			}
1539
		    } else {
1502
		    } else {
1540
			height = fromDeviceHeight(GEStrHeight(sbuf, 
1503
			height = fromDeviceHeight(GEStrHeight(sbuf, gc,
1541
							      fontfamily,
-
 
1542
							      fontface,
1504
							      dd),
1543
							      lineheight,
-
 
1544
							      cex, ps, dd),
-
 
1545
						  GE_INCHES, dd);
1505
						  GE_INCHES, dd);
1546
		    }
1506
		    }
1547
		    if (dd->dev->canHAdj == 2) hadj = xc;
1507
		    if (dd->dev->canHAdj == 2) hadj = xc;
1548
		    else if (dd->dev->canHAdj == 1) {
1508
		    else if (dd->dev->canHAdj == 1) {
1549
			hadj = 0.5 * floor(2*xc + 0.5);
1509
			hadj = 0.5 * floor(2*xc + 0.5);
Line 1561... Line 1521...
1561
		/* Convert GE_INCHES back to device.
1521
		/* Convert GE_INCHES back to device.
1562
		 */
1522
		 */
1563
		xleft = toDeviceX(xleft, GE_INCHES, dd);
1523
		xleft = toDeviceX(xleft, GE_INCHES, dd);
1564
		ybottom = toDeviceY(ybottom, GE_INCHES, dd);
1524
		ybottom = toDeviceY(ybottom, GE_INCHES, dd);
1565
		if(dd->dev->canClip) {
1525
		if(dd->dev->canClip) {
1566
		    clipText(xleft, ybottom, sbuf, rot, hadj,
1526
		    clipText(xleft, ybottom, sbuf, rot, hadj, gc, 1, dd);
1567
			     col, gamma, fontfamily, fontface, lineheight,
-
 
1568
			     cex, ps, 1, dd);
-
 
1569
		} else
1527
		} else
1570
		    clipText(xleft, ybottom, sbuf, rot, hadj,
1528
		    clipText(xleft, ybottom, sbuf, rot, hadj, gc, 0, dd);
1571
			     col, gamma, fontfamily, fontface, lineheight,
-
 
1572
			     cex, ps, 0, dd);
-
 
1573
		sb = sbuf;
1529
		sb = sbuf;
1574
		i += 1;
1530
		i += 1;
1575
	    }
1531
	    }
1576
	    else *sb++ = *s;
1532
	    else *sb++ = *s;
1577
	    if (!*s) break;
1533
	    if (!*s) break;
Line 1614... Line 1570...
1614
 * This could cause a problem for devices which have ipr[0] != ipr[1]
1570
 * This could cause a problem for devices which have ipr[0] != ipr[1]
1615
 * The problem would be evident where calculations are done on
1571
 * The problem would be evident where calculations are done on
1616
 * angles -- in those cases, a conversion to and from GE_INCHES is done
1572
 * angles -- in those cases, a conversion to and from GE_INCHES is done
1617
 * to preserve angles.
1573
 * to preserve angles.
1618
 */
1574
 */
1619
/* 
-
 
1620
 * FIXME:  Need to pass fontfamily and lineheight to 
-
 
1621
 * GESymbol too
-
 
1622
 */
-
 
1623
void GESymbol(double x, double y, int pch, double size,
1575
void GESymbol(double x, double y, int pch, double size,
1624
	      int col, int fill, double gamma, double lty, double lwd,
-
 
1625
	      int font, double cex, double ps,
1576
	      R_GE_gcontext *gc,
1626
	      GEDevDesc *dd)
1577
	      GEDevDesc *dd)
1627
{
1578
{
1628
    double r, xc, yc;
1579
    double r, xc, yc;
1629
    double xx[4], yy[4];
1580
    double xx[4], yy[4];
1630
    char str[2];
1581
    char str[2];
Line 1636... Line 1587...
1636
	    /* 
1587
	    /* 
1637
	     * NOTE:  we are *filling* a rect with the current
1588
	     * NOTE:  we are *filling* a rect with the current
1638
	     * colour (we are not drawing the border AND we are
1589
	     * colour (we are not drawing the border AND we are
1639
	     * not using the current fill colour)
1590
	     * not using the current fill colour)
1640
	     */
1591
	     */
-
 
1592
	    gc->fill = gc->col;
1641
	    GERect(x-.5, y-.5, x+.5, y+.5, NA_INTEGER, col, gamma, 
1593
	    gc->col = NA_INTEGER;
1642
		   lty, lwd, dd);
1594
	    GERect(x-.5, y-.5, x+.5, y+.5, gc, dd);
1643
	} else {
1595
	} else {
1644
	    str[0] = pch;
1596
	    str[0] = pch;
1645
	    str[1] = '\0';
1597
	    str[1] = '\0';
1646
	    GEText(x, y, str, NA_REAL, NA_REAL, 0., col, gamma, 
1598
	    GEText(x, y, str, NA_REAL, NA_REAL, 0., gc, dd);
1647
		   /* 
-
 
1648
		    * FIXME:  When fontfamily and lineheight are 
-
 
1649
		    * passed to GESymbol, use them here instead
-
 
1650
		    * of "" and 1
-
 
1651
		    */
-
 
1652
		   "", font, 1, cex, ps, dd);
-
 
1653
	}
1599
	}
1654
    }
1600
    }
1655
    else {
1601
    else {
1656
	double GSTR_0 = fromDeviceWidth(size, GE_INCHES, dd);
1602
	double GSTR_0 = fromDeviceWidth(size, GE_INCHES, dd);
1657
 
1603
 
1658
	switch(pch) {
1604
	switch(pch) {
1659
 
1605
 
1660
	case 0: /* S square */
1606
	case 0: /* S square */
1661
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1607
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1662
	    yc = toDeviceHeight(RADIUS * GSTR_0, GE_INCHES, dd);
1608
	    yc = toDeviceHeight(RADIUS * GSTR_0, GE_INCHES, dd);
1663
	    GERect(x-xc, y-yc, x+xc, y+yc, 
1609
	    gc->fill = NA_INTEGER;
1664
		   col, NA_INTEGER, gamma, lty, lwd, dd);
1610
	    GERect(x-xc, y-yc, x+xc, y+yc, gc, dd);
1665
	    break;
1611
	    break;
1666
 
1612
 
1667
	case 1: /* S octahedron ( circle) */
1613
	case 1: /* S octahedron ( circle) */
1668
	    xc = RADIUS * size;
1614
	    xc = RADIUS * size;
-
 
1615
	    gc->fill = NA_INTEGER;
1669
	    GECircle(x, y, xc, col, NA_INTEGER, gamma, lty, lwd, dd);
1616
	    GECircle(x, y, xc, gc, dd);
1670
	    break;
1617
	    break;
1671
 
1618
 
1672
	case 2:	/* S triangle - point up */
1619
	case 2:	/* S triangle - point up */
1673
	    xc = RADIUS * GSTR_0;
1620
	    xc = RADIUS * GSTR_0;
1674
	    r = toDeviceHeight(TRC0 * xc, GE_INCHES, dd);
1621
	    r = toDeviceHeight(TRC0 * xc, GE_INCHES, dd);
1675
	    yc = toDeviceHeight(TRC2 * xc, GE_INCHES, dd);
1622
	    yc = toDeviceHeight(TRC2 * xc, GE_INCHES, dd);
1676
	    xc = toDeviceWidth(TRC1 * xc, GE_INCHES, dd);
1623
	    xc = toDeviceWidth(TRC1 * xc, GE_INCHES, dd);
1677
	    xx[0] = x; yy[0] = y+r;
1624
	    xx[0] = x; yy[0] = y+r;
1678
	    xx[1] = x+xc; yy[1] = y-yc;
1625
	    xx[1] = x+xc; yy[1] = y-yc;
1679
	    xx[2] = x-xc; yy[2] = y-yc;
1626
	    xx[2] = x-xc; yy[2] = y-yc;
-
 
1627
	    gc->fill = NA_INTEGER;
1680
	    GEPolygon(3, xx, yy, col, NA_INTEGER, gamma, lty, lwd, dd);
1628
	    GEPolygon(3, xx, yy, gc, dd);
1681
	    break;
1629
	    break;
1682
 
1630
 
1683
	case 3: /* S plus */
1631
	case 3: /* S plus */
1684
	    xc = toDeviceWidth(M_SQRT2*RADIUS*GSTR_0, GE_INCHES, dd);
1632
	    xc = toDeviceWidth(M_SQRT2*RADIUS*GSTR_0, GE_INCHES, dd);
1685
	    yc = toDeviceHeight(M_SQRT2*RADIUS*GSTR_0, GE_INCHES, dd);
1633
	    yc = toDeviceHeight(M_SQRT2*RADIUS*GSTR_0, GE_INCHES, dd);
1686
	    GELine(x-xc, y, x+xc, y, col, gamma, lty, lwd, dd);
1634
	    GELine(x-xc, y, x+xc, y, gc, dd);
1687
	    GELine(x, y-yc, x, y+yc, col, gamma, lty, lwd, dd);
1635
	    GELine(x, y-yc, x, y+yc, gc, dd);
1688
	    break;
1636
	    break;
1689
 
1637
 
1690
	case 4: /* S times */
1638
	case 4: /* S times */
1691
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1639
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1692
	    yc = toDeviceHeight(RADIUS * GSTR_0, GE_INCHES, dd);
1640
	    yc = toDeviceHeight(RADIUS * GSTR_0, GE_INCHES, dd);
1693
	    GELine(x-xc, y-yc, x+xc, y+yc, col, gamma, lty, lwd, dd);
1641
	    GELine(x-xc, y-yc, x+xc, y+yc, gc, dd);
1694
	    GELine(x-xc, y+yc, x+xc, y-yc, col, gamma, lty, lwd, dd);
1642
	    GELine(x-xc, y+yc, x+xc, y-yc, gc, dd);
1695
	    break;
1643
	    break;
1696
 
1644
 
1697
	case 5: /* S diamond */
1645
	case 5: /* S diamond */
1698
	    xc = toDeviceWidth(M_SQRT2 * RADIUS * GSTR_0, GE_INCHES, dd);
1646
	    xc = toDeviceWidth(M_SQRT2 * RADIUS * GSTR_0, GE_INCHES, dd);
1699
	    yc = toDeviceHeight(M_SQRT2 * RADIUS * GSTR_0, GE_INCHES, dd);
1647
	    yc = toDeviceHeight(M_SQRT2 * RADIUS * GSTR_0, GE_INCHES, dd);
1700
	    xx[0] = x-xc; yy[0] = y;
1648
	    xx[0] = x-xc; yy[0] = y;
1701
	    xx[1] = x; yy[1] = y+yc;
1649
	    xx[1] = x; yy[1] = y+yc;
1702
	    xx[2] = x+xc; yy[2] = y;
1650
	    xx[2] = x+xc; yy[2] = y;
1703
	    xx[3] = x; yy[3] = y-yc;
1651
	    xx[3] = x; yy[3] = y-yc;
-
 
1652
	    gc->fill = NA_INTEGER;
1704
	    GEPolygon(4, xx, yy, col, NA_INTEGER, gamma, lty, lwd, dd);
1653
	    GEPolygon(4, xx, yy, gc, dd);
1705
	    break;
1654
	    break;
1706
 
1655
 
1707
	case 6: /* S triangle - point down */
1656
	case 6: /* S triangle - point down */
1708
	    xc = RADIUS * GSTR_0;
1657
	    xc = RADIUS * GSTR_0;
1709
	    r = toDeviceHeight(TRC0 * xc, GE_INCHES, dd);
1658
	    r = toDeviceHeight(TRC0 * xc, GE_INCHES, dd);
1710
	    yc = toDeviceHeight(TRC2 * xc, GE_INCHES, dd);
1659
	    yc = toDeviceHeight(TRC2 * xc, GE_INCHES, dd);
1711
	    xc = toDeviceWidth(TRC1 * xc, GE_INCHES, dd);
1660
	    xc = toDeviceWidth(TRC1 * xc, GE_INCHES, dd);
1712
	    xx[0] = x; yy[0] = y-r;
1661
	    xx[0] = x; yy[0] = y-r;
1713
	    xx[1] = x+xc; yy[1] = y+yc;
1662
	    xx[1] = x+xc; yy[1] = y+yc;
1714
	    xx[2] = x-xc; yy[2] = y+yc;
1663
	    xx[2] = x-xc; yy[2] = y+yc;
-
 
1664
	    gc->fill = NA_INTEGER;
1715
	    GEPolygon(3, xx, yy, col, NA_INTEGER, gamma, lty, lwd, dd);
1665
	    GEPolygon(3, xx, yy, gc, dd);
1716
	    break;
1666
	    break;
1717
 
1667
 
1718
	case 7:	/* S square and times superimposed */
1668
	case 7:	/* S square and times superimposed */
1719
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1669
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1720
	    yc = toDeviceHeight(RADIUS * GSTR_0, GE_INCHES, dd);
1670
	    yc = toDeviceHeight(RADIUS * GSTR_0, GE_INCHES, dd);
1721
	    GERect(x-xc, y-yc, x+xc, y+yc,
1671
	    gc->fill = NA_INTEGER;
1722
		   col, NA_INTEGER, gamma, lty, lwd, dd);
1672
	    GERect(x-xc, y-yc, x+xc, y+yc, gc, dd);
1723
	    GELine(x-xc, y-yc, x+xc, y+yc, col, gamma, lty, lwd, dd);
1673
	    GELine(x-xc, y-yc, x+xc, y+yc, gc, dd);
1724
	    GELine(x-xc, y+yc, x+xc, y-yc, col, gamma, lty, lwd, dd);
1674
	    GELine(x-xc, y+yc, x+xc, y-yc, gc, dd);
1725
	    break;
1675
	    break;
1726
 
1676
 
1727
	case 8: /* S plus and times superimposed */
1677
	case 8: /* S plus and times superimposed */
1728
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1678
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1729
	    yc = toDeviceHeight(RADIUS * GSTR_0, GE_INCHES, dd);
1679
	    yc = toDeviceHeight(RADIUS * GSTR_0, GE_INCHES, dd);
1730
	    GELine(x-xc, y-yc, x+xc, y+yc, col, gamma, lty, lwd, dd);
1680
	    GELine(x-xc, y-yc, x+xc, y+yc, gc, dd);
1731
	    GELine(x-xc, y+yc, x+xc, y-yc, col, gamma, lty, lwd, dd);
1681
	    GELine(x-xc, y+yc, x+xc, y-yc, gc, dd);
1732
	    xc = toDeviceWidth(M_SQRT2*RADIUS*GSTR_0, GE_INCHES, dd);
1682
	    xc = toDeviceWidth(M_SQRT2*RADIUS*GSTR_0, GE_INCHES, dd);
1733
	    yc = toDeviceHeight(M_SQRT2*RADIUS*GSTR_0, GE_INCHES, dd);
1683
	    yc = toDeviceHeight(M_SQRT2*RADIUS*GSTR_0, GE_INCHES, dd);
1734
	    GELine(x-xc, y, x+xc, y, col, gamma, lty, lwd, dd);
1684
	    GELine(x-xc, y, x+xc, y, gc, dd);
1735
	    GELine(x, y-yc, x, y+yc, col, gamma, lty, lwd, dd);
1685
	    GELine(x, y-yc, x, y+yc, gc, dd);
1736
	    break;
1686
	    break;
1737
 
1687
 
1738
	case 9: /* S diamond and plus superimposed */
1688
	case 9: /* S diamond and plus superimposed */
1739
	    xc = toDeviceWidth(M_SQRT2 * RADIUS * GSTR_0, GE_INCHES, dd);
1689
	    xc = toDeviceWidth(M_SQRT2 * RADIUS * GSTR_0, GE_INCHES, dd);
1740
	    yc = toDeviceHeight(M_SQRT2 * RADIUS * GSTR_0, GE_INCHES, dd);
1690
	    yc = toDeviceHeight(M_SQRT2 * RADIUS * GSTR_0, GE_INCHES, dd);
1741
	    GELine(x-xc, y, x+xc, y, col, gamma, lty, lwd, dd);
1691
	    GELine(x-xc, y, x+xc, y, gc, dd);
1742
	    GELine(x, y-yc, x, y+yc, col, gamma, lty, lwd, dd);
1692
	    GELine(x, y-yc, x, y+yc, gc, dd);
1743
	    xx[0] = x-xc; yy[0] = y;
1693
	    xx[0] = x-xc; yy[0] = y;
1744
	    xx[1] = x; yy[1] = y+yc;
1694
	    xx[1] = x; yy[1] = y+yc;
1745
	    xx[2] = x+xc; yy[2] = y;
1695
	    xx[2] = x+xc; yy[2] = y;
1746
	    xx[3] = x; yy[3] = y-yc;
1696
	    xx[3] = x; yy[3] = y-yc;
-
 
1697
	    gc->fill = NA_INTEGER;
1747
	    GEPolygon(4, xx, yy, col, NA_INTEGER, gamma, lty, lwd, dd);
1698
	    GEPolygon(4, xx, yy, gc, dd);
1748
	    break;
1699
	    break;
1749
 
1700
 
1750
	case 10: /* S hexagon (circle) and plus superimposed */
1701
	case 10: /* S hexagon (circle) and plus superimposed */
1751
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1702
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1752
	    yc = toDeviceHeight(RADIUS * GSTR_0, GE_INCHES, dd);
1703
	    yc = toDeviceHeight(RADIUS * GSTR_0, GE_INCHES, dd);
-
 
1704
	    gc->fill = NA_INTEGER;
1753
	    GECircle(x, y, xc, col, NA_INTEGER, gamma, lty, lwd, dd);
1705
	    GECircle(x, y, xc, gc, dd);
1754
	    GELine(x-xc, y, x+xc, y, col, gamma, lty, lwd, dd);
1706
	    GELine(x-xc, y, x+xc, y, gc, dd);
1755
	    GELine(x, y-yc, x, y+yc, col, gamma, lty, lwd, dd);
1707
	    GELine(x, y-yc, x, y+yc, gc, dd);
1756
	    break;
1708
	    break;
1757
 
1709
 
1758
	case 11: /* S superimposed triangles */
1710
	case 11: /* S superimposed triangles */
1759
	    xc = RADIUS * GSTR_0;
1711
	    xc = RADIUS * GSTR_0;
1760
	    r = toDeviceHeight(TRC0 * xc, GE_INCHES, dd);
1712
	    r = toDeviceHeight(TRC0 * xc, GE_INCHES, dd);
Line 1762... Line 1714...
1762
	    yc = 0.5 * (yc + r);
1714
	    yc = 0.5 * (yc + r);
1763
	    xc = toDeviceWidth(TRC1 * xc, GE_INCHES, dd);
1715
	    xc = toDeviceWidth(TRC1 * xc, GE_INCHES, dd);
1764
	    xx[0] = x; yy[0] = y-r;
1716
	    xx[0] = x; yy[0] = y-r;
1765
	    xx[1] = x+xc; yy[1] = y+yc;
1717
	    xx[1] = x+xc; yy[1] = y+yc;
1766
	    xx[2] = x-xc; yy[2] = y+yc;
1718
	    xx[2] = x-xc; yy[2] = y+yc;
-
 
1719
	    gc->fill = NA_INTEGER;
1767
	    GEPolygon(3, xx, yy, col, NA_INTEGER, gamma, lty, lwd, dd);
1720
	    GEPolygon(3, xx, yy, gc, dd);
1768
	    xx[0] = x; yy[0] = y+r;
1721
	    xx[0] = x; yy[0] = y+r;
1769
	    xx[1] = x+xc; yy[1] = y-yc;
1722
	    xx[1] = x+xc; yy[1] = y-yc;
1770
	    xx[2] = x-xc; yy[2] = y-yc;
1723
	    xx[2] = x-xc; yy[2] = y-yc;
1771
	    GEPolygon(3, xx, yy, col, NA_INTEGER, gamma, lty, lwd, dd);
1724
	    GEPolygon(3, xx, yy, gc, dd);
1772
	    break;
1725
	    break;
1773
 
1726
 
1774
	case 12: /* S square and plus superimposed */
1727
	case 12: /* S square and plus superimposed */
1775
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1728
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1776
	    yc = toDeviceHeight(RADIUS * GSTR_0, GE_INCHES, dd);
1729
	    yc = toDeviceHeight(RADIUS * GSTR_0, GE_INCHES, dd);
1777
	    GELine(x-xc, y, x+xc, y, col, gamma, lty, lwd, dd);
1730
	    GELine(x-xc, y, x+xc, y, gc, dd);
1778
	    GELine(x, y-yc, x, y+yc, col, gamma, lty, lwd, dd);
1731
	    GELine(x, y-yc, x, y+yc, gc, dd);
1779
	    GERect(x-xc, y-yc, x+xc, y+yc,
1732
	    gc->fill = NA_INTEGER;
1780
		   col, NA_INTEGER, gamma, lty, lwd, dd);
1733
	    GERect(x-xc, y-yc, x+xc, y+yc, gc, dd);
1781
	    break;
1734
	    break;
1782
 
1735
 
1783
	case 13: /* S octagon (circle) and times superimposed */
1736
	case 13: /* S octagon (circle) and times superimposed */
1784
	    xc = RADIUS * size;
1737
	    xc = RADIUS * size;
-
 
1738
	    gc->fill = NA_INTEGER;
1785
	    GECircle(x, y, xc, col, NA_INTEGER, gamma, lty, lwd, dd);
1739
	    GECircle(x, y, xc, gc, dd);
1786
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1740
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1787
	    yc = toDeviceHeight(RADIUS * GSTR_0, GE_INCHES, dd);
1741
	    yc = toDeviceHeight(RADIUS * GSTR_0, GE_INCHES, dd);
1788
	    GELine(x-xc, y-yc, x+xc, y+yc, col, gamma, lty, lwd, dd);
1742
	    GELine(x-xc, y-yc, x+xc, y+yc, gc, dd);
1789
	    GELine(x-xc, y+yc, x+xc, y-yc, col, gamma, lty, lwd, dd);
1743
	    GELine(x-xc, y+yc, x+xc, y-yc, gc, dd);
1790
	    break;
1744
	    break;
1791
 
1745
 
1792
	case 14: /* S square and point-up triangle superimposed */
1746
	case 14: /* S square and point-up triangle superimposed */
1793
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1747
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1794
	    xx[0] = x; yy[0] = y+xc;
1748
	    xx[0] = x; yy[0] = y+xc;
1795
	    xx[1] = x+xc; yy[1] = y-xc;
1749
	    xx[1] = x+xc; yy[1] = y-xc;
1796
	    xx[2] = x-xc; yy[2] = y-xc;
1750
	    xx[2] = x-xc; yy[2] = y-xc;
1797
	    GEPolygon(3, xx, yy, col, NA_INTEGER, gamma, lty, lwd, dd);
1751
	    gc->fill = NA_INTEGER;
1798
	    GERect(x-xc, y-xc, x+xc, y+xc, col, 
1752
	    GEPolygon(3, xx, yy, gc, dd);
1799
		   NA_INTEGER, gamma, lty, lwd, dd);
1753
	    GERect(x-xc, y-xc, x+xc, y+xc, gc, dd);
1800
	    break;
1754
	    break;
1801
 
1755
 
1802
	case 15: /* S filled square */
1756
	case 15: /* S filled square */
1803
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1757
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1804
	    yc = toDeviceHeight(RADIUS * GSTR_0, GE_INCHES, dd);
1758
	    yc = toDeviceHeight(RADIUS * GSTR_0, GE_INCHES, dd);
1805
	    xx[0] = x-xc; yy[0] = y-yc;
1759
	    xx[0] = x-xc; yy[0] = y-yc;
1806
	    xx[1] = x+xc; yy[1] = y-yc;
1760
	    xx[1] = x+xc; yy[1] = y-yc;
1807
	    xx[2] = x+xc; yy[2] = y+yc;
1761
	    xx[2] = x+xc; yy[2] = y+yc;
1808
	    xx[3] = x-xc; yy[3] = y+yc;
1762
	    xx[3] = x-xc; yy[3] = y+yc;
-
 
1763
	    gc->fill = gc->col;
-
 
1764
	    gc->col = NA_INTEGER;
1809
	    GEPolygon(4, xx, yy, NA_INTEGER, col, gamma, lty, lwd, dd);
1765
	    GEPolygon(4, xx, yy, gc, dd);
1810
	    break;
1766
	    break;
1811
 
1767
 
1812
	case 16: /* S filled octagon (circle) */
1768
	case 16: /* S filled octagon (circle) */
1813
	    xc = RADIUS * size;
1769
	    xc = RADIUS * size;
-
 
1770
	    gc->fill = gc->col;
1814
	    GECircle(x, y, xc, col, col, gamma, lty, lwd, dd);
1771
	    GECircle(x, y, xc, gc, dd);
1815
	    break;
1772
	    break;
1816
 
1773
 
1817
	case 17: /* S filled point-up triangle */
1774
	case 17: /* S filled point-up triangle */
1818
	    xc = RADIUS * GSTR_0;
1775
	    xc = RADIUS * GSTR_0;
1819
	    r = toDeviceHeight(TRC0 * xc, GE_INCHES, dd);
1776
	    r = toDeviceHeight(TRC0 * xc, GE_INCHES, dd);
1820
	    yc = toDeviceHeight(TRC2 * xc, GE_INCHES, dd);
1777
	    yc = toDeviceHeight(TRC2 * xc, GE_INCHES, dd);
1821
	    xc = toDeviceWidth(TRC1 * xc, GE_INCHES, dd);
1778
	    xc = toDeviceWidth(TRC1 * xc, GE_INCHES, dd);
1822
	    xx[0] = x; yy[0] = y+r;
1779
	    xx[0] = x; yy[0] = y+r;
1823
	    xx[1] = x+xc; yy[1] = y-yc;
1780
	    xx[1] = x+xc; yy[1] = y-yc;
1824
	    xx[2] = x-xc; yy[2] = y-yc;
1781
	    xx[2] = x-xc; yy[2] = y-yc;
-
 
1782
	    gc->fill = gc->col;
-
 
1783
	    gc->col = NA_INTEGER;
1825
	    GEPolygon(3, xx, yy, NA_INTEGER, col, gamma, lty, lwd, dd);
1784
	    GEPolygon(3, xx, yy, gc, dd);
1826
	    break;
1785
	    break;
1827
 
1786
 
1828
	case 18: /* S filled diamond */
1787
	case 18: /* S filled diamond */
1829
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1788
	    xc = toDeviceWidth(RADIUS * GSTR_0, GE_INCHES, dd);
1830
	    yc = toDeviceHeight(RADIUS * GSTR_0, GE_INCHES, dd);
1789
	    yc = toDeviceHeight(RADIUS * GSTR_0, GE_INCHES, dd);
1831
	    xx[0] = x-xc; yy[0] = y;
1790
	    xx[0] = x-xc; yy[0] = y;
1832
	    xx[1] = x; yy[1] = y+yc;
1791
	    xx[1] = x; yy[1] = y+yc;
1833
	    xx[2] = x+xc; yy[2] = y;
1792
	    xx[2] = x+xc; yy[2] = y;
1834
	    xx[3] = x; yy[3] = y-yc;
1793
	    xx[3] = x; yy[3] = y-yc;
-
 
1794
	    gc->fill = gc->col;
-
 
1795
	    gc->col = NA_INTEGER;
1835
	    GEPolygon(4, xx, yy, NA_INTEGER, col, gamma, lty, lwd, dd);
1796
	    GEPolygon(4, xx, yy, gc, dd);
1836
	    break;
1797
	    break;
1837
 
1798
 
1838
	case 19: /* R filled circle */
1799
	case 19: /* R filled circle */
1839
	    xc = RADIUS * size;
1800
	    xc = RADIUS * size;
-
 
1801
	    gc->fill = gc->col;
1840
	    GECircle(x, y, xc, col, col, gamma, lty, lwd, dd);
1802
	    GECircle(x, y, xc, gc, dd);
1841
	    break;
1803
	    break;
1842
 
1804
 
1843
 
1805
 
1844
	case 20: /* R `Dot' (small circle) */
1806
	case 20: /* R `Dot' (small circle) */
1845
	    xc = SMALL * size;
1807
	    xc = SMALL * size;
-
 
1808
	    gc->fill = gc->col;
1846
	    GECircle(x, y, xc, col, col, gamma, lty, lwd, dd);
1809
	    GECircle(x, y, xc, gc, dd);
1847
	    break;
1810
	    break;
1848
 
1811
 
1849
 
1812
 
1850
	case 21: /* circles */
1813
	case 21: /* circles */
1851
	    xc = RADIUS * size;
1814
	    xc = RADIUS * size;
1852
	    GECircle(x, y, xc, col, fill, gamma, lty, lwd, dd);
1815
	    GECircle(x, y, xc, gc, dd);
1853
	    break;
1816
	    break;
1854
 
1817
 
1855
	case  22: /* squares */
1818
	case  22: /* squares */
1856
	    xc = toDeviceWidth(RADIUS * SQRC * GSTR_0, GE_INCHES, dd);
1819
	    xc = toDeviceWidth(RADIUS * SQRC * GSTR_0, GE_INCHES, dd);
1857
	    yc = toDeviceHeight(RADIUS * SQRC * GSTR_0, GE_INCHES, dd);
1820
	    yc = toDeviceHeight(RADIUS * SQRC * GSTR_0, GE_INCHES, dd);
1858
	    GERect(x-xc, y-yc, x+xc, y+yc, col, fill, gamma, lty, lwd, dd);
1821
	    GERect(x-xc, y-yc, x+xc, y+yc, gc, dd);
1859
	    break;
1822
	    break;
1860
 
1823
 
1861
	case 23: /* diamonds */
1824
	case 23: /* diamonds */
1862
	    xc = toDeviceWidth(RADIUS * DMDC * GSTR_0, GE_INCHES, dd);
1825
	    xc = toDeviceWidth(RADIUS * DMDC * GSTR_0, GE_INCHES, dd);
1863
	    yc = toDeviceHeight(RADIUS * DMDC * GSTR_0, GE_INCHES, dd);
1826
	    yc = toDeviceHeight(RADIUS * DMDC * GSTR_0, GE_INCHES, dd);
1864
	    xx[0] = x	  ; yy[0] = y-yc;
1827
	    xx[0] = x	  ; yy[0] = y-yc;
1865
	    xx[1] = x+xc; yy[1] = y;
1828
	    xx[1] = x+xc; yy[1] = y;
1866
	    xx[2] = x	  ; yy[2] = y+yc;
1829
	    xx[2] = x	  ; yy[2] = y+yc;
1867
	    xx[3] = x-xc; yy[3] = y;
1830
	    xx[3] = x-xc; yy[3] = y;
1868
	    GEPolygon(4, xx, yy, col, fill, gamma, lty, lwd, dd);
1831
	    GEPolygon(4, xx, yy, gc, dd);
1869
	    break;
1832
	    break;
1870
 
1833
 
1871
	case 24: /* triangle (point up) */
1834
	case 24: /* triangle (point up) */
1872
	    xc = RADIUS * GSTR_0;
1835
	    xc = RADIUS * GSTR_0;
1873
	    r = toDeviceHeight(TRC0 * xc, GE_INCHES, dd);
1836
	    r = toDeviceHeight(TRC0 * xc, GE_INCHES, dd);
1874
	    yc = toDeviceHeight(TRC2 * xc, GE_INCHES, dd);
1837
	    yc = toDeviceHeight(TRC2 * xc, GE_INCHES, dd);
1875
	    xc = toDeviceWidth(TRC1 * xc, GE_INCHES, dd);
1838
	    xc = toDeviceWidth(TRC1 * xc, GE_INCHES, dd);
1876
	    xx[0] = x; yy[0] = y+r;
1839
	    xx[0] = x; yy[0] = y+r;
1877
	    xx[1] = x+xc; yy[1] = y-yc;
1840
	    xx[1] = x+xc; yy[1] = y-yc;
1878
	    xx[2] = x-xc; yy[2] = y-yc;
1841
	    xx[2] = x-xc; yy[2] = y-yc;
1879
	    GEPolygon(3, xx, yy, col, fill, gamma, lty, lwd, dd);
1842
	    GEPolygon(3, xx, yy, gc, dd);
1880
	    break;
1843
	    break;
1881
 
1844
 
1882
	case 25: /* triangle (point down) */
1845
	case 25: /* triangle (point down) */
1883
	    xc = RADIUS * GSTR_0;
1846
	    xc = RADIUS * GSTR_0;
1884
	    r = toDeviceHeight(TRC0 * xc, GE_INCHES, dd);
1847
	    r = toDeviceHeight(TRC0 * xc, GE_INCHES, dd);
1885
	    yc = toDeviceHeight(TRC2 * xc, GE_INCHES, dd);
1848
	    yc = toDeviceHeight(TRC2 * xc, GE_INCHES, dd);
1886
	    xc = toDeviceWidth(TRC1 * xc, GE_INCHES, dd);
1849
	    xc = toDeviceWidth(TRC1 * xc, GE_INCHES, dd);
1887
	    xx[0] = x; yy[0] = y-r;
1850
	    xx[0] = x; yy[0] = y-r;
1888
	    xx[1] = x+xc; yy[1] = y+yc;
1851
	    xx[1] = x+xc; yy[1] = y+yc;
1889
	    xx[2] = x-xc; yy[2] = y+yc;
1852
	    xx[2] = x-xc; yy[2] = y+yc;
1890
	    GEPolygon(3, xx, yy, col, fill, gamma, lty, lwd, dd);
1853
	    GEPolygon(3, xx, yy, gc, dd);
1891
	    break;
1854
	    break;
1892
	}
1855
	}
1893
    }
1856
    }
1894
}
1857
}
1895
 
1858
 
Line 1961... Line 1924...
1961
 
1924
 
1962
/****************************************************************
1925
/****************************************************************
1963
 * GEMetricInfo
1926
 * GEMetricInfo
1964
 ****************************************************************
1927
 ****************************************************************
1965
 */
1928
 */
1966
/* 
-
 
1967
 * FIXME:  Need to pass fontfamily to 
-
 
1968
 * GEMetricInfo too
1929
void GEMetricInfo(int c, 
1969
 */
-
 
1970
void GEMetricInfo(int c, int font, double cex, double ps,
1930
		  R_GE_gcontext *gc,
1971
		  double *ascent, double *descent, double *width,
1931
		  double *ascent, double *descent, double *width,
1972
		  GEDevDesc *dd)
1932
		  GEDevDesc *dd)
1973
{
1933
{
1974
    dd->dev->metricInfo(c & 0xFF, font, cex, ps, ascent, descent, width,
1934
    dd->dev->metricInfo(c & 0xFF, gc, ascent, descent, width, dd->dev);
1975
			dd->dev);
-
 
1976
}
1935
}
1977
 
1936
 
1978
/****************************************************************
1937
/****************************************************************
1979
 * GEStrWidth
1938
 * GEStrWidth
1980
 ****************************************************************
1939
 ****************************************************************
1981
 */
1940
 */
1982
double GEStrWidth(char *str, 
1941
double GEStrWidth(char *str, 
1983
		  char *fontfamily, int fontface, double lineheight,
1942
		  R_GE_gcontext *gc,
1984
		  double cex, double ps, GEDevDesc *dd)
1943
		  GEDevDesc *dd)
1985
{
1944
{
1986
    /* 
1945
    /* 
1987
     * If the fontfamily is a Hershey font family, call R_GE_VStrWidth
1946
     * If the fontfamily is a Hershey font family, call R_GE_VStrWidth
1988
     */
1947
     */
1989
    int vfontcode = VFontFamilyCode(fontfamily);
1948
    int vfontcode = VFontFamilyCode(gc->fontfamily);
1990
    if (vfontcode >= 0) {
1949
    if (vfontcode >= 0) {
-
 
1950
	gc->fontfamily[0] = vfontcode;
1991
	/* 
1951
	/* 
1992
	 * R's "font" par has historically made 2=bold and 3=italic
1952
	 * R's "font" par has historically made 2=bold and 3=italic
1993
	 * These must be switched to correspond to Hershey fontfaces
1953
	 * These must be switched to correspond to Hershey fontfaces
1994
	 */
1954
	 */
1995
	if (fontface == 2)
1955
	if (gc->fontface == 2)
1996
	    fontface = 3;
1956
	    gc->fontface = 3;
1997
	else if (fontface == 3)
1957
	else if (gc->fontface == 3)
1998
	    fontface = 2;
1958
	    gc->fontface = 2;
1999
	return R_GE_VStrWidth((unsigned char *) str, 
1959
	return R_GE_VStrWidth((unsigned char *) str, gc, dd);
2000
			      vfontcode, fontface, lineheight,
-
 
2001
			      cex, ps, dd);
-
 
2002
    } else {
1960
    } else {
2003
	double w;
1961
	double w;
2004
	char *sbuf = NULL;
1962
	char *sbuf = NULL;
2005
	w = 0;
1963
	w = 0;
2006
	if(str && *str) {
1964
	if(str && *str) {
Line 2015... Line 1973...
2015
		     * FIXME:  Pass on the fontfamily, fontface, and
1973
		     * FIXME:  Pass on the fontfamily, fontface, and
2016
		     * lineheight so that the device can use them
1974
		     * lineheight so that the device can use them
2017
		     * if it wants to.
1975
		     * if it wants to.
2018
		     * NOTE: fontface corresponds to old "font"
1976
		     * NOTE: fontface corresponds to old "font"
2019
		     */
1977
		     */
2020
		    wdash = dd->dev->strWidth(sbuf, fontface, 
1978
		    wdash = dd->dev->strWidth(sbuf, gc, dd->dev);
2021
					      cex, ps, dd->dev);
-
 
2022
		    if (wdash > w) w = wdash;
1979
		    if (wdash > w) w = wdash;
2023
		    sb = sbuf;
1980
		    sb = sbuf;
2024
		}
1981
		}
2025
		else *sb++ = *s;
1982
		else *sb++ = *s;
2026
		if (!*s) break;
1983
		if (!*s) break;
Line 2033... Line 1990...
2033
/****************************************************************
1990
/****************************************************************
2034
 * GEStrHeight
1991
 * GEStrHeight
2035
 ****************************************************************
1992
 ****************************************************************
2036
 */
1993
 */
2037
double GEStrHeight(char *str, 
1994
double GEStrHeight(char *str, 
2038
		   char *fontfamily, int fontface, double lineheight,
1995
		   R_GE_gcontext *gc,
2039
		   double cex, double ps, GEDevDesc *dd)
1996
		   GEDevDesc *dd)
2040
{
1997
{
2041
    /* 
1998
    /* 
2042
     * If the fontfamily is a Hershey font family, call R_GE_VStrHeight
1999
     * If the fontfamily is a Hershey font family, call R_GE_VStrHeight
2043
     */
2000
     */
2044
    int vfontcode = VFontFamilyCode(fontfamily);
2001
    int vfontcode = VFontFamilyCode(gc->fontfamily);
2045
    if (vfontcode >= 0) {
2002
    if (vfontcode >= 0) {
-
 
2003
	gc->fontfamily[0] = vfontcode;
2046
	/* 
2004
	/* 
2047
	 * R's "font" par has historically made 2=bold and 3=italic
2005
	 * R's "font" par has historically made 2=bold and 3=italic
2048
	 * These must be switched to correspond to Hershey fontfaces
2006
	 * These must be switched to correspond to Hershey fontfaces
2049
	 */
2007
	 */
2050
	if (fontface == 2)
2008
	if (gc->fontface == 2)
2051
	    fontface = 3;
2009
	    gc->fontface = 3;
2052
	else if (fontface == 3)
2010
	else if (gc->fontface == 3)
2053
	    fontface = 2;
2011
	    gc->fontface = 2;
2054
	return R_GE_VStrHeight((unsigned char *) str, 
2012
	return R_GE_VStrHeight((unsigned char *) str, gc, dd);
2055
			       vfontcode, fontface, lineheight,
-
 
2056
			       cex, ps, dd);
-
 
2057
    } else {
2013
    } else {
2058
	double h;
2014
	double h;
2059
	char *s;
2015
	char *s;
2060
	double asc, dsc, wid;
2016
	double asc, dsc, wid;
2061
	int n;
2017
	int n;
Line 2069... Line 2025...
2069
	 * Adjust for potentially different current pointsize
2025
	 * Adjust for potentially different current pointsize
2070
	 * This is a crude calculation that might be better
2026
	 * This is a crude calculation that might be better
2071
	 * performed using a device call that responds with
2027
	 * performed using a device call that responds with
2072
	 * the current font pointsize in device coordinates.
2028
	 * the current font pointsize in device coordinates.
2073
	 */
2029
	 */
2074
	/* 
-
 
2075
	 * FIXME:  make use of lineheight passed in !
-
 
2076
	 * May need to wait until cra has been dealt to.
2030
	h = n * gc->lineheight * gc->cex * dd->dev->cra[1] * 
2077
	 */
-
 
2078
	h = n * cex * dd->dev->cra[1] * ps/dd->dev->startps;
2031
	    gc->ps/dd->dev->startps;
2079
	/* Add in the ascent of the font, if available */
2032
	/* Add in the ascent of the font, if available */
2080
	/* 
-
 
2081
	 * FIXME:  Need to pass fontfamily to 
-
 
2082
	 * GEMetricInfo too
-
 
2083
	 */
-
 
2084
	GEMetricInfo('M', fontface, cex, ps, &asc, &dsc, &wid, dd);
2033
	GEMetricInfo('M', gc, &asc, &dsc, &wid, dd);
2085
	if ((asc == 0.0) && (dsc == 0.0) && (wid == 0.0))
2034
	if ((asc == 0.0) && (dsc == 0.0) && (wid == 0.0))
2086
	    asc = cex * dd->dev->cra[1] * ps/dd->dev->startps;
2035
	    asc = gc->lineheight * gc->cex * dd->dev->cra[1] * 
-
 
2036
		gc->ps/dd->dev->startps;
2087
	h += asc;
2037
	h += asc;
2088
	return h;
2038
	return h;
2089
    }
2039
    }
2090
}
2040
}
2091
 
2041
 
2092
/****************************************************************
2042
/****************************************************************
2093
 * GENewPage
2043
 * GENewPage
2094
 ****************************************************************
2044
 ****************************************************************
2095
 */
2045
 */
2096
 
2046
 
2097
void GENewPage(int fill, double gamma, GEDevDesc *dd)
2047
void GENewPage(R_GE_gcontext *gc, GEDevDesc *dd)
2098
{
2048
{
2099
    dd->dev->newPage(fill, gamma, dd->dev);
2049
    dd->dev->newPage(gc, dd->dev);
2100
}
2050
}
2101
 
2051
 
2102
/****************************************************************
2052
/****************************************************************
2103
 * GEinitDisplayList
2053
 * GEinitDisplayList
2104
 ****************************************************************
2054
 ****************************************************************