The R Project SVN R

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
30691 murdoch 1
/*
2
 *  R : A Computer Language for Statistical Data Analysis
3
 *  Copyright (C) 2001-4 The R Development Core Team.
4
 *
5
 *  This program is free software; you can redistribute it and/or modify
6
 *  it under the terms of the GNU Lesser General Public License as published by
7
 *  the Free Software Foundation; either version 2.1 of the License, or
8
 *  (at your option) any later version.
9
 *
10
 *  This program is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU Lesser General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU Lesser General Public License
16
 *  along with this program; if not, write to the Free Software
17
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 */
17204 hornik 19
 
30691 murdoch 20
/* Used by third-party graphics devices */
21
 
17204 hornik 22
/* New device driver structure
23
 * NOTES:
24
 * 1. All locations and dimensions are in device coordinates.
25
 * 2. I found this comment in the doc for dev_Open -- looks nasty
26
 *    Any known instances of such a thing happening?  Should be
27
 *    replaced by a function to query the device for preferred gpars
28
 *    settings? (to be called when the device is initialised)
29
         *
30
         * NOTE that it is perfectly acceptable for this	
31
         * function to set generic graphics parameters too	
32
         * (i.e., override the generic parameter settings	
33
         * which GInit sets up) all at the author's own risk	
34
         * of course :)						
35
	 *
36
 * 3. Do we really need dev_StrWidth as well as dev_MetricInfo?
37
 *    I can see the difference between the two -- its just a 
38
 *    question of whether dev_MetricInfo should just return
39
 *    what dev_StrWidth would give if font metric information is
40
 *    not available.  I guess having both allows the developer
41
 *    to decide when to ask for which sort of value, and to decide
42
 *    what to do when font metric information is not available.
43
 *    And why not a dev_StrHeight?
27236 murrell 44
 * 4. Should "ipr", "asp", and "cra" be in the device description?
17204 hornik 45
 *    If not, then where?
46
 *    I guess they don't need to be if no device makes use of them.
47
 *    On the other hand, they would need to be replaced by a device
48
 *    call that R base graphics could use to get enough information
49
 *    to figure them out.  (e.g., some sort of dpi() function to
50
 *    complement the size() function.)
51
 */
27236 murrell 52
 
17204 hornik 53
typedef struct {
54
    /* The first element is a boolean indicating whether this is 
55
     * a new device driver (always 1) -- the old device driver structure
56
     * has had a similar element added (which will always be 0)
19874 murrell 57
     *
58
     * This needs to be removed once the old DevDesc structure has been
59
     * removed from the system.
17204 hornik 60
     */
61
    int newDevStruct; 
62
    /********************************************************
19874 murrell 63
     * Device physical characteristics
17204 hornik 64
     ********************************************************/
65
    double left;	        /* left raster coordinate */
66
    double right;	        /* right raster coordinate */
67
    double bottom;	        /* bottom raster coordinate */
68
    double top;		        /* top raster coordinate */
19874 murrell 69
    /* R only has the notion of a rectangular clipping region
70
     */
17204 hornik 71
    double clipLeft;
72
    double clipRight;
73
    double clipBottom;
74
    double clipTop;
19874 murrell 75
    /* I hate these next three -- they seem like a real fudge
76
     * BUT I'm not sure what to replace them with so they stay for now.
77
     */
17204 hornik 78
    double xCharOffset;	        /* x character addressing offset */
79
    double yCharOffset;	        /* y character addressing offset */
80
    double yLineBias;	        /* 1/2 interline space as frac of line hght */
19874 murrell 81
    double ipr[2];	        /* Inches per raster; [0]=x, [1]=y */
82
    double asp;		        /* Pixel aspect ratio = ipr[1]/ipr[0] */
83
    /* I hate this guy too -- seems to assume that a device can only
84
     * have one font size during its lifetime
85
     * BUT removing/replacing it would take quite a lot of work
86
     * to design and insert a good replacement so it stays for now.
87
     */
88
    double cra[2];	        /* Character size in rasters; [0]=x, [1]=y */
89
    double gamma;	        /* Device Gamma Correction */
90
    /********************************************************
91
     * Device capabilities
92
     ********************************************************/
17204 hornik 93
    Rboolean canResizePlot;	/* can the graphics surface be resized */
94
    Rboolean canChangeFont;	/* device has multiple fonts */
95
    Rboolean canRotateText;	/* text can be rotated */
96
    Rboolean canResizeText;	/* text can be resized */
97
    Rboolean canClip;		/* Hardware clipping */
98
    Rboolean canChangeGamma;    /* can the gamma factor be modified */
99
    int canHAdj;	        /* Can do at least some horiz adjust of text
100
 
19874 murrell 101
    /********************************************************
102
     * Device initial settings
103
     ********************************************************/
104
    /* These are things that the device must set up when it is created.
105
     * The graphics system can modify them and track current values,
106
     * but some devices want to know what the original setting was.
107
     */
17204 hornik 108
    double startps;             
109
    int startcol;
110
    int startfill;
111
    int startlty;
112
    int startfont;
113
    double startgamma;
19874 murrell 114
    /********************************************************
115
     * Device specific information
116
     ********************************************************/
17204 hornik 117
    void *deviceSpecific;	/* pointer to device specific parameters */
19874 murrell 118
    /********************************************************
119
     * Device display list
120
     ********************************************************/
121
    /* I think it would feel nicer if this stuff was part of the 
122
     * graphics engine (GEDevDesc), but this is another thing that
123
     * needs more time to implement a change properly.
124
     */
17204 hornik 125
    Rboolean displayListOn;     /* toggle for display list status */
126
    SEXP displayList;           /* display list */
18917 murrell 127
    SEXP savedSnapshot;         /* The last value of the display list
128
				 * just prior to when the display list
129
				 * was last initialised
130
				 */
17204 hornik 131
    /********************************************************
132
     * Device procedures.
133
     ********************************************************/
27236 murrell 134
 
17204 hornik 135
    /*
27236 murrell 136
     * ---------------------------------------
137
     * GENERAL COMMENT ON GRAPHICS PARAMETERS:
138
     * ---------------------------------------
139
     * Graphical parameters are now passed in a graphics context
140
     * structure (R_GE_gcontext*) rather than individually.
141
     * Each device action should extract the parameters it needs
142
     * and ignore the others.  Thought should be given to which 
143
     * parameters are relevant in each case -- the graphics engine
144
     * does not REQUIRE that each parameter is honoured, but if
145
     * a parameter is NOT honoured, it might be a good idea to
146
     * issue a warning when a parameter is not honoured (or at
147
     * the very least document which parameters are not honoured
148
     * in the user-level documentation for the device).  [An example
149
     * of a parameter that may not be honoured by many devices is
150
     * transparency.]
151
     */
152
 
153
    /*
17204 hornik 154
     * device_Activate is called when a device becomes the	
155
     * active device.  For example, it can be used to change the
156
     * title of a window to indicate the active status of	
157
     * the device to the user.  Not all device types will	
158
     * do anything.			
159
     * The only parameter is a device driver structure.
160
     * An example is ...
161
     *
162
     * static void   X11_Activate(NewDevDesc *dd);
163
     *
164
     */
165
    void (*activate)();
166
    /*
167
     * device_Circle should have the side-effect that a	
168
     * circle is drawn, centred at the given location, with 
169
     * the given radius.  The border of the circle should be
170
     * drawn in the given "col", and the circle should be	
171
     * filled with the given "fill" colour.		
172
     * If "col" is NA_INTEGER then no border should be drawn
173
     * If "fill" is NA_INTEGER then the circle should not 
174
     * be filled.
175
     * An example is ...
176
     *
177
     * static void X11_Circle(double x, double y, double r,
27236 murrell 178
     *                        R_GE_gcontext *gc,
17204 hornik 179
     *                        NewDevDesc *dd);
180
     *
27236 murrell 181
     * R_GE_gcontext parameters that should be honoured (if possible):
182
     *   col, fill, gamma, lty, lwd
17204 hornik 183
     */
184
    void (*circle)();
185
    /*
186
     * device_Clip is given the left, right, bottom, and	
187
     * top of a rectangle (in DEVICE coordinates).	
188
     * It should have the side-effect that subsequent output	
189
     * is clipped to the given rectangle.
190
     * NOTE that R's graphics engine already clips to the 
191
     * extent of the device.
192
     * NOTE also that this will probably only be called if
193
     * the flag canClip is true.
194
     * An example is ...
195
     *
196
     * static void X11_Clip(double x0, double x1, double y0, double y1, 
197
     *                      NewDevDesc *dd)
198
     */
199
    void (*clip)();
200
    /*
201
     * device_Close is called when the device is killed.
202
     * This function is responsible for destroying any	
203
     * device-specific resources that were created in	
204
     * device_Open and for FREEing the device-specific	
205
     * parameters structure.	
206
     * An example is ...
207
     *
208
     * static void X11_Close(NewDevDesc *dd)
209
     *
210
     */
211
    void (*close)();
212
    /*
213
     * device_Deactivate is called when a device becomes	
214
     * inactive.  
215
     * This allows the device to undo anything it did in 
216
     * dev_Activate.
217
     * Not all device types will do anything.
218
     * An example is ...
219
     *
220
     * static void X11_Deactivate(NewDevDesc *dd)
221
     *
222
     */
223
    void (*deactivate)();
224
    void (*dot)();
225
    /*
226
     * I don't know what this is for and i can't find it	
227
     * being used anywhere, but i'm loath to kill it in	
228
     * case i'm missing something important			
229
     * An example is ...
230
     *
231
     * static void X11_Hold(NewDevDesc *dd)
232
     *
233
     */
234
    void (*hold)();
235
    /*
236
     * device_Locator should return the location of the next
237
     * mouse click (in DEVICE coordinates)	
238
     * Not all devices will do anything (e.g., postscript)	
239
     * An example is ...
240
     *
241
     * static Rboolean X11_Locator(double *x, double *y, NewDevDesc *dd)
242
     *
243
     */
244
    Rboolean (*locator)();
245
    /*
246
     * device_Line should have the side-effect that a single
247
     * line is drawn (from x1,y1 to x2,y2)			
248
     * An example is ...
249
     *
250
     * static void X11_Line(double x1, double y1, double x2, double y2,
27236 murrell 251
     *                      R_GE_gcontext *gc,
17204 hornik 252
     *                      NewDevDesc *dd);
253
     *
27236 murrell 254
     * R_GE_gcontext parameters that should be honoured (if possible):
255
     *   col, gamma, lty, lwd
17204 hornik 256
     */
257
    void (*line)();
258
    /*
259
     * device_MetricInfo should return height, depth, and	
260
     * width information for the given character in DEVICE	
261
     * units.
262
     * This is used for formatting mathematical expressions	
263
     * and for exact centering of text (see GText)		
264
     * If the device cannot provide metric information then 
265
     * it MUST return 0.0 for ascent, descent, and width.
266
     * An example is ...
267
     *
27236 murrell 268
     * static void X11_MetricInfo(int c,
269
     *                            R_GE_gcontext *gc,
17204 hornik 270
     *                            double* ascent, double* descent,
271
     *                            double* width, NewDevDesc *dd);
27236 murrell 272
     *
273
     * R_GE_gcontext parameters that should be honoured (if possible):
274
     *   font, cex, ps
17204 hornik 275
     */
276
    void (*metricInfo)();
277
    /*
278
     * device_Mode is called whenever the graphics engine	
279
     * starts drawing (mode=1) or stops drawing (mode=0)	
280
     * The device is not required to do anything		
281
     * An example is ...
282
     *
283
     * static void X11_Mode(int mode, NewDevDesc *dd);
284
     *
285
     */
286
    void (*mode)();
287
    /*
288
     * device_NewPage is called whenever a new plot requires
289
     * a new page.	
290
     * A new page might mean just clearing the	
291
     * device (e.g., X11) or moving to a new page	
292
     * (e.g., postscript)					
293
     * An example is ...
294
     *
295
     *
27236 murrell 296
     * static void X11_NewPage(R_GE_gcontext *gc,
297
     *                         NewDevDesc *dd);
17204 hornik 298
     *
299
     */
300
    void (*newPage)();
301
    /*
302
     * device_Open is not usually called directly by the	
303
     * graphics engine;  it is usually only called from	
304
     * the device-driver entry point.			
305
     * This function should set up all of the device-	
306
     * specific resources for a new device			
307
     * This function is given a newly-allocated NewDevDesc structure 
308
     * and it must FREE the structure if anything goes seriously wrong.
309
     * NOTE that different devices will accept different parameter
310
     * lists, corresponding to different device-specific preferences.
311
     * An example is ...
312
     *
313
     * Rboolean X11_Open(NewDevDesc *dd, char *dsp, double w, double h, 
314
     *                   double gamma_fac, X_COLORTYPE colormodel, 
315
     *                   int maxcube, int canvascolor);
316
     *
317
     */
318
    Rboolean (*open)();
319
    /*
320
     * device_Polygon should have the side-effect that a	
321
     * polygon is drawn using the given x and y values	
322
     * the polygon border should be drawn in the "col"	
323
     * colour and filled with the "fill" colour.
324
     * If "col" is NA_INTEGER don't draw the border		
325
     * If "fill" is NA_INTEGER don't fill the polygon		
326
     * An example is ...
327
     *
328
     * static void X11_Polygon(int n, double *x, double *y, 
27236 murrell 329
     *                         R_GE_gcontext *gc,
17204 hornik 330
     *                         NewDevDesc *dd);
331
     *
27236 murrell 332
     * R_GE_gcontext parameters that should be honoured (if possible):
333
     *   col, fill, gamma, lty, lwd
17204 hornik 334
     */
335
    void (*polygon)();
336
    /*
337
     * device_Polyline should have the side-effect that a	
338
     * series of line segments are drawn using the given x	
339
     * and y values.
340
     * An example is ...
341
     *
342
     * static void X11_Polyline(int n, double *x, double *y, 
27236 murrell 343
     *                          R_GE_gcontext *gc,
17204 hornik 344
     *                          NewDevDesc *dd);
345
     *
27236 murrell 346
     * R_GE_gcontext parameters that should be honoured (if possible):
347
     *   col, gamma, lty, lwd
17204 hornik 348
     */
349
    void (*polyline)();
350
    /*
351
     * device_Rect should have the side-effect that a	
352
     * rectangle is drawn with the given locations for its	
353
     * opposite corners.  The border of the rectangle	
354
     * should be in the given "col" colour and the rectangle	
355
     * should be filled with the given "fill" colour.
356
     * If "col" is NA_INTEGER then no border should be drawn 
357
     * If "fill" is NA_INTEGER then the rectangle should not	
358
     * be filled.						
359
     * An example is ...
360
     *
361
     * static void X11_Rect(double x0, double y0, double x1, double y1,
27236 murrell 362
     *                      R_GE_gcontext *gc,
17204 hornik 363
     *                      NewDevDesc *dd);
364
     *
365
     */
366
    void (*rect)();
367
    /*
368
     * device_Size is called whenever the device is	
369
     * resized.  
370
     * The function returns (left, right, bottom, and top) for the	
371
     * new device size.					
372
     * This is not usually called directly by the graphics	
373
     * engine because the detection of device resizes	
374
     * (e.g., a window resize) are usually detected by	
375
     * device-specific code.
376
     * An example is ...
377
     *
378
     * static void X11_Size(double *left, double *right,
379
     *                      double *bottom, double *top,
380
     *                      NewDevDesc *dd);
381
     *
27236 murrell 382
     * R_GE_gcontext parameters that should be honoured (if possible):
383
     *   col, fill, gamma, lty, lwd
17204 hornik 384
     */
385
    void (*size)();
386
    /*
387
     * device_StrWidth should return the width of the given 
388
     * string in DEVICE units.				
389
     * An example is ...
390
     *
27236 murrell 391
     * static double X11_StrWidth(char *str, 
392
     *                            R_GE_gcontext *gc,
17204 hornik 393
     *                            NewDevDesc *dd)
394
     *
27236 murrell 395
     * R_GE_gcontext parameters that should be honoured (if possible):
396
     *   font, cex, ps
17204 hornik 397
     */
398
    double (*strWidth)();
399
    /*
400
     * device_Text should have the side-effect that the	
401
     * given text is drawn at the given location.
402
     * The text should be rotated according to rot (degrees)
403
     * An example is ...
404
     *
405
     * static void X11_Text(double x, double y, char *str, 
406
     *                      double rot, double hadj, 
27236 murrell 407
     *                      R_GE_gcontext *gc,
17204 hornik 408
     * 	                    NewDevDesc *dd);
409
     *
27236 murrell 410
     * R_GE_gcontext parameters that should be honoured (if possible):
411
     *   font, cex, ps, col, gamma
17204 hornik 412
     */
413
    void (*text)();
414
} NewDevDesc;
415
 
416
	/********************************************************/
417
	/* the device-driver entry point is given a device	*/
418
	/* description structure that it must set up.  this	*/
419
	/* involves several important jobs ...			*/
420
	/* (1) it must ALLOCATE a new device-specific parameters*/
421
	/* structure and FREE that structure if anything goes	*/
422
	/* wrong (i.e., it won't report a successful setup to	*/
423
	/* the graphics engine (the graphics engine is NOT	*/
424
	/* responsible for allocating or freeing device-specific*/
425
	/* resources or parameters)				*/
426
	/* (2) it must initialise the device-specific resources */
427
	/* and parameters (mostly done by calling device_Open)	*/
428
	/* (3) it must initialise the generic graphical		*/
429
	/* parameters that are not initialised by GInit (because*/
430
	/* only the device knows what values they should have)	*/
431
	/* see Graphics.h for the official list of these	*/
432
	/* (4) it may reset generic graphics parameters that	*/
433
	/* have already been initialised by GInit (although you	*/
434
	/* should know what you are doing if you do this)	*/
435
	/* (5) it must attach the device-specific parameters	*/
436
	/* structure to the device description structure	*/
437
	/* e.g., dd->deviceSpecfic = (void *) xd;		*/
438
	/* (6) it must FREE the overall device description if	*/
439
	/* it wants to bail out to the top-level		*/
440
	/* the graphics engine is responsible for allocating	*/
441
	/* the device description and freeing it in most cases	*/
442
	/* but if the device driver freaks out it needs to do	*/
443
	/* the clean-up itself					*/
444
	/********************************************************/
445