The R Project SVN R

Rev

Rev 26795 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 26795 Rev 26846
Line 30... Line 30...
30
#include <Defn.h>
30
#include <Defn.h>
31
#include <Rmath.h>
31
#include <Rmath.h>
32
#include <Graphics.h>
32
#include <Graphics.h>
33
 
33
 
34
 
34
 
35
/* The R graphics device */
-
 
36
 
-
 
37
/* These are a bit unthreadable aren't they?
-
 
38
 * Better to pass them all down, but that's a heck of a lot of 
-
 
39
 * changes to make to the function call argument lists!!
-
 
40
 */
35
/*
41
static GEDevDesc *MathDevice;
36
 *  TeX Math Styles
42
static unsigned int BoxColor;
-
 
43
static unsigned int TextColor;
-
 
44
/* The value of cex passed into GEMathText
-
 
45
 */
37
 *
46
static double BaseCex = 1;
-
 
47
static double MathGamma;
-
 
48
static char *MathFontFamily;
-
 
49
/* The value of font passed into GEMathText
38
 *  The TeXBook, Appendix G, Page 441.
50
 * May be modified by plotmath code -- it is plotmath code's 
-
 
51
 * responsibility to save and restore temporary changes.
-
 
52
 */
39
 *
53
static int MathFont;
-
 
54
static double MathLineHeight;
-
 
55
/* A temporary value of cex that may be modified by plotmath code.
-
 
56
 */
40
 */
-
 
41
 
-
 
42
typedef enum {
-
 
43
    STYLE_SS1 = 1,
-
 
44
    STYLE_SS  = 2,
-
 
45
    STYLE_S1  = 3,
-
 
46
    STYLE_S   = 4,
-
 
47
    STYLE_T1  = 5,
-
 
48
    STYLE_T   = 6,
-
 
49
    STYLE_D1  = 7,
-
 
50
    STYLE_D   = 8
-
 
51
} STYLE;
-
 
52
 
-
 
53
typedef struct {
-
 
54
    unsigned int BoxColor;
57
static double MathCex;
55
    double BaseCex;
-
 
56
    double ReferenceX;
-
 
57
    double ReferenceY;
-
 
58
    double CurrentX;
-
 
59
    double CurrentY;
-
 
60
    double CurrentAngle;
-
 
61
    double CosAngle;
58
static double MathPs;
62
    double SinAngle;
-
 
63
    STYLE CurrentStyle;
-
 
64
} mathContext;
-
 
65
 
59
static GEUnit MetricUnit = GE_INCHES;
66
static GEUnit MetricUnit = GE_INCHES;
60
 
67
 
61
/* Font Definitions */
68
/* Font Definitions */
62
 
69
 
63
typedef enum {
70
typedef enum {
Line 79... Line 86...
79
 
86
 
80
static double ItalicFactor = 0.15;
87
static double ItalicFactor = 0.15;
81
 
88
 
82
/* Drawing basics */
89
/* Drawing basics */
83
 
90
 
84
static double ReferenceX;
-
 
85
static double ReferenceY;
-
 
86
static double CurrentX;
-
 
87
static double CurrentY;
-
 
88
static double CurrentAngle;
-
 
89
static double CosAngle;
-
 
90
static double SinAngle;
-
 
91
 
91
 
92
/* Convert CurrentX and CurrentY from */
92
/* Convert CurrentX and CurrentY from */
93
/* 0 angle to and CurrentAngle */
93
/* 0 angle to and CurrentAngle */
94
 
94
 
95
static double ConvertedX()
95
static double ConvertedX(mathContext *mc, GEDevDesc *dd)
96
{
96
{
97
    double rotatedX = ReferenceX +
97
    double rotatedX = mc->ReferenceX +
98
	(CurrentX - ReferenceX) * CosAngle -
98
	(mc->CurrentX - mc->ReferenceX) * mc->CosAngle -
99
	(CurrentY - ReferenceY) * SinAngle;
99
	(mc->CurrentY - mc->ReferenceY) * mc->SinAngle;
100
    return toDeviceX(rotatedX, MetricUnit, MathDevice);
100
    return toDeviceX(rotatedX, MetricUnit, dd);
101
}
101
}
102
 
102
 
103
static double ConvertedY()
103
static double ConvertedY(mathContext *mc, GEDevDesc *dd)
104
{
104
{
105
    double rotatedY = ReferenceY +
105
    double rotatedY = mc->ReferenceY +
106
	(CurrentY - ReferenceY) * CosAngle +
106
	(mc->CurrentY - mc->ReferenceY) * mc->CosAngle +
107
	(CurrentX - ReferenceX) * SinAngle;
107
	(mc->CurrentX - mc->ReferenceX) * mc->SinAngle;
108
    return toDeviceY(rotatedY, MetricUnit, MathDevice);
108
    return toDeviceY(rotatedY, MetricUnit, dd);
109
}
109
}
110
 
110
 
111
static void PMoveAcross(double xamount)
111
static void PMoveAcross(double xamount, mathContext *mc)
112
{
112
{
113
    CurrentX += xamount;
113
    mc->CurrentX += xamount;
114
}
114
}
115
 
115
 
116
static void PMoveUp(double yamount)
116
static void PMoveUp(double yamount, mathContext *mc)
117
{
117
{
118
    CurrentY += yamount;
118
    mc->CurrentY += yamount;
119
}
119
}
120
 
120
 
121
static void PMoveTo(double x, double y)
121
static void PMoveTo(double x, double y, mathContext *mc)
122
{
122
{
123
    CurrentX = x;
123
    mc->CurrentX = x;
124
    CurrentY = y;
124
    mc->CurrentY = y;
125
}
125
}
126
 
126
 
127
/* Basic Font Properties */
127
/* Basic Font Properties */
128
 
128
 
129
static double xHeight()
129
static double xHeight(R_GE_gcontext *gc, GEDevDesc *dd)
130
{
130
{
131
    double height, depth, width;
131
    double height, depth, width;
132
    GEMetricInfo('x', 
132
    GEMetricInfo('x', gc,
133
		MathFont, MathCex, MathPs,
-
 
134
		&height, &depth, &width, MathDevice);
133
		&height, &depth, &width, dd);
135
    return fromDeviceHeight(height, MetricUnit, MathDevice);
134
    return fromDeviceHeight(height, MetricUnit, dd);
136
}
135
}
137
 
136
 
138
static double XHeight()
137
static double XHeight(R_GE_gcontext *gc, GEDevDesc *dd)
139
{
138
{
140
    double height, depth, width;
139
    double height, depth, width;
141
    GEMetricInfo('X', 
140
    GEMetricInfo('X', gc,
142
		MathFont, MathCex, MathPs,
-
 
143
		&height, &depth, &width, MathDevice);
141
		&height, &depth, &width, dd);
144
    return fromDeviceHeight(height, MetricUnit, MathDevice);
142
    return fromDeviceHeight(height, MetricUnit, dd);
145
}
143
}
146
 
144
 
147
static double AxisHeight()
145
static double AxisHeight(R_GE_gcontext *gc, GEDevDesc *dd)
148
{
146
{
149
    double height, depth, width;
147
    double height, depth, width;
150
    GEMetricInfo('+', 
148
    GEMetricInfo('+', gc,
151
		MathFont, MathCex, MathPs,
-
 
152
		&height, &depth, &width, MathDevice);
149
		&height, &depth, &width, dd);
153
    return fromDeviceHeight(0.5 * height, MetricUnit, MathDevice);
150
    return fromDeviceHeight(0.5 * height, MetricUnit, dd);
154
}
151
}
155
 
152
 
156
static double Quad()
153
static double Quad(R_GE_gcontext *gc, GEDevDesc *dd)
157
{
154
{
158
    double height, depth, width;
155
    double height, depth, width;
159
    GEMetricInfo('M', 
156
    GEMetricInfo('M', gc,
160
		MathFont, MathCex, MathPs,
-
 
161
		&height, &depth, &width, MathDevice);
157
		&height, &depth, &width, dd);
162
    return fromDeviceHeight(width, MetricUnit, MathDevice);
158
    return fromDeviceHeight(width, MetricUnit, dd);
163
}
159
}
164
 
160
 
165
/* The height of digits */
161
/* The height of digits */
166
static double FigHeight()
162
static double FigHeight(R_GE_gcontext *gc, GEDevDesc *dd)
167
{
163
{
168
    double height, depth, width;
164
    double height, depth, width;
169
    GEMetricInfo('0', 
165
    GEMetricInfo('0', gc,
170
		MathFont, MathCex, MathPs,
-
 
171
		&height, &depth, &width, MathDevice);
166
		&height, &depth, &width, dd);
172
    return fromDeviceHeight(height, MetricUnit, MathDevice);
167
    return fromDeviceHeight(height, MetricUnit, dd);
173
}
168
}
174
 
169
 
175
/* Depth of lower case descenders */
170
/* Depth of lower case descenders */
176
static double DescDepth()
171
static double DescDepth(R_GE_gcontext *gc, GEDevDesc *dd)
177
{
172
{
178
    double height, depth, width;
173
    double height, depth, width;
179
    GEMetricInfo('g', 
174
    GEMetricInfo('g', gc,
180
		MathFont, MathCex, MathPs,
-
 
181
		&height, &depth, &width, MathDevice);
175
		&height, &depth, &width, dd);
182
    return fromDeviceHeight(depth, MetricUnit, MathDevice);
176
    return fromDeviceHeight(depth, MetricUnit, dd);
183
}
177
}
184
 
178
 
185
/* Thickness of rules */
179
/* Thickness of rules */
186
static double RuleThickness()
180
static double RuleThickness()
187
{
181
{
188
    return 0.015;
182
    return 0.015;
189
}
183
}
190
 
184
 
191
static double ThinSpace()
185
static double ThinSpace(R_GE_gcontext *gc, GEDevDesc *dd)
192
{
186
{
193
    double height, depth, width;
187
    double height, depth, width;
194
    static double OneSixth = 0.16666666666666666666;
188
    static double OneSixth = 0.16666666666666666666;
195
    GEMetricInfo('M', 
189
    GEMetricInfo('M', gc,
196
		MathFont, MathCex, MathPs,
-
 
197
		&height, &depth, &width, MathDevice);
190
		&height, &depth, &width, dd);
198
    return fromDeviceHeight(OneSixth * width, MetricUnit, MathDevice);
191
    return fromDeviceHeight(OneSixth * width, MetricUnit, dd);
199
}
192
}
200
 
193
 
201
static double MediumSpace()
194
static double MediumSpace(R_GE_gcontext *gc, GEDevDesc *dd)
202
{
195
{
203
    double height, depth, width;
196
    double height, depth, width;
204
    static double TwoNinths = 0.22222222222222222222;
197
    static double TwoNinths = 0.22222222222222222222;
205
    GEMetricInfo('M', 
198
    GEMetricInfo('M', gc,
206
		MathFont, MathCex, MathPs,
-
 
207
		&height, &depth, &width, MathDevice);
199
		&height, &depth, &width, dd);
208
    return fromDeviceHeight(TwoNinths * width, MetricUnit, MathDevice);
200
    return fromDeviceHeight(TwoNinths * width, MetricUnit, dd);
209
}
201
}
210
 
202
 
211
static double ThickSpace()
203
static double ThickSpace(R_GE_gcontext *gc, GEDevDesc *dd)
212
{
204
{
213
    double height, depth, width;
205
    double height, depth, width;
214
    static double FiveEighteenths = 0.27777777777777777777;
206
    static double FiveEighteenths = 0.27777777777777777777;
215
    GEMetricInfo('M', 
207
    GEMetricInfo('M', gc,
216
		MathFont, MathCex, MathPs,
-
 
217
		&height, &depth, &width, MathDevice);
208
		&height, &depth, &width, dd);
218
    return fromDeviceHeight(FiveEighteenths * width, MetricUnit, MathDevice);
209
    return fromDeviceHeight(FiveEighteenths * width, MetricUnit, dd);
219
}
210
}
220
 
211
 
221
static double MuSpace()
212
static double MuSpace(R_GE_gcontext *gc, GEDevDesc *dd)
222
{
213
{
223
    double height, depth, width;
214
    double height, depth, width;
224
    static double OneEighteenth = 0.05555555555555555555;
215
    static double OneEighteenth = 0.05555555555555555555;
225
    GEMetricInfo('M', 
216
    GEMetricInfo('M', gc,
226
		MathFont, MathCex, MathPs,
-
 
227
		&height, &depth, &width, MathDevice);
217
		&height, &depth, &width, dd);
228
    return fromDeviceHeight(OneEighteenth * width, MetricUnit, MathDevice);
218
    return fromDeviceHeight(OneEighteenth * width, MetricUnit, dd);
229
}
219
}
230
 
220
 
231
 
221
 
232
/*
222
/*
233
 *  Mathematics Layout Parameters
223
 *  Mathematics Layout Parameters
Line 248... Line 238...
248
}
238
}
249
TEXPAR;
239
TEXPAR;
250
 
240
 
251
#define SUBS	       0.7
241
#define SUBS	       0.7
252
 
242
 
253
static double TeX(TEXPAR which)
243
static double TeX(TEXPAR which, R_GE_gcontext *gc, GEDevDesc *dd)
254
{
244
{
255
    switch(which) {
245
    switch(which) {
256
    case sigma2:  /* space */
246
    case sigma2:  /* space */
257
    case sigma5:  /* x_height */
247
    case sigma5:  /* x_height */
258
	return xHeight();
248
	return xHeight(gc, dd);
259
 
249
 
260
    case sigma6:  /* quad */
250
    case sigma6:  /* quad */
261
	return Quad();
251
	return Quad(gc, dd);
262
 
252
 
263
    case sigma8:  /* num1 */
253
    case sigma8:  /* num1 */
264
	return AxisHeight()
254
	return AxisHeight(gc, dd)
265
	    + 3.51 * RuleThickness()
255
	    + 3.51 * RuleThickness(gc, dd)
266
	    + 0.15 * XHeight()		/* 54/36 * 0.1 */
256
	    + 0.15 * XHeight(gc, dd)		/* 54/36 * 0.1 */
267
	    + SUBS * DescDepth();
257
	    + SUBS * DescDepth(gc, dd);
268
    case sigma9:  /* num2 */
258
    case sigma9:  /* num2 */
269
	return AxisHeight()
259
	return AxisHeight(gc, dd)
270
	    + 1.51 * RuleThickness()
260
	    + 1.51 * RuleThickness(gc, dd)
271
	    + 0.08333333 * XHeight();	/* 30/36 * 0.1 */
261
	    + 0.08333333 * XHeight(gc, dd);	/* 30/36 * 0.1 */
272
    case sigma10: /* num3 */
262
    case sigma10: /* num3 */
273
	return AxisHeight()
263
	return AxisHeight(gc, dd)
274
	    + 1.51 * RuleThickness()
264
	    + 1.51 * RuleThickness(gc, dd)
275
	    + 0.1333333 * XHeight();	/* 48/36 * 0.1 */
265
	    + 0.1333333 * XHeight(gc, dd);	/* 48/36 * 0.1 */
276
    case sigma11: /* denom1 */
266
    case sigma11: /* denom1 */
277
	return	- AxisHeight()
267
	return	- AxisHeight(gc, dd)
278
	    + 3.51 * RuleThickness()
268
	    + 3.51 * RuleThickness(gc, dd)
279
	    + SUBS * FigHeight()
269
	    + SUBS * FigHeight(gc, dd)
280
	    + 0.344444 * XHeight();	/* 124/36 * 0.1 */
270
	    + 0.344444 * XHeight(gc, dd);	/* 124/36 * 0.1 */
281
    case sigma12: /* denom2 */
271
    case sigma12: /* denom2 */
282
	return	- AxisHeight()
272
	return	- AxisHeight(gc, dd)
283
	    + 1.51 * RuleThickness()
273
	    + 1.51 * RuleThickness(gc, dd)
284
	    + SUBS * FigHeight()
274
	    + SUBS * FigHeight(gc, dd)
285
	    + 0.08333333 * XHeight();	/* 30/36 * 0.1 */
275
	    + 0.08333333 * XHeight(gc, dd);	/* 30/36 * 0.1 */
286
 
276
 
287
    case sigma13: /* sup1 */
277
    case sigma13: /* sup1 */
288
	return 0.95 * xHeight();
278
	return 0.95 * xHeight(gc, dd);
289
    case sigma14: /* sup2 */
279
    case sigma14: /* sup2 */
290
	return 0.825 * xHeight();
280
	return 0.825 * xHeight(gc, dd);
291
    case sigma15: /* sup3 */
281
    case sigma15: /* sup3 */
292
	return 0.7 * xHeight();
282
	return 0.7 * xHeight(gc, dd);
293
 
283
 
294
    case sigma16: /* sub1 */
284
    case sigma16: /* sub1 */
295
	return 0.35 * xHeight();
285
	return 0.35 * xHeight(gc, dd);
296
    case sigma17: /* sub2 */
286
    case sigma17: /* sub2 */
297
	return 0.45 * XHeight();
287
	return 0.45 * XHeight(gc, dd);
298
 
288
 
299
    case sigma18: /* sup_drop */
289
    case sigma18: /* sup_drop */
300
	return 0.3861111 * XHeight();
290
	return 0.3861111 * XHeight(gc, dd);
301
 
291
 
302
    case sigma19: /* sub_drop */
292
    case sigma19: /* sub_drop */
303
	return 0.05 * XHeight();
293
	return 0.05 * XHeight(gc, dd);
304
 
294
 
305
    case sigma20: /* delim1 */
295
    case sigma20: /* delim1 */
306
	return 2.39 * XHeight();
296
	return 2.39 * XHeight(gc, dd);
307
    case sigma21: /* delim2 */
297
    case sigma21: /* delim2 */
308
	return 1.01 *XHeight();
298
	return 1.01 *XHeight(gc, dd);
309
 
299
 
310
    case sigma22: /* axis_height */
300
    case sigma22: /* axis_height */
311
	return AxisHeight();
301
	return AxisHeight(gc, dd);
312
 
302
 
313
    case xi8:	  /* default_rule_thickness */
303
    case xi8:	  /* default_rule_thickness */
314
	return RuleThickness();
304
	return RuleThickness(gc, dd);
315
 
305
 
316
    case xi9:	  /* big_op_spacing1 */
306
    case xi9:	  /* big_op_spacing1 */
317
    case xi10:	  /* big_op_spacing2 */
307
    case xi10:	  /* big_op_spacing2 */
318
    case xi11:	  /* big_op_spacing3 */
308
    case xi11:	  /* big_op_spacing3 */
319
    case xi12:	  /* big_op_spacing4 */
309
    case xi12:	  /* big_op_spacing4 */
320
    case xi13:	  /* big_op_spacing5 */
310
    case xi13:	  /* big_op_spacing5 */
321
	return 0.15 * XHeight();
311
	return 0.15 * XHeight(gc, dd);
322
    default:/* never happens (enum type) */
312
    default:/* never happens (enum type) */
323
	error("invalid `which' in TeX()!"); return 0;/*-Wall*/
313
	error("invalid `which' in TeX()!"); return 0;/*-Wall*/
324
    }
314
    }
325
}
315
}
326
 
316
 
327
/*
-
 
328
 *  TeX Math Styles
-
 
329
 *
-
 
330
 *  The TeXBook, Appendix G, Page 441.
-
 
331
 *
-
 
332
 */
-
 
333
 
-
 
334
typedef enum {
-
 
335
    STYLE_SS1 = 1,
-
 
336
    STYLE_SS  = 2,
-
 
337
    STYLE_S1  = 3,
-
 
338
    STYLE_S   = 4,
-
 
339
    STYLE_T1  = 5,
-
 
340
    STYLE_T   = 6,
-
 
341
    STYLE_D1  = 7,
-
 
342
    STYLE_D   = 8
-
 
343
} STYLE;
-
 
344
 
-
 
345
static STYLE CurrentStyle;
-
 
346
 
-
 
347
static STYLE GetStyle()
317
static STYLE GetStyle(mathContext *mc)
348
{
318
{
349
    return CurrentStyle;
319
    return mc->CurrentStyle;
350
}
320
}
351
 
321
 
352
static void SetStyle(STYLE newstyle)
322
static void SetStyle(STYLE newstyle, mathContext *mc, R_GE_gcontext *gc)
353
{
323
{
354
    switch (newstyle) {
324
    switch (newstyle) {
355
    case STYLE_D:
325
    case STYLE_D:
356
    case STYLE_T:
326
    case STYLE_T:
357
    case STYLE_D1:
327
    case STYLE_D1:
358
    case STYLE_T1:
328
    case STYLE_T1:
359
	MathCex = 1.0 * BaseCex;
329
	gc->cex = 1.0 * mc->BaseCex;
360
	break;
330
	break;
361
    case STYLE_S:
331
    case STYLE_S:
362
    case STYLE_S1:
332
    case STYLE_S1:
363
	MathCex = 0.7 * BaseCex;
333
	gc->cex = 0.7 * mc->BaseCex;
364
	break;
334
	break;
365
    case STYLE_SS:
335
    case STYLE_SS:
366
    case STYLE_SS1:
336
    case STYLE_SS1:
367
	MathCex = 0.5 * BaseCex;
337
	gc->cex = 0.5 * mc->BaseCex;
368
	break;
338
	break;
369
    default:
339
    default:
370
	error("invalid math style encountered");
340
	error("invalid math style encountered");
371
    }
341
    }
372
    CurrentStyle = newstyle;
342
    mc->CurrentStyle = newstyle;
373
}
343
}
374
 
344
 
375
static void SetPrimeStyle(STYLE style)
345
static void SetPrimeStyle(STYLE style, mathContext *mc, R_GE_gcontext *gc)
376
{
346
{
377
    switch (style) {
347
    switch (style) {
378
    case STYLE_D:
348
    case STYLE_D:
379
    case STYLE_D1:
349
    case STYLE_D1:
380
	SetStyle(STYLE_D1);
350
	SetStyle(STYLE_D1, mc, gc);
381
	break;
351
	break;
382
    case STYLE_T:
352
    case STYLE_T:
383
    case STYLE_T1:
353
    case STYLE_T1:
384
	SetStyle(STYLE_T1);
354
	SetStyle(STYLE_T1, mc, gc);
385
	break;
355
	break;
386
    case STYLE_S:
356
    case STYLE_S:
387
    case STYLE_S1:
357
    case STYLE_S1:
388
	SetStyle(STYLE_S1);
358
	SetStyle(STYLE_S1, mc, gc);
389
	break;
359
	break;
390
    case STYLE_SS:
360
    case STYLE_SS:
391
    case STYLE_SS1:
361
    case STYLE_SS1:
392
	SetStyle(STYLE_SS1);
362
	SetStyle(STYLE_SS1, mc, gc);
393
	break;
363
	break;
394
    }
364
    }
395
}
365
}
396
 
366
 
397
static void SetSupStyle(STYLE style)
367
static void SetSupStyle(STYLE style, mathContext *mc, R_GE_gcontext *gc)
398
{
368
{
399
    switch (style) {
369
    switch (style) {
400
    case STYLE_D:
370
    case STYLE_D:
401
    case STYLE_T:
371
    case STYLE_T:
402
	SetStyle(STYLE_S);
372
	SetStyle(STYLE_S, mc, gc);
403
	break;
373
	break;
404
    case STYLE_D1:
374
    case STYLE_D1:
405
    case STYLE_T1:
375
    case STYLE_T1:
406
	SetStyle(STYLE_S1);
376
	SetStyle(STYLE_S1, mc, gc);
407
	break;
377
	break;
408
    case STYLE_S:
378
    case STYLE_S:
409
    case STYLE_SS:
379
    case STYLE_SS:
410
	SetStyle(STYLE_SS);
380
	SetStyle(STYLE_SS, mc, gc);
411
	break;
381
	break;
412
    case STYLE_S1:
382
    case STYLE_S1:
413
    case STYLE_SS1:
383
    case STYLE_SS1:
414
	SetStyle(STYLE_SS1);
384
	SetStyle(STYLE_SS1, mc, gc);
415
	break;
385
	break;
416
    }
386
    }
417
}
387
}
418
 
388
 
419
static void SetSubStyle(STYLE style)
389
static void SetSubStyle(STYLE style, mathContext *mc, R_GE_gcontext *gc)
420
{
390
{
421
    switch (style) {
391
    switch (style) {
422
    case STYLE_D:
392
    case STYLE_D:
423
    case STYLE_T:
393
    case STYLE_T:
424
    case STYLE_D1:
394
    case STYLE_D1:
425
    case STYLE_T1:
395
    case STYLE_T1:
426
	SetStyle(STYLE_S1);
396
	SetStyle(STYLE_S1, mc, gc);
427
	break;
397
	break;
428
    case STYLE_S:
398
    case STYLE_S:
429
    case STYLE_SS:
399
    case STYLE_SS:
430
    case STYLE_S1:
400
    case STYLE_S1:
431
    case STYLE_SS1:
401
    case STYLE_SS1:
432
	SetStyle(STYLE_SS1);
402
	SetStyle(STYLE_SS1, mc, gc);
433
	break;
403
	break;
434
    }
404
    }
435
}
405
}
436
 
406
 
437
static void SetNumStyle(STYLE style)
407
static void SetNumStyle(STYLE style, mathContext *mc, R_GE_gcontext *gc)
438
{
408
{
439
    switch (style) {
409
    switch (style) {
440
    case STYLE_D:
410
    case STYLE_D:
441
	SetStyle(STYLE_T);
411
	SetStyle(STYLE_T, mc, gc);
442
	break;
412
	break;
443
    case STYLE_D1:
413
    case STYLE_D1:
444
	SetStyle(STYLE_T1);
414
	SetStyle(STYLE_T1, mc, gc);
445
	break;
415
	break;
446
    default:
416
    default:
447
	SetSupStyle(style);
417
	SetSupStyle(style, mc, gc);
448
    }
418
    }
449
}
419
}
450
 
420
 
451
static void SetDenomStyle(STYLE style)
421
static void SetDenomStyle(STYLE style, mathContext *mc, R_GE_gcontext *gc)
452
{
422
{
453
    if (style > STYLE_T)
423
    if (style > STYLE_T)
454
	SetStyle(STYLE_T1);
424
	SetStyle(STYLE_T1, mc, gc);
455
    else
425
    else
456
	SetSubStyle(style);
426
	SetSubStyle(style, mc, gc);
457
}
427
}
458
 
428
 
459
static int IsCompactStyle(STYLE style)
429
static int IsCompactStyle(STYLE style, mathContext *mc, R_GE_gcontext *gc)
460
{
430
{
461
    switch (style) {
431
    switch (style) {
462
    case STYLE_D1:
432
    case STYLE_D1:
463
    case STYLE_T1:
433
    case STYLE_T1:
464
    case STYLE_S1:
434
    case STYLE_S1:
Line 581... Line 551...
581
{
551
{
582
    return 0.5 * (bboxHeight(bbox) - bboxDepth(bbox));
552
    return 0.5 * (bboxHeight(bbox) - bboxDepth(bbox));
583
}
553
}
584
 
554
 
585
#ifdef NOT_used_currently/*-- out 'def'	 (-Wall) --*/
555
#ifdef NOT_used_currently/*-- out 'def'	 (-Wall) --*/
586
static BBOX DrawBBox(BBOX bbox, double xoffset, double yoffset)
556
static BBOX DrawBBox(BBOX bbox, double xoffset, double yoffset,
-
 
557
		     mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
587
{
558
{
588
    double xsaved = CurrentX;
559
    double xsaved = mc->CurrentX;
589
    double ysaved = CurrentY;
560
    double ysaved = mc->CurrentY;
590
    double x[5], y[5];
561
    double x[5], y[5];
-
 
562
    int savedcol = gc->col;
-
 
563
    int savedlty = gc->lty;
-
 
564
    double savedlwd = gc->lwd;
591
    CurrentX += xoffset;
565
    mc->CurrentX += xoffset;
592
    CurrentY += yoffset;
566
    mc->CurrentY += yoffset;
593
    PMoveUp(-bboxDepth(bbox));
567
    PMoveUp(-bboxDepth(bbox), mc);
594
    x[4] = x[0] = ConvertedX();
568
    x[4] = x[0] = ConvertedX(mc, dd);
595
    y[4] = y[0] = ConvertedY();
569
    y[4] = y[0] = ConvertedY(mc, dd);
596
    PMoveAcross(bboxWidth(bbox));
570
    PMoveAcross(bboxWidth(bbox), mc);
597
    x[1] = ConvertedX();
571
    x[1] = ConvertedX(mc, dd);
598
    y[1] = ConvertedY();
572
    y[1] = ConvertedY(mc, dd);
599
    PMoveUp(bboxHeight(bbox) + bboxDepth(bbox));
573
    PMoveUp(bboxHeight(bbox) + bboxDepth(bbox), mc);
600
    x[2] = ConvertedX();
574
    x[2] = ConvertedX(mc, dd);
601
    y[2] = ConvertedY();
575
    y[2] = ConvertedY(mc, dd);
602
    PMoveAcross(-bboxWidth(bbox));
576
    PMoveAcross(-bboxWidth(bbox), mc);
603
    x[3] = ConvertedX();
577
    x[3] = ConvertedX(mc, dd);
604
    y[3] = ConvertedY();
578
    y[3] = ConvertedY(mc, dd);
-
 
579
    gc->col = mc->BoxColor;
-
 
580
    gc->lty = LTY_SOLID;
-
 
581
    gc->lwd = 1;
605
    GEPolyline(5, x, y, BoxColor, MathGamma, LTY_SOLID, 1, INCHES, MathDevice);
582
    GEPolyline(5, x, y, gc, dd);
606
    PMoveTo(xsaved, ysaved);
583
    PMoveTo(xsaved, ysaved, mc);
-
 
584
    gc->col = savedcol;
-
 
585
    gc->lty = savedlty;
-
 
586
    gc->lwd = savedlwd;
607
    return bbox;
587
    return bbox;
608
}
588
}
609
#endif
589
#endif
610
 
590
 
611
typedef struct {
591
typedef struct {
Line 924... Line 904...
924
#endif
904
#endif
925
/* Code to determine a font from the */
905
/* Code to determine a font from the */
926
/* nature of the expression */
906
/* nature of the expression */
927
 
907
 
928
#ifdef NOT_used_currently/*-- out 'def'	 (-Wall) --*/
908
#ifdef NOT_used_currently/*-- out 'def'	 (-Wall) --*/
929
static FontType CurrentFont = 3;
909
static FontType mc->CurrentFont = 3;
930
#endif
910
#endif
931
static FontType GetFont()
911
static FontType GetFont(R_GE_gcontext *gc)
932
{
912
{
933
    return MathFont;
913
    return gc->fontface;
934
}
914
}
935
 
915
 
936
static FontType SetFont(FontType font)
916
static FontType SetFont(FontType font, R_GE_gcontext *gc)
937
{
917
{
938
    FontType prevfont = MathFont;
918
    FontType prevfont = gc->fontface;
939
    MathFont = font;
919
    gc->fontface = font;
940
    return prevfont;
920
    return prevfont;
941
}
921
}
942
 
922
 
943
static int UsingItalics()
923
static int UsingItalics(R_GE_gcontext *gc)
944
{
924
{
945
    return (MathFont == ItalicFont ||
925
    return (gc->fontface == ItalicFont ||
946
	    MathFont == BoldItalicFont);
926
	    gc->fontface == BoldItalicFont);
947
}
927
}
948
 
928
 
949
static BBOX GlyphBBox(int chr)
929
static BBOX GlyphBBox(int chr, R_GE_gcontext *gc, GEDevDesc *dd)
950
{
930
{
951
    BBOX bbox;
931
    BBOX bbox;
952
    double height, depth, width;
932
    double height, depth, width;
953
    GEMetricInfo(chr, 
933
    GEMetricInfo(chr, gc,
954
		MathFont, MathCex, MathPs,
-
 
955
		&height, &depth, &width, MathDevice);
934
		&height, &depth, &width, dd);
956
    bboxHeight(bbox) = fromDeviceHeight(height, MetricUnit, MathDevice);
935
    bboxHeight(bbox) = fromDeviceHeight(height, MetricUnit, dd);
957
    bboxDepth(bbox)  = fromDeviceHeight(depth, MetricUnit, MathDevice);
936
    bboxDepth(bbox)  = fromDeviceHeight(depth, MetricUnit, dd);
958
    bboxWidth(bbox)  = fromDeviceHeight(width, MetricUnit, MathDevice);
937
    bboxWidth(bbox)  = fromDeviceHeight(width, MetricUnit, dd);
959
    bboxItalic(bbox) = 0;
938
    bboxItalic(bbox) = 0;
960
    bboxSimple(bbox) = 1;
939
    bboxSimple(bbox) = 1;
961
    return bbox;
940
    return bbox;
962
}
941
}
963
 
942
 
964
static BBOX RenderElement(SEXP, int);
943
static BBOX RenderElement(SEXP, int,
-
 
944
			  mathContext*, R_GE_gcontext*, GEDevDesc*);
965
static BBOX RenderOffsetElement(SEXP, double, double, int);
945
static BBOX RenderOffsetElement(SEXP, double, double, int,
-
 
946
				mathContext*, R_GE_gcontext*, GEDevDesc*);
966
static BBOX RenderExpression(SEXP, int);
947
static BBOX RenderExpression(SEXP, int,
-
 
948
			     mathContext*, R_GE_gcontext*, GEDevDesc*);
967
static BBOX RenderSymbolChar(int, int);
949
static BBOX RenderSymbolChar(int, int, 
-
 
950
			     mathContext*, R_GE_gcontext*, GEDevDesc*);
968
 
951
 
969
 
952
 
970
/*  Code to Generate Bounding Boxes and Draw Formulae.	*/
953
/*  Code to Generate Bounding Boxes and Draw Formulae.	*/
971
 
954
 
972
static BBOX RenderItalicCorr(BBOX bbox, int draw)
955
static BBOX RenderItalicCorr(BBOX bbox, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
973
{
956
{
974
    if (bboxItalic(bbox) > 0) {
957
    if (bboxItalic(bbox) > 0) {
975
	if (draw)
958
	if (draw)
976
	    PMoveAcross(bboxItalic(bbox));
959
	    PMoveAcross(bboxItalic(bbox), mc);
977
	bboxWidth(bbox) += bboxItalic(bbox);
960
	bboxWidth(bbox) += bboxItalic(bbox);
978
	bboxItalic(bbox) = 0;
961
	bboxItalic(bbox) = 0;
979
    }
962
    }
980
    return bbox;
963
    return bbox;
981
}
964
}
982
 
965
 
983
static BBOX RenderGap(double gap, int draw)
966
static BBOX RenderGap(double gap, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
984
{
967
{
985
    if (draw)
968
    if (draw)
986
	PMoveAcross(gap);
969
	PMoveAcross(gap, mc);
987
    return MakeBBox(0, 0, gap);
970
    return MakeBBox(0, 0, gap);
988
}
971
}
989
 
972
 
990
/* Draw a Symbol from the Special Font */
973
/* Draw a Symbol from the Special Font */
991
 
974
 
992
static BBOX RenderSymbolChar(int ascii, int draw)
975
static BBOX RenderSymbolChar(int ascii, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
993
{
976
{
994
    FontType prev;
977
    FontType prev;
995
    BBOX bbox;
978
    BBOX bbox;
996
    char asciiStr[2];
979
    char asciiStr[2];
997
    if (ascii == A_HAT || ascii == A_TILDE)
980
    if (ascii == A_HAT || ascii == A_TILDE)
998
	prev = SetFont(PlainFont);
981
	prev = SetFont(PlainFont, gc);
999
    else
982
    else
1000
	prev = SetFont(SymbolFont);
983
	prev = SetFont(SymbolFont, gc);
1001
    bbox = GlyphBBox(ascii);
984
    bbox = GlyphBBox(ascii, gc, dd);
1002
    if (draw) {
985
    if (draw) {
1003
	asciiStr[0] = ascii;
986
	asciiStr[0] = ascii;
1004
	asciiStr[1] = '\0';
987
	asciiStr[1] = '\0';
1005
	GEText(ConvertedX(), ConvertedY(), asciiStr, 
988
	GEText(ConvertedX(mc ,dd), ConvertedY(mc, dd), asciiStr, 
1006
	       0.0, 0.0, CurrentAngle, 
989
	       0.0, 0.0, mc->CurrentAngle, gc,
1007
	       TextColor, MathGamma, 
-
 
1008
	       MathFontFamily, MathFont, MathLineHeight, MathCex, MathPs,
-
 
1009
	       MathDevice);
990
	       dd);
1010
	PMoveAcross(bboxWidth(bbox));
991
	PMoveAcross(bboxWidth(bbox), mc);
1011
    }
992
    }
1012
    SetFont(prev);
993
    SetFont(prev, gc);
1013
    return bbox;
994
    return bbox;
1014
}
995
}
1015
 
996
 
1016
/* Draw a Symbol String in "Math Mode */
997
/* Draw a Symbol String in "Math Mode */
1017
/* This code inserts italic corrections after */
998
/* This code inserts italic corrections after */
1018
/* every character. */
999
/* every character. */
1019
 
1000
 
1020
static BBOX RenderSymbolStr(char *str, int draw)
1001
static BBOX RenderSymbolStr(char *str, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1021
{
1002
{
1022
    char chr[2];
1003
    char chr[2];
1023
    BBOX glyphBBox;
1004
    BBOX glyphBBox;
1024
    BBOX resultBBox = NullBBox();
1005
    BBOX resultBBox = NullBBox();
1025
    double lastItalicCorr = 0;
1006
    double lastItalicCorr = 0;
1026
    FontType prevfont = GetFont();
1007
    FontType prevfont = GetFont(gc);
1027
    FontType font = prevfont;
1008
    FontType font = prevfont;
1028
    chr[1] = '\0';
1009
    chr[1] = '\0';
1029
    if (str) {
1010
    if (str) {
1030
	char *s = str;
1011
	char *s = str;
1031
	while (*s) {
1012
	while (*s) {
1032
	    if (isdigit((int)*s) && font != PlainFont) {
1013
	    if (isdigit((int)*s) && font != PlainFont) {
1033
		font = PlainFont;
1014
		font = PlainFont;
1034
		SetFont(PlainFont);
1015
		SetFont(PlainFont, gc);
1035
	    }
1016
	    }
1036
	    else if (font != prevfont) {
1017
	    else if (font != prevfont) {
1037
		font = prevfont;
1018
		font = prevfont;
1038
		SetFont(prevfont);
1019
		SetFont(prevfont, gc);
1039
	    }
1020
	    }
1040
	    glyphBBox = GlyphBBox(*s);
1021
	    glyphBBox = GlyphBBox(*s, gc, dd);
1041
	    if (UsingItalics())
1022
	    if (UsingItalics(gc))
1042
		bboxItalic(glyphBBox) = ItalicFactor * bboxHeight(glyphBBox);
1023
		bboxItalic(glyphBBox) = ItalicFactor * bboxHeight(glyphBBox);
1043
	    else
1024
	    else
1044
		bboxItalic(glyphBBox) = 0;
1025
		bboxItalic(glyphBBox) = 0;
1045
	    if (draw) {
1026
	    if (draw) {
1046
		chr[0] = *s;
1027
		chr[0] = *s;
1047
		PMoveAcross(lastItalicCorr);
1028
		PMoveAcross(lastItalicCorr, mc);
1048
		GEText(ConvertedX(), ConvertedY(), chr,
1029
		GEText(ConvertedX(mc ,dd), ConvertedY(mc, dd), chr,
1049
		       0.0, 0.0, CurrentAngle, 
1030
		       0.0, 0.0, mc->CurrentAngle, gc,
1050
		       TextColor, MathGamma, 
-
 
1051
		       MathFontFamily, MathFont, MathLineHeight, 
-
 
1052
		       MathCex, MathPs,
-
 
1053
		       MathDevice);
1031
		       dd);
1054
		PMoveAcross(bboxWidth(glyphBBox));
1032
		PMoveAcross(bboxWidth(glyphBBox), mc);
1055
	    }
1033
	    }
1056
	    bboxWidth(resultBBox) += lastItalicCorr;
1034
	    bboxWidth(resultBBox) += lastItalicCorr;
1057
	    resultBBox = CombineBBoxes(resultBBox, glyphBBox);
1035
	    resultBBox = CombineBBoxes(resultBBox, glyphBBox);
1058
	    lastItalicCorr = bboxItalic(glyphBBox);
1036
	    lastItalicCorr = bboxItalic(glyphBBox);
1059
	    s++;
1037
	    s++;
1060
	}
1038
	}
1061
	if (font != prevfont)
1039
	if (font != prevfont)
1062
	    SetFont(prevfont);
1040
	    SetFont(prevfont, gc);
1063
    }
1041
    }
1064
    bboxSimple(resultBBox) = 1;
1042
    bboxSimple(resultBBox) = 1;
1065
    return resultBBox;
1043
    return resultBBox;
1066
}
1044
}
1067
 
1045
 
1068
/* Code for Character String Atoms. */
1046
/* Code for Character String Atoms. */
1069
 
1047
 
1070
static BBOX RenderChar(int ascii, int draw)
1048
static BBOX RenderChar(int ascii, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1071
{
1049
{
1072
    BBOX bbox;
1050
    BBOX bbox;
1073
    char asciiStr[2];
1051
    char asciiStr[2];
1074
    bbox = GlyphBBox(ascii);
1052
    bbox = GlyphBBox(ascii, gc, dd);
1075
    if (draw) {
1053
    if (draw) {
1076
	asciiStr[0] = ascii;
1054
	asciiStr[0] = ascii;
1077
	asciiStr[1] = '\0';
1055
	asciiStr[1] = '\0';
1078
	GEText(ConvertedX(), ConvertedY(), asciiStr,
1056
	GEText(ConvertedX(mc ,dd), ConvertedY(mc, dd), asciiStr,
1079
	       0.0, 0.0, CurrentAngle, 
1057
	       0.0, 0.0, mc->CurrentAngle, gc,
1080
	       TextColor, MathGamma, 
-
 
1081
	       MathFontFamily, MathFont, MathLineHeight, MathCex, MathPs,
-
 
1082
	       MathDevice);
1058
	       dd);
1083
	PMoveAcross(bboxWidth(bbox));
1059
	PMoveAcross(bboxWidth(bbox), mc);
1084
    }
1060
    }
1085
    return bbox;
1061
    return bbox;
1086
}
1062
}
1087
 
1063
 
1088
static BBOX RenderStr(char *str, int draw)
1064
static BBOX RenderStr(char *str, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1089
{
1065
{
1090
    BBOX glyphBBox;
1066
    BBOX glyphBBox;
1091
    BBOX resultBBox = NullBBox();
1067
    BBOX resultBBox = NullBBox();
1092
    if (str) {
1068
    if (str) {
1093
	char *s = str;
1069
	char *s = str;
1094
	while (*s) {
1070
	while (*s) {
1095
	    glyphBBox = GlyphBBox(*s);
1071
	    glyphBBox = GlyphBBox(*s, gc, dd);
1096
	    resultBBox = CombineBBoxes(resultBBox, glyphBBox);
1072
	    resultBBox = CombineBBoxes(resultBBox, glyphBBox);
1097
	    s++;
1073
	    s++;
1098
	}
1074
	}
1099
	if (draw) {
1075
	if (draw) {
1100
	    GEText(ConvertedX(), ConvertedY(), str,
1076
	    GEText(ConvertedX(mc ,dd), ConvertedY(mc, dd), str,
1101
		   0.0, 0.0, CurrentAngle, 
1077
		   0.0, 0.0, mc->CurrentAngle, gc,
1102
		   TextColor, MathGamma, 
-
 
1103
		   MathFontFamily, MathFont, MathLineHeight, 
-
 
1104
		   MathCex, MathPs,
-
 
1105
		   MathDevice);
1078
		   dd);
1106
	    PMoveAcross(bboxWidth(resultBBox));
1079
	    PMoveAcross(bboxWidth(resultBBox), mc);
1107
	}
1080
	}
1108
	if (UsingItalics())
1081
	if (UsingItalics(gc))
1109
	    bboxItalic(resultBBox) = ItalicFactor * bboxHeight(glyphBBox);
1082
	    bboxItalic(resultBBox) = ItalicFactor * bboxHeight(glyphBBox);
1110
	else
1083
	else
1111
	    bboxItalic(resultBBox) = 0;
1084
	    bboxItalic(resultBBox) = 0;
1112
    }
1085
    }
1113
    bboxSimple(resultBBox) = 1;
1086
    bboxSimple(resultBBox) = 1;
Line 1115... Line 1088...
1115
}
1088
}
1116
 
1089
 
1117
 
1090
 
1118
/* Code for Symbol Font Atoms */
1091
/* Code for Symbol Font Atoms */
1119
 
1092
 
1120
static BBOX RenderSymbol(SEXP expr, int draw)
1093
static BBOX RenderSymbol(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1121
{
1094
{
1122
    int code;
1095
    int code;
1123
    if ((code = TranslatedSymbol(expr)))
1096
    if ((code = TranslatedSymbol(expr)))
1124
	return RenderSymbolChar(code, draw);
1097
	return RenderSymbolChar(code, draw, mc, gc, dd);
1125
    else
1098
    else
1126
	return RenderSymbolStr(CHAR(PRINTNAME(expr)), draw);
1099
	return RenderSymbolStr(CHAR(PRINTNAME(expr)), draw, mc, gc, dd);
1127
}
1100
}
1128
 
1101
 
1129
static BBOX RenderSymbolString(SEXP expr, int draw)
1102
static BBOX RenderSymbolString(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1130
{
1103
{
1131
    int code;
1104
    int code;
1132
    if ((code = TranslatedSymbol(expr)))
1105
    if ((code = TranslatedSymbol(expr)))
1133
	return RenderSymbolChar(code, draw);
1106
	return RenderSymbolChar(code, draw, mc, gc, dd);
1134
    else
1107
    else
1135
	return RenderStr(CHAR(PRINTNAME(expr)), draw);
1108
	return RenderStr(CHAR(PRINTNAME(expr)), draw, mc, gc, dd);
1136
}
1109
}
1137
 
1110
 
1138
 
1111
 
1139
/* Code for Numeric Atoms */
1112
/* Code for Numeric Atoms */
1140
 
1113
 
1141
static BBOX RenderNumber(SEXP expr, int draw)
1114
static BBOX RenderNumber(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1142
{
1115
{
1143
    BBOX bbox;
1116
    BBOX bbox;
1144
    FontType prevfont = SetFont(PlainFont);
1117
    FontType prevfont = SetFont(PlainFont, gc);
1145
    bbox = RenderStr(CHAR(asChar(expr)), draw);
1118
    bbox = RenderStr(CHAR(asChar(expr)), draw, mc, gc, dd);
1146
    SetFont(prevfont);
1119
    SetFont(prevfont, gc);
1147
    return bbox;
1120
    return bbox;
1148
}
1121
}
1149
 
1122
 
1150
/* Code for String Atoms */
1123
/* Code for String Atoms */
1151
 
1124
 
1152
static BBOX RenderString(SEXP expr, int draw)
1125
static BBOX RenderString(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1153
{
1126
{
1154
    return RenderStr(CHAR(STRING_ELT(expr, 0)), draw);
1127
    return RenderStr(CHAR(STRING_ELT(expr, 0)), draw, mc, gc, dd);
1155
}
1128
}
1156
 
1129
 
1157
/* Code for Ellipsis (ldots, cdots, ...) */
1130
/* Code for Ellipsis (ldots, cdots, ...) */
1158
 
1131
 
1159
static int DotsAtom(SEXP expr)
1132
static int DotsAtom(SEXP expr)
Line 1163... Line 1136...
1163
	NameMatch(expr, "ldots"))
1136
	NameMatch(expr, "ldots"))
1164
	    return 1;
1137
	    return 1;
1165
    return 0;
1138
    return 0;
1166
}
1139
}
1167
 
1140
 
1168
static BBOX RenderDots(SEXP expr, int draw)
1141
static BBOX RenderDots(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1169
{
1142
{
1170
    BBOX bbox = RenderSymbolChar(S_ELLIPSIS, 0);
1143
    BBOX bbox = RenderSymbolChar(S_ELLIPSIS, 0, mc, gc, dd);
1171
    if (NameMatch(expr, "cdots") || NameMatch(expr, "...")) {
1144
    if (NameMatch(expr, "cdots") || NameMatch(expr, "...")) {
1172
	double shift = AxisHeight() - 0.5 * bboxHeight(bbox);
1145
	double shift = AxisHeight(gc, dd) - 0.5 * bboxHeight(bbox);
1173
	if (draw) {
1146
	if (draw) {
1174
	    PMoveUp(shift);
1147
	    PMoveUp(shift, mc);
1175
	    RenderSymbolChar(S_ELLIPSIS, 1);
1148
	    RenderSymbolChar(S_ELLIPSIS, 1, mc, gc, dd);
1176
	    PMoveUp(-shift);
1149
	    PMoveUp(-shift, mc);
1177
	}
1150
	}
1178
	return ShiftBBox(bbox, shift);
1151
	return ShiftBBox(bbox, shift);
1179
    }
1152
    }
1180
    else {
1153
    else {
1181
	if (draw)
1154
	if (draw)
1182
	    RenderSymbolChar(S_ELLIPSIS, 1);
1155
	    RenderSymbolChar(S_ELLIPSIS, 1, mc, gc, dd);
1183
	return bbox;
1156
	return bbox;
1184
    }
1157
    }
1185
}
1158
}
1186
 
1159
 
1187
/*----------------------------------------------------------------------
1160
/*----------------------------------------------------------------------
1188
 *
1161
 *
1189
 *  Code for Atoms
1162
 *  Code for Atoms
1190
 *
1163
 *
1191
 */
1164
 */
1192
 
1165
 
1193
static BBOX RenderAtom(SEXP expr, int draw)
1166
static BBOX RenderAtom(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1194
{
1167
{
1195
    if (NameAtom(expr)) {
1168
    if (NameAtom(expr)) {
1196
	if (DotsAtom(expr))
1169
	if (DotsAtom(expr))
1197
	    return RenderDots(expr, draw);
1170
	    return RenderDots(expr, draw, mc, gc, dd);
1198
	else
1171
	else
1199
	    return RenderSymbol(expr, draw);
1172
	    return RenderSymbol(expr, draw, mc, gc, dd);
1200
    }
1173
    }
1201
    else if (NumberAtom(expr))
1174
    else if (NumberAtom(expr))
1202
	return RenderNumber(expr, draw);
1175
	return RenderNumber(expr, draw, mc, gc, dd);
1203
    else if (StringAtom(expr))
1176
    else if (StringAtom(expr))
1204
	return RenderString(expr, draw);
1177
	return RenderString(expr, draw, mc, gc, dd);
1205
 
1178
 
1206
    return NullBBox();		/* -Wall */
1179
    return NullBBox();		/* -Wall */
1207
}
1180
}
1208
 
1181
 
1209
 
1182
 
Line 1219... Line 1192...
1219
{
1192
{
1220
    return NameAtom(expr) && NameMatch(expr, "~");
1193
    return NameAtom(expr) && NameMatch(expr, "~");
1221
}
1194
}
1222
 
1195
 
1223
 
1196
 
1224
static BBOX RenderSpace(SEXP expr, int draw)
1197
static BBOX RenderSpace(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1225
{
1198
{
1226
 
1199
 
1227
    BBOX opBBox, arg1BBox, arg2BBox;
1200
    BBOX opBBox, arg1BBox, arg2BBox;
1228
    int nexpr = length(expr);
1201
    int nexpr = length(expr);
1229
 
1202
 
1230
    if (nexpr == 2) {
1203
    if (nexpr == 2) {
1231
	opBBox = RenderSymbolChar(' ', draw);
1204
	opBBox = RenderSymbolChar(' ', draw, mc, gc, dd);
1232
	arg1BBox = RenderElement(CADR(expr), draw);
1205
	arg1BBox = RenderElement(CADR(expr), draw, mc, gc, dd);
1233
	return CombineBBoxes(opBBox, arg1BBox);
1206
	return CombineBBoxes(opBBox, arg1BBox);
1234
    }
1207
    }
1235
    else if (nexpr == 3) {
1208
    else if (nexpr == 3) {
1236
	arg1BBox = RenderElement(CADR(expr), draw);
1209
	arg1BBox = RenderElement(CADR(expr), draw, mc, gc, dd);
1237
	opBBox = RenderSymbolChar(' ', draw);
1210
	opBBox = RenderSymbolChar(' ', draw, mc, gc, dd);
1238
	arg2BBox = RenderElement(CADDR(expr), draw);
1211
	arg2BBox = RenderElement(CADDR(expr), draw, mc, gc, dd);
1239
	opBBox = CombineBBoxes(arg1BBox, opBBox);
1212
	opBBox = CombineBBoxes(arg1BBox, opBBox);
1240
	opBBox = CombineBBoxes(opBBox, arg2BBox);
1213
	opBBox = CombineBBoxes(opBBox, arg2BBox);
1241
	return opBBox;
1214
	return opBBox;
1242
    }
1215
    }
1243
    else
1216
    else
Line 1270... Line 1243...
1270
    return 0;
1243
    return 0;
1271
}
1244
}
1272
 
1245
 
1273
#define SLASH2
1246
#define SLASH2
1274
 
1247
 
1275
static BBOX RenderSlash(int draw)
1248
static BBOX RenderSlash(int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1276
{
1249
{
1277
#ifdef SLASH0
1250
#ifdef SLASH0
1278
    /* The Default Font Character */
1251
    /* The Default Font Character */
1279
    return RenderSymbolChar(S_SLASH, draw);
1252
    return RenderSymbolChar(S_SLASH, draw, mc, gc, dd);
1280
#endif
1253
#endif
1281
#ifdef SLASH1
1254
#ifdef SLASH1
1282
    /* Symbol Magnify Version */
1255
    /* Symbol Magnify Version */
1283
    double savecex = MathCex;
1256
    double savecex = gc->cex;
1284
    BBOX bbox;
1257
    BBOX bbox;
1285
    double height1, height2;
1258
    double height1, height2;
1286
    height1 = bboxHeight(RenderSymbolChar(S_SLASH, 0));
1259
    height1 = bboxHeight(RenderSymbolChar(S_SLASH, 0), mc, gc, dd);
1287
    MathCex = 1.2 * MathCex;
1260
    gc->cex = 1.2 * gc->cex;
1288
    height2 = bboxHeight(RenderSymbolChar(S_SLASH, 0));
1261
    height2 = bboxHeight(RenderSymbolChar(S_SLASH, 0), mc, gc, dd);
1289
    if (draw)
1262
    if (draw)
1290
	PMoveUp(- 0.5 * (height2 - height1));
1263
	PMoveUp(- 0.5 * (height2 - height1), mc);
1291
    bbox = RenderSymbolChar(S_SLASH, draw);
1264
    bbox = RenderSymbolChar(S_SLASH, draw, mc, gc, dd);
1292
    if (draw)
1265
    if (draw)
1293
	PMoveUp(0.5 * (height2 - height1));
1266
	PMoveUp(0.5 * (height2 - height1), mc);
1294
    MathCex = savecex;
1267
    gc->cex = savecex;
1295
    return bbox;
1268
    return bbox;
1296
#endif
1269
#endif
1297
#ifdef SLASH2
1270
#ifdef SLASH2
1298
    /* Line Drawing Version */
1271
    /* Line Drawing Version */
1299
    double x[2], y[2];
1272
    double x[2], y[2];
1300
    double depth = 0.5 * TeX(sigma22);
1273
    double depth = 0.5 * TeX(sigma22, gc, dd);
1301
    double height = XHeight() + 0.5 * TeX(sigma22);
1274
    double height = XHeight(gc, dd) + 0.5 * TeX(sigma22, gc, dd);
1302
    double width = 0.5 * xHeight();
1275
    double width = 0.5 * xHeight(gc, dd);
1303
    if (draw) {
1276
    if (draw) {
-
 
1277
	int savedlty = gc->lty;
-
 
1278
	double savedlwd = gc->lwd;
1304
	PMoveAcross(0.5 * width);
1279
	PMoveAcross(0.5 * width, mc);
1305
	PMoveUp(-depth);
1280
	PMoveUp(-depth, mc);
1306
	x[0] = ConvertedX();
1281
	x[0] = ConvertedX(mc, dd);
1307
	y[0] = ConvertedY();
1282
	y[0] = ConvertedY(mc, dd);
1308
	PMoveAcross(width);
1283
	PMoveAcross(width, mc);
1309
	PMoveUp(depth + height);
1284
	PMoveUp(depth + height, mc);
1310
	x[1] = ConvertedX();
1285
	x[1] = ConvertedX(mc, dd);
1311
	y[1] = ConvertedY();
1286
	y[1] = ConvertedY(mc, dd);
1312
	PMoveUp(-height);
1287
	PMoveUp(-height, mc);
1313
	GEPolyline(2, x, y,
1288
	gc->lty = LTY_SOLID;
-
 
1289
	gc->lwd = 1;
1314
		  TextColor, MathGamma, LTY_SOLID, 1, MathDevice);
1290
	GEPolyline(2, x, y, gc, dd);
1315
	PMoveAcross(0.5 * width);
1291
	PMoveAcross(0.5 * width, mc);
-
 
1292
	gc->lty = savedlty;
-
 
1293
	gc->lwd = savedlwd;
1316
    }
1294
    }
1317
    return MakeBBox(height, depth, 2 * width);
1295
    return MakeBBox(height, depth, 2 * width);
1318
#endif
1296
#endif
1319
#ifdef SLASH3
1297
#ifdef SLASH3
1320
    /* Offset Overprinting - A Failure! */
1298
    /* Offset Overprinting - A Failure! */
1321
    BBOX slashBBox = RenderSymbolChar(S_SLASH, 0);
1299
    BBOX slashBBox = RenderSymbolChar(S_SLASH, 0, mc, gc, dd);
1322
    BBOX ansBBox;
1300
    BBOX ansBBox;
1323
    double height = bboxHeight(slashBBox);
1301
    double height = bboxHeight(slashBBox);
1324
    double depth = bboxDepth(slashBBox);
1302
    double depth = bboxDepth(slashBBox);
1325
    double width = bboxWidth(slashBBox);
1303
    double width = bboxWidth(slashBBox);
1326
    double slope = (height + depth) / slope;
1304
    double slope = (height + depth) / slope;
1327
    double delta = TeX(sigma22);
1305
    double delta = TeX(sigma22, gc, dd);
1328
    if (draw)
1306
    if (draw)
1329
	PMoveUp(-delta);
1307
	PMoveUp(-delta, mc);
1330
    ansBBox = ShiftBBox(RenderSymbolChar(S_SLASH, draw), -delta);
1308
    ansBBox = ShiftBBox(RenderSymbolChar(S_SLASH, draw), -delta, mc, gc, dd);
1331
    PMoveUp(2 * delta);
1309
    PMoveUp(2 * delta, mc);
1332
    ansBBox = CombineBBoxes(ansBBox, RenderGap(2 * delta / slope, draw));
1310
    ansBBox = CombineBBoxes(ansBBox, RenderGap(2 * delta / slope, draw, mc, gc, dd));
1333
    ansBBox = ShiftBBox(RenderSymbolChar(S_SLASH, draw), 2 * delta);
1311
    ansBBox = ShiftBBox(RenderSymbolChar(S_SLASH, draw), 2 * delta, mc, gc, dd);
1334
    PMoveUp(-delta);
1312
    PMoveUp(-delta, mc);
1335
    return ansBBox;
1313
    return ansBBox;
1336
#endif
1314
#endif
1337
}
1315
}
1338
 
1316
 
1339
static BBOX RenderBin(SEXP expr, int draw)
1317
static BBOX RenderBin(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1340
{
1318
{
1341
    int op = BinAtom(CAR(expr));
1319
    int op = BinAtom(CAR(expr));
1342
    int nexpr = length(expr);
1320
    int nexpr = length(expr);
1343
    BBOX bbox;
1321
    BBOX bbox;
1344
    double gap;
1322
    double gap;
1345
 
1323
 
1346
    if(nexpr == 3) {
1324
    if(nexpr == 3) {
1347
	if (op == S_ASTERISKMATH) {
1325
	if (op == S_ASTERISKMATH) {
1348
	    bbox = RenderElement(CADR(expr), draw);
1326
	    bbox = RenderElement(CADR(expr), draw, mc, gc, dd);
1349
	    bbox = RenderItalicCorr(bbox, draw);
1327
	    bbox = RenderItalicCorr(bbox, draw, mc, gc, dd);
1350
	    return CombineBBoxes(bbox, RenderElement(CADDR(expr), draw));
1328
	    return CombineBBoxes(bbox, RenderElement(CADDR(expr), draw, mc, gc, dd));
1351
	}
1329
	}
1352
	else if (op == S_SLASH) {
1330
	else if (op == S_SLASH) {
1353
	    gap = 0;
1331
	    gap = 0;
1354
	    bbox = RenderElement(CADR(expr), draw);
1332
	    bbox = RenderElement(CADR(expr), draw, mc, gc, dd);
1355
	    bbox = RenderItalicCorr(bbox, draw);
1333
	    bbox = RenderItalicCorr(bbox, draw, mc, gc, dd);
1356
	    bbox = CombineBBoxes(bbox, RenderGap(gap, draw));
1334
	    bbox = CombineBBoxes(bbox, RenderGap(gap, draw, mc, gc, dd));
1357
	    bbox = CombineBBoxes(bbox, RenderSlash(draw));
1335
	    bbox = CombineBBoxes(bbox, RenderSlash(draw, mc, gc, dd));
1358
	    bbox = CombineBBoxes(bbox, RenderGap(gap, draw));
1336
	    bbox = CombineBBoxes(bbox, RenderGap(gap, draw, mc, gc, dd));
1359
	    return CombineBBoxes(bbox, RenderElement(CADDR(expr), draw));
1337
	    return CombineBBoxes(bbox, RenderElement(CADDR(expr), draw, mc, gc, dd));
1360
	}
1338
	}
1361
	else {
1339
	else {
1362
	    gap = (CurrentStyle > STYLE_S) ? MediumSpace() : 0;
1340
	    gap = (mc->CurrentStyle > STYLE_S) ? MediumSpace(gc, dd) : 0;
1363
	    bbox = RenderElement(CADR(expr), draw);
1341
	    bbox = RenderElement(CADR(expr), draw, mc, gc, dd);
1364
	    bbox = RenderItalicCorr(bbox, draw);
1342
	    bbox = RenderItalicCorr(bbox, draw, mc, gc, dd);
1365
	    bbox = CombineBBoxes(bbox, RenderGap(gap, draw));
1343
	    bbox = CombineBBoxes(bbox, RenderGap(gap, draw, mc, gc, dd));
1366
	    bbox = CombineBBoxes(bbox, RenderSymbolChar(op, draw));
1344
	    bbox = CombineBBoxes(bbox, RenderSymbolChar(op, draw, mc, gc, dd));
1367
	    bbox = CombineBBoxes(bbox, RenderGap(gap, draw));
1345
	    bbox = CombineBBoxes(bbox, RenderGap(gap, draw, mc, gc, dd));
1368
	    return CombineBBoxes(bbox, RenderElement(CADDR(expr), draw));
1346
	    return CombineBBoxes(bbox, RenderElement(CADDR(expr), draw, mc, gc, dd));
1369
	}
1347
	}
1370
    }
1348
    }
1371
    else if(nexpr == 2) {
1349
    else if(nexpr == 2) {
1372
	gap = (CurrentStyle > STYLE_S) ? ThinSpace() : 0;
1350
	gap = (mc->CurrentStyle > STYLE_S) ? ThinSpace(gc, dd) : 0;
1373
	bbox = RenderSymbolChar(op, draw);
1351
	bbox = RenderSymbolChar(op, draw, mc, gc, dd);
1374
	bbox = CombineBBoxes(bbox, RenderGap(gap, draw));
1352
	bbox = CombineBBoxes(bbox, RenderGap(gap, draw, mc, gc, dd));
1375
	return CombineBBoxes(bbox, RenderElement(CADR(expr), draw));
1353
	return CombineBBoxes(bbox, RenderElement(CADR(expr), draw, mc, gc, dd));
1376
    }
1354
    }
1377
    else
1355
    else
1378
	error("invalid mathematical annotation");
1356
	error("invalid mathematical annotation");
1379
 
1357
 
1380
    return NullBBox();		/* -Wall */
1358
    return NullBBox();		/* -Wall */
Line 1401... Line 1379...
1401
}
1379
}
1402
 
1380
 
1403
/* Note : If all computations are correct */
1381
/* Note : If all computations are correct */
1404
/* We do not need to save and restore the */
1382
/* We do not need to save and restore the */
1405
/* current location here.  This is paranoia. */
1383
/* current location here.  This is paranoia. */
1406
static BBOX RenderSub(SEXP expr, int draw)
1384
static BBOX RenderSub(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1407
{
1385
{
1408
    BBOX bodyBBox, subBBox;
1386
    BBOX bodyBBox, subBBox;
1409
    SEXP body = CADR(expr);
1387
    SEXP body = CADR(expr);
1410
    SEXP sub = CADDR(expr);
1388
    SEXP sub = CADDR(expr);
1411
    STYLE style = GetStyle();
1389
    STYLE style = GetStyle(mc);
1412
    double savedX = CurrentX;
1390
    double savedX = mc->CurrentX;
1413
    double savedY = CurrentY;
1391
    double savedY = mc->CurrentY;
1414
    double v, s5, s16;
1392
    double v, s5, s16;
1415
    bodyBBox = RenderElement(body, draw);
1393
    bodyBBox = RenderElement(body, draw, mc, gc, dd);
1416
    bodyBBox = RenderItalicCorr(bodyBBox, draw);
1394
    bodyBBox = RenderItalicCorr(bodyBBox, draw, mc, gc, dd);
1417
    v = bboxSimple(bodyBBox) ? 0 : bboxDepth(bodyBBox) + TeX(sigma19);
1395
    v = bboxSimple(bodyBBox) ? 0 : bboxDepth(bodyBBox) + TeX(sigma19, gc, dd);
1418
    s5 = TeX(sigma5);
1396
    s5 = TeX(sigma5, gc, dd);
1419
    s16 = TeX(sigma16);
1397
    s16 = TeX(sigma16, gc, dd);
1420
    SetSubStyle(style);
1398
    SetSubStyle(style, mc, gc);
1421
    subBBox = RenderElement(sub, 0);
1399
    subBBox = RenderElement(sub, 0, mc, gc, dd);
1422
    v = max(max(v, s16), bboxHeight(subBBox) - 0.8 * sigma5);
1400
    v = max(max(v, s16), bboxHeight(subBBox) - 0.8 * sigma5);
1423
    subBBox = RenderOffsetElement(sub, 0, -v, draw);
1401
    subBBox = RenderOffsetElement(sub, 0, -v, draw, mc, gc, dd);
1424
    bodyBBox = CombineBBoxes(bodyBBox, subBBox);
1402
    bodyBBox = CombineBBoxes(bodyBBox, subBBox);
1425
    SetStyle(style);
1403
    SetStyle(style, mc, gc);
1426
    if (draw)
1404
    if (draw)
1427
	PMoveTo(savedX + bboxWidth(bodyBBox), savedY);
1405
	PMoveTo(savedX + bboxWidth(bodyBBox), savedY, mc);
1428
    return bodyBBox;
1406
    return bodyBBox;
1429
}
1407
}
1430
 
1408
 
1431
static BBOX RenderSup(SEXP expr, int draw)
1409
static BBOX RenderSup(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1432
{
1410
{
1433
    BBOX bodyBBox, subBBox, supBBox;
1411
    BBOX bodyBBox, subBBox, supBBox;
1434
    SEXP body = CADR(expr);
1412
    SEXP body = CADR(expr);
1435
    SEXP sup = CADDR(expr);
1413
    SEXP sup = CADDR(expr);
1436
    SEXP sub = R_NilValue;	/* -Wall */
1414
    SEXP sub = R_NilValue;	/* -Wall */
1437
    STYLE style = GetStyle();
1415
    STYLE style = GetStyle(mc);
1438
    double savedX = CurrentX;
1416
    double savedX = mc->CurrentX;
1439
    double savedY = CurrentY;
1417
    double savedY = mc->CurrentY;
1440
    double theta, delta, width;
1418
    double theta, delta, width;
1441
    double u, p;
1419
    double u, p;
1442
    double v, s5, s17;
1420
    double v, s5, s17;
1443
    int haveSub;
1421
    int haveSub;
1444
    if (FormulaExpression(body) && SubAtom(CAR(body))) {
1422
    if (FormulaExpression(body) && SubAtom(CAR(body))) {
1445
	sub = CADDR(body);
1423
	sub = CADDR(body);
1446
	body = CADR(body);
1424
	body = CADR(body);
1447
	haveSub = 1;
1425
	haveSub = 1;
1448
    }
1426
    }
1449
    else haveSub = 0;
1427
    else haveSub = 0;
1450
    bodyBBox = RenderElement(body, draw);
1428
    bodyBBox = RenderElement(body, draw, mc, gc, dd);
1451
    delta = bboxItalic(bodyBBox);
1429
    delta = bboxItalic(bodyBBox);
1452
    bodyBBox = RenderItalicCorr(bodyBBox, draw);
1430
    bodyBBox = RenderItalicCorr(bodyBBox, draw, mc, gc, dd);
1453
    width = bboxWidth(bodyBBox);
1431
    width = bboxWidth(bodyBBox);
1454
    if (bboxSimple(bodyBBox)) {
1432
    if (bboxSimple(bodyBBox)) {
1455
	u = 0;
1433
	u = 0;
1456
	v = 0;
1434
	v = 0;
1457
    }
1435
    }
1458
    else {
1436
    else {
1459
	u = bboxHeight(bodyBBox) - TeX(sigma18);
1437
	u = bboxHeight(bodyBBox) - TeX(sigma18, gc, dd);
1460
	v = bboxDepth(bodyBBox) + TeX(sigma19);
1438
	v = bboxDepth(bodyBBox) + TeX(sigma19, gc, dd);
1461
    }
1439
    }
1462
    theta = TeX(xi8);
1440
    theta = TeX(xi8, gc, dd);
1463
    s5 = TeX(sigma5);
1441
    s5 = TeX(sigma5, gc, dd);
1464
    s17 = TeX(sigma17);
1442
    s17 = TeX(sigma17, gc, dd);
1465
    if (style == STYLE_D)
1443
    if (style == STYLE_D)
1466
	p = TeX(sigma13);
1444
	p = TeX(sigma13, gc, dd);
1467
    else if (IsCompactStyle(style))
1445
    else if (IsCompactStyle(style, mc, gc))
1468
	p = TeX(sigma15);
1446
	p = TeX(sigma15, gc, dd);
1469
    else
1447
    else
1470
	p = TeX(sigma14);
1448
	p = TeX(sigma14, gc, dd);
1471
    SetSupStyle(style);
1449
    SetSupStyle(style, mc, gc);
1472
    supBBox = RenderElement(sup, 0);
1450
    supBBox = RenderElement(sup, 0, mc, gc, dd);
1473
    u = max(max(u, p), bboxDepth(supBBox) + 0.25 * s5);
1451
    u = max(max(u, p), bboxDepth(supBBox) + 0.25 * s5);
1474
 
1452
 
1475
    if (haveSub) {
1453
    if (haveSub) {
1476
	SetSubStyle(style);
1454
	SetSubStyle(style, mc, gc);
1477
	subBBox = RenderElement(sub, 0);
1455
	subBBox = RenderElement(sub, 0, mc, gc, dd);
1478
	v = max(v, s17);
1456
	v = max(v, s17);
1479
	if ((u - bboxDepth(supBBox)) - (bboxHeight(subBBox) - v) < 4 * theta) {
1457
	if ((u - bboxDepth(supBBox)) - (bboxHeight(subBBox) - v) < 4 * theta) {
1480
	    double psi = 0.8 * s5 - (u - bboxDepth(supBBox));
1458
	    double psi = 0.8 * s5 - (u - bboxDepth(supBBox));
1481
	    if (psi > 0) {
1459
	    if (psi > 0) {
1482
		u += psi;
1460
		u += psi;
1483
		v -= psi;
1461
		v -= psi;
1484
	    }
1462
	    }
1485
	}
1463
	}
1486
	if (draw)
1464
	if (draw)
1487
	    PMoveTo(savedX, savedY);
1465
	    PMoveTo(savedX, savedY, mc);
1488
	subBBox = RenderOffsetElement(sub, width, -v, draw);
1466
	subBBox = RenderOffsetElement(sub, width, -v, draw, mc, gc, dd);
1489
	if (draw)
1467
	if (draw)
1490
	    PMoveTo(savedX, savedY);
1468
	    PMoveTo(savedX, savedY, mc);
1491
	SetSupStyle(style);
1469
	SetSupStyle(style, mc, gc);
1492
	supBBox = RenderOffsetElement(sup, width + delta, u, draw);
1470
	supBBox = RenderOffsetElement(sup, width + delta, u, draw, mc, gc, dd);
1493
	bodyBBox = CombineAlignedBBoxes(bodyBBox, subBBox);
1471
	bodyBBox = CombineAlignedBBoxes(bodyBBox, subBBox);
1494
	bodyBBox = CombineAlignedBBoxes(bodyBBox, supBBox);
1472
	bodyBBox = CombineAlignedBBoxes(bodyBBox, supBBox);
1495
    }
1473
    }
1496
    else {
1474
    else {
1497
	supBBox = RenderOffsetElement(sup, 0, u, draw);
1475
	supBBox = RenderOffsetElement(sup, 0, u, draw, mc, gc, dd);
1498
	bodyBBox = CombineBBoxes(bodyBBox, supBBox);
1476
	bodyBBox = CombineBBoxes(bodyBBox, supBBox);
1499
    }
1477
    }
1500
    if (draw)
1478
    if (draw)
1501
	PMoveTo(savedX + bboxWidth(bodyBBox), savedY);
1479
	PMoveTo(savedX + bboxWidth(bodyBBox), savedY, mc);
1502
    SetStyle(style);
1480
    SetStyle(style, mc, gc);
1503
    return bodyBBox;
1481
    return bodyBBox;
1504
}
1482
}
1505
 
1483
 
1506
 
1484
 
1507
/*----------------------------------------------------------------------
1485
/*----------------------------------------------------------------------
Line 1519... Line 1497...
1519
static int WideTildeAtom(SEXP expr)
1497
static int WideTildeAtom(SEXP expr)
1520
{
1498
{
1521
    return NameAtom(expr) && NameMatch(expr, "widetilde");
1499
    return NameAtom(expr) && NameMatch(expr, "widetilde");
1522
}
1500
}
1523
 
1501
 
1524
static BBOX RenderWideTilde(SEXP expr, int draw)
1502
static BBOX RenderWideTilde(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1525
{
1503
{
1526
    double savedX = CurrentX;
1504
    double savedX = mc->CurrentX;
1527
    double savedY = CurrentY;
1505
    double savedY = mc->CurrentY;
1528
    BBOX bbox = RenderElement(CADR(expr), draw);
1506
    BBOX bbox = RenderElement(CADR(expr), draw, mc, gc, dd);
1529
    double height = bboxHeight(bbox);
1507
    double height = bboxHeight(bbox);
1530
    /*double width = bboxWidth(bbox);*/
1508
    /*double width = bboxWidth(bbox);*/
1531
    double totalwidth = bboxWidth(bbox) + bboxItalic(bbox);
1509
    double totalwidth = bboxWidth(bbox) + bboxItalic(bbox);
1532
    double delta = totalwidth * (1 - 2 * DELTA) / NTILDE;
1510
    double delta = totalwidth * (1 - 2 * DELTA) / NTILDE;
1533
    double start = DELTA * totalwidth;
1511
    double start = DELTA * totalwidth;
1534
    double accentGap = ACCENT_GAP * XHeight();
1512
    double accentGap = ACCENT_GAP * XHeight(gc, dd);
1535
    double hatHeight = 0.5 * HAT_HEIGHT * XHeight();
1513
    double hatHeight = 0.5 * HAT_HEIGHT * XHeight(gc, dd);
1536
    double c = 8 * atan(1.0) / NTILDE;
1514
    double c = 8 * atan(1.0) / NTILDE;
1537
    double x[NTILDE + 3], y[NTILDE + 3];
1515
    double x[NTILDE + 3], y[NTILDE + 3];
1538
    double baseX, baseY, xval, yval;
1516
    double baseX, baseY, xval, yval;
1539
    int i;
1517
    int i;
1540
 
1518
 
1541
    if (draw) {
1519
    if (draw) {
-
 
1520
	int savedlty = gc->lty;
-
 
1521
	double savedlwd = gc->lwd;
1542
	baseX = savedX;
1522
	baseX = savedX;
1543
	baseY = savedY + height + accentGap;
1523
	baseY = savedY + height + accentGap;
1544
	PMoveTo(baseX, baseY);
1524
	PMoveTo(baseX, baseY, mc);
1545
	x[0] = ConvertedX();
1525
	x[0] = ConvertedX(mc, dd);
1546
	y[0] = ConvertedY();
1526
	y[0] = ConvertedY(mc, dd);
1547
	for (i = 0; i <= NTILDE; i++) {
1527
	for (i = 0; i <= NTILDE; i++) {
1548
	    xval = start + i * delta;
1528
	    xval = start + i * delta;
1549
	    yval = 0.5 * hatHeight * (sin(c * i) + 1);
1529
	    yval = 0.5 * hatHeight * (sin(c * i) + 1);
1550
	    PMoveTo(baseX + xval, baseY + yval);
1530
	    PMoveTo(baseX + xval, baseY + yval, mc);
1551
	    x[i + 1] = ConvertedX();
1531
	    x[i + 1] = ConvertedX(mc, dd);
1552
	    y[i + 1] = ConvertedY();
1532
	    y[i + 1] = ConvertedY(mc, dd);
1553
	}
1533
	}
1554
	PMoveTo(baseX + totalwidth, baseY + hatHeight);
1534
	PMoveTo(baseX + totalwidth, baseY + hatHeight, mc);
1555
	x[NTILDE + 2] = ConvertedX();
1535
	x[NTILDE + 2] = ConvertedX(mc, dd);
1556
	y[NTILDE + 2] = ConvertedY();
1536
	y[NTILDE + 2] = ConvertedY(mc, dd);
-
 
1537
	gc->lty = LTY_SOLID;
-
 
1538
	gc->lwd = 1;
1557
	GEPolyline(NTILDE + 3, x, y, 
1539
	GEPolyline(NTILDE + 3, x, y, gc, dd);
1558
		  TextColor, MathGamma, LTY_SOLID, 1, MathDevice);
-
 
1559
	PMoveTo(savedX + totalwidth, savedY);
1540
	PMoveTo(savedX + totalwidth, savedY, mc);
-
 
1541
	gc->lty = savedlty;
-
 
1542
	gc->lwd = savedlwd;
1560
    }
1543
    }
1561
    return MakeBBox(height + accentGap + hatHeight,
1544
    return MakeBBox(height + accentGap + hatHeight,
1562
		    bboxDepth(bbox), totalwidth);
1545
		    bboxDepth(bbox), totalwidth);
1563
}
1546
}
1564
 
1547
 
1565
static int WideHatAtom(SEXP expr)
1548
static int WideHatAtom(SEXP expr)
1566
{
1549
{
1567
    return NameAtom(expr) && NameMatch(expr, "widehat");
1550
    return NameAtom(expr) && NameMatch(expr, "widehat");
1568
}
1551
}
1569
 
1552
 
1570
static BBOX RenderWideHat(SEXP expr, int draw)
1553
static BBOX RenderWideHat(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1571
{
1554
{
1572
    double savedX = CurrentX;
1555
    double savedX = mc->CurrentX;
1573
    double savedY = CurrentY;
1556
    double savedY = mc->CurrentY;
1574
    BBOX bbox = RenderElement(CADR(expr), draw);
1557
    BBOX bbox = RenderElement(CADR(expr), draw, mc, gc, dd);
1575
    double accentGap = ACCENT_GAP * XHeight();
1558
    double accentGap = ACCENT_GAP * XHeight(gc, dd);
1576
    double hatHeight = HAT_HEIGHT * XHeight();
1559
    double hatHeight = HAT_HEIGHT * XHeight(gc, dd);
1577
    double totalwidth = bboxWidth(bbox) + bboxItalic(bbox);
1560
    double totalwidth = bboxWidth(bbox) + bboxItalic(bbox);
1578
    double height = bboxHeight(bbox);
1561
    double height = bboxHeight(bbox);
1579
    double width = bboxWidth(bbox);
1562
    double width = bboxWidth(bbox);
1580
    double x[3], y[3];
1563
    double x[3], y[3];
1581
 
1564
 
1582
    if (draw) {
1565
    if (draw) {
-
 
1566
	int savedlty = gc->lty;
-
 
1567
	double savedlwd = gc->lwd;
1583
	PMoveTo(savedX, savedY + height + accentGap);
1568
	PMoveTo(savedX, savedY + height + accentGap, mc);
1584
	x[0] = ConvertedX();
1569
	x[0] = ConvertedX(mc, dd);
1585
	y[0] = ConvertedY();
1570
	y[0] = ConvertedY(mc, dd);
1586
	PMoveAcross(0.5 * totalwidth);
1571
	PMoveAcross(0.5 * totalwidth, mc);
1587
	PMoveUp(hatHeight);
1572
	PMoveUp(hatHeight, mc);
1588
	x[1] = ConvertedX();
1573
	x[1] = ConvertedX(mc, dd);
1589
	y[1] = ConvertedY();
1574
	y[1] = ConvertedY(mc, dd);
1590
	PMoveAcross(0.5 * totalwidth);
1575
	PMoveAcross(0.5 * totalwidth, mc);
1591
	PMoveUp(-hatHeight);
1576
	PMoveUp(-hatHeight, mc);
1592
	x[2] = ConvertedX();
1577
	x[2] = ConvertedX(mc, dd);
1593
	y[2] = ConvertedY();
1578
	y[2] = ConvertedY(mc, dd);
1594
	GEPolyline(3, x, y, 
1579
	gc->lty = LTY_SOLID;
-
 
1580
	gc->lwd = 1;
1595
		  TextColor, MathGamma, LTY_SOLID, 1, MathDevice);
1581
	GEPolyline(3, x, y, gc, dd);
1596
	PMoveTo(savedX + width, savedY);
1582
	PMoveTo(savedX + width, savedY, mc);
-
 
1583
	gc->lty = savedlty;
-
 
1584
	gc->lwd = savedlwd;
1597
    }
1585
    }
1598
    return EnlargeBBox(bbox, accentGap + hatHeight, 0, 0);
1586
    return EnlargeBBox(bbox, accentGap + hatHeight, 0, 0);
1599
}
1587
}
1600
 
1588
 
1601
static int BarAtom(SEXP expr)
1589
static int BarAtom(SEXP expr)
1602
{
1590
{
1603
    return NameAtom(expr) && NameMatch(expr, "bar");
1591
    return NameAtom(expr) && NameMatch(expr, "bar");
1604
}
1592
}
1605
 
1593
 
1606
static BBOX RenderBar(SEXP expr, int draw)
1594
static BBOX RenderBar(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1607
{
1595
{
1608
    double savedX = CurrentX;
1596
    double savedX = mc->CurrentX;
1609
    double savedY = CurrentY;
1597
    double savedY = mc->CurrentY;
1610
    BBOX bbox = RenderElement(CADR(expr), draw);
1598
    BBOX bbox = RenderElement(CADR(expr), draw, mc, gc, dd);
1611
    double accentGap = ACCENT_GAP * XHeight();
1599
    double accentGap = ACCENT_GAP * XHeight(gc, dd);
1612
    /*double hatHeight = HAT_HEIGHT * XHeight();*/
1600
    /*double hatHeight = HAT_HEIGHT * XHeight(gc, dd);*/
1613
    double height = bboxHeight(bbox);
1601
    double height = bboxHeight(bbox);
1614
    double width = bboxWidth(bbox);
1602
    double width = bboxWidth(bbox);
1615
    double offset = bboxItalic(bbox);
1603
    double offset = bboxItalic(bbox);
1616
    double x[2], y[2];
1604
    double x[2], y[2];
1617
 
1605
 
1618
    if (draw) {
1606
    if (draw) {
-
 
1607
	int savedlty = gc->lty;
-
 
1608
	double savedlwd = gc->lwd;
1619
	PMoveTo(savedX + offset, savedY + height + accentGap);
1609
	PMoveTo(savedX + offset, savedY + height + accentGap, mc);
1620
	x[0] = ConvertedX();
1610
	x[0] = ConvertedX(mc, dd);
1621
	y[0] = ConvertedY();
1611
	y[0] = ConvertedY(mc, dd);
1622
	PMoveAcross(width);
1612
	PMoveAcross(width, mc);
1623
	x[1] = ConvertedX();
1613
	x[1] = ConvertedX(mc, dd);
1624
	y[1] = ConvertedY();
1614
	y[1] = ConvertedY(mc, dd);
1625
	GEPolyline(2, x, y, 
1615
	gc->lty = LTY_SOLID;
-
 
1616
	gc->lwd = 1;
1626
		  TextColor, MathGamma, LTY_SOLID, 1, MathDevice);
1617
	GEPolyline(2, x, y, gc, dd);
1627
	PMoveTo(savedX + width, savedY);
1618
	PMoveTo(savedX + width, savedY, mc);
-
 
1619
	gc->lty = savedlty;
-
 
1620
	gc->lwd = savedlwd;
1628
    }
1621
    }
1629
    return EnlargeBBox(bbox, accentGap, 0, 0);
1622
    return EnlargeBBox(bbox, accentGap, 0, 0);
1630
}
1623
}
1631
 
1624
 
1632
static struct {
1625
static struct {
Line 1658... Line 1651...
1658
static void InvalidAccent(SEXP expr)
1651
static void InvalidAccent(SEXP expr)
1659
{
1652
{
1660
    errorcall(expr, "invalid accent");
1653
    errorcall(expr, "invalid accent");
1661
}
1654
}
1662
 
1655
 
1663
static BBOX RenderAccent(SEXP expr, int draw)
1656
static BBOX RenderAccent(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1664
{
1657
{
1665
    SEXP body, accent;
1658
    SEXP body, accent;
1666
    double savedX = CurrentX;
1659
    double savedX = mc->CurrentX;
1667
    double savedY = CurrentY;
1660
    double savedY = mc->CurrentY;
1668
    BBOX bodyBBox, accentBBox;
1661
    BBOX bodyBBox, accentBBox;
1669
    double xoffset, yoffset, width, italic;
1662
    double xoffset, yoffset, width, italic;
1670
    int code;
1663
    int code;
1671
    if (length(expr) != 2)
1664
    if (length(expr) != 2)
1672
	InvalidAccent(expr);
1665
	InvalidAccent(expr);
1673
    accent = CAR(expr);
1666
    accent = CAR(expr);
1674
    body = CADR(expr);
1667
    body = CADR(expr);
1675
    code = AccentCode(accent);
1668
    code = AccentCode(accent);
1676
    if (code == 0)
1669
    if (code == 0)
1677
	InvalidAccent(expr);
1670
	InvalidAccent(expr);
1678
    bodyBBox = RenderElement(body, 0);
1671
    bodyBBox = RenderElement(body, 0, mc, gc, dd);
1679
    italic = bboxItalic(bodyBBox);
1672
    italic = bboxItalic(bodyBBox);
1680
    if (code == 215) /* dotmath */
1673
    if (code == 215) /* dotmath */
1681
	accentBBox = RenderSymbolChar(code, 0);
1674
	accentBBox = RenderSymbolChar(code, 0, mc, gc, dd);
1682
    else
1675
    else
1683
	accentBBox = RenderChar(code, 0);
1676
	accentBBox = RenderChar(code, 0, mc, gc, dd);
1684
    width = max(bboxWidth(bodyBBox) + bboxItalic(bodyBBox),
1677
    width = max(bboxWidth(bodyBBox) + bboxItalic(bodyBBox),
1685
		bboxWidth(accentBBox));
1678
		bboxWidth(accentBBox));
1686
    xoffset = 0.5 *(width - bboxWidth(bodyBBox));
1679
    xoffset = 0.5 *(width - bboxWidth(bodyBBox));
1687
    bodyBBox = RenderGap(xoffset, draw);
1680
    bodyBBox = RenderGap(xoffset, draw, mc, gc, dd);
1688
    bodyBBox = CombineBBoxes(bodyBBox, RenderElement(body, draw));
1681
    bodyBBox = CombineBBoxes(bodyBBox, RenderElement(body, draw, mc, gc, dd));
1689
    bodyBBox = CombineBBoxes(bodyBBox, RenderGap(xoffset, draw));
1682
    bodyBBox = CombineBBoxes(bodyBBox, RenderGap(xoffset, draw, mc, gc, dd));
1690
    PMoveTo(savedX, savedY);
1683
    PMoveTo(savedX, savedY, mc);
1691
    xoffset = 0.5 *(width - bboxWidth(accentBBox))
1684
    xoffset = 0.5 *(width - bboxWidth(accentBBox))
1692
	+ 0.9 * italic;
1685
	+ 0.9 * italic;
1693
    yoffset = bboxHeight(bodyBBox) + bboxDepth(accentBBox) + 0.1 * XHeight();
1686
    yoffset = bboxHeight(bodyBBox) + bboxDepth(accentBBox) + 0.1 * XHeight(gc, dd);
1694
    if (draw) {
1687
    if (draw) {
1695
	PMoveTo(savedX + xoffset, savedY + yoffset);
1688
	PMoveTo(savedX + xoffset, savedY + yoffset, mc);
1696
	if (code == 215) /* dotmath */
1689
	if (code == 215) /* dotmath */
1697
	    RenderSymbolChar(code, draw);
1690
	    RenderSymbolChar(code, draw, mc, gc, dd);
1698
	else
1691
	else
1699
	    RenderChar(code, draw);
1692
	    RenderChar(code, draw, mc, gc, dd);
1700
    }
1693
    }
1701
    bodyBBox = CombineOffsetBBoxes(bodyBBox, 0, accentBBox, 0,
1694
    bodyBBox = CombineOffsetBBoxes(bodyBBox, 0, accentBBox, 0,
1702
				   xoffset, yoffset);
1695
				   xoffset, yoffset);
1703
    PMoveTo(savedX + width, savedY);
1696
    PMoveTo(savedX + width, savedY, mc);
1704
    return bodyBBox;
1697
    return bodyBBox;
1705
}
1698
}
1706
 
1699
 
1707
 
1700
 
1708
/*----------------------------------------------------------------------
1701
/*----------------------------------------------------------------------
Line 1712... Line 1705...
1712
 *  Rules 15, 15a, ..., 15e of the TeXBook
1705
 *  Rules 15, 15a, ..., 15e of the TeXBook
1713
 *
1706
 *
1714
 */
1707
 */
1715
 
1708
 
1716
static void NumDenomVShift(BBOX numBBox, BBOX denomBBox,
1709
static void NumDenomVShift(BBOX numBBox, BBOX denomBBox,
1717
			     double *u, double *v)
1710
			   double *u, double *v,
-
 
1711
			   mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1718
{
1712
{
1719
    double a, delta, phi, theta;
1713
    double a, delta, phi, theta;
1720
    a = TeX(sigma22);
1714
    a = TeX(sigma22, gc, dd);
1721
    theta = TeX(xi8);
1715
    theta = TeX(xi8, gc, dd);
1722
    if(CurrentStyle > STYLE_T) {
1716
    if(mc->CurrentStyle > STYLE_T) {
1723
	*u = TeX(sigma8);
1717
	*u = TeX(sigma8, gc, dd);
1724
	*v = TeX(sigma11);
1718
	*v = TeX(sigma11, gc, dd);
1725
	phi = 3 * theta;
1719
	phi = 3 * theta;
1726
    }
1720
    }
1727
    else {
1721
    else {
1728
	*u = TeX(sigma9);
1722
	*u = TeX(sigma9, gc, dd);
1729
	*v = TeX(sigma12);
1723
	*v = TeX(sigma12, gc, dd);
1730
	phi = theta;
1724
	phi = theta;
1731
    }
1725
    }
1732
    delta = (*u - bboxDepth(numBBox)) - (a + 0.5 * theta);
1726
    delta = (*u - bboxDepth(numBBox)) - (a + 0.5 * theta);
1733
    if (delta < phi)
1727
    if (delta < phi)
1734
	*u += (phi - delta) + theta;
1728
	*u += (phi - delta) + theta;
Line 1750... Line 1744...
1750
	*numShift = (denomWidth - numWidth) / 2;
1744
	*numShift = (denomWidth - numWidth) / 2;
1751
	*denomShift = 0;
1745
	*denomShift = 0;
1752
    }
1746
    }
1753
}
1747
}
1754
 
1748
 
1755
static BBOX RenderFraction(SEXP expr, int rule, int draw)
1749
static BBOX RenderFraction(SEXP expr, int rule, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1756
{
1750
{
1757
    SEXP numerator = CADR(expr);
1751
    SEXP numerator = CADR(expr);
1758
    SEXP denominator = CADDR(expr);
1752
    SEXP denominator = CADDR(expr);
1759
    BBOX numBBox, denomBBox;
1753
    BBOX numBBox, denomBBox;
1760
    double nHShift, dHShift;
1754
    double nHShift, dHShift;
1761
    double nVShift, dVShift;
1755
    double nVShift, dVShift;
1762
    double width, x[2], y[2];
1756
    double width, x[2], y[2];
1763
    double savedX = CurrentX;
1757
    double savedX = mc->CurrentX;
1764
    double savedY = CurrentY;
1758
    double savedY = mc->CurrentY;
1765
    STYLE style;
1759
    STYLE style;
1766
 
1760
 
1767
    style = GetStyle();
1761
    style = GetStyle(mc);
1768
    SetNumStyle(style);
1762
    SetNumStyle(style, mc, gc);
1769
    numBBox = RenderItalicCorr(RenderElement(numerator, 0), 0);
1763
    numBBox = RenderItalicCorr(RenderElement(numerator, 0, mc, gc, dd), 0, mc, gc, dd);
1770
    SetDenomStyle(style);
1764
    SetDenomStyle(style, mc, gc);
1771
    denomBBox = RenderItalicCorr(RenderElement(denominator, 0), 0);
1765
    denomBBox = RenderItalicCorr(RenderElement(denominator, 0, mc, gc, dd), 0, mc, gc, dd);
1772
    SetStyle(style);
1766
    SetStyle(style, mc, gc);
1773
 
1767
 
1774
    width = max(bboxWidth(numBBox), bboxWidth(denomBBox));
1768
    width = max(bboxWidth(numBBox), bboxWidth(denomBBox));
1775
    NumDenomHShift(numBBox, denomBBox, &nHShift, &dHShift);
1769
    NumDenomHShift(numBBox, denomBBox, &nHShift, &dHShift);
1776
    NumDenomVShift(numBBox, denomBBox, &nVShift, &dVShift);
1770
    NumDenomVShift(numBBox, denomBBox, &nVShift, &dVShift, mc, gc, dd);
1777
 
1771
 
1778
    CurrentX = savedX;
1772
    mc->CurrentX = savedX;
1779
    CurrentY = savedY;
1773
    mc->CurrentY = savedY;
1780
    SetNumStyle(style);
1774
    SetNumStyle(style, mc, gc);
1781
    numBBox = RenderOffsetElement(numerator, nHShift, nVShift, draw);
1775
    numBBox = RenderOffsetElement(numerator, nHShift, nVShift, draw, mc, gc, dd);
1782
 
1776
 
1783
    CurrentX = savedX;
1777
    mc->CurrentX = savedX;
1784
    CurrentY = savedY;
1778
    mc->CurrentY = savedY;
1785
    SetDenomStyle(style);
1779
    SetDenomStyle(style, mc, gc);
1786
    denomBBox = RenderOffsetElement(denominator, dHShift, -dVShift, draw);
1780
    denomBBox = RenderOffsetElement(denominator, dHShift, -dVShift, draw, mc, gc, dd);
1787
 
1781
 
1788
    SetStyle(style);
1782
    SetStyle(style, mc, gc);
1789
 
1783
 
1790
    if (draw) {
1784
    if (draw) {
1791
	if (rule) {
1785
	if (rule) {
-
 
1786
	    int savedlty = gc->lty;
-
 
1787
	    double savedlwd = gc->lwd;
1792
	    CurrentX = savedX;
1788
	    mc->CurrentX = savedX;
1793
	    CurrentY = savedY;
1789
	    mc->CurrentY = savedY;
1794
	    PMoveUp(AxisHeight());
1790
	    PMoveUp(AxisHeight(gc, dd), mc);
1795
	    x[0] = ConvertedX();
1791
	    x[0] = ConvertedX(mc, dd);
1796
	    y[0] = ConvertedY();
1792
	    y[0] = ConvertedY(mc, dd);
1797
	    PMoveAcross(width);
1793
	    PMoveAcross(width, mc);
1798
	    x[1] = ConvertedX();
1794
	    x[1] = ConvertedX(mc, dd);
1799
	    y[1] = ConvertedY();
1795
	    y[1] = ConvertedY(mc, dd);
1800
	    GEPolyline(2, x, y, 
1796
	    gc->lty = LTY_SOLID;
-
 
1797
	    gc->lwd = 1;
1801
		  TextColor, MathGamma, LTY_SOLID, 1, MathDevice);
1798
	    GEPolyline(2, x, y, gc, dd);
1802
	    PMoveUp(-AxisHeight());
1799
	    PMoveUp(-AxisHeight(gc, dd), mc);
-
 
1800
	    gc->lty = savedlty;
-
 
1801
	    gc->lwd = savedlwd;
1803
	}
1802
	}
1804
	PMoveTo(savedX + width, savedY);
1803
	PMoveTo(savedX + width, savedY, mc);
1805
    }
1804
    }
1806
    return CombineAlignedBBoxes(numBBox, denomBBox);
1805
    return CombineAlignedBBoxes(numBBox, denomBBox);
1807
}
1806
}
1808
 
1807
 
1809
static int OverAtom(SEXP expr)
1808
static int OverAtom(SEXP expr)
1810
{
1809
{
1811
    return NameAtom(expr) &&
1810
    return NameAtom(expr) &&
1812
	(NameMatch(expr, "over") || NameMatch(expr, "frac"));
1811
	(NameMatch(expr, "over") || NameMatch(expr, "frac"));
1813
}
1812
}
1814
 
1813
 
1815
static BBOX RenderOver(SEXP expr, int draw)
1814
static BBOX RenderOver(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1816
{
1815
{
1817
    return RenderFraction(expr, 1, draw);
1816
    return RenderFraction(expr, 1, draw, mc, gc, dd);
1818
}
1817
}
1819
 
1818
 
1820
static int AtopAtom(SEXP expr)
1819
static int AtopAtom(SEXP expr)
1821
{
1820
{
1822
    return NameAtom(expr) && NameMatch(expr, "atop");
1821
    return NameAtom(expr) && NameMatch(expr, "atop");
1823
}
1822
}
1824
 
1823
 
1825
static BBOX RenderAtop(SEXP expr, int draw)
1824
static BBOX RenderAtop(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1826
{
1825
{
1827
    return RenderFraction(expr, 0, draw);
1826
    return RenderFraction(expr, 0, draw, mc, gc, dd);
1828
}
1827
}
1829
 
1828
 
1830
/*----------------------------------------------------------------------
1829
/*----------------------------------------------------------------------
1831
 *
1830
 *
1832
 *  Code for Grouped Expressions  (e.g. ( ... ))
1831
 *  Code for Grouped Expressions  (e.g. ( ... ))
Line 1875... Line 1874...
1875
    if (code == 0)
1874
    if (code == 0)
1876
	errorcall(expr, "invalid group delimiter");
1875
	errorcall(expr, "invalid group delimiter");
1877
    return code;
1876
    return code;
1878
}
1877
}
1879
 
1878
 
1880
static BBOX RenderDelimiter(int delim, int draw)
1879
static BBOX RenderDelimiter(int delim, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1881
{
1880
{
1882
    BBOX bbox;
1881
    BBOX bbox;
1883
    double savecex = MathCex;
1882
    double savecex = gc->cex;
1884
    MathCex = DelimSymbolMag * MathCex;
1883
    gc->cex = DelimSymbolMag * gc->cex;
1885
    bbox = RenderSymbolChar(delim, draw);
1884
    bbox = RenderSymbolChar(delim, draw, mc, gc, dd);
1886
    MathCex = savecex;
1885
    gc->cex = savecex;
1887
    return bbox;
1886
    return bbox;
1888
}
1887
}
1889
 
1888
 
1890
static int GroupAtom(SEXP expr)
1889
static int GroupAtom(SEXP expr)
1891
{
1890
{
1892
    return NameAtom(expr) && NameMatch(expr, "group");
1891
    return NameAtom(expr) && NameMatch(expr, "group");
1893
}
1892
}
1894
 
1893
 
1895
static BBOX RenderGroup(SEXP expr, int draw)
1894
static BBOX RenderGroup(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1896
{
1895
{
1897
    double cexSaved = MathCex;
1896
    double cexSaved = gc->cex;
1898
    BBOX bbox;
1897
    BBOX bbox;
1899
    int code;
1898
    int code;
1900
    if (length(expr) != 4)
1899
    if (length(expr) != 4)
1901
	errorcall(expr, "invalid group specification");
1900
	errorcall(expr, "invalid group specification");
1902
    bbox = NullBBox();
1901
    bbox = NullBBox();
1903
    code = DelimCode(expr, CADR(expr));
1902
    code = DelimCode(expr, CADR(expr));
1904
    MathCex = DelimSymbolMag * MathCex;
1903
    gc->cex = DelimSymbolMag * gc->cex;
1905
    if (code == 2) {
1904
    if (code == 2) {
1906
	bbox = RenderSymbolChar('|', draw);
1905
	bbox = RenderSymbolChar('|', draw, mc, gc, dd);
1907
	bbox = RenderSymbolChar('|', draw);
1906
	bbox = RenderSymbolChar('|', draw, mc, gc, dd);
1908
    }
1907
    }
1909
    else if (code != '.')
1908
    else if (code != '.')
1910
	bbox = RenderSymbolChar(code, draw);
1909
	bbox = RenderSymbolChar(code, draw, mc, gc, dd);
1911
    MathCex = cexSaved;
1910
    gc->cex = cexSaved;
1912
    bbox = CombineBBoxes(bbox, RenderElement(CADDR(expr), draw));
1911
    bbox = CombineBBoxes(bbox, RenderElement(CADDR(expr), draw, mc, gc, dd));
1913
    bbox = RenderItalicCorr(bbox, draw);
1912
    bbox = RenderItalicCorr(bbox, draw, mc, gc, dd);
1914
    code = DelimCode(expr, CADDDR(expr));
1913
    code = DelimCode(expr, CADDDR(expr));
1915
    MathCex = DelimSymbolMag * MathCex;
1914
    gc->cex = DelimSymbolMag * gc->cex;
1916
    if (code == 2) {
1915
    if (code == 2) {
1917
	bbox = CombineBBoxes(bbox, RenderSymbolChar('|', draw));
1916
	bbox = CombineBBoxes(bbox, RenderSymbolChar('|', draw, mc, gc, dd));
1918
	bbox = CombineBBoxes(bbox, RenderSymbolChar('|', draw));
1917
	bbox = CombineBBoxes(bbox, RenderSymbolChar('|', draw, mc, gc, dd));
1919
    }
1918
    }
1920
    else if (code != '.')
1919
    else if (code != '.')
1921
	bbox = CombineBBoxes(bbox, RenderSymbolChar(code, draw));
1920
	bbox = CombineBBoxes(bbox, RenderSymbolChar(code, draw, mc, gc, dd));
1922
    MathCex = cexSaved;
1921
    gc->cex = cexSaved;
1923
    return bbox;
1922
    return bbox;
1924
}
1923
}
1925
 
1924
 
1926
static int BGroupAtom(SEXP expr)
1925
static int BGroupAtom(SEXP expr)
1927
{
1926
{
1928
    return NameAtom(expr) && NameMatch(expr, "bgroup");
1927
    return NameAtom(expr) && NameMatch(expr, "bgroup");
1929
}
1928
}
1930
 
1929
 
1931
static BBOX RenderDelim(int which, double dist, int draw)
1930
static BBOX RenderDelim(int which, double dist, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
1932
{
1931
{
1933
    double savedX = CurrentX;
1932
    double savedX = mc->CurrentX;
1934
    double savedY = CurrentY;
1933
    double savedY = mc->CurrentY;
1935
    FontType prev = SetFont(SymbolFont);
1934
    FontType prev = SetFont(SymbolFont, gc);
1936
    BBOX ansBBox, topBBox, botBBox, extBBox, midBBox;
1935
    BBOX ansBBox, topBBox, botBBox, extBBox, midBBox;
1937
    int top, bot, ext, mid;
1936
    int top, bot, ext, mid;
1938
    int i, n;
1937
    int i, n;
1939
    double topShift, botShift, extShift, midShift;
1938
    double topShift, botShift, extShift, midShift;
1940
    double ytop, ybot, extHeight, delta;
1939
    double ytop, ybot, extHeight, delta;
1941
    double axisHeight = TeX(sigma22);
1940
    double axisHeight = TeX(sigma22, gc, dd);
1942
 
1941
 
1943
    switch(which) {
1942
    switch(which) {
1944
    case '.': 
1943
    case '.': 
1945
	SetFont(prev);
1944
	SetFont(prev, gc);
1946
	return NullBBox();
1945
	return NullBBox();
1947
	break;
1946
	break;
1948
    case '|':
1947
    case '|':
1949
    case 2:
1948
    case 2:
1950
	top = 239; ext = 239; bot = 239; mid = 0;
1949
	top = 239; ext = 239; bot = 239; mid = 0;
Line 1969... Line 1968...
1969
	break;
1968
	break;
1970
    default:
1969
    default:
1971
	error("group is incomplete");
1970
	error("group is incomplete");
1972
	return ansBBox;/*never reached*/
1971
	return ansBBox;/*never reached*/
1973
    }
1972
    }
1974
    topBBox = GlyphBBox(top);
1973
    topBBox = GlyphBBox(top, gc, dd);
1975
    extBBox = GlyphBBox(ext);
1974
    extBBox = GlyphBBox(ext, gc, dd);
1976
    botBBox = GlyphBBox(bot);
1975
    botBBox = GlyphBBox(bot, gc, dd);
1977
    if (which == '{' || which == '}') {
1976
    if (which == '{' || which == '}') {
1978
	if (1.2 * (bboxHeight(topBBox) + bboxDepth(topBBox)) > dist)
1977
	if (1.2 * (bboxHeight(topBBox) + bboxDepth(topBBox)) > dist)
1979
	    dist = 1.2 * (bboxHeight(topBBox) + bboxDepth(botBBox));
1978
	    dist = 1.2 * (bboxHeight(topBBox) + bboxDepth(botBBox));
1980
    }
1979
    }
1981
    else {
1980
    else {
Line 1988... Line 1987...
1988
    extShift = 0.5 * (bboxHeight(extBBox) - bboxDepth(extBBox));
1987
    extShift = 0.5 * (bboxHeight(extBBox) - bboxDepth(extBBox));
1989
    topBBox = ShiftBBox(topBBox, topShift);
1988
    topBBox = ShiftBBox(topBBox, topShift);
1990
    botBBox = ShiftBBox(botBBox, -botShift);
1989
    botBBox = ShiftBBox(botBBox, -botShift);
1991
    ansBBox = CombineAlignedBBoxes(topBBox, botBBox);
1990
    ansBBox = CombineAlignedBBoxes(topBBox, botBBox);
1992
    if (which == '{' || which == '}') {
1991
    if (which == '{' || which == '}') {
1993
	midBBox = GlyphBBox(mid);
1992
	midBBox = GlyphBBox(mid, gc, dd);
1994
	midShift = axisHeight
1993
	midShift = axisHeight
1995
	    - 0.5 * (bboxHeight(midBBox) - bboxDepth(midBBox));
1994
	    - 0.5 * (bboxHeight(midBBox) - bboxDepth(midBBox));
1996
	midBBox = ShiftBBox(midBBox, midShift);
1995
	midBBox = ShiftBBox(midBBox, midShift);
1997
	ansBBox = CombineAlignedBBoxes(ansBBox, midBBox);
1996
	ansBBox = CombineAlignedBBoxes(ansBBox, midBBox);
1998
	if (draw) {
1997
	if (draw) {
1999
	    PMoveTo(savedX, savedY + topShift);
1998
	    PMoveTo(savedX, savedY + topShift, mc);
2000
	    RenderSymbolChar(top, draw);
1999
	    RenderSymbolChar(top, draw, mc, gc, dd);
2001
	    PMoveTo(savedX, savedY + midShift);
2000
	    PMoveTo(savedX, savedY + midShift, mc);
2002
	    RenderSymbolChar(mid, draw);
2001
	    RenderSymbolChar(mid, draw, mc, gc, dd);
2003
	    PMoveTo(savedX, savedY - botShift);
2002
	    PMoveTo(savedX, savedY - botShift, mc);
2004
	    RenderSymbolChar(bot, draw);
2003
	    RenderSymbolChar(bot, draw, mc, gc, dd);
2005
	    PMoveTo(savedX + bboxWidth(ansBBox), savedY);
2004
	    PMoveTo(savedX + bboxWidth(ansBBox), savedY, mc);
2006
	}
2005
	}
2007
    }
2006
    }
2008
    else {
2007
    else {
2009
	if (draw) {
2008
	if (draw) {
2010
	    /* draw the top and bottom elements */
2009
	    /* draw the top and bottom elements */
2011
	    PMoveTo(savedX, savedY + topShift);
2010
	    PMoveTo(savedX, savedY + topShift, mc);
2012
	    RenderSymbolChar(top, draw);
2011
	    RenderSymbolChar(top, draw, mc, gc, dd);
2013
	    PMoveTo(savedX, savedY - botShift);
2012
	    PMoveTo(savedX, savedY - botShift, mc);
2014
	    RenderSymbolChar(bot, draw);
2013
	    RenderSymbolChar(bot, draw, mc, gc, dd);
2015
	    /* now join with extenders */
2014
	    /* now join with extenders */
2016
	    ytop = axisHeight + dist
2015
	    ytop = axisHeight + dist
2017
		- (bboxHeight(topBBox) + bboxDepth(topBBox));
2016
		- (bboxHeight(topBBox) + bboxDepth(topBBox));
2018
	    ybot = axisHeight - dist
2017
	    ybot = axisHeight - dist
2019
		+ (bboxHeight(botBBox) + bboxDepth(botBBox));
2018
		+ (bboxHeight(botBBox) + bboxDepth(botBBox));
2020
	    n = ceil((ytop - ybot) / (0.99 * extHeight));
2019
	    n = ceil((ytop - ybot) / (0.99 * extHeight));
2021
	    if (n > 0) {
2020
	    if (n > 0) {
2022
		delta = (ytop - ybot) / n;
2021
		delta = (ytop - ybot) / n;
2023
		for (i = 0; i < n; i++) {
2022
		for (i = 0; i < n; i++) {
2024
		    PMoveTo(savedX, savedY + ybot + (i + 0.5) * delta - extShift);
2023
		    PMoveTo(savedX, savedY + ybot + (i + 0.5) * delta - extShift, mc);
2025
		    RenderSymbolChar(ext, draw);
2024
		    RenderSymbolChar(ext, draw, mc, gc, dd);
2026
		}
2025
		}
2027
	    }
2026
	    }
2028
	    PMoveTo(savedX + bboxWidth(ansBBox), savedY);
2027
	    PMoveTo(savedX + bboxWidth(ansBBox), savedY, mc);
2029
 
2028
 
2030
	}
2029
	}
2031
    }
2030
    }
2032
    SetFont(prev);
2031
    SetFont(prev, gc);
2033
    return ansBBox;
2032
    return ansBBox;
2034
}
2033
}
2035
 
2034
 
2036
static BBOX RenderBGroup(SEXP expr, int draw)
2035
static BBOX RenderBGroup(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2037
{
2036
{
2038
    double dist;
2037
    double dist;
2039
    BBOX bbox;
2038
    BBOX bbox;
2040
    double axisHeight = TeX(sigma22);
2039
    double axisHeight = TeX(sigma22, gc, dd);
2041
    double extra = 0.2 * xHeight();
2040
    double extra = 0.2 * xHeight(gc, dd);
2042
    int delim1, delim2;
2041
    int delim1, delim2;
2043
    if (length(expr) != 4)
2042
    if (length(expr) != 4)
2044
	errorcall(expr, "invalid group specification");
2043
	errorcall(expr, "invalid group specification");
2045
    bbox = NullBBox();
2044
    bbox = NullBBox();
2046
    delim1 = DelimCode(expr, CADR(expr));
2045
    delim1 = DelimCode(expr, CADR(expr));
2047
    delim2 = DelimCode(expr, CADDDR(expr));
2046
    delim2 = DelimCode(expr, CADDDR(expr));
2048
    bbox = RenderElement(CADDR(expr), 0);
2047
    bbox = RenderElement(CADDR(expr), 0, mc, gc, dd);
2049
    dist = max(bboxHeight(bbox) - axisHeight, bboxDepth(bbox) + axisHeight);
2048
    dist = max(bboxHeight(bbox) - axisHeight, bboxDepth(bbox) + axisHeight);
2050
    bbox = RenderDelim(delim1, dist + extra, draw);
2049
    bbox = RenderDelim(delim1, dist + extra, draw, mc, gc, dd);
2051
    bbox = CombineBBoxes(bbox,	RenderElement(CADDR(expr), draw));
2050
    bbox = CombineBBoxes(bbox,	RenderElement(CADDR(expr), draw, mc, gc, dd));
2052
    bbox = RenderItalicCorr(bbox, draw);
2051
    bbox = RenderItalicCorr(bbox, draw, mc, gc, dd);
2053
    bbox = CombineBBoxes(bbox,	RenderDelim(delim2, dist + extra, draw));
2052
    bbox = CombineBBoxes(bbox,	RenderDelim(delim2, dist + extra, draw, mc, gc, dd));
2054
    return bbox;
2053
    return bbox;
2055
}
2054
}
2056
 
2055
 
2057
/*----------------------------------------------------------------------
2056
/*----------------------------------------------------------------------
2058
 *
2057
 *
Line 2063... Line 2062...
2063
static int ParenAtom(SEXP expr)
2062
static int ParenAtom(SEXP expr)
2064
{
2063
{
2065
    return NameAtom(expr) && NameMatch(expr, "(");
2064
    return NameAtom(expr) && NameMatch(expr, "(");
2066
}
2065
}
2067
 
2066
 
2068
static BBOX RenderParen(SEXP expr, int draw)
2067
static BBOX RenderParen(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2069
{
2068
{
2070
    BBOX bbox;
2069
    BBOX bbox;
2071
    bbox = RenderDelimiter(S_PARENLEFT, draw);
2070
    bbox = RenderDelimiter(S_PARENLEFT, draw, mc, gc, dd);
2072
    bbox = CombineBBoxes(bbox, RenderElement(CADR(expr), draw));
2071
    bbox = CombineBBoxes(bbox, RenderElement(CADR(expr), draw, mc, gc, dd));
2073
    bbox = RenderItalicCorr(bbox, draw);
2072
    bbox = RenderItalicCorr(bbox, draw, mc, gc, dd);
2074
    return CombineBBoxes(bbox, RenderDelimiter(S_PARENRIGHT, draw));
2073
    return CombineBBoxes(bbox, RenderDelimiter(S_PARENRIGHT, draw, mc, gc, dd));
2075
}
2074
}
2076
 
2075
 
2077
/*----------------------------------------------------------------------
2076
/*----------------------------------------------------------------------
2078
 *
2077
 *
2079
 *  Code for Integral Operators.
2078
 *  Code for Integral Operators.
Line 2084... Line 2083...
2084
{
2083
{
2085
    return NameAtom(expr) && NameMatch(expr, "integral");
2084
    return NameAtom(expr) && NameMatch(expr, "integral");
2086
}
2085
}
2087
 
2086
 
2088
 
2087
 
2089
static BBOX RenderIntSymbol(int draw)
2088
static BBOX RenderIntSymbol(int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2090
{
2089
{
2091
    double savedX = CurrentX;
2090
    double savedX = mc->CurrentX;
2092
    double savedY = CurrentY;
2091
    double savedY = mc->CurrentY;
2093
    if (GetStyle() > STYLE_T) {
2092
    if (GetStyle(mc) > STYLE_T) {
2094
	BBOX bbox1 = RenderSymbolChar(243, 0);
2093
	BBOX bbox1 = RenderSymbolChar(243, 0, mc, gc, dd);
2095
	BBOX bbox2 = RenderSymbolChar(245, 0);
2094
	BBOX bbox2 = RenderSymbolChar(245, 0, mc, gc, dd);
2096
	double shift;
2095
	double shift;
2097
	shift = TeX(sigma22) + 0.99 * bboxDepth(bbox1);
2096
	shift = TeX(sigma22, gc, dd) + 0.99 * bboxDepth(bbox1);
2098
	PMoveUp(shift);
2097
	PMoveUp(shift, mc);
2099
	bbox1 = ShiftBBox(RenderSymbolChar(243, draw), shift);
2098
	bbox1 = ShiftBBox(RenderSymbolChar(243, draw, mc, gc, dd), shift);
2100
	CurrentX = savedX;
2099
	mc->CurrentX = savedX;
2101
	CurrentY = savedY;
2100
	mc->CurrentY = savedY;
2102
	shift = TeX(sigma22) - 0.99 * bboxHeight(bbox2);
2101
	shift = TeX(sigma22, gc, dd) - 0.99 * bboxHeight(bbox2);
2103
	PMoveUp(shift);
2102
	PMoveUp(shift, mc);
2104
	bbox2 = ShiftBBox(RenderSymbolChar(245, draw), shift);
2103
	bbox2 = ShiftBBox(RenderSymbolChar(245, draw, mc, gc, dd), shift);
2105
	if (draw)
2104
	if (draw)
2106
	    PMoveTo(savedX + max(bboxWidth(bbox1), bboxWidth(bbox2)), savedY);
2105
	    PMoveTo(savedX + max(bboxWidth(bbox1), bboxWidth(bbox2)), savedY, mc);
2107
	else
2106
	else
2108
	    PMoveTo(savedX, savedY);
2107
	    PMoveTo(savedX, savedY, mc);
2109
	return CombineAlignedBBoxes(bbox1, bbox2);
2108
	return CombineAlignedBBoxes(bbox1, bbox2);
2110
    }
2109
    }
2111
    else {
2110
    else {
2112
	return RenderSymbolChar(0362, draw);
2111
	return RenderSymbolChar(0362, draw, mc, gc, dd);
2113
    }
2112
    }
2114
}
2113
}
2115
 
2114
 
2116
static BBOX RenderInt(SEXP expr, int draw)
2115
static BBOX RenderInt(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2117
{
2116
{
2118
    BBOX opBBox, lowerBBox, upperBBox, bodyBBox;
2117
    BBOX opBBox, lowerBBox, upperBBox, bodyBBox;
2119
    int nexpr = length(expr);
2118
    int nexpr = length(expr);
2120
    STYLE style = GetStyle();
2119
    STYLE style = GetStyle(mc);
2121
    double savedX = CurrentX;
2120
    double savedX = mc->CurrentX;
2122
    double savedY = CurrentY;
2121
    double savedY = mc->CurrentY;
2123
    double hshift, vshift, width;
2122
    double hshift, vshift, width;
2124
 
2123
 
2125
    opBBox = RenderIntSymbol(draw);
2124
    opBBox = RenderIntSymbol(draw, mc, gc, dd);
2126
    width = bboxWidth(opBBox);
2125
    width = bboxWidth(opBBox);
2127
    CurrentX = savedX;
2126
    mc->CurrentX = savedX;
2128
    CurrentY = savedY;
2127
    mc->CurrentY = savedY;
2129
    if (nexpr > 2) {
2128
    if (nexpr > 2) {
2130
	hshift = 0.5 * width + ThinSpace();
2129
	hshift = 0.5 * width + ThinSpace(gc, dd);
2131
	SetSubStyle(style);
2130
	SetSubStyle(style, mc, gc);
2132
	lowerBBox = RenderElement(CADDR(expr), 0);
2131
	lowerBBox = RenderElement(CADDR(expr), 0, mc, gc, dd);
2133
	vshift = bboxDepth(opBBox) + CenterShift(lowerBBox);
2132
	vshift = bboxDepth(opBBox) + CenterShift(lowerBBox);
2134
	lowerBBox = RenderOffsetElement(CADDR(expr), hshift, -vshift, draw);
2133
	lowerBBox = RenderOffsetElement(CADDR(expr), hshift, -vshift, draw, mc, gc, dd);
2135
	opBBox = CombineAlignedBBoxes(opBBox, lowerBBox);
2134
	opBBox = CombineAlignedBBoxes(opBBox, lowerBBox);
2136
	SetStyle(style);
2135
	SetStyle(style, mc, gc);
2137
	CurrentX = savedX;
2136
	mc->CurrentX = savedX;
2138
	CurrentY = savedY;
2137
	mc->CurrentY = savedY;
2139
    }
2138
    }
2140
    if (nexpr > 3) {
2139
    if (nexpr > 3) {
2141
	hshift = width + ThinSpace();
2140
	hshift = width + ThinSpace(gc, dd);
2142
	SetSupStyle(style);
2141
	SetSupStyle(style, mc, gc);
2143
	upperBBox = RenderElement(CADDDR(expr), 0);
2142
	upperBBox = RenderElement(CADDDR(expr), 0, mc, gc, dd);
2144
	vshift = bboxHeight(opBBox) - CenterShift(upperBBox);
2143
	vshift = bboxHeight(opBBox) - CenterShift(upperBBox);
2145
	upperBBox = RenderOffsetElement(CADDDR(expr), hshift, vshift, draw);
2144
	upperBBox = RenderOffsetElement(CADDDR(expr), hshift, vshift, draw, mc, gc, dd);
2146
	opBBox = CombineAlignedBBoxes(opBBox, upperBBox);
2145
	opBBox = CombineAlignedBBoxes(opBBox, upperBBox);
2147
	SetStyle(style);
2146
	SetStyle(style, mc, gc);
2148
	CurrentX = savedX;
2147
	mc->CurrentX = savedX;
2149
	CurrentY = savedY;
2148
	mc->CurrentY = savedY;
2150
    }
2149
    }
2151
    PMoveAcross(bboxWidth(opBBox));
2150
    PMoveAcross(bboxWidth(opBBox), mc);
2152
    if (nexpr > 1) {
2151
    if (nexpr > 1) {
2153
	bodyBBox = RenderElement(CADR(expr), draw);
2152
	bodyBBox = RenderElement(CADR(expr), draw, mc, gc, dd);
2154
	opBBox = CombineBBoxes(opBBox, bodyBBox);
2153
	opBBox = CombineBBoxes(opBBox, bodyBBox);
2155
    }
2154
    }
2156
    return opBBox;
2155
    return opBBox;
2157
}
2156
}
2158
 
2157
 
Line 2187... Line 2186...
2187
	if (NameMatch(expr, OpTable[i].name))
2186
	if (NameMatch(expr, OpTable[i].name))
2188
	    return OpTable[i].code;
2187
	    return OpTable[i].code;
2189
    return 0;
2188
    return 0;
2190
}
2189
}
2191
 
2190
 
2192
static BBOX RenderOpSymbol(SEXP op, int draw)
2191
static BBOX RenderOpSymbol(SEXP op, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2193
{
2192
{
2194
    BBOX bbox;
2193
    BBOX bbox;
2195
    double cexSaved = MathCex;
2194
    double cexSaved = gc->cex;
2196
    /*double savedX = CurrentX;*/
2195
    /*double savedX = mc->CurrentX;*/
2197
    /*double savedY = CurrentY;*/
2196
    /*double savedY = mc->CurrentY;*/
2198
    double shift;
2197
    double shift;
2199
    int display = (GetStyle() > STYLE_T);
2198
    int display = (GetStyle(mc) > STYLE_T);
2200
    int opId = OpAtom(op);
2199
    int opId = OpAtom(op);
2201
 
2200
 
2202
    if (opId == S_SUM || opId == S_PRODUCT ||
2201
    if (opId == S_SUM || opId == S_PRODUCT ||
2203
	opId == S_UNION || opId == S_INTERSECTION) {
2202
	opId == S_UNION || opId == S_INTERSECTION) {
2204
	if (display) {
2203
	if (display) {
2205
	    MathCex = OperatorSymbolMag * MathCex;
2204
	    gc->cex = OperatorSymbolMag * gc->cex;
2206
	    bbox = RenderSymbolChar(OpAtom(op), 0);
2205
	    bbox = RenderSymbolChar(OpAtom(op), 0, mc, gc, dd);
2207
	    shift = 0.5 * (bboxHeight(bbox) - bboxDepth(bbox)) - TeX(sigma22);
2206
	    shift = 0.5 * (bboxHeight(bbox) - bboxDepth(bbox)) - TeX(sigma22, gc, dd);
2208
	    if (draw) {
2207
	    if (draw) {
2209
		PMoveUp(-shift);
2208
		PMoveUp(-shift, mc);
2210
		bbox = RenderSymbolChar(opId, 1);
2209
		bbox = RenderSymbolChar(opId, 1, mc, gc, dd);
2211
		PMoveUp(shift);
2210
		PMoveUp(shift, mc);
2212
	    }
2211
	    }
2213
	    MathCex = cexSaved;
2212
	    gc->cex = cexSaved;
2214
	    return ShiftBBox(bbox, -shift);
2213
	    return ShiftBBox(bbox, -shift);
2215
	}
2214
	}
2216
	else return RenderSymbolChar(opId, draw);
2215
	else return RenderSymbolChar(opId, draw, mc, gc, dd);
2217
    }
2216
    }
2218
    else {
2217
    else {
2219
	FontType prevfont = SetFont(PlainFont);
2218
	FontType prevfont = SetFont(PlainFont, gc);
2220
	bbox = RenderStr(CHAR(PRINTNAME(op)), draw);
2219
	bbox = RenderStr(CHAR(PRINTNAME(op)), draw, mc, gc, dd);
2221
	SetFont(prevfont);
2220
	SetFont(prevfont, gc);
2222
	return bbox;
2221
	return bbox;
2223
    }
2222
    }
2224
}
2223
}
2225
 
2224
 
2226
static BBOX RenderOp(SEXP expr, int draw)
2225
static BBOX RenderOp(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2227
{
2226
{
2228
    BBOX lowerBBox, upperBBox, bodyBBox;
2227
    BBOX lowerBBox, upperBBox, bodyBBox;
2229
    double savedX = CurrentX;
2228
    double savedX = mc->CurrentX;
2230
    double savedY = CurrentY;
2229
    double savedY = mc->CurrentY;
2231
    int nexpr = length(expr);
2230
    int nexpr = length(expr);
2232
    STYLE style = GetStyle();
2231
    STYLE style = GetStyle(mc);
2233
    BBOX opBBox = RenderOpSymbol(CAR(expr), 0);
2232
    BBOX opBBox = RenderOpSymbol(CAR(expr), 0, mc, gc, dd);
2234
    double width = bboxWidth(opBBox);
2233
    double width = bboxWidth(opBBox);
2235
    double hshift, lvshift, uvshift;
2234
    double hshift, lvshift, uvshift;
2236
    lvshift = uvshift = 0;	/* -Wall */
2235
    lvshift = uvshift = 0;	/* -Wall */
2237
    if (nexpr > 2) {
2236
    if (nexpr > 2) {
2238
	SetSubStyle(style);
2237
	SetSubStyle(style, mc, gc);
2239
	lowerBBox = RenderElement(CADDR(expr), 0);
2238
	lowerBBox = RenderElement(CADDR(expr), 0, mc, gc, dd);
2240
	SetStyle(style);
2239
	SetStyle(style, mc, gc);
2241
	width = max(width, bboxWidth(lowerBBox));
2240
	width = max(width, bboxWidth(lowerBBox));
2242
	lvshift = max(TeX(xi10), TeX(xi12) - bboxHeight(lowerBBox));
2241
	lvshift = max(TeX(xi10, gc, dd), TeX(xi12, gc, dd) - bboxHeight(lowerBBox));
2243
	lvshift = bboxDepth(opBBox) + bboxHeight(lowerBBox) + lvshift;
2242
	lvshift = bboxDepth(opBBox) + bboxHeight(lowerBBox) + lvshift;
2244
    }
2243
    }
2245
    if (nexpr > 3) {
2244
    if (nexpr > 3) {
2246
	SetSupStyle(style);
2245
	SetSupStyle(style, mc, gc);
2247
	upperBBox = RenderElement(CADDDR(expr), 0);
2246
	upperBBox = RenderElement(CADDDR(expr), 0, mc, gc, dd);
2248
	SetStyle(style);
2247
	SetStyle(style, mc, gc);
2249
	width = max(width, bboxWidth(upperBBox));
2248
	width = max(width, bboxWidth(upperBBox));
2250
	uvshift = max(TeX(xi9), TeX(xi11) - bboxDepth(upperBBox));
2249
	uvshift = max(TeX(xi9, gc, dd), TeX(xi11, gc, dd) - bboxDepth(upperBBox));
2251
	uvshift = bboxHeight(opBBox) + bboxDepth(upperBBox) + uvshift;
2250
	uvshift = bboxHeight(opBBox) + bboxDepth(upperBBox) + uvshift;
2252
    }
2251
    }
2253
    hshift = 0.5 * (width - bboxWidth(opBBox));
2252
    hshift = 0.5 * (width - bboxWidth(opBBox));
2254
    opBBox = RenderGap(hshift, draw);
2253
    opBBox = RenderGap(hshift, draw, mc, gc, dd);
2255
    opBBox = CombineBBoxes(opBBox, RenderOpSymbol(CAR(expr), draw));
2254
    opBBox = CombineBBoxes(opBBox, RenderOpSymbol(CAR(expr), draw, mc, gc, dd));
2256
    CurrentX = savedX;
2255
    mc->CurrentX = savedX;
2257
    CurrentY = savedY;
2256
    mc->CurrentY = savedY;
2258
    if (nexpr > 2) {
2257
    if (nexpr > 2) {
2259
	SetSubStyle(style);
2258
	SetSubStyle(style, mc, gc);
2260
	hshift = 0.5 * (width - bboxWidth(lowerBBox));
2259
	hshift = 0.5 * (width - bboxWidth(lowerBBox));
2261
	lowerBBox = RenderOffsetElement(CADDR(expr), hshift, -lvshift, draw);
2260
	lowerBBox = RenderOffsetElement(CADDR(expr), hshift, -lvshift, draw, mc, gc, dd);
2262
	SetStyle(style);
2261
	SetStyle(style, mc, gc);
2263
	opBBox = CombineAlignedBBoxes(opBBox, lowerBBox);
2262
	opBBox = CombineAlignedBBoxes(opBBox, lowerBBox);
2264
	CurrentX = savedX;
2263
	mc->CurrentX = savedX;
2265
	CurrentY = savedY;
2264
	mc->CurrentY = savedY;
2266
    }
2265
    }
2267
    if (nexpr > 3) {
2266
    if (nexpr > 3) {
2268
	SetSupStyle(style);
2267
	SetSupStyle(style, mc, gc);
2269
	hshift = 0.5 * (width - bboxWidth(upperBBox));
2268
	hshift = 0.5 * (width - bboxWidth(upperBBox));
2270
	upperBBox = RenderOffsetElement(CADDDR(expr), hshift, uvshift, draw);
2269
	upperBBox = RenderOffsetElement(CADDDR(expr), hshift, uvshift, draw, mc, gc, dd);
2271
	SetStyle(style);
2270
	SetStyle(style, mc, gc);
2272
	opBBox = CombineAlignedBBoxes(opBBox, upperBBox);
2271
	opBBox = CombineAlignedBBoxes(opBBox, upperBBox);
2273
	CurrentX = savedX;
2272
	mc->CurrentX = savedX;
2274
	CurrentY = savedY;
2273
	mc->CurrentY = savedY;
2275
    }
2274
    }
2276
    opBBox = EnlargeBBox(opBBox, TeX(xi13), TeX(xi13), 0);
2275
    opBBox = EnlargeBBox(opBBox, TeX(xi13, gc, dd), TeX(xi13, gc, dd), 0);
2277
    if (draw)
2276
    if (draw)
2278
	PMoveAcross(width);
2277
	PMoveAcross(width, mc);
2279
    opBBox = CombineBBoxes(opBBox, RenderGap(ThinSpace(), draw));
2278
    opBBox = CombineBBoxes(opBBox, RenderGap(ThinSpace(gc, dd), draw, mc, gc, dd));
2280
    bodyBBox = RenderElement(CADR(expr), draw);
2279
    bodyBBox = RenderElement(CADR(expr), draw, mc, gc, dd);
2281
    return CombineBBoxes(opBBox, bodyBBox);
2280
    return CombineBBoxes(opBBox, bodyBBox);
2282
}
2281
}
2283
 
2282
 
2284
 
2283
 
2285
/*----------------------------------------------------------------------
2284
/*----------------------------------------------------------------------
Line 2301... Line 2300...
2301
    return NameAtom(expr) &&
2300
    return NameAtom(expr) &&
2302
	(NameMatch(expr, "root") ||
2301
	(NameMatch(expr, "root") ||
2303
	 NameMatch(expr, "sqrt"));
2302
	 NameMatch(expr, "sqrt"));
2304
}
2303
}
2305
 
2304
 
2306
static BBOX RenderScript(SEXP expr, int draw)
2305
static BBOX RenderScript(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2307
{
2306
{
2308
    BBOX bbox;
2307
    BBOX bbox;
2309
    STYLE style = GetStyle();
2308
    STYLE style = GetStyle(mc);
2310
    SetSupStyle(style);
2309
    SetSupStyle(style, mc, gc);
2311
    bbox = RenderElement(expr, draw);
2310
    bbox = RenderElement(expr, draw, mc, gc, dd);
2312
    SetStyle(style);
2311
    SetStyle(style, mc, gc);
2313
    return bbox;
2312
    return bbox;
2314
}
2313
}
2315
 
2314
 
2316
static BBOX RenderRadical(SEXP expr, int draw)
2315
static BBOX RenderRadical(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2317
{
2316
{
2318
    SEXP body = CADR(expr);
2317
    SEXP body = CADR(expr);
2319
    SEXP order = CADDR(expr);
2318
    SEXP order = CADDR(expr);
2320
    BBOX bodyBBox, orderBBox;
2319
    BBOX bodyBBox, orderBBox;
2321
    double radWidth, radHeight, radDepth;
2320
    double radWidth, radHeight, radDepth;
2322
    double leadWidth, leadHeight, twiddleHeight;
2321
    double leadWidth, leadHeight, twiddleHeight;
2323
    double hshift, vshift;
2322
    double hshift, vshift;
2324
    double radGap, radSpace, radTrail;
2323
    double radGap, radSpace, radTrail;
2325
    STYLE style = GetStyle();
2324
    STYLE style = GetStyle(mc);
2326
    double savedX = CurrentX;
2325
    double savedX = mc->CurrentX;
2327
    double savedY = CurrentY;
2326
    double savedY = mc->CurrentY;
2328
    double x[5], y[5];
2327
    double x[5], y[5];
2329
 
2328
 
2330
    radGap = RADICAL_GAP * xHeight();
2329
    radGap = RADICAL_GAP * xHeight(gc, dd);
2331
    radSpace = RADICAL_SPACE * xHeight();
2330
    radSpace = RADICAL_SPACE * xHeight(gc, dd);
2332
    radTrail = MuSpace();
2331
    radTrail = MuSpace(gc, dd);
2333
    SetPrimeStyle(style);
2332
    SetPrimeStyle(style, mc, gc);
2334
    bodyBBox = RenderElement(body, 0);
2333
    bodyBBox = RenderElement(body, 0, mc, gc, dd);
2335
    bodyBBox = RenderItalicCorr(bodyBBox, 0);
2334
    bodyBBox = RenderItalicCorr(bodyBBox, 0, mc, gc, dd);
2336
 
2335
 
2337
    radWidth = 0.6 *XHeight();
2336
    radWidth = 0.6 *XHeight(gc, dd);
2338
    radHeight = bboxHeight(bodyBBox) + radGap;
2337
    radHeight = bboxHeight(bodyBBox) + radGap;
2339
    radDepth = bboxDepth(bodyBBox);
2338
    radDepth = bboxDepth(bodyBBox);
2340
    twiddleHeight = CenterShift(bodyBBox);
2339
    twiddleHeight = CenterShift(bodyBBox);
2341
 
2340
 
2342
    leadWidth = radWidth;
2341
    leadWidth = radWidth;
2343
    leadHeight = radHeight;
2342
    leadHeight = radHeight;
2344
    if (order != R_NilValue) {
2343
    if (order != R_NilValue) {
2345
	SetSupStyle(style);
2344
	SetSupStyle(style, mc, gc);
2346
	orderBBox = RenderScript(order, 0);
2345
	orderBBox = RenderScript(order, 0, mc, gc, dd);
2347
	leadWidth = max(leadWidth, bboxWidth(orderBBox) + 0.4 * radWidth);
2346
	leadWidth = max(leadWidth, bboxWidth(orderBBox) + 0.4 * radWidth);
2348
	hshift = leadWidth - bboxWidth(orderBBox) - 0.4 * radWidth;
2347
	hshift = leadWidth - bboxWidth(orderBBox) - 0.4 * radWidth;
2349
	vshift = leadHeight - bboxHeight(orderBBox);
2348
	vshift = leadHeight - bboxHeight(orderBBox);
2350
	if (vshift - bboxDepth(orderBBox) < twiddleHeight + radGap)
2349
	if (vshift - bboxDepth(orderBBox) < twiddleHeight + radGap)
2351
	    vshift = twiddleHeight + bboxDepth(orderBBox) + radGap;
2350
	    vshift = twiddleHeight + bboxDepth(orderBBox) + radGap;
2352
	if (draw) {
2351
	if (draw) {
2353
	    PMoveTo(savedX + hshift, savedY + vshift);
2352
	    PMoveTo(savedX + hshift, savedY + vshift, mc);
2354
	    orderBBox = RenderScript(order, draw);
2353
	    orderBBox = RenderScript(order, draw, mc, gc, dd);
2355
	}
2354
	}
2356
	orderBBox = EnlargeBBox(orderBBox, vshift, 0, hshift);
2355
	orderBBox = EnlargeBBox(orderBBox, vshift, 0, hshift);
2357
    }
2356
    }
2358
    else
2357
    else
2359
	orderBBox = NullBBox();
2358
	orderBBox = NullBBox();
2360
    if (draw) {
2359
    if (draw) {
-
 
2360
	int savedlty = gc->lty;
-
 
2361
	double savedlwd = gc->lwd;
2361
	PMoveTo(savedX + leadWidth - radWidth, savedY);
2362
	PMoveTo(savedX + leadWidth - radWidth, savedY, mc);
2362
	PMoveUp(0.8 * twiddleHeight);
2363
	PMoveUp(0.8 * twiddleHeight, mc);
2363
	x[0] = ConvertedX();
2364
	x[0] = ConvertedX(mc, dd);
2364
	y[0] = ConvertedY();
2365
	y[0] = ConvertedY(mc, dd);
2365
	PMoveUp(0.2 * twiddleHeight);
2366
	PMoveUp(0.2 * twiddleHeight, mc);
2366
	PMoveAcross(0.3 * radWidth);
2367
	PMoveAcross(0.3 * radWidth, mc);
2367
	x[1] = ConvertedX();
2368
	x[1] = ConvertedX(mc, dd);
2368
	y[1] = ConvertedY();
2369
	y[1] = ConvertedY(mc, dd);
2369
	PMoveUp(-(twiddleHeight + bboxDepth(bodyBBox)));
2370
	PMoveUp(-(twiddleHeight + bboxDepth(bodyBBox)), mc);
2370
	PMoveAcross(0.3 * radWidth);
2371
	PMoveAcross(0.3 * radWidth, mc);
2371
	x[2] = ConvertedX();
2372
	x[2] = ConvertedX(mc, dd);
2372
	y[2] = ConvertedY();
2373
	y[2] = ConvertedY(mc, dd);
2373
	PMoveUp(bboxDepth(bodyBBox) + bboxHeight(bodyBBox) + radGap);
2374
	PMoveUp(bboxDepth(bodyBBox) + bboxHeight(bodyBBox) + radGap, mc);
2374
	PMoveAcross(0.4 * radWidth);
2375
	PMoveAcross(0.4 * radWidth, mc);
2375
	x[3] = ConvertedX();
2376
	x[3] = ConvertedX(mc, dd);
2376
	y[3] = ConvertedY();
2377
	y[3] = ConvertedY(mc, dd);
2377
	PMoveAcross(radSpace + bboxWidth(bodyBBox) + radTrail);
2378
	PMoveAcross(radSpace + bboxWidth(bodyBBox) + radTrail, mc);
2378
	x[4] = ConvertedX();
2379
	x[4] = ConvertedX(mc, dd);
2379
	y[4] = ConvertedY();
2380
	y[4] = ConvertedY(mc, dd);
2380
	GEPolyline(5, x, y, 
2381
	gc->lty = LTY_SOLID;
-
 
2382
	gc->lwd = 1;
2381
		  TextColor, MathGamma, LTY_SOLID, 1, MathDevice);
2383
	GEPolyline(5, x, y, gc, dd);
2382
	PMoveTo(savedX, savedY);
2384
	PMoveTo(savedX, savedY, mc);
-
 
2385
	gc->lty = savedlty;
-
 
2386
	gc->lwd = savedlwd;
2383
    }
2387
    }
2384
    orderBBox = CombineAlignedBBoxes(orderBBox,
2388
    orderBBox = CombineAlignedBBoxes(orderBBox,
2385
				     RenderGap(leadWidth + radSpace, draw));
2389
				     RenderGap(leadWidth + radSpace, draw, mc, gc, dd));
2386
    SetPrimeStyle(style);
2390
    SetPrimeStyle(style, mc, gc);
2387
    orderBBox = CombineBBoxes(orderBBox, RenderElement(body, draw));
2391
    orderBBox = CombineBBoxes(orderBBox, RenderElement(body, draw, mc, gc, dd));
2388
    orderBBox = CombineBBoxes(orderBBox, RenderGap(2 * radTrail, draw));
2392
    orderBBox = CombineBBoxes(orderBBox, RenderGap(2 * radTrail, draw, mc, gc, dd));
2389
    orderBBox = EnlargeBBox(orderBBox, radGap, 0, 0);/* << fixes PR#1101 */
2393
    orderBBox = EnlargeBBox(orderBBox, radGap, 0, 0);/* << fixes PR#1101 */
2390
    SetStyle(style);
2394
    SetStyle(style, mc, gc);
2391
    return orderBBox;
2395
    return orderBBox;
2392
}
2396
}
2393
 
2397
 
2394
/*----------------------------------------------------------------------
2398
/*----------------------------------------------------------------------
2395
 *
2399
 *
Line 2400... Line 2404...
2400
static int AbsAtom(SEXP expr)
2404
static int AbsAtom(SEXP expr)
2401
{
2405
{
2402
    return NameAtom(expr) && NameMatch(expr, "abs");
2406
    return NameAtom(expr) && NameMatch(expr, "abs");
2403
}
2407
}
2404
 
2408
 
2405
static BBOX RenderAbs(SEXP expr, int draw)
2409
static BBOX RenderAbs(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2406
{
2410
{
2407
    BBOX bbox = RenderElement(CADR(expr), 0);
2411
    BBOX bbox = RenderElement(CADR(expr), 0, mc, gc, dd);
2408
    double height = bboxHeight(bbox);
2412
    double height = bboxHeight(bbox);
2409
    double depth = bboxDepth(bbox);
2413
    double depth = bboxDepth(bbox);
2410
    double x[2], y[2];
2414
    double x[2], y[2];
2411
 
2415
 
2412
    bbox= RenderGap(MuSpace(), draw);
2416
    bbox= RenderGap(MuSpace(gc, dd), draw, mc, gc, dd);
2413
    if (draw) {
2417
    if (draw) {
-
 
2418
	int savedlty = gc->lty;
-
 
2419
	double savedlwd = gc->lwd;
2414
	PMoveUp(-depth);
2420
	PMoveUp(-depth, mc);
2415
	x[0] = ConvertedX();
2421
	x[0] = ConvertedX(mc, dd);
2416
	y[0] = ConvertedY();
2422
	y[0] = ConvertedY(mc, dd);
2417
	PMoveUp(depth + height);
2423
	PMoveUp(depth + height, mc);
2418
	x[1] = ConvertedX();
2424
	x[1] = ConvertedX(mc, dd);
2419
	y[1] = ConvertedY();
2425
	y[1] = ConvertedY(mc, dd);
2420
	GEPolyline(2, x, y, 
2426
	gc->lty = LTY_SOLID;
-
 
2427
	gc->lwd = 1;
2421
		  TextColor, MathGamma, LTY_SOLID, 1, MathDevice);
2428
	GEPolyline(2, x, y, gc, dd);
2422
	PMoveUp(-height);
2429
	PMoveUp(-height, mc);
-
 
2430
	gc->lty = savedlty;
-
 
2431
	gc->lwd = savedlwd;
2423
    }
2432
    }
2424
    bbox = CombineBBoxes(bbox, RenderGap(MuSpace(), draw));
2433
    bbox = CombineBBoxes(bbox, RenderGap(MuSpace(gc, dd), draw, mc, gc, dd));
2425
    bbox = CombineBBoxes(bbox, RenderElement(CADR(expr), draw));
2434
    bbox = CombineBBoxes(bbox, RenderElement(CADR(expr), draw, mc, gc, dd));
2426
    bbox = RenderItalicCorr(bbox, draw);
2435
    bbox = RenderItalicCorr(bbox, draw, mc, gc, dd);
2427
    bbox = CombineBBoxes(bbox, RenderGap(MuSpace(), draw));
2436
    bbox = CombineBBoxes(bbox, RenderGap(MuSpace(gc, dd), draw, mc, gc, dd));
2428
    if (draw) {
2437
    if (draw) {
-
 
2438
	int savedlty = gc->lty;
-
 
2439
	double savedlwd = gc->lwd;
2429
	PMoveUp(-depth);
2440
	PMoveUp(-depth, mc);
2430
	x[0] = ConvertedX();
2441
	x[0] = ConvertedX(mc, dd);
2431
	y[0] = ConvertedY();
2442
	y[0] = ConvertedY(mc, dd);
2432
	PMoveUp(depth + height);
2443
	PMoveUp(depth + height, mc);
2433
	x[1] = ConvertedX();
2444
	x[1] = ConvertedX(mc, dd);
2434
	y[1] = ConvertedY();
2445
	y[1] = ConvertedY(mc, dd);
2435
	GEPolyline(2, x, y, 
2446
	gc->lty = LTY_SOLID;
-
 
2447
	gc->lwd = 1;
2436
		  TextColor, MathGamma, LTY_SOLID, 1, MathDevice);
2448
	GEPolyline(2, x, y, gc, dd);
2437
	PMoveUp(-height);
2449
	PMoveUp(-height, mc);
-
 
2450
	gc->lty = savedlty;
-
 
2451
	gc->lwd = savedlwd;
2438
    }
2452
    }
2439
    bbox = CombineBBoxes(bbox, RenderGap(MuSpace(), draw));
2453
    bbox = CombineBBoxes(bbox, RenderGap(MuSpace(gc, dd), draw, mc, gc, dd));
2440
    return bbox;
2454
    return bbox;
2441
}
2455
}
2442
 
2456
 
2443
/*----------------------------------------------------------------------
2457
/*----------------------------------------------------------------------
2444
 *
2458
 *
Line 2450... Line 2464...
2450
{
2464
{
2451
    return NameAtom(expr) &&
2465
    return NameAtom(expr) &&
2452
	NameMatch(expr, "{");
2466
	NameMatch(expr, "{");
2453
}
2467
}
2454
 
2468
 
2455
static BBOX RenderCurly(SEXP expr, int draw)
2469
static BBOX RenderCurly(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2456
{
2470
{
2457
    return RenderElement(CADR(expr), draw);
2471
    return RenderElement(CADR(expr), draw, mc, gc, dd);
2458
}
2472
}
2459
 
2473
 
2460
 
2474
 
2461
/*----------------------------------------------------------------------
2475
/*----------------------------------------------------------------------
2462
 *
2476
 *
Line 2507... Line 2521...
2507
	if (NameMatch(expr, RelTable[i].name))
2521
	if (NameMatch(expr, RelTable[i].name))
2508
	    return RelTable[i].code;
2522
	    return RelTable[i].code;
2509
    return 0;
2523
    return 0;
2510
}
2524
}
2511
 
2525
 
2512
static BBOX RenderRel(SEXP expr, int draw)
2526
static BBOX RenderRel(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2513
{
2527
{
2514
    int op = RelAtom(CAR(expr));
2528
    int op = RelAtom(CAR(expr));
2515
    int nexpr = length(expr);
2529
    int nexpr = length(expr);
2516
    BBOX bbox;
2530
    BBOX bbox;
2517
    double gap;
2531
    double gap;
2518
 
2532
 
2519
    if(nexpr == 3) {
2533
    if(nexpr == 3) {
2520
	gap = (CurrentStyle > STYLE_S) ? ThickSpace() : 0;
2534
	gap = (mc->CurrentStyle > STYLE_S) ? ThickSpace(gc, dd) : 0;
2521
	bbox = RenderElement(CADR(expr), draw);
2535
	bbox = RenderElement(CADR(expr), draw, mc, gc, dd);
2522
	bbox = RenderItalicCorr(bbox, draw);
2536
	bbox = RenderItalicCorr(bbox, draw, mc, gc, dd);
2523
	bbox = CombineBBoxes(bbox, RenderGap(gap, draw));
2537
	bbox = CombineBBoxes(bbox, RenderGap(gap, draw, mc, gc, dd));
2524
	bbox = CombineBBoxes(bbox, RenderSymbolChar(op, draw));
2538
	bbox = CombineBBoxes(bbox, RenderSymbolChar(op, draw, mc, gc, dd));
2525
	bbox = CombineBBoxes(bbox, RenderGap(gap, draw));
2539
	bbox = CombineBBoxes(bbox, RenderGap(gap, draw, mc, gc, dd));
2526
	return CombineBBoxes(bbox, RenderElement(CADDR(expr), draw));
2540
	return CombineBBoxes(bbox, RenderElement(CADDR(expr), draw, mc, gc, dd));
2527
    }
2541
    }
2528
    else error("invalid mathematical annotation");
2542
    else error("invalid mathematical annotation");
2529
 
2543
 
2530
    return NullBBox();		/* -Wall */
2544
    return NullBBox();		/* -Wall */
2531
}
2545
}
Line 2541... Line 2555...
2541
{
2555
{
2542
    return NameAtom(expr) &&
2556
    return NameAtom(expr) &&
2543
	NameMatch(expr, "bold");
2557
	NameMatch(expr, "bold");
2544
}
2558
}
2545
 
2559
 
2546
static BBOX RenderBold(SEXP expr, int draw)
2560
static BBOX RenderBold(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2547
{
2561
{
2548
    BBOX bbox;
2562
    BBOX bbox;
2549
    FontType prevfont = SetFont(BoldFont);
2563
    FontType prevfont = SetFont(BoldFont, gc);
2550
    bbox = RenderElement(CADR(expr), draw);
2564
    bbox = RenderElement(CADR(expr), draw, mc, gc, dd);
2551
    SetFont(prevfont);
2565
    SetFont(prevfont, gc);
2552
    return bbox;
2566
    return bbox;
2553
}
2567
}
2554
 
2568
 
2555
/*----------------------------------------------------------------------
2569
/*----------------------------------------------------------------------
2556
 *
2570
 *
Line 2562... Line 2576...
2562
{
2576
{
2563
    return NameAtom(expr) &&
2577
    return NameAtom(expr) &&
2564
	(NameMatch(expr, "italic") || NameMatch(expr, "math"));
2578
	(NameMatch(expr, "italic") || NameMatch(expr, "math"));
2565
}
2579
}
2566
 
2580
 
2567
static BBOX RenderItalic(SEXP expr, int draw)
2581
static BBOX RenderItalic(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2568
{
2582
{
2569
    BBOX bbox;
2583
    BBOX bbox;
2570
    FontType prevfont = SetFont(ItalicFont);
2584
    FontType prevfont = SetFont(ItalicFont, gc);
2571
    bbox = RenderElement(CADR(expr), draw);
2585
    bbox = RenderElement(CADR(expr), draw, mc, gc, dd);
2572
    SetFont(prevfont);
2586
    SetFont(prevfont, gc);
2573
    return bbox;
2587
    return bbox;
2574
}
2588
}
2575
 
2589
 
2576
/*----------------------------------------------------------------------
2590
/*----------------------------------------------------------------------
2577
 *
2591
 *
Line 2583... Line 2597...
2583
{
2597
{
2584
    return NameAtom(expr) &&
2598
    return NameAtom(expr) &&
2585
	NameMatch(expr, "plain");
2599
	NameMatch(expr, "plain");
2586
}
2600
}
2587
 
2601
 
2588
static BBOX RenderPlain(SEXP expr, int draw)
2602
static BBOX RenderPlain(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2589
{
2603
{
2590
    BBOX bbox;
2604
    BBOX bbox;
2591
    int prevfont = SetFont(PlainFont);
2605
    int prevfont = SetFont(PlainFont, gc);
2592
    bbox = RenderElement(CADR(expr), draw);
2606
    bbox = RenderElement(CADR(expr), draw, mc, gc, dd);
2593
    SetFont(prevfont);
2607
    SetFont(prevfont, gc);
2594
    return bbox;
2608
    return bbox;
2595
}
2609
}
2596
 
2610
 
2597
/*----------------------------------------------------------------------
2611
/*----------------------------------------------------------------------
2598
 *
2612
 *
Line 2604... Line 2618...
2604
{
2618
{
2605
    return NameAtom(expr) &&
2619
    return NameAtom(expr) &&
2606
	(NameMatch(expr, "bolditalic") || NameMatch(expr, "boldmath"));
2620
	(NameMatch(expr, "bolditalic") || NameMatch(expr, "boldmath"));
2607
}
2621
}
2608
 
2622
 
2609
static BBOX RenderBoldItalic(SEXP expr, int draw)
2623
static BBOX RenderBoldItalic(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2610
{
2624
{
2611
    BBOX bbox;
2625
    BBOX bbox;
2612
    int prevfont = SetFont(BoldItalicFont);
2626
    int prevfont = SetFont(BoldItalicFont, gc);
2613
    bbox = RenderElement(CADR(expr), draw);
2627
    bbox = RenderElement(CADR(expr), draw, mc, gc, dd);
2614
    SetFont(prevfont);
2628
    SetFont(prevfont, gc);
2615
    return bbox;
2629
    return bbox;
2616
}
2630
}
2617
 
2631
 
2618
/*----------------------------------------------------------------------
2632
/*----------------------------------------------------------------------
2619
 *
2633
 *
Line 2628... Line 2642...
2628
	     NameMatch(expr, "textstyle")    ||
2642
	     NameMatch(expr, "textstyle")    ||
2629
	     NameMatch(expr, "scriptstyle")   ||
2643
	     NameMatch(expr, "scriptstyle")   ||
2630
	     NameMatch(expr, "scriptscriptstyle")));
2644
	     NameMatch(expr, "scriptscriptstyle")));
2631
}
2645
}
2632
 
2646
 
2633
static BBOX RenderStyle(SEXP expr, int draw)
2647
static BBOX RenderStyle(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2634
{
2648
{
2635
    STYLE prevstyle = GetStyle();
2649
    STYLE prevstyle = GetStyle(mc);
2636
    BBOX bbox;
2650
    BBOX bbox;
2637
    if (NameMatch(CAR(expr), "displaystyle"))
2651
    if (NameMatch(CAR(expr), "displaystyle"))
2638
	SetStyle(STYLE_D);
2652
	SetStyle(STYLE_D, mc, gc);
2639
    else if (NameMatch(CAR(expr), "textstyle"))
2653
    else if (NameMatch(CAR(expr), "textstyle"))
2640
	SetStyle(STYLE_T);
2654
	SetStyle(STYLE_T, mc, gc);
2641
    else if (NameMatch(CAR(expr), "scriptstyle"))
2655
    else if (NameMatch(CAR(expr), "scriptstyle"))
2642
	SetStyle(STYLE_S);
2656
	SetStyle(STYLE_S, mc, gc);
2643
    else if (NameMatch(CAR(expr), "scriptscriptstyle"))
2657
    else if (NameMatch(CAR(expr), "scriptscriptstyle"))
2644
	SetStyle(STYLE_SS);
2658
	SetStyle(STYLE_SS, mc, gc);
2645
    bbox = RenderElement(CADR(expr), draw);
2659
    bbox = RenderElement(CADR(expr), draw, mc, gc, dd);
2646
    SetStyle(prevstyle);
2660
    SetStyle(prevstyle, mc, gc);
2647
    return bbox;
2661
    return bbox;
2648
}
2662
}
2649
 
2663
 
2650
/*----------------------------------------------------------------------
2664
/*----------------------------------------------------------------------
2651
 *
2665
 *
Line 2658... Line 2672...
2658
    return (NameAtom(expr) &&
2672
    return (NameAtom(expr) &&
2659
	    (NameMatch(expr, "phantom") ||
2673
	    (NameMatch(expr, "phantom") ||
2660
	     NameMatch(expr, "vphantom")));
2674
	     NameMatch(expr, "vphantom")));
2661
}
2675
}
2662
 
2676
 
2663
static BBOX RenderPhantom(SEXP expr, int draw)
2677
static BBOX RenderPhantom(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2664
{
2678
{
2665
    BBOX bbox = RenderElement(CADR(expr), 0);
2679
    BBOX bbox = RenderElement(CADR(expr), 0, mc, gc, dd);
2666
    if (NameMatch(CAR(expr), "vphantom")) {
2680
    if (NameMatch(CAR(expr), "vphantom")) {
2667
	bboxWidth(bbox) = 0;
2681
	bboxWidth(bbox) = 0;
2668
	bboxItalic(bbox) = 0;
2682
	bboxItalic(bbox) = 0;
2669
    }
2683
    }
2670
    else RenderGap(bboxWidth(bbox), draw);
2684
    else RenderGap(bboxWidth(bbox), draw, mc, gc, dd);
2671
    return bbox;
2685
    return bbox;
2672
}
2686
}
2673
 
2687
 
2674
/*----------------------------------------------------------------------
2688
/*----------------------------------------------------------------------
2675
 *
2689
 *
Line 2680... Line 2694...
2680
static int ConcatenateAtom(SEXP expr)
2694
static int ConcatenateAtom(SEXP expr)
2681
{
2695
{
2682
    return NameAtom(expr) && NameMatch(expr, "paste");
2696
    return NameAtom(expr) && NameMatch(expr, "paste");
2683
}
2697
}
2684
 
2698
 
2685
static BBOX RenderConcatenate(SEXP expr, int draw)
2699
static BBOX RenderConcatenate(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2686
{
2700
{
2687
    BBOX bbox = NullBBox();
2701
    BBOX bbox = NullBBox();
2688
    int i, n;
2702
    int i, n;
2689
 
2703
 
2690
    expr = CDR(expr);
2704
    expr = CDR(expr);
2691
    n = length(expr);
2705
    n = length(expr);
2692
 
2706
 
2693
    for (i = 0; i < n; i++) {
2707
    for (i = 0; i < n; i++) {
2694
	bbox = CombineBBoxes(bbox, RenderElement(CAR(expr), draw));
2708
	bbox = CombineBBoxes(bbox, RenderElement(CAR(expr), draw, mc, gc, dd));
2695
	if (i != n - 1)
2709
	if (i != n - 1)
2696
	    bbox = RenderItalicCorr(bbox, draw);
2710
	    bbox = RenderItalicCorr(bbox, draw, mc, gc, dd);
2697
	expr = CDR(expr);
2711
	expr = CDR(expr);
2698
    }
2712
    }
2699
    return bbox;
2713
    return bbox;
2700
}
2714
}
2701
 
2715
 
Line 2703... Line 2717...
2703
 *
2717
 *
2704
 *  Code for Comma-Separated Lists
2718
 *  Code for Comma-Separated Lists
2705
 *
2719
 *
2706
 */
2720
 */
2707
 
2721
 
2708
static BBOX RenderCommaList(SEXP expr, int draw)
2722
static BBOX RenderCommaList(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2709
{
2723
{
2710
    BBOX bbox = NullBBox();
2724
    BBOX bbox = NullBBox();
2711
    double small = 0.4 * ThinSpace();
2725
    double small = 0.4 * ThinSpace(gc, dd);
2712
    int i, n;
2726
    int i, n;
2713
    n = length(expr);
2727
    n = length(expr);
2714
    for (i = 0; i < n; i++) {
2728
    for (i = 0; i < n; i++) {
2715
	if (NameAtom(CAR(expr)) && NameMatch(CAR(expr), "...")) {
2729
	if (NameAtom(CAR(expr)) && NameMatch(CAR(expr), "...")) {
2716
	    if (i > 0) {
2730
	    if (i > 0) {
2717
		bbox = CombineBBoxes(bbox, RenderSymbolChar(S_COMMA, draw));
2731
		bbox = CombineBBoxes(bbox, RenderSymbolChar(S_COMMA, draw, mc, gc, dd));
2718
		bbox = CombineBBoxes(bbox, RenderSymbolChar(S_SPACE, draw));
2732
		bbox = CombineBBoxes(bbox, RenderSymbolChar(S_SPACE, draw, mc, gc, dd));
2719
	    }
2733
	    }
2720
	    bbox = CombineBBoxes(bbox, RenderSymbolChar(S_ELLIPSIS, draw));
2734
	    bbox = CombineBBoxes(bbox, RenderSymbolChar(S_ELLIPSIS, draw, mc, gc, dd));
2721
	    bbox = CombineBBoxes(bbox, RenderGap(small, draw));
2735
	    bbox = CombineBBoxes(bbox, RenderGap(small, draw, mc, gc, dd));
2722
	}
2736
	}
2723
	else {
2737
	else {
2724
	    if (i > 0) {
2738
	    if (i > 0) {
2725
		bbox = CombineBBoxes(bbox, RenderSymbolChar(S_COMMA, draw));
2739
		bbox = CombineBBoxes(bbox, RenderSymbolChar(S_COMMA, draw, mc, gc, dd));
2726
		bbox = CombineBBoxes(bbox, RenderSymbolChar(S_SPACE, draw));
2740
		bbox = CombineBBoxes(bbox, RenderSymbolChar(S_SPACE, draw, mc, gc, dd));
2727
	    }
2741
	    }
2728
	    bbox = CombineBBoxes(bbox, RenderElement(CAR(expr), draw));
2742
	    bbox = CombineBBoxes(bbox, RenderElement(CAR(expr), draw, mc, gc, dd));
2729
	}
2743
	}
2730
	expr = CDR(expr);
2744
	expr = CDR(expr);
2731
    }
2745
    }
2732
    return bbox;
2746
    return bbox;
2733
}
2747
}
Line 2736... Line 2750...
2736
 *
2750
 *
2737
 *  Code for General Expressions
2751
 *  Code for General Expressions
2738
 *
2752
 *
2739
 */
2753
 */
2740
 
2754
 
2741
static BBOX RenderExpression(SEXP expr, int draw)
2755
static BBOX RenderExpression(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2742
{
2756
{
2743
    BBOX bbox;
2757
    BBOX bbox;
2744
    if (NameAtom(CAR(expr)))
2758
    if (NameAtom(CAR(expr)))
2745
	bbox = RenderSymbolString(CAR(expr), draw);
2759
	bbox = RenderSymbolString(CAR(expr), draw, mc, gc, dd);
2746
    else
2760
    else
2747
	bbox = RenderElement(CAR(expr), draw);
2761
	bbox = RenderElement(CAR(expr), draw, mc, gc, dd);
2748
    bbox = RenderItalicCorr(bbox, draw);
2762
    bbox = RenderItalicCorr(bbox, draw, mc, gc, dd);
2749
    bbox = CombineBBoxes(bbox, RenderDelimiter(S_PARENLEFT, draw));
2763
    bbox = CombineBBoxes(bbox, RenderDelimiter(S_PARENLEFT, draw, mc, gc, dd));
2750
    bbox = CombineBBoxes(bbox, RenderCommaList(CDR(expr), draw));
2764
    bbox = CombineBBoxes(bbox, RenderCommaList(CDR(expr), draw, mc, gc, dd));
2751
    bbox = RenderItalicCorr(bbox, draw);
2765
    bbox = RenderItalicCorr(bbox, draw, mc, gc, dd);
2752
    bbox = CombineBBoxes(bbox, RenderDelimiter(S_PARENRIGHT, draw));
2766
    bbox = CombineBBoxes(bbox, RenderDelimiter(S_PARENRIGHT, draw, mc, gc, dd));
2753
    return bbox;
2767
    return bbox;
2754
}
2768
}
2755
 
2769
 
2756
/*----------------------------------------------------------------------
2770
/*----------------------------------------------------------------------
2757
 *
2771
 *
Line 2762... Line 2776...
2762
static int ListAtom(SEXP expr)
2776
static int ListAtom(SEXP expr)
2763
{
2777
{
2764
    return NameAtom(expr) && NameMatch(expr, "list");
2778
    return NameAtom(expr) && NameMatch(expr, "list");
2765
}
2779
}
2766
 
2780
 
2767
static BBOX RenderList(SEXP expr, int draw)
2781
static BBOX RenderList(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2768
{
2782
{
2769
    return RenderCommaList(CDR(expr), draw);
2783
    return RenderCommaList(CDR(expr), draw, mc, gc, dd);
2770
}
2784
}
2771
 
2785
 
2772
/* Dispatching procedure which determines nature of expression. */
2786
/* Dispatching procedure which determines nature of expression. */
2773
 
2787
 
2774
 
2788
 
2775
static BBOX RenderFormula(SEXP expr, int draw)
2789
static BBOX RenderFormula(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2776
{
2790
{
2777
    SEXP head = CAR(expr);
2791
    SEXP head = CAR(expr);
2778
 
2792
 
2779
    if (SpaceAtom(head))
2793
    if (SpaceAtom(head))
2780
	return RenderSpace(expr, draw);
2794
	return RenderSpace(expr, draw, mc, gc, dd);
2781
    else if (BinAtom(head))
2795
    else if (BinAtom(head))
2782
	return RenderBin(expr, draw);
2796
	return RenderBin(expr, draw, mc, gc, dd);
2783
    else if (SuperAtom(head))
2797
    else if (SuperAtom(head))
2784
	return RenderSup(expr, draw);
2798
	return RenderSup(expr, draw, mc, gc, dd);
2785
    else if (SubAtom(head))
2799
    else if (SubAtom(head))
2786
	return RenderSub(expr, draw);
2800
	return RenderSub(expr, draw, mc, gc, dd);
2787
    else if (WideTildeAtom(head))
2801
    else if (WideTildeAtom(head))
2788
	return RenderWideTilde(expr, draw);
2802
	return RenderWideTilde(expr, draw, mc, gc, dd);
2789
    else if (WideHatAtom(head))
2803
    else if (WideHatAtom(head))
2790
	return RenderWideHat(expr, draw);
2804
	return RenderWideHat(expr, draw, mc, gc, dd);
2791
    else if (BarAtom(head))
2805
    else if (BarAtom(head))
2792
	return RenderBar(expr, draw);
2806
	return RenderBar(expr, draw, mc, gc, dd);
2793
    else if (AccentAtom(head))
2807
    else if (AccentAtom(head))
2794
	return RenderAccent(expr, draw);
2808
	return RenderAccent(expr, draw, mc, gc, dd);
2795
    else if (OverAtom(head))
2809
    else if (OverAtom(head))
2796
	return RenderOver(expr, draw);
2810
	return RenderOver(expr, draw, mc, gc, dd);
2797
    else if (AtopAtom(head))
2811
    else if (AtopAtom(head))
2798
	return RenderAtop(expr, draw);
2812
	return RenderAtop(expr, draw, mc, gc, dd);
2799
    else if (ParenAtom(head))
2813
    else if (ParenAtom(head))
2800
	return RenderParen(expr, draw);
2814
	return RenderParen(expr, draw, mc, gc, dd);
2801
    else if (BGroupAtom(head))
2815
    else if (BGroupAtom(head))
2802
	return RenderBGroup(expr, draw);
2816
	return RenderBGroup(expr, draw, mc, gc, dd);
2803
    else if (GroupAtom(head))
2817
    else if (GroupAtom(head))
2804
	return RenderGroup(expr, draw);
2818
	return RenderGroup(expr, draw, mc, gc, dd);
2805
    else if (IntAtom(head))
2819
    else if (IntAtom(head))
2806
	return RenderInt(expr, draw);
2820
	return RenderInt(expr, draw, mc, gc, dd);
2807
    else if (OpAtom(head))
2821
    else if (OpAtom(head))
2808
	return RenderOp(expr, draw);
2822
	return RenderOp(expr, draw, mc, gc, dd);
2809
    else if (RadicalAtom(head))
2823
    else if (RadicalAtom(head))
2810
	return RenderRadical(expr, draw);
2824
	return RenderRadical(expr, draw, mc, gc, dd);
2811
    else if (AbsAtom(head))
2825
    else if (AbsAtom(head))
2812
	return RenderAbs(expr, draw);
2826
	return RenderAbs(expr, draw, mc, gc, dd);
2813
    else if (CurlyAtom(head))
2827
    else if (CurlyAtom(head))
2814
	return RenderCurly(expr, draw);
2828
	return RenderCurly(expr, draw, mc, gc, dd);
2815
    else if (RelAtom(head))
2829
    else if (RelAtom(head))
2816
	return RenderRel(expr, draw);
2830
	return RenderRel(expr, draw, mc, gc, dd);
2817
    else if (BoldAtom(head))
2831
    else if (BoldAtom(head))
2818
	return RenderBold(expr, draw);
2832
	return RenderBold(expr, draw, mc, gc, dd);
2819
    else if (ItalicAtom(head))
2833
    else if (ItalicAtom(head))
2820
	return RenderItalic(expr, draw);
2834
	return RenderItalic(expr, draw, mc, gc, dd);
2821
    else if (PlainAtom(head))
2835
    else if (PlainAtom(head))
2822
	return RenderPlain(expr, draw);
2836
	return RenderPlain(expr, draw, mc, gc, dd);
2823
    else if (BoldItalicAtom(head))
2837
    else if (BoldItalicAtom(head))
2824
	return RenderBoldItalic(expr, draw);
2838
	return RenderBoldItalic(expr, draw, mc, gc, dd);
2825
    else if (StyleAtom(head))
2839
    else if (StyleAtom(head))
2826
	return RenderStyle(expr, draw);
2840
	return RenderStyle(expr, draw, mc, gc, dd);
2827
    else if (PhantomAtom(head))
2841
    else if (PhantomAtom(head))
2828
	return RenderPhantom(expr, draw);
2842
	return RenderPhantom(expr, draw, mc, gc, dd);
2829
    else if (ConcatenateAtom(head))
2843
    else if (ConcatenateAtom(head))
2830
	return RenderConcatenate(expr, draw);
2844
	return RenderConcatenate(expr, draw, mc, gc, dd);
2831
    else if (ListAtom(head))
2845
    else if (ListAtom(head))
2832
	return RenderList(expr, draw);
2846
	return RenderList(expr, draw, mc, gc, dd);
2833
    else
2847
    else
2834
	return RenderExpression(expr, draw);
2848
	return RenderExpression(expr, draw, mc, gc, dd);
2835
}
2849
}
2836
 
2850
 
2837
 
2851
 
2838
/* Dispatch on whether atom (symbol, string, number, ...) */
2852
/* Dispatch on whether atom (symbol, string, number, ...) */
2839
/* or formula (some sort of expression) */
2853
/* or formula (some sort of expression) */
2840
 
2854
 
2841
static BBOX RenderElement(SEXP expr, int draw)
2855
static BBOX RenderElement(SEXP expr, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2842
{
2856
{
2843
    if (FormulaExpression(expr))
2857
    if (FormulaExpression(expr))
2844
	return RenderFormula(expr, draw);
2858
	return RenderFormula(expr, draw, mc, gc, dd);
2845
    else
2859
    else
2846
	return RenderAtom(expr, draw);
2860
	return RenderAtom(expr, draw, mc, gc, dd);
2847
}
2861
}
2848
 
2862
 
2849
static BBOX RenderOffsetElement(SEXP expr, double x, double y, int draw)
2863
static BBOX RenderOffsetElement(SEXP expr, double x, double y, int draw, mathContext *mc, R_GE_gcontext *gc, GEDevDesc *dd)
2850
{
2864
{
2851
    BBOX bbox;
2865
    BBOX bbox;
2852
    double savedX = CurrentX;
2866
    double savedX = mc->CurrentX;
2853
    double savedY = CurrentY;
2867
    double savedY = mc->CurrentY;
2854
    if (draw) {
2868
    if (draw) {
2855
	CurrentX += x;
2869
	mc->CurrentX += x;
2856
	CurrentY += y;
2870
	mc->CurrentY += y;
2857
    }
2871
    }
2858
    bbox = RenderElement(expr, draw);
2872
    bbox = RenderElement(expr, draw, mc, gc, dd);
2859
    bboxWidth(bbox) += x;
2873
    bboxWidth(bbox) += x;
2860
    bboxHeight(bbox) += y;
2874
    bboxHeight(bbox) += y;
2861
    bboxDepth(bbox) -= y;
2875
    bboxDepth(bbox) -= y;
2862
    CurrentX = savedX;
2876
    mc->CurrentX = savedX;
2863
    CurrentY = savedY;
2877
    mc->CurrentY = savedY;
2864
    return bbox;
2878
    return bbox;
2865
 
2879
 
2866
}
2880
}
2867
 
2881
 
2868
/* Functions forming the R API */
2882
/* Functions forming the R API */
2869
 
2883
 
2870
/* Calculate width of expression */
2884
/* Calculate width of expression */
2871
/* BBOXes are in INCHES (see MetricUnit) */
2885
/* BBOXes are in INCHES (see MetricUnit) */
2872
 
2886
 
2873
double GEExpressionWidth(SEXP expr, 
2887
double GEExpressionWidth(SEXP expr, 
2874
			 int font, double cex, double ps,
2888
			 R_GE_gcontext *gc,
2875
			 GEDevDesc *dd)
2889
			 GEDevDesc *dd)
2876
{
2890
{
2877
    BBOX bbox;
2891
    BBOX bbox;
2878
    double width;
2892
    double width;
-
 
2893
 
-
 
2894
    /*
-
 
2895
     * Build a "drawing context" for the current expression
-
 
2896
     */
2879
    MathDevice = dd;
2897
    mathContext mc;
2880
    BaseCex = cex;
2898
    mc.BaseCex = gc->cex;
-
 
2899
    mc.BoxColor = name2col("pink");
-
 
2900
    mc.CurrentStyle = STYLE_D;
-
 
2901
    /*
-
 
2902
     * Some "empty" values.  Will be filled in after BBox is calc'ed
-
 
2903
     */
-
 
2904
    mc.ReferenceX = 0;
-
 
2905
    mc.ReferenceY = 0;
2881
    MathFont = font;
2906
    mc.CurrentX = 0;
2882
    MathCex = cex;
2907
    mc.CurrentY = 0;
-
 
2908
    mc.CurrentAngle = 0;
2883
    MathPs = ps;
2909
    mc.CosAngle = 0;
2884
    CurrentStyle = STYLE_D;
2910
    mc.SinAngle = 0;
-
 
2911
 
2885
    SetFont(PlainFont);
2912
    SetFont(PlainFont, gc);
2886
    bbox = RenderElement(expr, 0);
2913
    bbox = RenderElement(expr, 0, &mc, gc, dd);
2887
    width  = bboxWidth(bbox);
2914
    width  = bboxWidth(bbox);
2888
    /* 
2915
    /* 
2889
     * NOTE that we do fabs() here in case the device
2916
     * NOTE that we do fabs() here in case the device
2890
     * runs right-to-left.
2917
     * runs right-to-left.
2891
     * This is so that these calculations match those
2918
     * This is so that these calculations match those
Line 2895... Line 2922...
2895
     */
2922
     */
2896
    return fabs(toDeviceWidth(width, GE_INCHES, dd));
2923
    return fabs(toDeviceWidth(width, GE_INCHES, dd));
2897
}
2924
}
2898
 
2925
 
2899
double GEExpressionHeight(SEXP expr, 
2926
double GEExpressionHeight(SEXP expr, 
2900
			  int font, double cex, double ps,
2927
			  R_GE_gcontext *gc,
2901
			  GEDevDesc *dd)
2928
			  GEDevDesc *dd)
2902
{
2929
{
2903
    BBOX bbox;
2930
    BBOX bbox;
2904
    double height;
2931
    double height;
-
 
2932
 
-
 
2933
    /*
-
 
2934
     * Build a "drawing context" for the current expression
-
 
2935
     */
2905
    MathDevice = dd;
2936
    mathContext mc;
2906
    BaseCex = cex;
2937
    mc.BaseCex = gc->cex;
-
 
2938
    mc.BoxColor = name2col("pink");
-
 
2939
    mc.CurrentStyle = STYLE_D;
-
 
2940
    /*
-
 
2941
     * Some "empty" values.  Will be filled in after BBox is calc'ed
-
 
2942
     */
-
 
2943
    mc.ReferenceX = 0;
-
 
2944
    mc.ReferenceY = 0;
2907
    MathFont = font;
2945
    mc.CurrentX = 0;
2908
    MathCex = cex;
2946
    mc.CurrentY = 0;
-
 
2947
    mc.CurrentAngle = 0;
2909
    MathPs = ps;
2948
    mc.CosAngle = 0;
2910
    CurrentStyle = STYLE_D;
2949
    mc.SinAngle = 0;
-
 
2950
 
2911
    SetFont(PlainFont);
2951
    SetFont(PlainFont, gc);
2912
    bbox = RenderElement(expr, 0);
2952
    bbox = RenderElement(expr, 0, &mc, gc, dd);
2913
    height = bboxHeight(bbox) + bboxDepth(bbox);
2953
    height = bboxHeight(bbox) + bboxDepth(bbox);
2914
    /* NOTE that we do fabs() here in case the device
2954
    /* NOTE that we do fabs() here in case the device
2915
     * draws top-to-bottom (like an X11 window).
2955
     * draws top-to-bottom (like an X11 window).
2916
     * This is so that these calculations match those
2956
     * This is so that these calculations match those
2917
     * for string widths and heights, where the width
2957
     * for string widths and heights, where the width
Line 2921... Line 2961...
2921
    return fabs(toDeviceHeight(height, GE_INCHES, dd));
2961
    return fabs(toDeviceHeight(height, GE_INCHES, dd));
2922
}
2962
}
2923
 
2963
 
2924
void GEMathText(double x, double y, SEXP expr,
2964
void GEMathText(double x, double y, SEXP expr,
2925
		double xc, double yc, double rot, 
2965
		double xc, double yc, double rot, 
2926
		int col, double gamma, int font, double cex, double ps,
2966
		R_GE_gcontext *gc,
2927
		GEDevDesc *dd)
2967
		GEDevDesc *dd)
2928
{
2968
{
2929
    BBOX bbox;
2969
    BBOX bbox;
-
 
2970
    mathContext mc;
2930
 
2971
 
2931
#ifdef BUG61
2972
#ifdef BUG61
2932
#else
2973
#else
2933
    /* IF font metric information is not available for device */
2974
    /* IF font metric information is not available for device */
2934
    /* then bail out */
2975
    /* then bail out */
2935
    double ascent, descent, width;
2976
    double ascent, descent, width;
2936
    GEMetricInfo(0, 
2977
    GEMetricInfo(0, gc,
2937
		font, cex, ps,
-
 
2938
		&ascent, &descent, &width, dd);
2978
		&ascent, &descent, &width, dd);
2939
    if ((ascent==0) && (descent==0) && (width==0))
2979
    if ((ascent==0) && (descent==0) && (width==0))
2940
	error("Metric information not yet available for this device");
2980
	error("Metric information not yet available for this device");
2941
#endif
2981
#endif
2942
 
2982
 
-
 
2983
    /*
-
 
2984
     * Build a "drawing context" for the current expression
2943
    MathDevice = dd;
2985
     */
2944
    BaseCex = cex;
2986
    mc.BaseCex = gc->cex;
2945
    BoxColor = name2col("pink");
2987
    mc.BoxColor = name2col("pink");
2946
    TextColor = col;
2988
    mc.CurrentStyle = STYLE_D;
2947
    MathGamma = gamma;
-
 
2948
    /* 
2989
    /*
2949
     * FIXME:  When fontfamily and lineheight are passed to GEMathText
2990
     * Some "empty" values.  Will be filled in after BBox is calc'ed
2950
     * need to use those instead of "" and 1 below
-
 
2951
     */
2991
     */
2952
    MathFontFamily = "";
2992
    mc.ReferenceX = 0;
2953
    MathFont = font;
2993
    mc.ReferenceY = 0;
2954
    MathLineHeight = 1;
2994
    mc.CurrentX = 0;
2955
    MathCex = cex;
2995
    mc.CurrentY = 0;
-
 
2996
    mc.CurrentAngle = 0;
2956
    MathPs = ps;
2997
    mc.CosAngle = 0;
2957
    CurrentStyle = STYLE_D;
2998
    mc.SinAngle = 0;
-
 
2999
 
2958
    SetFont(PlainFont);
3000
    SetFont(PlainFont, gc);
2959
    bbox = RenderElement(expr, 0);
3001
    bbox = RenderElement(expr, 0, &mc, gc, dd);
2960
    ReferenceX = fromDeviceX(x, GE_INCHES, dd);
3002
    mc.ReferenceX = fromDeviceX(x, GE_INCHES, dd);
2961
    ReferenceY = fromDeviceY(y, GE_INCHES, dd);
3003
    mc.ReferenceY = fromDeviceY(y, GE_INCHES, dd);
2962
    if (R_FINITE(xc))
3004
    if (R_FINITE(xc))
2963
	CurrentX = ReferenceX - xc * bboxWidth(bbox);
3005
	mc.CurrentX = mc.ReferenceX - xc * bboxWidth(bbox);
2964
    else
3006
    else
2965
	/* Paul 11/2/02
3007
	/* Paul 11/2/02
2966
	 * If xc == NA then should centre horizontally.
3008
	 * If xc == NA then should centre horizontally.
2967
	 * Used to left-adjust.
3009
	 * Used to left-adjust.
2968
	 */
3010
	 */
2969
	CurrentX = ReferenceX - 0.5 * bboxWidth(bbox);
3011
	mc.CurrentX = mc.ReferenceX - 0.5 * bboxWidth(bbox);
2970
    if (R_FINITE(yc))
3012
    if (R_FINITE(yc))
2971
	CurrentY = ReferenceY + bboxDepth(bbox)
3013
	mc.CurrentY = mc.ReferenceY + bboxDepth(bbox)
2972
	    - yc * (bboxHeight(bbox) + bboxDepth(bbox));
3014
	    - yc * (bboxHeight(bbox) + bboxDepth(bbox));
2973
    else
3015
    else
2974
	/* Paul 11/2/02
3016
	/* Paul 11/2/02
2975
	 * If xc == NA then should centre vertically.
3017
	 * If xc == NA then should centre vertically.
2976
	 * Used to bottom-adjust.
3018
	 * Used to bottom-adjust.
2977
	 */
3019
	 */
2978
	CurrentY = ReferenceY + bboxDepth(bbox)
3020
	mc.CurrentY = mc.ReferenceY + bboxDepth(bbox)
2979
	    - 0.5 * (bboxHeight(bbox) + bboxDepth(bbox));
3021
	    - 0.5 * (bboxHeight(bbox) + bboxDepth(bbox));
2980
    CurrentAngle = rot;
3022
    mc.CurrentAngle = rot;
2981
    rot *= M_PI_2 / 90 ;/* radians */
3023
    rot *= M_PI_2 / 90 ;/* radians */
2982
    CosAngle = cos(rot);
3024
    mc.CosAngle = cos(rot);
2983
    SinAngle = sin(rot);
3025
    mc.SinAngle = sin(rot);
2984
    RenderElement(expr, 1);
3026
    RenderElement(expr, 1, &mc, gc, dd);
2985
}/* GMathText */
3027
}/* GMathText */
2986
 
3028
 
2987
 
3029
 
2988
/********************************
3030
/********************************
2989
 * Code below here ...
3031
 * Code below here ...
Line 2991... Line 3033...
2991
 * ... is part of the base graphics API NOT the graphics engine API
3033
 * ... is part of the base graphics API NOT the graphics engine API
2992
 ********************************
3034
 ********************************
2993
 */
3035
 */
2994
double GExpressionWidth(SEXP expr, GUnit units, DevDesc *dd)
3036
double GExpressionWidth(SEXP expr, GUnit units, DevDesc *dd)
2995
{
3037
{
-
 
3038
    R_GE_gcontext gc;
2996
    double width = GEExpressionWidth(expr, 
3039
    double width; 
2997
				     Rf_gpptr(dd)->font, Rf_gpptr(dd)->cex, 
3040
    gcontextFromGP(&gc, dd);
2998
				     Rf_gpptr(dd)->ps, (GEDevDesc*) dd);
3041
    width = GEExpressionWidth(expr, &gc, (GEDevDesc*) dd);
2999
    if (units == DEVICE)
3042
    if (units == DEVICE)
3000
	return width;
3043
	return width;
3001
    else
3044
    else
3002
	return GConvertXUnits(width, DEVICE, units, dd);
3045
	return GConvertXUnits(width, DEVICE, units, dd);
3003
}
3046
}
3004
 
3047
 
3005
double GExpressionHeight(SEXP expr, GUnit units, DevDesc *dd)
3048
double GExpressionHeight(SEXP expr, GUnit units, DevDesc *dd)
3006
{
3049
{
-
 
3050
    R_GE_gcontext gc;
3007
    double height = GEExpressionHeight(expr, 
3051
    double height;
3008
				       Rf_gpptr(dd)->font, Rf_gpptr(dd)->cex, 
3052
    gcontextFromGP(&gc, dd);
3009
				       Rf_gpptr(dd)->ps, (GEDevDesc*) dd);
3053
    height = GEExpressionHeight(expr, &gc, (GEDevDesc*) dd);
3010
    if (units == DEVICE)
3054
    if (units == DEVICE)
3011
	return height;
3055
	return height;
3012
    else
3056
    else
3013
	return GConvertYUnits(height, DEVICE, units, dd);
3057
	return GConvertYUnits(height, DEVICE, units, dd);
3014
}
3058
}
Line 3023... Line 3067...
3023
 */
3067
 */
3024
void GMathText(double x, double y, int coords, SEXP expr,
3068
void GMathText(double x, double y, int coords, SEXP expr,
3025
	       double xc, double yc, double rot, 
3069
	       double xc, double yc, double rot, 
3026
	       DevDesc *dd)
3070
	       DevDesc *dd)
3027
{
3071
{
-
 
3072
    R_GE_gcontext gc;
-
 
3073
    gcontextFromGP(&gc, dd);
3028
    GConvert(&x, &y, coords, DEVICE, dd);
3074
    GConvert(&x, &y, coords, DEVICE, dd);
3029
    GClip(dd);
3075
    GClip(dd);
3030
    GEMathText(x, y, expr, xc, yc, rot, 
3076
    GEMathText(x, y, expr, xc, yc, rot, &gc, (GEDevDesc*) dd);
3031
	       Rf_gpptr(dd)->col, Rf_gpptr(dd)->gamma, Rf_gpptr(dd)->font,
-
 
3032
	       Rf_gpptr(dd)->cex, Rf_gpptr(dd)->ps, (GEDevDesc*) dd);
-
 
3033
}
3077
}
3034
 
3078
 
3035
void GMMathText(SEXP str, int side, double line, int outer,
3079
void GMMathText(SEXP str, int side, double line, int outer,
3036
		double at, int las, DevDesc *dd)
3080
		double at, int las, DevDesc *dd)
3037
{
3081
{
Line 3046... Line 3090...
3046
    GMetricInfo(0, &ascent, &descent, &width, DEVICE, dd);
3090
    GMetricInfo(0, &ascent, &descent, &width, DEVICE, dd);
3047
    if ((ascent==0) && (descent==0) && (width==0))
3091
    if ((ascent==0) && (descent==0) && (width==0))
3048
	error("Metric information not yet available for this device");
3092
	error("Metric information not yet available for this device");
3049
#endif
3093
#endif
3050
 
3094
 
3051
    MathDevice = (GEDevDesc*) dd;
-
 
3052
 
-
 
3053
    xadj = Rf_gpptr(dd)->adj;
3095
    xadj = Rf_gpptr(dd)->adj;
3054
 
3096
 
3055
    /* This is MOSTLY the same as the same section of GMtext
3097
    /* This is MOSTLY the same as the same section of GMtext
3056
     * BUT it differs because it sets different values for yadj for
3098
     * BUT it differs because it sets different values for yadj for
3057
     * different situations.
3099
     * different situations.
Line 3135... Line 3177...
3135
	    angle = 90;
3177
	    angle = 90;
3136
	    yadj = 0;
3178
	    yadj = 0;
3137
	}
3179
	}
3138
	break;
3180
	break;
3139
    }
3181
    }
3140
    GConvert(&at, &line, coords, DEVICE, dd);
-
 
3141
    /* The graphics engine (unlike graphics.c code) knows nothing about
-
 
3142
     * xpd settings (that is a base graphics system concept), hence
-
 
3143
     * the graphics engine does not call GClip.  So we must call GClip
-
 
3144
     * here to make sure that the current xpd setting is enforced
-
 
3145
     * on the device.
-
 
3146
     */
-
 
3147
    GClip(dd);
-
 
3148
    GEMathText(at, line, str, xadj, yadj, angle, 
3182
    GMathText(at, line, coords, str, xadj, yadj, angle, dd);
3149
	       Rf_gpptr(dd)->col, Rf_gpptr(dd)->gamma, Rf_gpptr(dd)->font,
-
 
3150
	       Rf_gpptr(dd)->cex, Rf_gpptr(dd)->ps, (GEDevDesc*) dd);
-
 
3151
}/* GMMathText */
3183
}/* GMMathText */