The R Project SVN R

Rev

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

Rev 11368 Rev 11629
Line 23... Line 23...
23
 */
23
 */
24
#ifdef HAVE_CONFIG_H
24
#ifdef HAVE_CONFIG_H
25
#include <config.h>
25
#include <config.h>
26
#endif
26
#endif
27
 
27
 
28
#include "Defn.h"
28
#include <Defn.h>
29
#include "Graphics.h"
29
#include <Graphics.h>
30
#include "Devices.h"
30
#include <Devices.h>
31
#include <stdio.h>
31
#include <stdio.h>
32
#include "opt.h"
32
#include "opt.h"
33
#include "graphapp/ga.h"
33
#include "graphapp/ga.h"
34
#include "graphapp/stdimg.h"
34
#include "graphapp/stdimg.h"
35
#include "console.h"
35
#include "console.h"
Line 84... Line 84...
84
    /* parameters with copy per x11 device */
84
    /* parameters with copy per x11 device */
85
 
85
 
86
    enum DeviceKinds kind;
86
    enum DeviceKinds kind;
87
    int   windowWidth;		/* Window width (pixels) */
87
    int   windowWidth;		/* Window width (pixels) */
88
    int   windowHeight;		/* Window height (pixels) */
88
    int   windowHeight;		/* Window height (pixels) */
-
 
89
    int   showWidth;		/* device width (pixels) */
-
 
90
    int   showHeight;		/* device height (pixels) */
-
 
91
    int   origWidth, origHeight, xshift, yshift;
89
    Rboolean resize;		/* Window resized */
92
    Rboolean resize;		/* Window resized */
90
    window gawin;		/* Graphics window */
93
    window gawin;		/* Graphics window */
91
  /*FIXME: we should have union for this stuff and
94
  /*FIXME: we should have union for this stuff and
92
    maybe change gawin to canvas*/
95
    maybe change gawin to canvas*/
93
  /* SCREEN section*/
96
  /* SCREEN section*/
Line 96... Line 99...
96
    menubar mbar, mbarloc;
99
    menubar mbar, mbarloc;
97
    menu  msubsave;
100
    menu  msubsave;
98
    menuitem mpng, mbmp, mjpeg50, mjpeg75, mjpeg100;
101
    menuitem mpng, mbmp, mjpeg50, mjpeg75, mjpeg100;
99
    menuitem mps, mwm, mclpbm, mclpwm, mprint, mclose;
102
    menuitem mps, mwm, mclpbm, mclpwm, mprint, mclose;
100
    menuitem mrec, madd, mreplace, mprev, mnext, mclear, msvar, mgvar;
103
    menuitem mrec, madd, mreplace, mprev, mnext, mclear, msvar, mgvar;
-
 
104
    menuitem mR, mfit, mfix;
101
    Rboolean recording, replaying, needsave;
105
    Rboolean recording, replaying, needsave;
102
    bitmap bm;
106
    bitmap bm;
103
  /* PNG and JPEG section */
107
  /* PNG and JPEG section */
104
    FILE *fp;
108
    FILE *fp;
105
    int quality;
109
    int quality;
Line 112... Line 116...
112
    font  fixedfont;
116
    font  fixedfont;
113
    font  font;
117
    font  font;
114
    Rboolean locator;
118
    Rboolean locator;
115
    int clicked; /* {0,1,2} */
119
    int clicked; /* {0,1,2} */
116
    int	px, py, lty, lwd;
120
    int	px, py, lty, lwd;
-
 
121
    int resizing; /* {1,2,3} */
-
 
122
    double rescale_factor;
117
} gadesc;
123
} gadesc;
118
 
124
 
-
 
125
rect getregion(gadesc *xd)
-
 
126
{
-
 
127
    rect r = getrect(xd->bm);
-
 
128
    r.x += max(0, xd->xshift);
-
 
129
    r.y += max(0, xd->yshift);
-
 
130
    r.width = min(r.width, xd->showWidth);
-
 
131
    r.height = min(r.height, xd->showHeight);
-
 
132
    return r;
-
 
133
}
119
 
134
 
120
	/********************************************************/
135
	/********************************************************/
121
	/* There are a number of actions that every device 	*/
136
	/* There are a number of actions that every device 	*/
122
	/* driver is expected to perform (even if, in some	*/
137
	/* driver is expected to perform (even if, in some	*/
123
	/* cases it does nothing - just so long as it doesn't 	*/
138
	/* cases it does nothing - just so long as it doesn't 	*/
124
	/* crash !).  this is how the graphics engine interacts */
139
	/* crash !).  this is how the graphics engine interacts */
125
	/* with each device. ecah action will be documented 	*/
140
	/* with each device. Each action will be documented 	*/
126
	/* individually. 					*/
141
	/* individually. 					*/
127
	/* hooks for these actions must be set up when the 	*/
142
	/* hooks for these actions must be set up when the 	*/
128
	/* device is first created				*/
143
	/* device is first created				*/
129
	/********************************************************/
144
	/********************************************************/
130
 
145
 
Line 138... Line 153...
138
static void   GA_Hold(DevDesc*);
153
static void   GA_Hold(DevDesc*);
139
static void   GA_Line(double, double, double, double, int, DevDesc*);
154
static void   GA_Line(double, double, double, double, int, DevDesc*);
140
static Rboolean GA_Locator(double*, double*, DevDesc*);
155
static Rboolean GA_Locator(double*, double*, DevDesc*);
141
static void   GA_Mode(int);
156
static void   GA_Mode(int);
142
static void   GA_NewPage(DevDesc*);
157
static void   GA_NewPage(DevDesc*);
143
static Rboolean GA_Open(DevDesc*, gadesc*, char*, double, double, Rboolean);
158
static Rboolean GA_Open(DevDesc*, gadesc*, char*, double, double, 
-
 
159
			Rboolean, int);
144
static void   GA_Polygon(int, double*, double*, int, int, int, DevDesc*);
160
static void   GA_Polygon(int, double*, double*, int, int, int, DevDesc*);
145
static void   GA_Polyline(int, double*, double*, int, DevDesc*);
161
static void   GA_Polyline(int, double*, double*, int, DevDesc*);
146
static void   GA_Rect(double, double, double, double, int, int, int, DevDesc*);
162
static void   GA_Rect(double, double, double, double, int, int, int, DevDesc*);
147
static void   GA_Resize(DevDesc*);
163
static void   GA_Resize(DevDesc*);
148
static double GA_StrWidth(char*, DevDesc*);
164
static double GA_StrWidth(char*, DevDesc*);
Line 194... Line 210...
194
    ndd->displayList = R_NilValue;
210
    ndd->displayList = R_NilValue;
195
    GInit(&ndd->dp);
211
    GInit(&ndd->dp);
196
    if (GADeviceDriver(ndd, display,
212
    if (GADeviceDriver(ndd, display,
197
			 GConvertXUnits(1.0, NDC, INCHES, dd),
213
			 GConvertXUnits(1.0, NDC, INCHES, dd),
198
			 GConvertYUnits(1.0, NDC, INCHES, dd),
214
			 GConvertYUnits(1.0, NDC, INCHES, dd),
199
			 dd->gp.ps, 0))
215
			 dd->gp.ps, 0, 1))
200
        PrivateCopyDevice(dd, ndd, display);
216
        PrivateCopyDevice(dd, ndd, display);
201
}
217
}
202
 
218
 
203
 
219
 
204
static void SaveAsPostscript(DevDesc *dd, char *fn)
220
static void SaveAsPostscript(DevDesc *dd, char *fn)
Line 382... Line 398...
382
{
398
{
383
    gadesc *xd = (gadesc *) dd->deviceSpecific;
399
    gadesc *xd = (gadesc *) dd->deviceSpecific;
384
 
400
 
385
    if (face < 1 || face > fontnum)
401
    if (face < 1 || face > fontnum)
386
	face = 1;
402
	face = 1;
387
    size = MulDiv(size,xd->wanteddpi,xd->truedpi);
403
    size = MulDiv(size, xd->wanteddpi, xd->truedpi);
388
    if (size < SMALLEST)
404
    if (size < SMALLEST)
389
	size = SMALLEST;
405
	size = SMALLEST;
390
    if (size > LARGEST)
406
    if (size > LARGEST)
391
	size = LARGEST;
407
	size = LARGEST;
392
    if (!xd->usefixed &&
408
    if (!xd->usefixed &&
Line 508... Line 524...
508
	DevDesc *dd = (DevDesc *) getdata(w);
524
	DevDesc *dd = (DevDesc *) getdata(w);
509
	KillDevice(dd);
525
	KillDevice(dd);
510
    }
526
    }
511
}
527
}
512
 
528
 
513
static void HelpExpose(window w,rect r)
529
static void HelpExpose(window w, rect r)
514
{
530
{
515
    if (AllDevicesKilled) return;
531
    if (AllDevicesKilled) return;
516
    {
532
    {
517
	DevDesc *dd = (DevDesc *) getdata(w);
533
	DevDesc *dd = (DevDesc *) getdata(w);
518
	gadesc *xd = (gadesc *) dd->deviceSpecific;
534
	gadesc *xd = (gadesc *) dd->deviceSpecific;
519
 
535
 
520
	if (xd->resize) {
536
	if (xd->resize) {
521
	    dd->dp.resize(dd);
537
	    dd->dp.resize(dd);
522
	    xd->replaying= TRUE;
538
	    xd->replaying = TRUE;
523
	    playDisplayList(dd);
539
	    playDisplayList(dd);
524
	    xd->replaying= FALSE;
540
	    xd->replaying = FALSE;
525
	    R_ProcessEvents();
541
	    R_ProcessEvents();
526
	} else
542
	} else
527
	    SHOW;
543
	    SHOW;
528
    }
544
    }
529
}
545
}
Line 886... Line 902...
886
static void menuconsole(control m)
902
static void menuconsole(control m)
887
{
903
{
888
   show(RConsole);
904
   show(RConsole);
889
}
905
}
890
 
906
 
-
 
907
static void menuR(control m)
-
 
908
{
-
 
909
    DevDesc *dd = (DevDesc *) getdata(m);
-
 
910
    gadesc *xd = (gadesc *) dd->deviceSpecific;
-
 
911
    check(xd->mR);
-
 
912
    uncheck(xd->mfix);
-
 
913
    uncheck(xd->mfit);
-
 
914
    xd->resizing = 1;
-
 
915
}
-
 
916
 
-
 
917
static void menufit(control m)
-
 
918
{
-
 
919
    DevDesc *dd = (DevDesc *) getdata(m);
-
 
920
    gadesc *xd = (gadesc *) dd->deviceSpecific;
-
 
921
 
-
 
922
    uncheck(xd->mR);
-
 
923
    check(xd->mfit);
-
 
924
    uncheck(xd->mfix);
-
 
925
    xd->resizing = 2;
-
 
926
}
-
 
927
 
-
 
928
static void menufix(control m)
-
 
929
{
-
 
930
    DevDesc *dd = (DevDesc *) getdata(m);
-
 
931
    gadesc *xd = (gadesc *) dd->deviceSpecific;
-
 
932
 
-
 
933
    uncheck(xd->mR);
-
 
934
    uncheck(xd->mfit);
-
 
935
    check(xd->mfix);
-
 
936
    xd->resizing = 3;
-
 
937
}
-
 
938
 
891
static void CHelpKeyIn(control w,int key)
939
static void CHelpKeyIn(control w,int key)
892
{
940
{
893
    DevDesc *dd = (DevDesc *) getdata(w);
941
    DevDesc *dd = (DevDesc *) getdata(w);
894
    gadesc *xd = (gadesc *) dd->deviceSpecific;
942
    gadesc *xd = (gadesc *) dd->deviceSpecific;
895
 
943
 
Line 998... Line 1046...
998
	/* of course :)						*/
1046
	/* of course :)						*/
999
	/********************************************************/
1047
	/********************************************************/
1000
 
1048
 
1001
#define MCHECK(m) {if(!(m)) {del(xd->gawin); return 0;}}
1049
#define MCHECK(m) {if(!(m)) {del(xd->gawin); return 0;}}
1002
 
1050
 
-
 
1051
static void devga_sbf(control c, int pos)
-
 
1052
{
-
 
1053
    DevDesc *dd = (DevDesc *) getdata(c);
-
 
1054
    gadesc *xd = (gadesc *) dd->deviceSpecific;
-
 
1055
    if (pos < 0) {
-
 
1056
	pos = min(-pos-1, xd->origWidth - xd->windowWidth);
-
 
1057
	xd->xshift = -pos;
-
 
1058
    } else {
-
 
1059
	pos = min(pos, xd->origHeight - xd->windowHeight);
-
 
1060
	xd->yshift = -pos;
-
 
1061
    }
-
 
1062
    xd->resize = 1;
-
 
1063
    HelpExpose(c, getrect(xd->gawin));
-
 
1064
}
-
 
1065
 
-
 
1066
 
1003
static int 
1067
static int 
1004
setupScreenDevice(DevDesc *dd, gadesc *xd, int w, int h, Rboolean recording) 
1068
setupScreenDevice(DevDesc *dd, gadesc *xd, int w, int h, 
-
 
1069
		  Rboolean recording, int resize) 
1005
{
1070
{
1006
    menu  m;
1071
    menu  m;
1007
    int   iw, ih;
1072
    int   iw, ih;
1008
    double dw, dh, d;
1073
    double dw, dw0, dh, d;
1009
 
1074
 
1010
    xd->kind = SCREEN;
1075
    xd->kind = SCREEN;
1011
    dw = w / pixelWidth(NULL);
1076
    dw = dw0 = w / pixelWidth(NULL);
1012
    dh = h / pixelHeight(NULL);
1077
    dh = h / pixelHeight(NULL);
1013
    if ((dw / devicewidth(NULL)) > 0.85) {
1078
    if ((dw / devicewidth(NULL)) > 0.85) {
1014
	d = dh / dw;
1079
	d = dh / dw;
1015
	dw = 0.85 * devicewidth(NULL);
1080
	dw = 0.85 * devicewidth(NULL);
1016
	dh = d * dw;
1081
	dh = d * dw;
Line 1020... Line 1085...
1020
	dh = 0.85 * deviceheight(NULL);
1085
	dh = 0.85 * deviceheight(NULL);
1021
	dw = d * dh;
1086
	dw = d * dh;
1022
    }
1087
    }
1023
    iw = dw + 0.5;
1088
    iw = dw + 0.5;
1024
    ih = dh + 0.5;
1089
    ih = dh + 0.5;
-
 
1090
    if (resize == 2) xd->rescale_factor = dw/dw0;
1025
    if (!(xd->gawin = newwindow("R Graphics",
1091
    if (!(xd->gawin = newwindow("R Graphics",
1026
				rect(devicewidth(NULL) - iw - 5, 0, iw, ih),
1092
				rect(devicewidth(NULL) - iw - 25, 0, iw, ih),
1027
				Document | StandardWindow | Menubar))) {
1093
				Document | StandardWindow | Menubar |
-
 
1094
				VScrollbar | HScrollbar))) {
1028
	return 0;
1095
	return 0;
1029
    }
1096
    }
-
 
1097
    gchangescrollbar(xd->gawin, VWINSB, 0, ih-1, ih, 0);
-
 
1098
    gchangescrollbar(xd->gawin, HWINSB, 0, iw-1, iw, 0);
1030
 
1099
 
1031
    addto(xd->gawin);
1100
    addto(xd->gawin);
1032
    gsetcursor(xd->gawin, ArrowCursor);
1101
    gsetcursor(xd->gawin, ArrowCursor);
1033
    if (ismdi() && (RguiMDI & RW_TOOLBAR)) {
1102
    if (ismdi() && (RguiMDI & RW_TOOLBAR)) {
1034
	int btsize = 24;
1103
	int btsize = 24;
Line 1108... Line 1177...
1108
    MCHECK(newmenuitem("-", 0, NULL));
1177
    MCHECK(newmenuitem("-", 0, NULL));
1109
    MCHECK(xd->msvar = newmenuitem("Save to variable", 0, menusvar));
1178
    MCHECK(xd->msvar = newmenuitem("Save to variable", 0, menusvar));
1110
    MCHECK(xd->mgvar = newmenuitem("Get from variable", 0, menugvar));
1179
    MCHECK(xd->mgvar = newmenuitem("Get from variable", 0, menugvar));
1111
    MCHECK(newmenuitem("-", 0, NULL));
1180
    MCHECK(newmenuitem("-", 0, NULL));
1112
    MCHECK(xd->mclear = newmenuitem("Clear history", 0, menuclear));
1181
    MCHECK(xd->mclear = newmenuitem("Clear history", 0, menuclear));
-
 
1182
    MCHECK(newmenu("Resize"));
-
 
1183
    MCHECK(xd->mR = newmenuitem("R mode", 0, menuR));
-
 
1184
    if(resize == 1) check(xd->mR);
-
 
1185
    MCHECK(xd->mfit = newmenuitem("Fit to window", 0, menufit));
-
 
1186
    if(resize == 2) check(xd->mfit);
-
 
1187
    MCHECK(xd->mfix = newmenuitem("Fixed size", 0, menufix));
-
 
1188
    if(resize == 3) check(xd->mfix);
1113
    newmdimenu();
1189
    newmdimenu();
1114
 
1190
 
1115
    /* Normal popup */
1191
    /* Normal popup */
1116
    MCHECK(xd->grpopup = newpopup(NULL));
1192
    MCHECK(xd->grpopup = newpopup(NULL));
1117
    MCHECK(m = newmenuitem("Copy as metafile", 0, menuclpwm));
1193
    MCHECK(m = newmenuitem("Copy as metafile", 0, menuclpwm));
Line 1128... Line 1204...
1128
    setdata(m, (void *) dd);
1204
    setdata(m, (void *) dd);
1129
    gchangepopup(xd->gawin, xd->grpopup);
1205
    gchangepopup(xd->gawin, xd->grpopup);
1130
 
1206
 
1131
    MCHECK(xd->bm = newbitmap(getwidth(xd->gawin), getheight(xd->gawin), 
1207
    MCHECK(xd->bm = newbitmap(getwidth(xd->gawin), getheight(xd->gawin), 
1132
			      getdepth(xd->gawin)));
1208
			      getdepth(xd->gawin)));
1133
 
-
 
-
 
1209
    gfillrect(xd->gawin, LightGray, getrect(xd->gawin));
-
 
1210
    gfillrect(xd->bm, LightGray, getrect(xd->bm));
1134
    addto(xd->gawin);
1211
    addto(xd->gawin);
1135
    setdata(xd->mbar, (void *) dd);
1212
    setdata(xd->mbar, (void *) dd);
1136
    setdata(xd->mpng, (void *) dd);
1213
    setdata(xd->mpng, (void *) dd);
1137
    setdata(xd->mbmp, (void *) dd);
1214
    setdata(xd->mbmp, (void *) dd);
1138
    setdata(xd->mjpeg50, (void *) dd);
1215
    setdata(xd->mjpeg50, (void *) dd);
Line 1148... Line 1225...
1148
    setdata(xd->mprev, (void *) dd);
1225
    setdata(xd->mprev, (void *) dd);
1149
    setdata(xd->mnext, (void *) dd);
1226
    setdata(xd->mnext, (void *) dd);
1150
    setdata(xd->mgvar, (void *) dd);
1227
    setdata(xd->mgvar, (void *) dd);
1151
    setdata(xd->madd, (void *) dd);
1228
    setdata(xd->madd, (void *) dd);
1152
    setdata(xd->mreplace, (void *) dd);
1229
    setdata(xd->mreplace, (void *) dd);
1153
    show(xd->gawin);
1230
    setdata(xd->mR, (void *) dd);
-
 
1231
    setdata(xd->mfit, (void *) dd);
-
 
1232
    setdata(xd->mfix, (void *) dd);
-
 
1233
    show(xd->gawin); /* twice, for a Windows bug */
1154
    show(xd->gawin);
1234
    show(xd->gawin);
1155
    BringToTop(xd->gawin);
1235
    BringToTop(xd->gawin);
-
 
1236
    sethit(xd->gawin, devga_sbf);
1156
    setresize(xd->gawin, HelpResize);
1237
    setresize(xd->gawin, HelpResize);
1157
    setredraw(xd->gawin, HelpExpose);
1238
    setredraw(xd->gawin, HelpExpose);
1158
    setmousedown(xd->gawin, HelpMouseClick);
1239
    setmousedown(xd->gawin, HelpMouseClick);
1159
    setkeydown(xd->gawin, NHelpKeyIn);
1240
    setkeydown(xd->gawin, NHelpKeyIn);
1160
    setkeyaction(xd->gawin, CHelpKeyIn);
1241
    setkeyaction(xd->gawin, CHelpKeyIn);
1161
    setclose(xd->gawin, HelpClose);
1242
    setclose(xd->gawin, HelpClose);
1162
    xd->recording = recording;
1243
    xd->recording = recording;
1163
    xd->replaying= FALSE;
1244
    xd->replaying = FALSE;
-
 
1245
    xd->resizing = resize;
1164
 
1246
 
1165
    return 1;
1247
    return 1;
1166
}
1248
}
1167
 
1249
 
1168
static Rboolean GA_Open(DevDesc *dd, gadesc *xd, char *dsp,
1250
static Rboolean GA_Open(DevDesc *dd, gadesc *xd, char *dsp,
1169
			double w, double h, Rboolean recording)
1251
			double w, double h, Rboolean recording, int resize)
1170
{
1252
{
1171
    rect  rr;
1253
    rect  rr;
1172
 
1254
 
1173
    if (!fontinitdone)
1255
    if (!fontinitdone)
1174
	RFontInit();
1256
	RFontInit();
Line 1178... Line 1260...
1178
    xd->fg = dd->dp.fg = R_RGB(0, 0, 0);
1260
    xd->fg = dd->dp.fg = R_RGB(0, 0, 0);
1179
    xd->col = dd->dp.col = xd->fg;
1261
    xd->col = dd->dp.col = xd->fg;
1180
 
1262
 
1181
    xd->fgcolor = Black;
1263
    xd->fgcolor = Black;
1182
    xd->bgcolor = White;
1264
    xd->bgcolor = White;
1183
 
-
 
-
 
1265
    xd->rescale_factor = 1.0;
-
 
1266
    xd->xshift = xd->yshift = 0;
1184
    if (!dsp[0]) {
1267
    if (!dsp[0]) {
1185
      if (!setupScreenDevice(dd, xd, w, h, recording)) 
1268
      if (!setupScreenDevice(dd, xd, w, h, recording, resize)) 
1186
	  return FALSE;
1269
	  return FALSE;
1187
    } else if (!strcmp(dsp, "win.print")) {
1270
    } else if (!strcmp(dsp, "win.print")) {
1188
	xd->kind = PRINTER;
1271
	xd->kind = PRINTER;
1189
	xd->gawin = newprinter(MM_PER_INCH * w, MM_PER_INCH * h);
1272
	xd->gawin = newprinter(MM_PER_INCH * w, MM_PER_INCH * h);
1190
	if (!xd->gawin)
1273
	if (!xd->gawin)
Line 1216... Line 1299...
1216
	}
1299
	}
1217
	*p = '\0';
1300
	*p = '\0';
1218
	xd->quality = atoi(&dsp[5]);
1301
	xd->quality = atoi(&dsp[5]);
1219
	*p = ':' ;
1302
	*p = ':' ;
1220
	if (((xd->gawin = newbitmap(w,h,256)) == NULL) || 
1303
	if (((xd->gawin = newbitmap(w,h,256)) == NULL) || 
1221
	    ((xd->fp=fopen(p+1,"wb")) == NULL )) {
1304
	    ((xd->fp = fopen(p+1, "wb")) == NULL )) {
1222
	  if (xd->gawin != NULL) del(xd->gawin);
1305
	  if (xd->gawin != NULL) del(xd->gawin);
1223
	  if (xd->fp != NULL) fclose(xd->fp);
1306
	  if (xd->fp != NULL) fclose(xd->fp);
1224
	  return FALSE;
1307
	  return FALSE;
1225
	}
1308
	}
1226
    } else {
1309
    } else {
Line 1245... Line 1328...
1245
    }
1328
    }
1246
    xd->truedpi = devicepixelsy(xd->gawin);
1329
    xd->truedpi = devicepixelsy(xd->gawin);
1247
    if ((xd->kind == PNG) || (xd->kind == JPEG) || (xd->kind == BMP)) 
1330
    if ((xd->kind == PNG) || (xd->kind == JPEG) || (xd->kind == BMP)) 
1248
      xd->wanteddpi = 72 ;
1331
      xd->wanteddpi = 72 ;
1249
    else
1332
    else
1250
      xd->wanteddpi = xd->truedpi;
1333
      xd->wanteddpi = xd->rescale_factor * xd->truedpi;
1251
    if (!SetBaseFont(xd)) {
1334
    if (!SetBaseFont(xd)) {
1252
	Rprintf("can't find any fonts\n");
1335
	Rprintf("can't find any fonts\n");
1253
	del(xd->gawin);
1336
	del(xd->gawin);
1254
	if (xd->kind == SCREEN) del(xd->bm);
1337
	if (xd->kind == SCREEN) del(xd->bm);
1255
	return FALSE;
1338
	return FALSE;
1256
    }
1339
    }
1257
    rr = getrect(xd->gawin);
1340
    rr = getrect(xd->gawin);
1258
    xd->windowWidth = rr.width;
1341
    xd->origWidth = xd->showWidth = xd->windowWidth = rr.width;
1259
    xd->windowHeight = rr.height;
1342
    xd->origHeight = xd->showHeight = xd->windowHeight = rr.height;
1260
    xd->clip = rr;
1343
    xd->clip = rr;
1261
    setdata(xd->gawin, (void *) dd);
1344
    setdata(xd->gawin, (void *) dd);
1262
    xd->needsave= FALSE;
1345
    xd->needsave= FALSE;
1263
    return TRUE;
1346
    return TRUE;
1264
}
1347
}
Line 1337... Line 1420...
1337
static void GA_Resize(DevDesc *dd)
1420
static void GA_Resize(DevDesc *dd)
1338
{
1421
{
1339
    gadesc *xd = (gadesc *) dd->deviceSpecific;
1422
    gadesc *xd = (gadesc *) dd->deviceSpecific;
1340
 
1423
 
1341
    if (xd->resize) {
1424
    if (xd->resize) {
-
 
1425
	int   iw, ih, iw0 = dd->dp.right - dd->dp.left, 
-
 
1426
	    ih0 = dd->dp.bottom - dd->dp.top;
1342
	int   iw, ih;
1427
	double fw, fh, rf, shift;
1343
 
1428
 
-
 
1429
	iw = xd->windowWidth;
-
 
1430
	ih = xd->windowHeight;
-
 
1431
	if(xd->resizing == 1) {
1344
	dd->dp.left = dd->gp.left = 0.0;
1432
	    dd->dp.left = dd->gp.left = 0.0;
-
 
1433
	    dd->dp.top = dd->gp.top = 0.0;
1345
	dd->dp.right = dd->gp.right = iw = xd->windowWidth;
1434
	    dd->dp.right = dd->gp.right = iw;
-
 
1435
	    dd->dp.bottom = dd->gp.bottom = ih;
-
 
1436
	} else if (xd->resizing == 2) {
-
 
1437
	    fw = (iw + 0.5)/(iw0 + 0.5);
-
 
1438
	    fh = (ih + 0.5)/(ih0 + 0.5);
-
 
1439
	    rf = min(fw, fh);
-
 
1440
	    xd->rescale_factor *= rf;
-
 
1441
	    xd->wanteddpi = xd->rescale_factor * xd->truedpi;
-
 
1442
	    dd->dp.ps *= rf; dd->dp.cra[0] *= rf; dd->dp.cra[1] *= rf;
-
 
1443
	    if (fw < fh) {
-
 
1444
		dd->dp.left = dd->gp.left = 0.0;
-
 
1445
		xd->showWidth = dd->dp.right = dd->gp.right = iw;
-
 
1446
		xd->showHeight =  ih0*fw;
-
 
1447
		shift = (ih - xd->showHeight)/2.0;
-
 
1448
		dd->dp.top = dd->gp.top = shift;
1346
	dd->dp.bottom = dd->gp.bottom = ih = xd->windowHeight;
1449
		dd->dp.bottom = dd->gp.bottom = ih0*fw + shift;
-
 
1450
		xd->xshift = 0; xd->yshift = shift;
-
 
1451
	    } else {
1347
	dd->dp.top = dd->gp.top = 0.0;
1452
		dd->dp.top = dd->gp.top = 0.0;
-
 
1453
		xd->showHeight = dd->dp.bottom = dd->gp.bottom = ih;
-
 
1454
		xd->showWidth = iw0*fh;
-
 
1455
		shift = (iw - xd->showWidth)/2.0;
-
 
1456
		dd->dp.left = dd->gp.left = shift;
-
 
1457
		dd->dp.right = dd->gp.right = iw0*fh + shift;
-
 
1458
		xd->xshift = shift; xd->yshift = 0;
-
 
1459
	    }
-
 
1460
	    xd->clip = getregion(xd);
-
 
1461
	} else if (xd->resizing == 3) {
-
 
1462
	    if(iw0 < iw) shift = (iw - iw0)/2.0; 
-
 
1463
	    else shift = min(0, xd->xshift);
-
 
1464
	    dd->dp.left = dd->gp.left = shift;
-
 
1465
	    dd->dp.right = dd->gp.right = iw0 + shift;
-
 
1466
	    xd->xshift = shift;
-
 
1467
	    gchangescrollbar(xd->gawin, HWINSB, max(-shift,0), 
-
 
1468
			     xd->origWidth - 1, xd->windowWidth, 0);
-
 
1469
	    if(ih0 < ih) shift = (ih - ih0)/2.0; 
-
 
1470
	    else shift = min(0, xd->yshift);
-
 
1471
	    dd->dp.top = dd->gp.top = shift;
-
 
1472
	    dd->dp.bottom = dd->gp.bottom = ih0 + shift;
-
 
1473
	    xd->yshift = shift;
-
 
1474
	    gchangescrollbar(xd->gawin, VWINSB, max(-shift,0), 
-
 
1475
			     xd->origHeight - 1, xd->windowHeight, 0);
-
 
1476
	}
1348
	xd->resize= FALSE;
1477
	xd->resize = FALSE;
1349
	if (xd->kind==SCREEN) {
1478
	if (xd->kind == SCREEN) {
1350
	    del(xd->bm);
1479
	    del(xd->bm);
1351
	    xd->bm = newbitmap(iw, ih, getdepth(xd->gawin));
1480
	    xd->bm = newbitmap(iw, ih, getdepth(xd->gawin));
1352
	    if (!xd->bm) {
1481
	    if (!xd->bm) {
1353
		R_ShowMessage("Insufficient memory for resize. Killing device");
1482
		R_ShowMessage("Insufficient memory for resize. Killing device");
1354
		KillDevice(dd);
1483
		KillDevice(dd);
1355
	    }
1484
	    }
-
 
1485
	    gfillrect(xd->gawin, LightGray, getrect(xd->gawin));
1356
	    setbackground(xd->bm, xd->bgcolor);
1486
	    gfillrect(xd->bm, LightGray, getrect(xd->bm));
1357
	}
1487
	}
1358
    }
1488
    }
1359
}
1489
}
1360
 
1490
 
1361
	/********************************************************/
1491
	/********************************************************/
Line 1381... Line 1511...
1381
	error("A bmp file can store only one figure.");
1511
	error("A bmp file can store only one figure.");
1382
    if (xd->kind == SCREEN) {
1512
    if (xd->kind == SCREEN) {
1383
	if (xd->recording && xd->needsave)
1513
	if (xd->recording && xd->needsave)
1384
	    AddtoPlotHistory(savedDisplayList, &savedGPar, 0);
1514
	    AddtoPlotHistory(savedDisplayList, &savedGPar, 0);
1385
	if (xd->replaying)
1515
	if (xd->replaying)
1386
	    xd->needsave= FALSE;
1516
	    xd->needsave = FALSE;
1387
	else
1517
	else
1388
	    xd->needsave= TRUE;
1518
	    xd->needsave = TRUE;
1389
    }
1519
    }
1390
    xd->bg = dd->dp.bg;
1520
    xd->bg = dd->dp.bg;
1391
    xd->bgcolor = rgb(R_RED(xd->bg),
1521
    xd->bgcolor = rgb(R_RED(xd->bg),
1392
		      R_GREEN(xd->bg),
1522
		      R_GREEN(xd->bg),
1393
		      R_BLUE(xd->bg));
1523
		      R_BLUE(xd->bg));
1394
    if (xd->kind!=SCREEN) {
1524
    if (xd->kind!=SCREEN) {
1395
	xd->needsave= TRUE;
1525
	xd->needsave = TRUE;
1396
	xd->clip = getrect(xd->gawin);
1526
	xd->clip = getrect(xd->gawin);
1397
    } else {
1527
    } else {
1398
	xd->clip = getrect(xd->bm);
1528
	xd->clip = getregion(xd);
1399
    }
1529
    }
1400
    DRAW(gfillrect(_d, xd->bgcolor, getrect(_d)));
1530
    DRAW(gfillrect(_d, xd->bgcolor, getregion(xd)));
1401
}
1531
}
1402
 
1532
 
1403
	/********************************************************/
1533
	/********************************************************/
1404
	/* device_Close is called when the device is killed	*/
1534
	/* device_Close is called when the device is killed	*/
1405
	/* this function is responsible for destroying any 	*/
1535
	/* this function is responsible for destroying any 	*/
Line 1806... Line 1936...
1806
	/* (4) it may reset generic graphics parameters that	*/
1936
	/* (4) it may reset generic graphics parameters that	*/
1807
	/* have already been initialised by GInit (although you	*/
1937
	/* have already been initialised by GInit (although you	*/
1808
	/* should know what you are doing if you do this)	*/
1938
	/* should know what you are doing if you do this)	*/
1809
	/* (5) it must attach the device-specific parameters	*/
1939
	/* (5) it must attach the device-specific parameters	*/
1810
        /* structure to the device description structure	*/
1940
        /* structure to the device description structure	*/
1811
	/* e.g., dd->deviceSpecfic = (void *) xd;		*/
1941
	/* e.g., dd->deviceSpecific = (void *) xd;		*/
1812
	/* (6) it must FREE the overall device description if 	*/
1942
	/* (6) it must FREE the overall device description if 	*/
1813
	/* it wants to bail out to the top-level		*/
1943
	/* it wants to bail out to the top-level		*/
1814
	/* the graphics engine is responsible for allocating 	*/
1944
	/* the graphics engine is responsible for allocating 	*/
1815
	/* the device description and freeing it in most cases	*/
1945
	/* the device description and freeing it in most cases	*/
1816
	/* but if the device driver freaks out it needs to do 	*/
1946
	/* but if the device driver freaks out it needs to do 	*/
Line 1818... Line 1948...
1818
	/********************************************************/
1948
	/********************************************************/
1819
 
1949
 
1820
 
1950
 
1821
 
1951
 
1822
Rboolean GADeviceDriver(DevDesc *dd, char *display, double width, 
1952
Rboolean GADeviceDriver(DevDesc *dd, char *display, double width, 
1823
			double height, double pointsize, Rboolean recording)
1953
			double height, double pointsize, 
-
 
1954
			Rboolean recording, int resize)
1824
{
1955
{
1825
    /* if need to bail out with some sort of "error" then */
1956
    /* if need to bail out with some sort of "error" then */
1826
    /* must free(dd) */
1957
    /* must free(dd) */
1827
 
1958
 
1828
    int   ps;
1959
    int   ps;
Line 1849... Line 1980...
1849
    dd->dp.font = 1;
1980
    dd->dp.font = 1;
1850
    dd->dp.ps = ps;
1981
    dd->dp.ps = ps;
1851
 
1982
 
1852
    /* Start the Device Driver and Hardcopy.  */
1983
    /* Start the Device Driver and Hardcopy.  */
1853
 
1984
 
1854
    if (!GA_Open(dd, xd, display, width, height, recording)) {
1985
    if (!GA_Open(dd, xd, display, width, height, recording, resize)) {
1855
	free(xd);
1986
	free(xd);
1856
	return FALSE;
1987
	return FALSE;
1857
    }
1988
    }
1858
    /* Set up Data Structures  */
1989
    /* Set up Data Structures  */
1859
 
1990
 
Line 1885... Line 2016...
1885
    dd->dp.bottom = dd->dp.top + rr.height;	/* bottom */
2016
    dd->dp.bottom = dd->dp.top + rr.height;	/* bottom */
1886
 
2017
 
1887
 
2018
 
1888
    /* Nominal Character Sizes in Pixels */
2019
    /* Nominal Character Sizes in Pixels */
1889
    gcharmetric(xd->gawin, xd->font, -1, &a, &d, &w);
2020
    gcharmetric(xd->gawin, xd->font, -1, &a, &d, &w);
1890
    dd->dp.cra[0] = w;
2021
    dd->dp.cra[0] = w * xd->rescale_factor;
1891
    dd->dp.cra[1] = a + d;
2022
    dd->dp.cra[1] = (a + d) * xd->rescale_factor;
-
 
2023
 
1892
    /* Character Addressing Offsets */
2024
    /* Character Addressing Offsets */
1893
    /* These are used to plot a single plotting character */
2025
    /* These are used to plot a single plotting character */
1894
    /* so that it is exactly over the plotting point */
2026
    /* so that it is exactly over the plotting point */
1895
 
2027
 
1896
    dd->dp.xCharOffset = 0.50;
2028
    dd->dp.xCharOffset = 0.50;
Line 2101... Line 2233...
2101
    R_SaveAsBmp(xd->bm, xd->windowWidth, xd->windowHeight,
2233
    R_SaveAsBmp(xd->bm, xd->windowWidth, xd->windowHeight,
2102
		privategetpixel, 0, fp) ;
2234
		privategetpixel, 0, fp) ;
2103
    gsetcliprect(xd->bm, r);
2235
    gsetcliprect(xd->bm, r);
2104
    fclose(fp);
2236
    fclose(fp);
2105
}
2237
}
-
 
2238
 
-
 
2239
SEXP do_bringtotop(SEXP call, SEXP op, SEXP args, SEXP env)
-
 
2240
{
-
 
2241
    int dev;
-
 
2242
    DevDesc *dd;
-
 
2243
    gadesc *xd;
-
 
2244
 
-
 
2245
    checkArity(op, args);
-
 
2246
    dev = asInteger(CAR(args));
-
 
2247
    if(dev < 1 || dev > NumDevices() || dev == NA_INTEGER)
-
 
2248
	errorcall(call, "invalid value of `which'");
-
 
2249
    dd = GetDevice(dev - 1);
-
 
2250
    if(!dd) errorcall(call, "invalid device");
-
 
2251
    xd = (gadesc *) dd->deviceSpecific;
-
 
2252
    if(!xd) errorcall(call, "invalid device");
-
 
2253
    BringToTop(xd->gawin);
-
 
2254
    return R_NilValue;
-
 
2255
}