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