RAPI
|
00001 /* 00002 * R : A Computer Language for Statistical Data Analysis 00003 * Copyright (C) 2007-12 The R Core Team 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, a copy is available at 00017 * https://www.R-project.org/Licenses/ 00018 * 00019 *--------------------------------------------------------------------- 00020 * This header file constitutes the (unofficial) API to the Quartz 00021 * device. Being unofficial, the API may change at any point without 00022 * warning. 00023 * 00024 * Quartz is a general device-independent way of drawing in macOS, 00025 * therefore the Quartz device modularizes the actual drawing target 00026 * implementation into separate modules (e.g. Carbon and Cocoa for 00027 * on-screen display and PDF, Bitmap for off-screen drawing). The API 00028 * below is used by the modules to talk to the Quartz device without 00029 * having to know anything about R graphics device API. 00030 * 00031 * Key functions are listed here: 00032 * QuartzDevice_Create - creates a Quartz device 00033 * QuartzDevice_ResetContext - should be called after the target 00034 * context has been created to initialize it. 00035 * QuartzDevice_Kill - closes the Quartz device (e.g. on window close) 00036 * QuartzDevice_SetScaledSize - resize device (does not include 00037 * re-painting, it should be followed by a call to 00038 * QuartzDevice_ReplayDisplayList) 00039 * QuartzDevice_ReplayDisplayList - replays all plot commands 00040 * 00041 * Key concepts 00042 * - all Quartz modules are expected to provide a device context 00043 * (CGContextRef) for drawing. A device can temporarily return NULL 00044 * (e.g. if the context is not available immediately) and replay 00045 * the display list later to catch up. 00046 * 00047 * - interactive devices can use QuartzDevice_SetScaledSize to resize 00048 * the device (no context is necessary), then prepare the context 00049 * (call QuartzDevice_ResetContext if a new context was created) 00050 * and finally re-draw using QuartzDevice_ReplayDisplayList. 00051 * 00052 * - snapshots can be created either off the current display list 00053 * (last=0) or off the last known one (last=1). NewPage callback 00054 * can only use last=1 as there is no display list during that 00055 * call. Restored snapshots become the current display list and 00056 * thus can be extended by further painting (yet the original saved 00057 * copy is not influenced). Also note that all snapshots are SEXPs 00058 * (the declaration doesn't use SEXP as to not depend on 00059 * Rinternals.h) therefore must be protected or preserved immediately 00060 * (i.e. the Quartz device does NOT protect them - except in the 00061 * call to RestoreSnapshot). 00062 * 00063 * - dirty flag: the dirty flag is not used internally by the Quartz 00064 * device, but can be useful for the modules to determine whether 00065 * the current graphics is a restored copy or in-progress 00066 * drawing. The Quartz device manages the flag as follows: a) 00067 * display list replay does NOT change the flag, b) snapshot 00068 * restoration resets the flag, c) all other paint operations 00069 * (i.e. outside of restore/replay) set the flag. Most common use 00070 * is to determine whether restored snapshots have been 00071 * subsequently modified. 00072 * 00073 * - history: currently the history management is not used by any 00074 * modules and as such is untested and strictly experimental. It 00075 * may be removed in the future as it is not clear whether it makes 00076 * sense to be part of the device. See Cocoa module for a 00077 * module-internal implementation of the display history. 00078 * 00079 * Quartz device creation path: 00080 * quartz() function -> SEXP Quartz(args) -> 00081 * setup QuartzParameters_t, call backend constructor 00082 * [e.g. QuartzCocoa_DeviceCreate(dd, fn, QuartzParameters_t *pars)] -> 00083 * create backend definition (QuartzBackend_t backend) -> 00084 * fn->Create(dd, &backend), return the result 00085 */ 00086 00087 #ifndef R_EXT_QUARTZDEVICE_H_ 00088 #define R_EXT_QUARTZDEVICE_H_ 00089 00090 /* FIXME: this is installed, but can it really work without config.h? */ 00091 00092 #ifdef HAVE_CONFIG_H 00093 #include <config.h> 00094 #endif 00095 00096 #ifdef __cplusplus 00097 extern "C" { 00098 #endif 00099 00100 #if HAVE_AQUA 00101 #include <ApplicationServices/ApplicationServices.h> 00102 #else 00103 typedef void* CGContextRef; 00104 #endif 00105 00106 /* flags passed to the newPage callback */ 00107 #define QNPF_REDRAW 0x0001 /* is set when NewPage really means re-draw of an existing page */ 00108 00109 /* flags passed to QuartzDevice_Create (as fs parameter) */ 00110 #define QDFLAG_DISPLAY_LIST 0x0001 00111 #define QDFLAG_INTERACTIVE 0x0002 00112 #define QDFLAG_RASTERIZED 0x0004 /* rasterized media - may imply disabling AA paritally for rects etc. */ 00113 00114 /* parameter flags (they should not conflict with QDFLAGS to allow chaining) */ 00115 #define QPFLAG_ANTIALIAS 0x0100 00116 00117 typedef void* QuartzDesc_t; 00118 00119 typedef struct QuartzBackend_s { 00120 int size; /* structure size */ 00121 double width, height; 00122 double scalex, scaley, pointsize; 00123 int bg, canvas; 00124 int flags; 00125 void* userInfo; 00126 CGContextRef (*getCGContext)(QuartzDesc_t dev, void*userInfo); /* Get the context for this device */ 00127 int (*locatePoint)(QuartzDesc_t dev, void*userInfo, double*x, double*y); 00128 void (*close)(QuartzDesc_t dev, void*userInfo); 00129 void (*newPage)(QuartzDesc_t dev, void*userInfo, int flags); 00130 void (*state)(QuartzDesc_t dev, void*userInfo, int state); 00131 void* (*par)(QuartzDesc_t dev, void*userInfo, int set, const char *key, void *value); 00132 void (*sync)(QuartzDesc_t dev, void*userInfo); 00133 void* (*cap)(QuartzDesc_t dev, void*userInfo); 00134 } QuartzBackend_t; 00135 00136 /* parameters that are passed to functions that create backends */ 00137 typedef struct QuartzParameters_s { 00138 int size; /* structure size */ 00139 const char *type, *file, *title; 00140 double x, y, width, height, pointsize; 00141 const char *family; 00142 int flags; 00143 int connection; 00144 int bg, canvas; 00145 double *dpi; 00146 /* the following parameters can be used to pass custom parameters when desired */ 00147 double pard1, pard2; 00148 int pari1, pari2; 00149 const char *pars1, *pars2; 00150 void *parv; 00151 } QuartzParameters_t; 00152 00153 /* all device implementations have to call this general Quartz device constructor at some point */ 00154 QuartzDesc_t QuartzDevice_Create(void *dd, QuartzBackend_t* def); 00155 00156 typedef struct QuartzFunctons_s { 00157 void* (*Create)(void *, QuartzBackend_t *); /* create a new device */ 00158 int (*DevNumber)(QuartzDesc_t desc); /* returns device number */ 00159 void (*Kill)(QuartzDesc_t desc); /* call to close the device */ 00160 void (*ResetContext)(QuartzDesc_t desc); /* notifies Q back-end that the implementation has created a new context */ 00161 double (*GetWidth)(QuartzDesc_t desc); /* get device width (in inches) */ 00162 double (*GetHeight)(QuartzDesc_t desc); /* get device height (in inches) */ 00163 void (*SetSize)(QuartzDesc_t desc, double width, double height); /* set device size (in inches) */ 00164 00165 double (*GetScaledWidth)(QuartzDesc_t desc); /* get device width (in pixels) */ 00166 double (*GetScaledHeight)(QuartzDesc_t desc); /* get device height (in pixels) */ 00167 void (*SetScaledSize)(QuartzDesc_t desc, double width, double height); /* set device size (in pixels) */ 00168 00169 double (*GetXScale)(QuartzDesc_t desc); /* get x scale factor (px/pt ratio) */ 00170 double (*GetYScale)(QuartzDesc_t desc); /* get y scale factor (px/pt ratio) */ 00171 void (*SetScale)(QuartzDesc_t desc,double scalex, double scaley); /* sets both scale factors (px/pt ratio) */ 00172 00173 void (*SetTextScale)(QuartzDesc_t desc,double scale); /* sets text scale factor */ 00174 double (*GetTextScale)(QuartzDesc_t desc); /* sets text scale factor */ 00175 00176 void (*SetPointSize)(QuartzDesc_t desc,double ps); /* sets point size */ 00177 double (*GetPointSize)(QuartzDesc_t desc); /* gets point size */ 00178 00179 int (*GetDirty)(QuartzDesc_t desc); /* sets dirty flag */ 00180 void (*SetDirty)(QuartzDesc_t desc,int dirty); /* gets dirty flag */ 00181 00182 void (*ReplayDisplayList)(QuartzDesc_t desc); /* replay display list 00183 Note: it inhibits sync calls during repaint, 00184 the caller is responsible for calling sync if needed. 00185 Dirty flag is kept unmodified */ 00186 void* (*GetSnapshot)(QuartzDesc_t desc, int last); 00187 /* create a (replayable) snapshot of the device contents. 00188 when 'last' is set then the last stored display list is used, 00189 otherwise a new snapshot is created */ 00190 void (*RestoreSnapshot)(QuartzDesc_t desc,void* snapshot); 00191 /* restore a snapshot. also clears the dirty flag */ 00192 00193 int (*GetAntialias)(QuartzDesc_t desc); /* get anti-alias flag */ 00194 void (*SetAntialias)(QuartzDesc_t desc, int aa); /* set anti-alias flag */ 00195 00196 int (*GetBackground)(QuartzDesc_t desc); /* get background color */ 00197 void (*Activate)(QuartzDesc_t desc); /* activate/select the device */ 00198 /* get/set Quartz-specific parameters. desc can be NULL for global parameters */ 00199 void* (*SetParameter)(QuartzDesc_t desc, const char *key, void *value); 00200 void* (*GetParameter)(QuartzDesc_t desc, const char *key); 00201 } QuartzFunctions_t; 00202 00203 #define QuartzParam_EmbeddingFlags "embeddeding flags" /* value: int[1] */ 00204 #define QP_Flags_CFLoop 0x0001 /* drives application event loop */ 00205 #define QP_Flags_Cocoa 0x0002 /* Cocoa is fully initialized */ 00206 #define QP_Flags_Front 0x0004 /* is front application */ 00207 00208 /* FIXME: no longer used, remove in due course */ 00209 /* from unix/aqua.c - loads grDevices if necessary and returns NULL on failure */ 00210 QuartzFunctions_t *getQuartzFunctions(); 00211 00212 /* type of a Quartz contructor */ 00213 typedef QuartzDesc_t (*quartz_create_fn_t)(void *dd, QuartzFunctions_t *fn, QuartzParameters_t *par); 00214 00215 /* grDevices currently supply following constructors: 00216 QuartzCocoa_DeviceCreate, QuartzCarbon_DeviceCreate, 00217 QuartzBitmap_DeviceCreate, QuartzPDF_DeviceCreate */ 00218 00219 /* embedded Quartz support hook (defined in unix/aqua.c): 00220 dd = should be passed-through to QuartzDevice_Create 00221 fn = Quartz API functions 00222 par = parameters (see above) */ 00223 #ifndef IN_AQUA_C 00224 extern 00225 #endif 00226 QuartzDesc_t (*ptr_QuartzBackend)(void *dd, QuartzFunctions_t *fn, QuartzParameters_t *par); 00227 00228 /* C version of the Quartz call (experimental) 00229 returns 0 on success, error code on failure */ 00230 QuartzDesc_t Quartz_C(QuartzParameters_t *par, quartz_create_fn_t q_create, int *errorCode); 00231 00232 #ifdef __cplusplus 00233 } 00234 #endif 00235 00236 #endif