The R Project SVN R

Rev

Rev 19874 | Rev 31643 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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