RAPI
R_ext/QuartzDevice.h
Go to the documentation of this file.
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
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines