~ubuntu-branches/ubuntu/maverick/ploticus/maverick

« back to all changes in this revision

Viewing changes to src/pcode.c

  • Committer: Bazaar Package Importer
  • Author(s): James W. Penny
  • Date: 2002-04-10 23:02:04 UTC
  • Revision ID: james.westby@ubuntu.com-20020410230204-64em4ns2f57c5u3l
Tags: 2.0.3-1
* The "That Tears it, Now You Have to Update Docs Package" Release.
* New upstream release (well, not so new :-( )   closes: Bug#137578
* Correct missing libpng2-dev in build-depends.  closes: Bug#142205
* Use correct syntax to:
* close URL type.                                closes: Bug#137577
* fix Architecture                               closes: Bug#141657
* close ITP                                      closes: Bug#132878

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* ploticus data display engine.  Software, documentation, and examples.  
 
2
 * Copyright 1998-2002 Stephen C. Grubb  (scg@jax.org).
 
3
 * Covered by GPL; see the file ./Copyright for details. */
 
4
 
 
5
/* PCODE - all text/graphics requests (except init) are processed
 
6
                via this function.  Many E function calls such
 
7
                as Emov and Elin are actually macros defined in
 
8
                elib.d, which call pcode with a single character
 
9
                op code and perhaps some parameters.
 
10
 
 
11
   ==========================================================================
 
12
   Device codes (Edev):
 
13
        p               postscript
 
14
        x               X11
 
15
 
 
16
   Op codes:
 
17
        L               lineto
 
18
        M               moveto
 
19
        P               path to
 
20
        T, C, J         text, centered text, right justified text
 
21
        r               set current color 
 
22
        s               Fill (color)
 
23
        c               closepath (ps only)
 
24
        O               paper (ps only)
 
25
        I               text size
 
26
        F               text font 
 
27
        D               text direction (ps only)
 
28
        Y               line properties
 
29
        Z               print/eject (ps only)
 
30
        W               wait for a key or mouse click (x11 only)
 
31
        w               cycle notifier from within a loop (x11 only)
 
32
        .               dot
 
33
        z               clear screen (x11 only)
 
34
        d               make window disappear (x11 only)
 
35
        a               make window re-appear (x11 only)
 
36
        e               set text scale factor (x11 only, when user resizes window)
 
37
        Q               end of file (tells ps and gif drivers to wrap up)
 
38
 
 
39
        b               save window to backing store (x11 only)
 
40
        B               restore window from backing store (x11 only)
 
41
 
 
42
 
 
43
   ==========================================================================
 
44
 
 
45
*/
 
46
 
 
47
#include "graphcore.h"
 
48
#ifdef PLOTICUS
 
49
  extern int Debug;
 
50
  extern FILE *Diagfp;
 
51
#endif
 
52
 
 
53
static int Enew = 0, Edrawing = 0;              /* used by postscript section */
 
54
static int Evertchar = 0;                       /* true if character direction is vertical..*/
 
55
                                                /* ..used only by x11 */
 
56
static double Ecurx;                            /* real starting place of centered &rt justified text */
 
57
static double Ewidth;                           /* width of most recently drawn text line. */
 
58
static char Eprevop;                            /* previous op */
 
59
static int Esquelched = 0;                      /* is output being squelched? 1=yes, 0=no */
 
60
static int Epspage = 1;                 /* current page # */
 
61
static int Epsvirginpage = 1;           /* 1 when nothing has yet been drawn on current page */
 
62
 
 
63
static int Ekeeping_bb = 1;
 
64
                                        
 
65
static double EBBx1 = 999;              /* coords of bounding box for entire run */
 
66
static double EBBy1 = 999;
 
67
static double EBBx2 = -999;
 
68
static double EBBy2 = -999;
 
69
 
 
70
static double Esbb_x1 = 999;            /* coords of "sub" bounding box available to app */
 
71
static double Esbb_y1 = 999;
 
72
static double Esbb_x2 = -999;
 
73
static double Esbb_y2 = -999;
 
74
static int keep_sub_bb = 0;
 
75
static int tightbb = 0;
 
76
static double scx1, scy1, scx2, scy2;   /* specified crop zone */
 
77
static int specifycrop = 0; /* 0 = no  1 = absolute values   2 = values relative to bounding box */
 
78
 
 
79
static double globalscale = 1.0;
 
80
static double globalscaley = 1.0;
 
81
static double posterxo = 0.0;
 
82
static double posteryo = 0.0;
 
83
static int postermode = 0;
 
84
static double lmlx = 0.0, lmly = 0.0;  /* last move local x and y  
 
85
        (saves location of last 'MOVE', including any effects of globalscale and poster ofs */
 
86
static int pcodedebug = 0;
 
87
static FILE *pcodedebugfp = 0;
 
88
 
 
89
 
 
90
/* ======================= */
 
91
Epcode( op, x, y, s )
 
92
char op; /* op code */
 
93
double x, y;  /* coordinates */
 
94
char s[];     /* optional character string */
 
95
{
 
96
char buf[512];
 
97
 
 
98
/* Postscript: inform driver we're beginning a new page.. */
 
99
if( Edev == 'p' && Epsvirginpage && !GL_member( op, "Q" ) ) {
 
100
        EPSnewpage( Epspage );
 
101
        Epsvirginpage = 0;
 
102
        }
 
103
 
 
104
 
 
105
/* For clear op: do it then return; don't include in bounding box calculations */
 
106
if( op == 'z' ) {
 
107
        Ekeeping_bb = 0;
 
108
        /* compensate EWinw and EWiny by globalscale because this op will
 
109
                be doubly affected by globalscale.. */
 
110
        Ecblock( 0.0, 0.0, EWinx/globalscale, EWiny/globalscaley, s, 0 );  
 
111
        Ekeeping_bb = 1;
 
112
        return( 0 );
 
113
        }
 
114
 
 
115
 
 
116
 
 
117
if( op == 'M' ) { Ex1 = x; Ey1 = y; } /* remember most recent 'move', untainted 
 
118
                                        by globalscale or posterofs.. */
 
119
 
 
120
/* scale x, y according to global scale, for all move, draw and text size ops */
 
121
if( globalscale != 1.0 ) {
 
122
        if( GL_member( op, "LMPI" )) { x *= globalscale; y *= globalscaley; }
 
123
        if( op == 'Y' ) y *= globalscale; /* dash scale */
 
124
        }
 
125
 
 
126
/* if poster offset specified, translate */
 
127
if( postermode ) {
 
128
        if( GL_member( Edev, "pcx" ) && GL_member( op, "LMP" )) { 
 
129
                x += posterxo; 
 
130
                y += posteryo; 
 
131
                }
 
132
        }
 
133
 
 
134
if( Debug && op == 'Q' ) 
 
135
        fprintf( Diagfp, "Done with page.  Writing out result file.  Computed bounding box is: %-5.2f, %-5.2f to %-5.2f, %-5.2f\n", EBBx1, EBBy1, EBBx2, EBBy2 );
 
136
        
 
137
 
 
138
/* device interfaces ======================== */
 
139
 
 
140
/* if output is squelched, do not do any draw operations, except textsize, which
 
141
   returns text width, which is necessary for bb calculations.. */
 
142
if( Esquelched ) {
 
143
        if( op == 'I' ) {
 
144
#ifndef NOX11
 
145
                if( Edev == 'x' ) { EXWpointsize( (int)(x), &Ecurtextwidth ); }
 
146
#endif
 
147
                }
 
148
        }
 
149
 
 
150
 
 
151
/* interface to X11 xlib driver.. */
 
152
else if( Edev == 'x' ) {
 
153
#ifndef NOX11
 
154
        switch (op) {
 
155
                case 'L' : EXWlineto( x, y ); break;
 
156
                case 'M' : EXWmoveto( x, y ); break;
 
157
                case 'P' : EXWpath( x, y ); break;
 
158
                case 'T' : if( !Evertchar ) EXWtext( s, &Ewidth ); 
 
159
                           break;
 
160
                case 'r' : EXWcolor( s ); return( 0 );
 
161
                case 's' : EXWfill( ); return( 0 );
 
162
                case 'U' : EXWflush(); return( 0 );
 
163
                case 'b' : EXWsavewin(); return( 0 );
 
164
                case 'B' : EXWrestorewin(); return( 0 );
 
165
                case 'I' : EXWpointsize( (int)(x), &Ecurtextwidth ); return( 0 );
 
166
                case 'C' : if( !Evertchar ) { 
 
167
                                EXWmoveto( lmlx-6.0, lmly ); 
 
168
                                EXWcentext( s, 12.0, &Ecurx, &Ewidth ); 
 
169
                                }
 
170
                           break;
 
171
                case 'J' : if( !Evertchar ) {
 
172
                                EXWmoveto( lmlx-12.0, lmly ); 
 
173
                                EXWrightjust( s, 12.0, &Ecurx, &Ewidth );
 
174
                                }
 
175
                           break;
 
176
                case 'W' : EXWwait(); return( 0 );
 
177
                case 'Y' : EXWlinetype( s, x, y ); return( 0 );
 
178
                case 'D' : if( x == 90 || x == 270 ) Evertchar = 1;
 
179
                           else Evertchar = 0;
 
180
                           return( 0 );
 
181
                        
 
182
                case 'w' : EXWasync(); return( 0 );
 
183
                case '.' : EXWdot( x, y ); break;
 
184
                case 'd' : EXWdisappear(); return( 0 );
 
185
                case 'a' : EXWappear(); return( 0 );
 
186
                case 'e' : EXWscaletext( x ); return( 0 );
 
187
                }
 
188
#endif
 
189
        }
 
190
else
 
191
 
 
192
/* interface to postscript driver */
 
193
if( Edev == 'p'  ) {
 
194
 
 
195
        if( op != 'L' ) { 
 
196
                if( Edrawing ) EPSstroke(); 
 
197
                Edrawing = 0;
 
198
                }
 
199
 
 
200
        switch( op ) {
 
201
                case 'L' : if( Enew ) EPSmoveto( lmlx, lmly ); 
 
202
                            EPSlineto( x, y );
 
203
                            Enew = 0;
 
204
                            Edrawing = 1;
 
205
                            break;
 
206
                case 'M' : Enew = 1; break;
 
207
                case 'P' : if( Enew ) EPSmoveto( lmlx, lmly ); 
 
208
                           EPSpath( x, y ); 
 
209
                           Enew = 0;
 
210
                           break;
 
211
                case 'T' : EPStext( op, lmlx, lmly, s, 0.0 ); break;
 
212
        
 
213
                case 'C' : if( !Evertchar ) EPStext( op, lmlx - 6.0, lmly, s, 12.0 );
 
214
                           else if( Evertchar )EPStext( op, lmlx, lmly - 6.0, s, 12.0 );
 
215
                           break;
 
216
                case 'J' : if( !Evertchar ) EPStext( op, lmlx-12.0, lmly, s, 12.0 );
 
217
                           else if( Evertchar ) EPStext( op, lmlx, lmly - 12.0, s, 12.0 );
 
218
                           break;
 
219
        
 
220
                case 's' : EPSfill( ); return( 0 );
 
221
                case 'r' : EPScolor( s ); return( 0 );
 
222
                case 'c' : EPSclosepath(); return( 0 );
 
223
                case 'O' : EPSpaper( (int)x ); return( 0 );
 
224
                case 'I' : EPSpointsize( (int)x ); return( 0 );
 
225
                case 'F' : EPSfont( s ); return( 0 );
 
226
                case 'D' : EPSchardir( (int)x );
 
227
                           if( x == 90 || x == 270 ) Evertchar = 1;
 
228
                           else Evertchar = 0;
 
229
                           return( 0 );
 
230
                case 'Y' : EPSlinetype( s, x, y ); return( 0 );
 
231
                case 'Z' : EPSshow(); Epspage++; Epsvirginpage = 1; return( 0 );
 
232
                case 'Q' : if( !Epsvirginpage ) { EPSshow(); Epspage++; }
 
233
                           if( tightbb ) 
 
234
                             EPStrailer( Epspage - 1, EBBx1-0.05, EBBy1-0.05, EBBx2+0.05, EBBy2+0.05 );
 
235
                           else if( specifycrop == 1 )
 
236
                             EPStrailer( Epspage - 1, scx1, scy1, scx2, scy2 );
 
237
                           else if( specifycrop == 2 ) {
 
238
                             EPStrailer( Epspage - 1, (EBBx1-0.05)-scx1, (EBBy1-0.05)-scy1, 
 
239
                                                        (EBBx2+0.05)+scx2, (EBBy2+0.05)+scy2 );
 
240
                                }
 
241
                           else 
 
242
                             /* add 0.2" margin to be generous in cases of fat lines, etc. */
 
243
                             EPStrailer( Epspage - 1, EBBx1-0.2, EBBy1-0.2, EBBx2+0.2, EBBy2+0.2 );
 
244
                           Eresetbb();
 
245
                           return( 0 );
 
246
                /* case '.' : EPSdot( x, y ); ??? */
 
247
                }
 
248
        }
 
249
 
 
250
/* Added for svg support - BT 05/11/01 */
 
251
/* interface to svg driver */
 
252
else if( Edev == 's'  ) {
 
253
 
 
254
        if( op != 'L' ) { 
 
255
                if( Edrawing ) SVGstroke(); 
 
256
                Edrawing = 0;
 
257
                }
 
258
 
 
259
        switch( op ) {
 
260
                case 'L' : if( Enew ) SVGmoveto( lmlx, lmly ); 
 
261
                            SVGlineto( x, y );
 
262
                            Enew = 0;
 
263
                            Edrawing = 1;
 
264
                            break;
 
265
                case 'M' : Enew = 1; break;
 
266
                case 'P' : if( Enew ) SVGmoveto( lmlx, lmly ); 
 
267
                           SVGpath( x, y ); 
 
268
                           Enew = 0;
 
269
                           break;
 
270
        
 
271
                case 'T' : SVGtext( op, lmlx, lmly, s, 0.0 ); break;
 
272
        
 
273
                case 'C' : if( !Evertchar ) SVGtext( op, lmlx , lmly, s, 0.0 );
 
274
                           else if( Evertchar )SVGtext( op, lmlx, lmly , s, 0.0 );
 
275
                           break;
 
276
                case 'J' : if( !Evertchar ) SVGtext( op, lmlx, lmly, s, 0.0 );
 
277
                           else if( Evertchar ) SVGtext( op, lmlx, lmly , s, 0.0 );
 
278
                           break;
 
279
 
 
280
                case 's' : SVGfill( ); return( 0 );
 
281
                case 'r' : SVGcolor( s ); return( 0 );
 
282
                case 'c' : SVGclosepath(); return( 0 );
 
283
                case 'O' : SVGpaper( (int)x ); return( 0 );
 
284
                case 'I' : SVGpointsize( (int)x ); return( 0 );
 
285
                case 'F' : SVGfont( s ); return( 0 );
 
286
                case 'D' : SVGchardir( (int)x );
 
287
                           if( x == 90 || x == 270 ) Evertchar = 1;
 
288
                           else Evertchar = 0;
 
289
                           return( 0 );
 
290
                case 'Y' : SVGlinetype( s, x, y ); return( 0 );
 
291
                case 'Z' : SVGshow(); Epspage++; Epsvirginpage = 1; return( 0 );
 
292
                case 'Q' : if( !Epsvirginpage ) { SVGshow(); Epspage++; }
 
293
                           if( tightbb ) 
 
294
                             SVGtrailer( Epspage - 1, EBBx1-0.05, EBBy1-0.05, EBBx2+0.05, EBBy2+0.05 );
 
295
                           else if( specifycrop == 1 )
 
296
                             SVGtrailer( Epspage - 1, scx1, scy1, scx2, scy2 );
 
297
                           else if( specifycrop == 2 ) {
 
298
                             SVGtrailer( Epspage - 1, (EBBx1-0.05)-scx1, (EBBy1-0.05)-scy1, 
 
299
                                                        (EBBx2+0.05)+scx2, (EBBy2+0.05)+scy2 );
 
300
                                }
 
301
                           else 
 
302
                             /* add 0.2" margin to be generous in cases of fat lines, etc. */
 
303
                             SVGtrailer( Epspage - 1, EBBx1-0.2, EBBy1-0.2, EBBx2+0.2, EBBy2+0.2 );
 
304
                           Eresetbb();
 
305
                           return( 0 );
 
306
                }
 
307
        }
 
308
 
 
309
/* interface to GD driver.. */
 
310
else if( Edev == 'g' ) {
 
311
#ifndef NOGD
 
312
        switch (op) {
 
313
                case 'L' : EGlineto( x, y ); break;
 
314
                case 'M' : EGmoveto( x, y ); break;
 
315
                case 'P' : EGpathto( x, y ); break;
 
316
                case 'T' : EGtext( s ); break; 
 
317
                case 'C' : EGcentext( s ); break; 
 
318
                case 'F' : EGfont( s ); break;
 
319
                case 'J' : EGrightjust( s ); break; 
 
320
                case 's' : EGfill(); return( 0 );
 
321
                case 'r' : EGcolor( s ); return( 0 );
 
322
                case 'I' : EGtextsize( (int)x ); return( 0 );
 
323
                case 'D' : EGchardir( (int)x ); 
 
324
                           if( (int)x != 0 ) Evertchar = 1;
 
325
                           else Evertchar = 0;
 
326
                           return( 0 );
 
327
                case 'Y' : EGlinetype( s, x, y ); return( 0 );
 
328
                case 'Q' : Egetoutfilename( buf );
 
329
                           if( buf[0] == '\0' ) strcpy( buf, "out.gif" );
 
330
 
 
331
                           /* see if anything has been drawn, if not, return */
 
332
                           if ( EBBx2 < -998 && EBBy2 < -998 ) return( 0 );
 
333
 
 
334
                           if( tightbb ) EGeof( buf, EBBx1,  EBBy1, EBBx2, EBBy2 ); 
 
335
                           else if( specifycrop == 1 )
 
336
                             EGeof( buf, scx1, scy1, scx2, scy2 );
 
337
                           else if( specifycrop == 2 )
 
338
                             EGeof( buf, (EBBx1)-scx1, (EBBy1)-scy1, (EBBx2)+scx2, (EBBy2)+scy2 );
 
339
                           else EGeof( buf, EBBx1-0.2,  EBBy1-0.2, EBBx2+0.2, EBBy2+0.2 ); 
 
340
                           Eresetbb();
 
341
                           return( 0 );
 
342
                }
 
343
#endif
 
344
        }
 
345
 
 
346
 
 
347
 
 
348
else    { 
 
349
        if( Edev == '\0' ) {
 
350
                fprintf( stderr, "[pcode got %c]", op );
 
351
                Eerr( 12021, "Graphcore has not yet been initialized", "" );
 
352
                }
 
353
 
 
354
        else    {
 
355
                char sdev[8];
 
356
                sprintf( sdev, "%c", Edev );
 
357
                Eerr( 12022, "Unrecognized graphic device code", sdev );
 
358
                }
 
359
        exit(1);
 
360
        }
 
361
 
 
362
 
 
363
 
 
364
 
 
365
if( op == 'M' ) { lmlx = x; lmly = y; } /* remember most recent 'move' */
 
366
 
 
367
 
 
368
 
 
369
/* figure approximate text dimensions */
 
370
if( Edev != 'x' && GL_member( op, "TCJ" )) {
 
371
        Ewidth = strlen( s ) * Ecurtextwidth;
 
372
        Ewidth *= globalscale;
 
373
        }
 
374
 
 
375
if( Ekeeping_bb ) {
 
376
        /* keep bounding box info (minima and maxima) */
 
377
        if( GL_member( op, "LP" ) ) {
 
378
                if( Eprevop == 'M' ) Ebb( lmlx, lmly );
 
379
                Ebb( x, y );
 
380
                }
 
381
        /* normal (horizontal) text operations.  (vertical text below) */
 
382
        else if( op == 'T' && !Evertchar ) {
 
383
                if( Eprevop == 'M' ) Ebb( lmlx, lmly );
 
384
                Ebb( lmlx + Ewidth+0.05, lmly + (Ecurtextheight*globalscale) );
 
385
                }
 
386
        else if( op == 'C' && !Evertchar ) { 
 
387
                Ebb( lmlx - ((Ewidth/2.0)+0.05), lmly );
 
388
                Ebb( lmlx + ((Ewidth/2.0)+0.05), lmly + (Ecurtextheight*globalscale) );
 
389
                }
 
390
        else if( op == 'J' && !Evertchar ) { 
 
391
                Ebb( lmlx - (Ewidth+0.05), lmly );
 
392
                Ebb( lmlx, lmly + (Ecurtextheight*globalscale) );
 
393
                }
 
394
        }
 
395
 
 
396
Eprevop = op;
 
397
 
 
398
 
 
399
/* handle vertical text .. must be simulated for x windows;
 
400
   also gets bounding box for vertical text operations (all devices) */
 
401
 
 
402
if( Evertchar && GL_member( op, "TCJ" )) Everttextsim( op, s );
 
403
 
 
404
}
 
405
 
 
406
#ifdef NOX11
 
407
Egetclick()
 
408
{
 
409
double x, y;
 
410
int e;
 
411
if( Edev == 'p' ) {
 
412
        Eshow(); /* eject page and return.. */
 
413
        return(0); 
 
414
        }
 
415
else if( Edev == 'g' ) {
 
416
        Eendoffile();
 
417
        return( 0 );
 
418
        }
 
419
}  
 
420
#endif
 
421
 
 
422
 
 
423
/* ============================================= */
 
424
/* EBB - keep an overall bounding box for the entire image.
 
425
         Also call Echeckbb() to maintain nested object bounding boxes.. */
 
426
/* Ebb( double x, double y ) */
 
427
Ebb( x, y )
 
428
double x, y;
 
429
{
 
430
if( Ekeeping_bb ) {
 
431
        if( pcodedebug ) {
 
432
                if( ( x < EBBx1 && x < 0.0 ) || (x > EBBx2 && x > 8.0 ) ) fprintf( pcodedebugfp, "draw out X = %g\n", x );
 
433
                if( ( y < EBBy1 && y < 0.0 ) || (y > EBBy2 && y > 8.0 ) ) fprintf( pcodedebugfp, "draw out Y = %g\n", y );
 
434
                }
 
435
        if( x < EBBx1 ) EBBx1 = x;  
 
436
        if( x > EBBx2 ) EBBx2 = x; 
 
437
        if( y < EBBy1 ) EBBy1 = y; 
 
438
        if( y > EBBy2 ) EBBy2 = y; 
 
439
        
 
440
        }
 
441
if( keep_sub_bb ) {
 
442
        if( x < Esbb_x1 ) Esbb_x1 = x;
 
443
        if( x > Esbb_x2 ) Esbb_x2 = x;
 
444
        if( y < Esbb_y1 ) Esbb_y1 = y;
 
445
        if( y > Esbb_y2 ) Esbb_y2 = y;
 
446
        }
 
447
 
 
448
 
 
449
return( 0 );
 
450
}
 
451
 
 
452
/* ============================================== */
 
453
/* ERESETBB - needed for multiple pages */
 
454
Eresetbb()
 
455
{
 
456
EBBx1 = 999;
 
457
EBBy1 = 999;
 
458
EBBx2 = -999;
 
459
EBBy2 = -999;
 
460
return( 0 );
 
461
}
 
462
 
 
463
/* ============================================= */
 
464
/* EGETBB - get current bounding box.. */
 
465
Egetbb( xlo, ylo, xhi, yhi )
 
466
double *xlo, *ylo, *xhi, *yhi;
 
467
{
 
468
*xlo = EBBx1 / globalscale;
 
469
*ylo = EBBy1 / globalscaley;
 
470
*xhi = EBBx2 / globalscale;
 
471
*yhi = EBBy2 / globalscaley;
 
472
return( 0 );
 
473
}
 
474
 
 
475
 
 
476
/* ============================================== */
 
477
/* EGETTEXTSIZE - get width and height of last text item.. */
 
478
 
 
479
Egettextsize( w, h )
 
480
  double *w, *h;
 
481
{
 
482
*w = Ewidth;
 
483
*h = Ecurtextheight;
 
484
}
 
485
 
 
486
/* ================================================ */
 
487
/* vertical text bounding box, also simulation for X11 displays */
 
488
Everttextsim( op, s )
 
489
char op, s[];
 
490
{
 
491
double dist, y1, y2, x, y;
 
492
char let[4];
 
493
int i, len;
 
494
double w;
 
495
 
 
496
len = strlen( s );
 
497
 
 
498
if( Edev == 'x' ) dist = len * Ecurtextheight;
 
499
else dist = len * Ecurtextwidth;
 
500
 
 
501
if( op == 'T' ) { y1 = lmly; y2 = lmly + dist; }
 
502
else if( op == 'C' ) { y1 = lmly - (dist/2); y2 = lmly + (dist/2); }
 
503
else if( op == 'J' ) { y1 = lmly - dist; y2 = lmly; }
 
504
if( Edev == 'x' ) x = lmlx - Ecurtextwidth;
 
505
else x = lmlx;
 
506
y = y2;
 
507
#ifndef NOX11
 
508
if( Edev == 'x' ) {
 
509
        for( i = 0; i < len; i++ ) {
 
510
                sprintf( let, "%c", s[i] );
 
511
                EXWmoveto( x, y ); 
 
512
                EXWtext( let, &w ); 
 
513
                y -= Ecurtextheight;
 
514
                }
 
515
        }
 
516
#endif
 
517
Ebb( x-(Ecurtextheight*globalscale), y1 );
 
518
Ebb( x-(Ecurtextheight*globalscale), y2 );
 
519
return( 0 );
 
520
}
 
521
 
 
522
 
 
523
 
 
524
/* ==================================================== */
 
525
/* 1 = squelch all display activity, 0 restore to normal */
 
526
/* Used to calculate bounding box without displaying */
 
527
/* handles nested calls. */
 
528
Esquelch_display( mode )
 
529
int mode;
 
530
{
 
531
static int snest = 0;
 
532
if( mode == 1 ) {
 
533
        snest++;
 
534
        Esquelched = 1;
 
535
        }
 
536
else if( mode == 0 ) { 
 
537
        if( snest > 0 ) snest--;
 
538
        if( snest == 0 )Esquelched = 0;
 
539
        }
 
540
}
 
541
 
 
542
/* ==================================================== */
 
543
Ekeep_sub_bb( mode )
 
544
int mode;
 
545
{
 
546
keep_sub_bb = mode;
 
547
 
 
548
if( mode == 0 ) {
 
549
        Esbb_x1 = 999.0;
 
550
        Esbb_y1 = 999.0;
 
551
        Esbb_x2 = -999.0;
 
552
        Esbb_y2 = -999.0;
 
553
        }
 
554
 
 
555
return( 0 );
 
556
}
 
557
/* ==================================================== */
 
558
/* ETIGHTBB - switch ON=don't add margin when doing final BB crop */
 
559
Etightbb( mode )
 
560
int mode;
 
561
{
 
562
tightbb = mode;
 
563
return( 0 );
 
564
}
 
565
/* ==================================================== */
 
566
/* ESPECIFYCROP -  */
 
567
Especifycrop( mode, x1, y1, x2, y2 )
 
568
int mode; /* 0=off   1=absolute values   2=relative to tightcrop values  */
 
569
double x1, y1, x2, y2;
 
570
{
 
571
specifycrop = mode;
 
572
if( specifycrop ) {
 
573
        scx1 = x1;
 
574
        scy1 = y1;
 
575
        scx2 = x2;
 
576
        scy2 = y2;
 
577
        }
 
578
return( 0 );
 
579
}
 
580
 
 
581
/* ==================================================== */
 
582
/* special GD calls... */
 
583
 
 
584
/* ==================================================== */
 
585
/* EGIFRECT - direct interface to GD driver for better efficiency on rectangles */
 
586
Egifrect( xlo, yhi, xhi, ylo, color )
 
587
double xlo, yhi, xhi, ylo;
 
588
char *color;
 
589
{
 
590
#ifndef NOGD
 
591
char oldcolor[40];
 
592
strcpy( oldcolor, Ecurcolor );
 
593
if( globalscale != 1.0 ) { 
 
594
        xlo *= globalscale; ylo *= globalscaley; 
 
595
        xhi *= globalscale; yhi *= globalscaley;
 
596
        }
 
597
EGrect( xlo, yhi, xhi, ylo, color );
 
598
Ebb( xlo, ylo );
 
599
Ebb( xhi, yhi );
 
600
Ecolor( oldcolor );
 
601
#endif
 
602
return( 0 );
 
603
}
 
604
/* ==================================================== */
 
605
/* EIMLOAD - tell the gif driver to load a GIF image */
 
606
Eimload( filename, scalex, scaley )
 
607
char *filename;
 
608
double scalex, scaley;
 
609
{
 
610
#ifndef NOGD
 
611
if( globalscale != 1.0 ) {
 
612
        scalex *= globalscale;
 
613
        scaley *= globalscaley;
 
614
        }
 
615
return( EGimload( filename, scalex, scaley ) );
 
616
#else
 
617
return( 1 );
 
618
#endif
 
619
}
 
620
 
 
621
/* ==================================================== */
 
622
/* EIMPLACE - tell the gif driver to place a GIF image */
 
623
Eimplace( x, y, imalign, xscale, yscale )
 
624
double x, y;
 
625
char *imalign;
 
626
double xscale, yscale;
 
627
{
 
628
#ifndef NOGD
 
629
if( globalscale != 1.0 ) {
 
630
        x *= globalscale;
 
631
        y *= globalscaley;
 
632
        /* xscale and yscale are always passed as 1.0; 
 
633
                do not scale here as image is scaled when read */
 
634
        }
 
635
return( EGimplace( x, y, imalign, xscale, yscale ) );
 
636
#else
 
637
return( 1 );
 
638
#endif
 
639
}
 
640
 
 
641
 
 
642
/* ===================================================== */
 
643
/* ESETGLOBALSCALE - set global scale factor */
 
644
Esetglobalscale( sx, sy )
 
645
double sx, sy;
 
646
{
 
647
if( sx < 0.01 || sx > 20.0 ) return( Eerr( 20815, "Invalid global scaling", "" ) );
 
648
if( sy < 0.01 || sy > 20.0 ) return( Eerr( 20815, "Invalid global scaling", "" ) );
 
649
globalscale = sx;
 
650
globalscaley = sy;
 
651
Estandard_lwscale = 1.0 * sx;
 
652
return( 0 );
 
653
}
 
654
/* ===================================================== */
 
655
/* EGETGLOBALSCALE - get global scale factor */
 
656
Egetglobalscale( sx, sy )
 
657
double *sx, *sy;
 
658
{
 
659
*sx = globalscale;
 
660
*sy = globalscaley;
 
661
return( 0 );
 
662
}
 
663
 
 
664
/* ======================================= */
 
665
/* ESETPOSTEROFS - set poster offset (paginated postscript only).
 
666
   x, y are in absolute units, and are where the lower-left of the page will be.
 
667
   So if I have a poster made of 4 8.5x11 sheets held portrait style,
 
668
        the lowerleft would use 0,0
 
669
        the lowerright would use 8,0
 
670
        the upperleft would use 0,10.5
 
671
        the lowerright would use 8,10.5
 
672
   (8 and 10.5 are used because of print margins).
 
673
   The four pages can then be trimmed w/ a paper cutter and butted up against 
 
674
   one another to create a poster.
 
675
*/
 
676
Esetposterofs( x, y )
 
677
double x, y;
 
678
{
 
679
postermode = 1;
 
680
posterxo = x * (-1.0);
 
681
posteryo = y * (-1.0);
 
682
}
 
683
 
 
684
/* ========================================== */
 
685
/* EPCODEDEBUG - turn on/off local debugging */
 
686
Epcodedebug( mode, fp )
 
687
int mode;
 
688
FILE *fp;  /* stream for diagnostic output */
 
689
{
 
690
pcodedebug = mode;
 
691
pcodedebugfp = fp;
 
692
return( 0 );
 
693
}