CXXR (C++ R)
GraphicsEngine.h
1 /*CXXR $Id: GraphicsEngine.h 1348 2013-02-25 17:49:03Z arr $
2  *CXXR
3  *CXXR This file is part of CXXR, a project to refactor the R interpreter
4  *CXXR into C++. It may consist in whole or in part of program code and
5  *CXXR documentation taken from the R project itself, incorporated into
6  *CXXR CXXR (and possibly MODIFIED) under the terms of the GNU General Public
7  *CXXR Licence.
8  *CXXR
9  *CXXR CXXR is Copyright (C) 2008-13 Andrew R. Runnalls, subject to such other
10  *CXXR copyrights and copyright restrictions as may be stated below.
11  *CXXR
12  *CXXR CXXR is not part of the R project, and bugs and other issues should
13  *CXXR not be reported via r-bugs or other R project channels; instead refer
14  *CXXR to the CXXR website.
15  *CXXR */
16 
17 /*
18  * R : A Computer Language for Statistical Data Analysis
19  * Copyright (C) 2001-11 The R Core Team.
20  *
21  * This program is free software; you can redistribute it and/or modify
22  * it under the terms of the GNU Lesser General Public License as published by
23  * the Free Software Foundation; either version 2.1 of the License, or
24  * (at your option) any later version.
25  *
26  * This program is distributed in the hope that it will be useful,
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29  * GNU Lesser General Public License for more details.
30  *
31  * You should have received a copy of the GNU Lesser General Public License
32  * along with this program; if not, a copy is available at
33  * http://www.r-project.org/Licenses/
34  */
35 
36 /* Used by graphics.c, grid and by third-party graphics devices */
37 
38 #ifndef R_GRAPHICSENGINE_H_
39 #define R_GRAPHICSENGINE_H_
40 
41 #include "CXXR/String.h"
42 
43 #ifdef __cplusplus
44 extern "C" {
45 #endif
46 
47 /*
48  * The current graphics engine (including graphics device) API version
49  * MUST be integer
50  *
51  * This number should be bumped whenever there are changes to
52  * GraphicsEngine.h or GraphicsDevice.h so that add-on packages
53  * that compile against these headers (graphics systems such as
54  * graphics and grid; graphics devices such as gtkDevice, RSvgDevice)
55  * can detect any version mismatch.
56  *
57  * Version 1: Introduction of the version number.
58  * Version 2: GEDevDesc *dd dropped from GEcontourLines().
59  * Version 3: R_GE_str2col() added to API. (r41887)
60  * Version 4: UTF-8 text hooks, useRotatedTextInContour,
61  * add newFrameConfirm() to NewDevDesc.
62  * New API: GEaddDevice[2] GEgetDevice, GEkillDevice,
63  * ndevNumber. (R 2.7.0)
64  * Version 5: Clean up 1.4.0/2.0.0 changes!
65  * Remove newDevStruct from GEDevDesc and NewDevDesc.
66  * Remove asp, dot(), hold(), open() from NewDevDesc.
67  * Move displayList, DLlastElt, savedSnapshot from
68  * NewDevDesc to GEDevDesc.
69  * Add 'ask' to GEDevDesc. (R 2.8.0)
70  * Version 6: Add dev_Raster() and dev_Cap() (R 2.11.0)
71  * Version 7: Change graphics event handling, adding eventEnv and eventHelper()
72  * to DevDesc. (R 2.12.0)
73  * Version 8: Add dev_Path() (R 2.12.0)
74  * Version 9: Add dev_HoldFlush(), haveTrans*, haveRaster,
75  * haveCapture, haveLocator. (R 2.14.0)
76  */
77 
78 #define R_GE_version 9
79 
80 int R_GE_getVersion(void);
81 
82 void R_GE_checkVersionOrDie(int version);
83 
84 /* The graphics engine will only accept locations and dimensions
85  * in native device coordinates, but it provides the following functions
86  * for converting between a couple of simple alternative coordinate
87  * systems and device coordinates:
88  * DEVICE = native units of the device
89  * NDC = Normalised device coordinates
90  * INCHES = inches (!)
91  * CM = centimetres (!!)
92  */
93 
94 typedef enum {
95  GE_DEVICE = 0, /* native device coordinates (rasters) */
96  GE_NDC = 1, /* normalised device coordinates x=(0,1), y=(0,1) */
97  GE_INCHES = 2,
98  GE_CM = 3
99 } GEUnit;
100 
101 #define MAX_GRAPHICS_SYSTEMS 24
102 
103 typedef enum {
104  /* In response to this event, the registered graphics system
105  * should allocate and initialise the systemSpecific structure
106  *
107  * Should return R_NilValue on failure so that engine
108  * can tidy up memory allocation
109  */
110  GE_InitState = 0,
111  /* This event gives the registered system a chance to undo
112  * anything done in the initialisation.
113  */
114  GE_FinaliseState = 1,
115  /* This is sent by the graphics engine prior to initialising
116  * the display list. It give the graphics system the chance
117  * to squirrel away information it will need for redrawing the
118  * the display list
119  */
120  GE_SaveState = 2,
121  /* This is sent by the graphics engine prior to replaying the
122  * display list. It gives the graphics system the chance to
123  * restore any information it saved on the GE_SaveState event
124  */
125  GE_RestoreState = 6,
126  /* Copy system state information to the current device.
127  * This is used when copying graphics from one device to another
128  * so all the graphics system needs to do is to copy across
129  * the bits required for the display list to draw faithfully
130  * on the new device.
131  */
132  GE_CopyState = 3,
133  /* Create a snapshot of the system state that is sufficient
134  * for the current "image" to be reproduced
135  */
136  GE_SaveSnapshotState = 4,
137  /* Restore the system state that is saved by GE_SaveSnapshotState
138  */
139  GE_RestoreSnapshotState = 5,
140  /* When replaying the display list, the graphics engine
141  * checks, after each replayed action, that the action
142  * produced valid output. This is the graphics system's
143  * chance to say that the output is crap (in which case the
144  * graphics engine will abort the display list replay).
145  */
146  GE_CheckPlot = 7,
147  /* The device wants to scale the current pointsize
148  * (for scaling an image)
149  * This is not a nice general solution, but a quick fix for
150  * the Windows device.
151  */
152  GE_ScalePS = 8
153 } GEevent;
154 
155 /*
156  * Some line end/join constants
157  */
158 typedef enum {
159  GE_ROUND_CAP = 1,
160  GE_BUTT_CAP = 2,
161  GE_SQUARE_CAP = 3
162 } R_GE_lineend;
163 
164 typedef enum {
165  GE_ROUND_JOIN = 1,
166  GE_MITRE_JOIN = 2,
167  GE_BEVEL_JOIN = 3
168 } R_GE_linejoin;
169 
170 /*
171  * A structure containing graphical parameters
172  *
173  * This is how graphical parameters are passed from graphics systems
174  * to the graphics engine AND from the graphics engine to graphics
175  * devices.
176  *
177  * Devices are not *required* to honour graphical parameters
178  * (e.g., alpha transparency is going to be tough for some)
179  */
180 typedef struct {
181  /*
182  * Colours
183  *
184  * NOTE: Alpha transparency included in col & fill
185  */
186  int col; /* pen colour (lines, text, borders, ...) */
187  int fill; /* fill colour (for polygons, circles, rects, ...) */
188  double gamma; /* Gamma correction */
189  /*
190  * Line characteristics
191  */
192  double lwd; /* Line width (roughly number of pixels) */
193  int lty; /* Line type (solid, dashed, dotted, ...) */
194  R_GE_lineend lend; /* Line end */
195  R_GE_linejoin ljoin; /* line join */
196  double lmitre; /* line mitre */
197  /*
198  * Text characteristics
199  */
200  double cex; /* Character expansion (font size = fontsize*cex) */
201  double ps; /* Font size in points */
202  double lineheight; /* Line height (multiply by font size) */
203  int fontface; /* Font face (plain, italic, bold, ...) */
204  char fontfamily[201]; /* Font family */
205 } R_GE_gcontext;
206 
207 typedef R_GE_gcontext* pGEcontext;
208 
209 #ifdef __cplusplus
210 } // extern "C"
211 #endif
212 
213 #include <R_ext/GraphicsDevice.h> /* needed for DevDesc */
214 
215 #ifdef __cplusplus
216 extern "C" {
217 #endif
218 
219 typedef struct _GEDevDesc GEDevDesc;
220 
221 typedef SEXP (* GEcallback)(GEevent, GEDevDesc *, SEXP);
222 
223 typedef struct {
224  /* An array of information about each graphics system that
225  * has registered with the graphics engine.
226  * This is used to store graphics state for each graphics
227  * system on each device.
228  */
229  void *systemSpecific;
230  /*
231  * An array of function pointers, one per graphics system that
232  * has registered with the graphics engine.
233  *
234  * system_Callback is called when the graphics engine wants
235  * to give a graphics system the chance to play with its
236  * device-specific information (stored in systemSpecific)
237  * There are two parameters: an "event" to tell the graphics
238  * system why the graphics engine has called this function,
239  * and the systemSpecific pointer. The graphics engine
240  * has to pass the systemSpecific pointer because only
241  * the graphics engine will know what array index to use.
242  */
243  GEcallback callback;
244 } GESystemDesc;
245 
246 struct _GEDevDesc {
247  /* Location within the R_Devices table, or -1 if not (yet) in
248  * table. (Temporary CXXR kludge.) */
249  int index;
250  /*
251  * Stuff that the devices can see (and modify).
252  * All detailed in GraphicsDevice.h
253  */
254  pDevDesc dev;
255  /*
256  * Stuff about the device that only the graphics engine sees
257  * (the devices don't see it). Note that in CXXR, displayList and
258  * savedSnapshot must be modified only by using the functions
259  * setDisplayList() and saveSnapshot() respectively. (In future,
260  * this should be enforced by class access controls.)
261  */
262  Rboolean displayListOn; /* toggle for display list status */
263  SEXP displayList; /* display list */
264  SEXP DLlastElt; /* A pointer to the end of the display list
265  to avoid tranversing pairlists */
266  SEXP savedSnapshot; /* The last element of the display list
267  * just prior to when the display list
268  * was last initialised
269  */
270  Rboolean dirty; /* Has the device received any output? */
271  Rboolean recordGraphics; /* Should a graphics call be stored
272  * on the display list?
273  * Set to FALSE by do_recordGraphics,
274  * do_dotcallgr, and do_Externalgr
275  * so that nested calls are not
276  * recorded on the display list
277  */
278  /*
279  * Stuff about the device that only graphics systems see.
280  * The graphics engine has no idea what is in here.
281  * Used by graphics systems to store system state per device.
282  */
283  GESystemDesc *gesd[MAX_GRAPHICS_SYSTEMS];
284 
285  /* per-device setting for 'ask' (use NewFrameConfirm) */
286  Rboolean ask;
287 };
288 
289 /* 2007/06/02 arr: Stuff previously here moved to GraphicsContext.h to avoid
290  * reciprocal dependencies between this file and GraphicsDevice.h.
291  */
292 
293 typedef GEDevDesc* pGEDevDesc;
294 
295 /* Mutator functions introduced in CXXR pending fuller refactorisation:
296  */
297 void setDisplayList(pGEDevDesc dev, SEXP newDisplayList);
298 void saveSnapshot(pGEDevDesc dev, SEXP newSnapshot);
299 
300 /* functions from devices.c for use by graphics devices */
301 
302 #define desc2GEDesc Rf_desc2GEDesc
303 /* map DevDesc to enclosing GEDevDesc */
304 pGEDevDesc desc2GEDesc(pDevDesc dd);
305 int GEdeviceNumber(pGEDevDesc);
306 pGEDevDesc GEgetDevice(int);
307 void GEaddDevice(pGEDevDesc);
308 void GEaddDevice2(pGEDevDesc, const char *);
309 void GEkillDevice(pGEDevDesc);
310 pGEDevDesc GEcreateDevDesc(pDevDesc dev);
311 
312 void GEdestroyDevDesc(pGEDevDesc dd);
313 void *GEsystemState(pGEDevDesc dd, int index);
314 void GEregisterWithDevice(pGEDevDesc dd);
315 void GEregisterSystem(GEcallback callback, int *systemRegisterIndex);
316 void GEunregisterSystem(int registerIndex);
317 SEXP GEhandleEvent(GEevent event, pDevDesc dev, SEXP data);
318 
319 #define fromDeviceX GEfromDeviceX
320 #define toDeviceX GEtoDeviceX
321 #define fromDeviceY GEfromDeviceY
322 #define toDeviceY GEtoDeviceY
323 #define fromDeviceWidth GEfromDeviceWidth
324 #define toDeviceWidth GEtoDeviceWidth
325 #define fromDeviceHeight GEfromDeviceHeight
326 #define toDeviceHeight GEtoDeviceHeight
327 
328 double fromDeviceX(double value, GEUnit to, pGEDevDesc dd);
329 double toDeviceX(double value, GEUnit from, pGEDevDesc dd);
330 double fromDeviceY(double value, GEUnit to, pGEDevDesc dd);
331 double toDeviceY(double value, GEUnit from, pGEDevDesc dd);
332 double fromDeviceWidth(double value, GEUnit to, pGEDevDesc dd);
333 double toDeviceWidth(double value, GEUnit from, pGEDevDesc dd);
334 double fromDeviceHeight(double value, GEUnit to, pGEDevDesc dd);
335 double toDeviceHeight(double value, GEUnit from, pGEDevDesc dd);
336 
337 /*-------------------------------------------------------------------
338  *
339  * COLOUR CODE is concerned with the internals of R colour representation
340  *
341  * From colors.c, used in par.c, grid/src/gpar.c
342  */
343 
344 #define RGBpar Rf_RGBpar
345 #define RGBpar3 Rf_RGBpar3
346 #define col2name Rf_col2name
347 #define name2col Rf_name2col
348 
349 /* Convert an element of a R colour specification (which might be a
350  number or a string) into an internal colour specification. */
351 unsigned int RGBpar(SEXP, int);
352 unsigned int RGBpar3(SEXP, int, unsigned int);
353 
354 /* Convert an internal colour specification to/from a colour name */
355 const char *col2name(unsigned int col); /* used in par.c, grid */
356 unsigned int name2col(const char *); /* used by plotmath.c */
357 
358 /* Convert either a name or a #RRGGBB[AA] string to internal.
359  Because people were using it, it also converts "1", "2" ...
360  to a colour in the palette, and "0" to transparent white.
361 */
362 unsigned int R_GE_str2col(const char *s);
363 
364 
365 
366 /*
367  * Some Notes on Line Textures
368  *
369  * Line textures are stored as an array of 4-bit integers within
370  * a single 32-bit word. These integers contain the lengths of
371  * lines to be drawn with the pen alternately down and then up.
372  * The device should try to arrange that these values are measured
373  * in points if possible, although pixels is ok on most displays.
374  *
375  * If newlty contains a line texture description it is decoded
376  * as follows:
377  *
378  * ndash = 0;
379  * for(i=0 ; i<8 && newlty & 15 ; i++) {
380  * dashlist[ndash++] = newlty & 15;
381  * newlty = newlty>>4;
382  * }
383  * dashlist[0] = length of pen-down segment
384  * dashlist[1] = length of pen-up segment
385  * etc
386  *
387  * An integer containing a zero terminates the pattern. Hence
388  * ndash in this code fragment gives the length of the texture
389  * description. If a description contains an odd number of
390  * elements it is replicated to create a pattern with an
391  * even number of elements. (If this is a pain, do something
392  * different its not crucial).
393  *
394  */
395 
396 /*--- The basic numbered & names line types; Here device-independent:
397  e.g. "dashed" == "44", "dotdash" == "1343"
398 */
399 
400 /* NB: was also in Rgraphics.h in R < 2.7.0 */
401 #define LTY_BLANK -1
402 #define LTY_SOLID 0
403 #define LTY_DASHED 4 + (4<<4)
404 #define LTY_DOTTED 1 + (3<<4)
405 #define LTY_DOTDASH 1 + (3<<4) + (4<<8) + (3<<12)
406 #define LTY_LONGDASH 7 + (3<<4)
407 #define LTY_TWODASH 2 + (2<<4) + (6<<8) + (2<<12)
408 
409 R_GE_lineend GE_LENDpar(SEXP value, int ind);
410 SEXP GE_LENDget(R_GE_lineend lend);
411 R_GE_linejoin GE_LJOINpar(SEXP value, int ind);
412 SEXP GE_LJOINget(R_GE_linejoin ljoin);
413 
414 void GESetClip(double x1, double y1, double x2, double y2, pGEDevDesc dd);
415 void GENewPage(const pGEcontext gc, pGEDevDesc dd);
416 void GELine(double x1, double y1, double x2, double y2,
417  const pGEcontext gc, pGEDevDesc dd);
418 void GEPolyline(int n, double *x, double *y,
419  const pGEcontext gc, pGEDevDesc dd);
420 void GEPolygon(int n, double *x, double *y,
421  const pGEcontext gc, pGEDevDesc dd);
422 SEXP GEXspline(int n, double *x, double *y, double *s, Rboolean open,
423  Rboolean repEnds, Rboolean draw,
424  const pGEcontext gc, pGEDevDesc dd);
425 void GECircle(double x, double y, double radius,
426  const pGEcontext gc, pGEDevDesc dd);
427 void GERect(double x0, double y0, double x1, double y1,
428  const pGEcontext gc, pGEDevDesc dd);
429 void GEPath(double *x, double *y,
430  int npoly, int *nper,
431  Rboolean winding,
432  const pGEcontext gc, pGEDevDesc dd);
433 void GERaster(unsigned int *raster, int w, int h,
434  double x, double y, double width, double height,
435  double angle, Rboolean interpolate,
436  const pGEcontext gc, pGEDevDesc dd);
437 SEXP GECap(pGEDevDesc dd);
438 void GEText(double x, double y, const char * const str, cetype_t enc,
439  double xc, double yc, double rot,
440  const pGEcontext gc, pGEDevDesc dd);
441 void GEMode(int mode, pGEDevDesc dd);
442 void GESymbol(double x, double y, int pch, double size,
443  const pGEcontext gc, pGEDevDesc dd);
444 void GEPretty(double *lo, double *up, int *ndiv);
445 void GEMetricInfo(int c, const pGEcontext gc,
446  double *ascent, double *descent, double *width,
447  pGEDevDesc dd);
448 double GEStrWidth(const char *str, cetype_t enc,
449  const pGEcontext gc, pGEDevDesc dd);
450 double GEStrHeight(const char *str, cetype_t enc,
451  const pGEcontext gc, pGEDevDesc dd);
452 void GEStrMetric(const char *str, cetype_t enc, const pGEcontext gc,
453  double *ascent, double *descent, double *width,
454  pGEDevDesc dd);
455 int GEstring_to_pch(SEXP pch);
456 
457 /*-------------------------------------------------------------------
458  *
459  * LINE TEXTURE CODE is concerned with the internals of R
460  * line texture representation.
461  */
462 unsigned int GE_LTYpar(SEXP, int);
463 SEXP GE_LTYget(unsigned int);
464 
465 /*
466  * Raster operations
467  */
468 void R_GE_rasterScale(unsigned int *sraster, int sw, int sh,
469  unsigned int *draster, int dw, int dh);
470 void R_GE_rasterInterpolate(unsigned int *sraster, int sw, int sh,
471  unsigned int *draster, int dw, int dh);
472 void R_GE_rasterRotatedSize(int w, int h, double angle,
473  int *wnew, int *hnew);
474 void R_GE_rasterRotatedOffset(int w, int h, double angle, int botleft,
475  double *xoff, double *yoff);
476 void R_GE_rasterResizeForRotation(unsigned int *sraster,
477  int w, int h,
478  unsigned int *newRaster,
479  int wnew, int hnew,
480  const pGEcontext gc);
481 void R_GE_rasterRotate(unsigned int *sraster, int w, int h, double angle,
482  unsigned int *draster, const pGEcontext gc,
483  Rboolean perPixelAlpha);
484 
485 
486 /*
487  * From plotmath.c
488  */
489 double GEExpressionWidth(SEXP expr,
490  const pGEcontext gc, pGEDevDesc dd);
491 double GEExpressionHeight(SEXP expr,
492  const pGEcontext gc, pGEDevDesc dd);
493 void GEExpressionMetric(SEXP expr, const pGEcontext gc,
494  double *ascent, double *descent, double *width,
495  pGEDevDesc dd);
496 void GEMathText(double x, double y, SEXP expr,
497  double xc, double yc, double rot,
498  const pGEcontext gc, pGEDevDesc dd);
499 /*
500  * (End from plotmath.c)
501  */
502 
503 /*
504  * From plot3d.c : used in package clines
505  */
506 SEXP GEcontourLines(double *x, int nx, double *y, int ny,
507  double *z, double *levels, int nl);
508 /*
509  * (End from plot3d.c)
510  */
511 
512 /*
513  * From vfonts.c
514  */
515 double R_GE_VStrWidth(const char *s, cetype_t enc, const pGEcontext gc, pGEDevDesc dd);
516 
517 double R_GE_VStrHeight(const char *s, cetype_t enc, const pGEcontext gc, pGEDevDesc dd);
518 void R_GE_VText(double x, double y, const char * const s, cetype_t enc,
519  double x_justify, double y_justify, double rotation,
520  const pGEcontext gc, pGEDevDesc dd);
521 /*
522  * (End from vfonts.c)
523  */
524 
525 /* Also in Graphics.h */
526 #define DEG2RAD 0.01745329251994329576
527 
528 pGEDevDesc GEcurrentDevice(void);
529 Rboolean GEdeviceDirty(pGEDevDesc dd);
530 void GEdirtyDevice(pGEDevDesc dd);
531 Rboolean GEcheckState(pGEDevDesc dd);
532 Rboolean GErecording(SEXP call, pGEDevDesc dd);
533 void GErecordGraphicOperation(SEXP op, SEXP args, pGEDevDesc dd);
534 void GEinitDisplayList(pGEDevDesc dd);
535 void GEplayDisplayList(pGEDevDesc dd);
536 void GEcopyDisplayList(int fromDevice);
537 SEXP GEcreateSnapshot(pGEDevDesc dd);
538 void GEplaySnapshot(SEXP snapshot, pGEDevDesc dd);
539 void GEonExit(void);
540 void GEnullDevice(void);
541 
542 
543 /* From ../../main/plot.c, used by ../../library/grid/src/grid.c */
544 #define CreateAtVector Rf_CreateAtVector
545 SEXP CreateAtVector(double*, double*, int, Rboolean);
546 /* From ../../main/graphics.c, used by ../../library/grDevices/src/axis_scales.c */
547 #define GAxisPars Rf_GAxisPars
548 void GAxisPars(double *min, double *max, int *n, Rboolean log, int axis);
549 
550 #ifdef __cplusplus
551 }
552 #endif
553 
554 #endif /* R_GRAPHICSENGINE_ */