The R Project SVN R

Rev

Rev 84150 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
42938 urbaneks 1
/*
2
 *  R : A Computer Language for Statistical Data Analysis
87075 kalibera 3
 *  Copyright (C) 2007-2024  The R Core Team
42938 urbaneks 4
 *
5
 *  This program is free software; you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation; either version 2 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 General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this program; if not, a copy is available at
68949 ripley 17
 *  https://www.R-project.org/Licenses/
42938 urbaneks 18
 *
44552 urbaneks 19
 *---------------------------------------------------------------------
44799 ripley 20
 *  This header file constitutes the (unofficial) API to the Quartz
21
 *  device. Being unofficial, the API may change at any point without
44552 urbaneks 22
 *  warning.
42938 urbaneks 23
 *
70779 ripley 24
 *  Quartz is a general device-independent way of drawing in macOS,
42938 urbaneks 25
 *  therefore the Quartz device modularizes the actual drawing target
26
 *  implementation into separate modules (e.g. Carbon and Cocoa for
44799 ripley 27
 *  on-screen display and PDF, Bitmap for off-screen drawing). The API
42938 urbaneks 28
 *  below is used by the modules to talk to the Quartz device without
29
 *  having to know anything about R graphics device API.
30
 *
31
 *  Key functions are listed here:
32
 *  QuartzDevice_Create - creates a Quartz device
44552 urbaneks 33
 *  QuartzDevice_ResetContext - should be called after the target
34
 *    context has been created to initialize it.
42938 urbaneks 35
 *  QuartzDevice_Kill - closes the Quartz device (e.g. on window close)
44552 urbaneks 36
 *  QuartzDevice_SetScaledSize - resize device (does not include
37
 *    re-painting, it should be followed by a call to
38
 *    QuartzDevice_ReplayDisplayList)
42938 urbaneks 39
 *  QuartzDevice_ReplayDisplayList - replays all plot commands
40
 *
43160 urbaneks 41
 *  Key concepts
42
 *  - all Quartz modules are expected to provide a device context
44552 urbaneks 43
 *    (CGContextRef) for drawing. A device can temporarily return NULL
44
 *    (e.g. if the context is not available immediately) and replay
45
 *    the display list later to catch up.
44799 ripley 46
 *
44552 urbaneks 47
 *  - interactive devices can use QuartzDevice_SetScaledSize to resize
48
 *    the device (no context is necessary), then prepare the context
49
 *    (call QuartzDevice_ResetContext if a new context was created)
50
 *    and finally re-draw using QuartzDevice_ReplayDisplayList.
44799 ripley 51
 *
44552 urbaneks 52
 *  - snapshots can be created either off the current display list
53
 *    (last=0) or off the last known one (last=1). NewPage callback
54
 *    can only use last=1 as there is no display list during that
55
 *    call. Restored snapshots become the current display list and
56
 *    thus can be extended by further painting (yet the original saved
57
 *    copy is not influenced). Also note that all snapshots are SEXPs
58
 *    (the declaration doesn't use SEXP as to not depend on
45255 urbaneks 59
 *    Rinternals.h) therefore must be protected or preserved immediately
60
 *    (i.e. the Quartz device does NOT protect them - except in the
61
 *    call to RestoreSnapshot).
44799 ripley 62
 *
44552 urbaneks 63
 *  - dirty flag: the dirty flag is not used internally by the Quartz
64
 *    device, but can be useful for the modules to determine whether
65
 *    the current graphics is a restored copy or in-progress
66
 *    drawing. The Quartz device manages the flag as follows: a)
67
 *    display list replay does NOT change the flag, b) snapshot
68
 *    restoration resets the flag, c) all other paint operations
69
 *    (i.e. outside of restore/replay) set the flag. Most common use
70
 *    is to determine whether restored snapshots have been
71
 *    subsequently modified.
44799 ripley 72
 *
44552 urbaneks 73
 *  - history: currently the history management is not used by any
74
 *    modules and as such is untested and strictly experimental. It
75
 *    may be removed in the future as it is not clear whether it makes
76
 *    sense to be part of the device. See Cocoa module for a
77
 *    module-internal implementation of the display history.
45759 urbaneks 78
 *
79
 *  Quartz device creation path:
80
 *    quartz() function -> SEXP Quartz(args) ->
81
 *    setup QuartzParameters_t, call backend constructor
82
 *    [e.g. QuartzCocoa_DeviceCreate(dd, fn, QuartzParameters_t *pars)] ->
83
 *    create backend definition (QuartzBackend_t backend) -> 
84
 *    fn->Create(dd, &backend), return the result
42938 urbaneks 85
 */
86
 
71512 ripley 87
/* Unix-only header */
88
 
42938 urbaneks 89
#ifndef R_EXT_QUARTZDEVICE_H_
90
#define R_EXT_QUARTZDEVICE_H_
91
 
61471 ripley 92
/* FIXME: this is installed, but can it really work without config.h? */
51833 ripley 93
 
45255 urbaneks 94
#ifdef HAVE_CONFIG_H
95
#include <config.h>
96
#endif
97
 
87075 kalibera 98
#if HAVE_AQUA
99
#include <ApplicationServices/ApplicationServices.h>
100
#endif
101
 
42938 urbaneks 102
#ifdef __cplusplus
103
extern "C" {
104
#endif   
45255 urbaneks 105
 
87075 kalibera 106
#ifndef HAVE_AQUA
45255 urbaneks 107
    typedef void* CGContextRef;
108
#endif
42938 urbaneks 109
 
43160 urbaneks 110
/* flags passed to the newPage callback */
111
#define QNPF_REDRAW 0x0001 /* is set when NewPage really means re-draw of an existing page */
112
 
113
/* flags passed to QuartzDevice_Create (as fs parameter) */
45147 urbaneks 114
#define QDFLAG_DISPLAY_LIST 0x0001
115
#define QDFLAG_INTERACTIVE  0x0002 
45759 urbaneks 116
#define QDFLAG_RASTERIZED   0x0004 /* rasterized media - may imply disabling AA paritally for rects etc. */
117
 
118
/* parameter flags (they should not conflict with QDFLAGS to allow chaining) */
119
#define QPFLAG_ANTIALIAS 0x0100
120
 
42938 urbaneks 121
typedef void* QuartzDesc_t;
122
 
44314 urbaneks 123
typedef struct QuartzBackend_s {
124
    int    size;                          /* structure size */
125
    double width, height;
126
    double scalex, scaley, pointsize;
127
    int    bg, canvas;
128
    int    flags;
129
    void*  userInfo;
44799 ripley 130
    CGContextRef (*getCGContext)(QuartzDesc_t dev, void*userInfo); /* Get the context for this device */
131
    int          (*locatePoint)(QuartzDesc_t dev, void*userInfo, double*x, double*y);
132
    void         (*close)(QuartzDesc_t dev, void*userInfo);
133
    void         (*newPage)(QuartzDesc_t dev, void*userInfo, int flags);
134
    void         (*state)(QuartzDesc_t dev, void*userInfo, int state);
45255 urbaneks 135
    void*        (*par)(QuartzDesc_t dev, void*userInfo, int set, const char *key, void *value);
44799 ripley 136
    void         (*sync)(QuartzDesc_t dev, void*userInfo);
50568 murrell 137
    void*        (*cap)(QuartzDesc_t dev, void*userInfo);
44314 urbaneks 138
} QuartzBackend_t;
42938 urbaneks 139
 
44314 urbaneks 140
/* parameters that are passed to functions that create backends */
141
typedef struct QuartzParameters_s {
142
    int        size;                   /* structure size */
143
    const char *type, *file, *title;
144
    double     x, y, width, height, pointsize;
145
    const char *family;
146
    int        flags;
147
    int        connection;
148
    int        bg, canvas;
149
    double     *dpi;
150
    /* the following parameters can be used to pass custom parameters when desired */
151
    double     pard1, pard2;
152
    int        pari1, pari2;
153
    const char *pars1, *pars2;
154
    void       *parv;
155
} QuartzParameters_t;
156
 
42938 urbaneks 157
/* all device implementations have to call this general Quartz device constructor at some point */
44314 urbaneks 158
QuartzDesc_t QuartzDevice_Create(void *dd, QuartzBackend_t* def);
159
 
160
typedef struct QuartzFunctons_s {
161
    void*  (*Create)(void *, QuartzBackend_t *);  /* create a new device */
162
    int    (*DevNumber)(QuartzDesc_t desc);       /* returns device number */
163
    void   (*Kill)(QuartzDesc_t desc);            /* call to close the device */
164
    void   (*ResetContext)(QuartzDesc_t desc);    /* notifies Q back-end that the implementation has created a new context */
165
    double (*GetWidth)(QuartzDesc_t desc);        /* get device width (in inches) */
166
    double (*GetHeight)(QuartzDesc_t desc);       /* get device height (in inches) */
167
    void   (*SetSize)(QuartzDesc_t desc, double width, double height); /* set device size (in inches) */
168
 
169
    double (*GetScaledWidth)(QuartzDesc_t desc);  /* get device width (in pixels) */
170
    double (*GetScaledHeight)(QuartzDesc_t desc); /* get device height (in pixels) */
171
    void   (*SetScaledSize)(QuartzDesc_t desc, double width, double height); /* set device size (in pixels) */
42938 urbaneks 172
 
44314 urbaneks 173
    double (*GetXScale)(QuartzDesc_t desc);     /* get x scale factor (px/pt ratio) */
174
    double (*GetYScale)(QuartzDesc_t desc);     /* get y scale factor (px/pt ratio) */
175
    void   (*SetScale)(QuartzDesc_t desc,double scalex, double scaley); /* sets both scale factors (px/pt ratio) */
42938 urbaneks 176
 
44314 urbaneks 177
    void   (*SetTextScale)(QuartzDesc_t desc,double scale); /* sets text scale factor */
178
    double (*GetTextScale)(QuartzDesc_t desc);  /* sets text scale factor */
42938 urbaneks 179
 
44314 urbaneks 180
    void   (*SetPointSize)(QuartzDesc_t desc,double ps); /* sets point size */
181
    double (*GetPointSize)(QuartzDesc_t desc);  /* gets point size */
42938 urbaneks 182
 
44314 urbaneks 183
    int    (*GetDirty)(QuartzDesc_t desc);        /* sets dirty flag */
184
    void   (*SetDirty)(QuartzDesc_t desc,int dirty); /* gets dirty flag */
42938 urbaneks 185
 
44314 urbaneks 186
    void   (*ReplayDisplayList)(QuartzDesc_t desc); /* replay display list
187
     Note: it inhibits sync calls during repaint,
188
     the caller is responsible for calling sync if needed.
189
     Dirty flag is kept unmodified */
44799 ripley 190
    void*  (*GetSnapshot)(QuartzDesc_t desc, int last);    
191
    /* create a (replayable) snapshot of the device contents. 
192
       when 'last' is set then the last stored display list is used, 
193
       otherwise a new snapshot is created */
194
    void   (*RestoreSnapshot)(QuartzDesc_t desc,void* snapshot);
195
    /* restore a snapshot. also clears the dirty flag */
42938 urbaneks 196
 
44314 urbaneks 197
    int    (*GetAntialias)(QuartzDesc_t desc);    /* get anti-alias flag */
44799 ripley 198
    void   (*SetAntialias)(QuartzDesc_t desc, int aa); /* set anti-alias flag */
42938 urbaneks 199
 
44314 urbaneks 200
    int    (*GetBackground)(QuartzDesc_t desc);   /* get background color */
45255 urbaneks 201
    void   (*Activate)(QuartzDesc_t desc);        /* activate/select the device */
202
    /* get/set Quartz-specific parameters. desc can be NULL for global parameters */
203
    void*  (*SetParameter)(QuartzDesc_t desc, const char *key, void *value);
204
    void*  (*GetParameter)(QuartzDesc_t desc, const char *key);
44314 urbaneks 205
} QuartzFunctions_t;
42938 urbaneks 206
 
84150 maechler 207
#define QuartzParam_EmbeddingFlags "embedding flags" /* value: int[1] */
45255 urbaneks 208
#define QP_Flags_CFLoop 0x0001  /* drives application event loop */
209
#define QP_Flags_Cocoa  0x0002  /* Cocoa is fully initialized */
210
#define QP_Flags_Front  0x0004  /* is front application */
211
 
61471 ripley 212
/* FIXME: no longer used, remove in due course */
44552 urbaneks 213
/* from unix/aqua.c - loads grDevices if necessary and returns NULL on failure */
82754 ripley 214
QuartzFunctions_t *getQuartzFunctions(void);
42938 urbaneks 215
 
44552 urbaneks 216
/* type of a Quartz contructor */
45255 urbaneks 217
typedef QuartzDesc_t (*quartz_create_fn_t)(void *dd, QuartzFunctions_t *fn, QuartzParameters_t *par);
44552 urbaneks 218
 
219
/* grDevices currently supply following constructors:
44799 ripley 220
   QuartzCocoa_DeviceCreate, QuartzCarbon_DeviceCreate,
221
   QuartzBitmap_DeviceCreate, QuartzPDF_DeviceCreate */
44552 urbaneks 222
 
44314 urbaneks 223
/* embedded Quartz support hook (defined in unix/aqua.c):
224
     dd = should be passed-through to QuartzDevice_Create
44552 urbaneks 225
     fn = Quartz API functions
226
     par = parameters (see above) */
45255 urbaneks 227
#ifndef IN_AQUA_C
228
    extern
229
#endif
230
    QuartzDesc_t (*ptr_QuartzBackend)(void *dd, QuartzFunctions_t *fn, QuartzParameters_t *par);
44552 urbaneks 231
 
42938 urbaneks 232
/* C version of the Quartz call (experimental)
233
   returns 0 on success, error code on failure */
45255 urbaneks 234
QuartzDesc_t Quartz_C(QuartzParameters_t *par, quartz_create_fn_t q_create, int *errorCode);
44552 urbaneks 235
 
42938 urbaneks 236
#ifdef __cplusplus
237
}
238
#endif   
44552 urbaneks 239
 
42938 urbaneks 240
#endif