1 /*
2  * $Id: gist.h,v 1.2 2009-10-19 04:37:51 dhmunro Exp $
3  * Declare GIST interface for C programs
4  */
5 /* Copyright (c) 2005, The Regents of the University of California.
6  * All rights reserved.
7  * This file is part of yorick (http://yorick.sourceforge.net).
8  * Read the accompanying LICENSE file for details.
9  */
10 
11 #ifndef GIST_H
12 #define GIST_H
13 
14 #include "plugin.h"
15 
16 /* current code breaks if GpReal is float instead of double */
17 typedef double GpReal;
18 typedef unsigned char GpColor;
19 
20 /* Normalized device coordinates (NDC) have a definite meaning to GIST--
21    PostScript and printing devices like units of 1/72.27 inch,
22    X11 release 4 likes units of 1/75 inch or 1/100 inch (for its fonts).
23    Next, 1.0 NDC should correspond roughly to 10.5 inches (the wide
24    dimension of an ordinary sheet of paper.  This will happen if
25    one point is 0.0013 NDC units (1.0 NDC unit is about 10.64 inch).
26    Then NDC origin is approximately in the lower left hand corner of
27    the page, although this can be shifted slightly to get nice margins.
28  */
29 #define ONE_POINT 0.0013000
30 #define INCHES_PER_POINT (1./72.27)
31 #define ONE_INCH (72.27*ONE_POINT)
32 
33 PLUG_API char gistError[128];  /* most recent error message */
34 
35 PLUG_API char *gistPathDefault;  /* set in Makefile or gread.c, can be
36                                   overridden by resetting directly */
37 
38 /* ------------------------------------------------------------------------ */
39 /* Initialization Functions */
40 
41 /*
42   An engine in GIST is a set of device drivers.  A particular instance
43   of an engine will also include a specific I/O connection for these
44   drivers.  Instead of opening a GKS workstation, in GIST, you create
45   a specific instance of a particular type of engine -- a PostScript
46   engine, a CGM engine, or an X window engine.  Since there is a
47   separate function for creating each different type of engine, GIST
48   has the important advantage over GKS that only those device drivers
49   actually used by your code are loaded.
50 
51    Four sets of device drivers are supplied with GIST:
52      PostScript - hopefully can be fed to your laser printer
53      CGM - binary format metafile, much more compact than PostScript,
54            especially if there are many pages of graphics
55      BX - basic play window
56      FX - play window with odometer bar at top, mouse zooming, etc
57  */
58 
59 typedef struct Engine Engine;
60 PLUG_API Engine *GpPSEngine(char *name, int landscape, int mode, char *file);
61 PLUG_API Engine *GpCGMEngine(char *name, int landscape, int mode, char *file);
62 PLUG_API Engine *GpBXEngine(char *name, int landscape, int dpi, char *display);
63 PLUG_API Engine *GpFXEngine(char *name, int landscape, int dpi, char *display);
64 
65 PLUG_API void GpKillEngine(Engine *engine);
66 
67 PLUG_API int gist_input_hint, gist_private_map, gist_rgb_hint;
68 PLUG_API void g_initializer(int *pargc, char *argv[]);
69 PLUG_API char *g_set_path(char *gpath);
70 PLUG_API void (*g_on_keyline)(char *msg);
71 PLUG_API void (*g_stdout)(char *output_line);
72 
73 typedef struct g_callbacks g_callbacks;
74 struct g_callbacks {
75   char *id;    /* just to ease debugging */
76   /* window system events */
77   void (*expose)(void *c, int *xy);
78   void (*destroy)(void *c);
79   void (*resize)(void *c,int w,int h);
80   void (*focus)(void *c,int in);
81   void (*key)(void *c,int k,int md);
82   void (*click)(void *c,int b,int md,int x,int y, unsigned long ms);
83   void (*motion)(void *c,int md,int x,int y);
84   void (*deselect)(void *c);
85 };
86 
87 PLUG_API int gist_expose_wait(Engine *eng, void (*e_callback)(void));
88 
89 /* ------------------------------------------------------------------------ */
90 /* Control Functions */
91 
92 /* Engines are kept in two lists - a list of all engines and
93    a ring of active engines.  To ignore the active list and send
94    only to a specific engine, call GpPreempt.  GpPreempt(0) turns
95    off preemptive mode.  The preempting engine need not be active;
96    it will still get all output until preempt mode is turned off, at
97    which time it returns to its original state.  */
98 PLUG_API int GpActivate(Engine *engine);
99 PLUG_API int GpDeactivate(Engine *engine);
100 PLUG_API int GpPreempt(Engine *engine);
101 PLUG_API int GpActive(Engine *engine);  /* 1 if active or preempting, else 0 */
102 
103 /* Pass engine==0 to GpClear or GpFlush to affect all active engines.  */
104 PLUG_API int GpClear(Engine *engine, int flag);
105 #define CONDITIONALLY 0
106 #define ALWAYS 1
107 PLUG_API int GpFlush(Engine *engine);
108 
109 /* The Next routines provide a way to iterate throught the engine lists.
110    Engines will be returned in order they are created or activated.
111    Use engine==0 to get the first engine in the list; will return 0
112    when there are no more engines in the list.  If preemptive mode has
113    been set with GpPreempt, GpNextActive returns the preempting engine,
114    whether or not it is in the active list.  */
115 PLUG_API Engine *GpNextEngine(Engine *engine);
116 PLUG_API Engine *GpNextActive(Engine *engine);
117 
118 /* ------------------------------------------------------------------------ */
119 /* Transformations and Clipping */
120 
121 typedef struct GpBox GpBox;
122 struct GpBox {
123   GpReal xmin, xmax, ymin, ymax;
124 };
125 
126 typedef struct GpTransform GpTransform;
127 struct GpTransform {
128   GpBox viewport, window;
129 };
130 
131 /* GpSetTrans sets the current transformation.  This involves notifying
132    each active engine of the change, in turn, so that an appropriate
133    transformation to device coordinates can be computed.  (GpActivate
134    also sets the device coordinate transformation in the engine.)
135    This transformation is also loaded into the gistA attribute list.  */
136 PLUG_API int GpSetTrans(const GpTransform *trans);
137 
138 /* Although NDC space has a particular meaning, an 8.5x11 sheet of
139    paper may have x along the 8.5 inch edge (portrait mode), or x along
140    the 11 inch edge (landscape mode).  In either case, the origin is the
141    lower left corner of the page.  This property can be set on a per
142    Engine basis using GpLandscape, or for all active engines with
143    GpLandscape(0).  If you use the D level routines, you shouldn't
144    need this.  */
145 PLUG_API int GpLandscape(Engine *engine, int landscape);
146 
147 /* current transformation */
148 PLUG_API GpTransform gistT;  /* use GpSetTrans to set this properly */
149 
150 /* Turn clipping on or off by setting gistClip.  */
151 PLUG_API int gistClip;         /* 1 to clip to map.viewport, 0 to not clip */
152 
153 /* Often, the linear transformation represented by a GpTransform is
154    required in the simpler form dst= scale*src+offset.  The following
155    convenience routines used internally by GIST are provided:  */
156 typedef struct GpMap GpMap;
157 struct GpMap {
158   GpReal scale, offset;
159 };
160 
161 typedef struct GpXYMap GpXYMap;
162 struct GpXYMap {
163   GpMap x, y;
164 };
165 
166 PLUG_API void GpSetMap(const GpBox *src, const GpBox *dst, GpXYMap *map);
167 
168 /* gPortrait and gLandscape contain, respectively, boxes representing
169    an 8.5-by-11 inch and an 11-by8.5 inch page in NDC */
170 PLUG_API GpBox gPortrait;
171 PLUG_API GpBox gLandscape;
172 
173 /* Utilities for GpBox, assuming min<=max for both boxes */
174 PLUG_API int GpIntersect(const GpBox *box1, const GpBox *box2);
175 PLUG_API int GpContains(const GpBox *box1, const GpBox *box2); /* box1>=box2 */
176 PLUG_API void GpSwallow(GpBox *preditor, const GpBox *prey);
177 
178 /* ------------------------------------------------------------------------ */
179 /* Output Primitives */
180 
181 PLUG_API int GpLines(long n, const GpReal *px, const GpReal *py);
182 PLUG_API int GpMarkers(long n, const GpReal *px, const GpReal *py);
183 PLUG_API int GpText(GpReal x0, GpReal y0, const char *text);
184   /* WARNING- for GpText, (x0,y0) are in WC, but the text size and
185               orientation are specified in NDC (unlike GKS).  */
186 PLUG_API int GpFill(long n, const GpReal *px, const GpReal *py);
187 PLUG_API int GpCells(GpReal px, GpReal py, GpReal qx, GpReal qy,
188                      long width, long height, long nColumns,
189                      const GpColor *colors);
190 
191 /* GKS seems to be missing a disjoint line primitive... */
192 PLUG_API int GpDisjoint(long n, const GpReal *px, const GpReal *py,
193                         const GpReal *qx, const GpReal *qy);
194 
195 /* ------------------------------------------------------------------------ */
196 /* Output attributes */
197 
198 /* Instead of a set and get function pair for each attribute, the GIST
199    C interface simply provides global access to its state table.  */
200 typedef struct GaAttributes GaAttributes;
201 
202 typedef struct GpLineAttribs GpLineAttribs;
203 struct GpLineAttribs {
204   unsigned long color;
205   int type;       /* line types given by L_SOLID, etc.  */
206   GpReal width;   /* default 1.0 is normal width of a line */
207 
208 #define L_NONE 0
209 #define L_SOLID 1
210 #define L_DASH 2
211 #define L_DOT 3
212 #define L_DASHDOT 4
213 #define L_DASHDOTDOT 5
214 
215 #define DEFAULT_LINE_WIDTH (0.5*ONE_POINT)
216 #define DEFAULT_LINE_INCHES (0.5*INCHES_PER_POINT)
217 };
218 
219 typedef struct GpMarkerAttribs GpMarkerAttribs;
220 struct GpMarkerAttribs {
221   unsigned long color;
222   int type;       /* marker types given by M_ASTERISK, etc., or by ASCII  */
223   GpReal size;    /* default 1.0 is normal size of a marker */
224 
225 #define M_POINT 1
226 #define M_PLUS 2
227 #define M_ASTERISK 3
228 #define M_CIRCLE 4
229 #define M_CROSS 5
230 
231 #define DEFAULT_MARKER_SIZE (10.0*ONE_POINT)
232 };
233 
234 typedef struct GpFillAttribs GpFillAttribs;
235 struct GpFillAttribs {
236   unsigned long color;
237   int style;      /* fill area styles given by F_SOLID, etc.  */
238 
239 #define F_HOLLOW 0
240 #define F_SOLID 1
241 #define F_PATTERN 2
242 #define F_HATCH 3
243 #define F_EMPTY 4
244 };
245 
246 typedef struct GpTextAttribs GpTextAttribs;
247 struct GpTextAttribs {
248   unsigned long color;
249   int font;         /* text font (T_HELVETICA, etc.) */
250   GpReal height;    /* character height in NDC, default 0.0156 (12pt)
251                        UNLIKE GKS, GIST font sizes are always specified
252                        in NDC.  This drastically simplifies coding for
253                        devices like X windows, which must load a font
254                        at each size.  It also conforms better with
255                        a Mac-like user interface in which font size
256                        in points is selected by the user.  */
257   int orient;          /* text paths given by TX_RIGHT, etc.  */
258   int alignH, alignV;  /* text alignments given by TH_NORMAL, etc.  */
259 
260   /* GKS is missing a text opacity flag.  */
261   int opaque;
262 
263 /* A font is a type face optionally ORed with T_BOLD and/or T_ITALIC. */
264 /* Available point sizes (for X) are 8, 10, 12, 14, 18, and 24 */
265 #define T_BOLD 1
266 #define T_ITALIC 2
267 #define T_COURIER 0
268 #define T_TIMES 4
269 #define T_HELVETICA 8
270 #define T_SYMBOL 12
271 #define T_NEWCENTURY 16
272 
273 #define TX_RIGHT 0
274 #define TX_UP 1
275 #define TX_LEFT 2
276 #define TX_DOWN 3
277 
278 #define TH_NORMAL 0
279 #define TH_LEFT 1
280 #define TH_CENTER 2
281 #define TH_RIGHT 3
282 
283 #define TV_NORMAL 0
284 #define TV_TOP 1
285 #define TV_CAP 2
286 #define TV_HALF 3
287 #define TV_BASE 4
288 #define TV_BOTTOM 5
289 };
290 
291 /* GaLines output function supports polylines with occasional marker
292    characters and/or ray arrows.  */
293 typedef struct GaLineAttribs GaLineAttribs;
294 struct GaLineAttribs {
295   int closed;   /* 0 for open curve, 1 for closed curve */
296   int smooth;   /* 0 for no smoothing, 1, 2, or 3 for progresively
297                    smoother splines (not implemented for all Engines)
298                    Note: If marks or rays, smooth is ignored.  */
299 
300   /* Note: GaLineAttribs and GaMarkerAttribs determine the style, size,
301      and color of the line and occasional markers.  If l.style is L_NONE,
302      polymarkers will be plotted at every point rather than occasional
303      markers.  */
304   int marks;    /* 0 if no occasional markers, 1 if occasional markers */
305   GpReal mSpace, mPhase;    /* occasional marker spacing and phase in NDC */
306 
307   int rays;     /* 0 if no ray arrows, 1 to get ray arrows */
308   GpReal rSpace, rPhase;    /* ray spacing and phase in NDC */
309   GpReal arrowL, arrowW;    /* ray arrowhead size, 1.0 is normal arrow */
310 
311 #define DEFAULT_ARROW_LENGTH (10.0*ONE_POINT)
312 #define DEFAULT_ARROW_WIDTH (4.0*ONE_POINT)
313 };
314 
315 typedef struct GaVectAttribs GaVectAttribs;
316 struct GaVectAttribs {
317   int hollow;      /* 1 to outline darts, 0 to fill
318                       (uses current line or filled area attibutes) */
319   GpReal aspect;   /*  half-width/length of dart arrows */
320 };
321 
322 struct GaAttributes {
323 
324   /* line attributes (GpLines, GpDisjoint) */
325   GpLineAttribs l;
326 
327   /* marker attributes (GpMarkers) */
328   GpMarkerAttribs m;
329 
330   /* filled area attributes (GpFill) */
331   GpFillAttribs f;
332 
333   /* text attributes (GpText) */
334   GpTextAttribs t;
335 
336   /* decorated line attributes (GaLines) */
337   GaLineAttribs dl;
338 
339   /* vector attributes (GpVectors) */
340   GaVectAttribs vect;
341 
342   /* edge attributes -- intended for 3D extensions (GpFill) */
343   GpLineAttribs e;
344 
345   int rgb;  /* for GpCells */
346 };
347 
348 PLUG_API GaAttributes gistA;
349 
350 typedef struct GaAxisStyle GaAxisStyle;
351 struct GaAxisStyle {
352 #define TICK_LEVELS 5
353   GpReal nMajor, nMinor, logAdjMajor, logAdjMinor;
354   int nDigits, gridLevel;
355   int flags;   /* TICK_L, ... LABEL_L, ... GRID_F below */
356 
357   GpReal tickOff, labelOff;  /* offsets in NDC from the edge of the
358                                 viewport to the ticks or labels */
359   GpReal tickLen[TICK_LEVELS];  /* tick lengths in NDC */
360 
361   GpLineAttribs tickStyle, gridStyle;
362   GpTextAttribs textStyle;   /* alignment ignored, set correctly */
363   GpReal xOver, yOver;       /* position for overflow label */
364 
365 /* Flags determine whether there are ticks at the lower or upper
366    (left or bottom is lower) edges of the viewport, whether the ticks
367    go inward or outward, whether the lower or upper edge ticks have
368    labels, and whether there is a full grid, or a single grid line
369    at the origin.
370    Also whether an alternative tick and/or label generator is used.  */
371 #define TICK_L 0x001
372 #define TICK_U 0x002
373 #define TICK_C 0x004
374 #define TICK_IN 0x008
375 #define TICK_OUT 0x010
376 #define LABEL_L 0x020
377 #define LABEL_U 0x040
378 #define GRID_F 0x080
379 #define GRID_O 0x100
380 #define ALT_TICK 0x200
381 #define ALT_LABEL 0x400
382 };
383 
384 typedef struct GaTickStyle GaTickStyle;
385 struct GaTickStyle {
386   GaAxisStyle horiz, vert;
387   int frame;
388   GpLineAttribs frameStyle;
389 };
390 
391 /* ------------------------------------------------------------------------ */
392 
393 /*
394   GIST includes a few output routines at a higher level than GKS.
395  */
396 
397 PLUG_API int GaLines(long n, const GpReal *px, const GpReal *py);
398        /* Like GpLines, but includes GaAttributes fancy line attributes
399           as well as the line attributes from GpAttributes.  */
400 
401 /* You must load the components of a mesh into a GaMeshXY data structure
402    before using the A level routines that require a mesh.  Only the
403    contour routines use the triangle array.  If you don't supply a
404    reg array (mesh->reg==0), GaMesh, GaFillMesh GaVectors, or
405    GaContourInit will supply a default region number array for you.
406    YOU ARE RESPONSIBLE FOR RELEASING THE ASSOCIATED STORAGE (using free).
407    Failure to supply a triangle array may result in crossing contours
408    in GaContours, but GaContourInit will not allocate one.  */
409 typedef struct GaQuadMesh GaQuadMesh;
410 struct GaQuadMesh {
411   long iMax, jMax; /* mesh logical dimensions */
412   GpReal *x, *y;   /* iMax-by-jMax mesh coordinate arrays */
413   int *reg;        /* iMax-by-(jMax+1)+1 mesh region number array:
414                       reg[j][i] non-zero means that the zone bounded by
415                         [j-1][i-1], [j-1][i], [j][i], and [j][i-1]
416                         exists,
417                       reg[0][i]= reg[j][0]= reg[jMax][i]= reg[j][iMax]= 0,
418                         so that the (iMax-1)-by-(jMax-1) possible zones
419                         are surrounded by non-existent zones.  */
420   short *triangle; /* iMax-by-jMax triangulation marker array
421                       triangle[j][i]= 1, -1, or 0 as the zone bounded by
422                         [j-1][i-1], [j-1][i], [j][i], and [j][i-1]
423                       has been triangulated from (-1,-1) to (0,0),
424                       from (-1,0) to (0,-1), or has not yet been
425                       triangulated.  */
426 };
427 
428 PLUG_API int GaMesh(GaQuadMesh *mesh, int region, int boundary, int inhibit);
429        /* Plots the quadrilateral mesh.  If boundary==0,
430           a mesh line is plotted whenever either zone it borders
431           belongs to the given region.  An exception is made if
432           region==0; in this case the entire mesh is plotted.
433           If boundary!=0, a mesh line is plotted whenever one but
434           not both of its bordering zones belong to the given region.
435           Again, if region==0, the boundary for the whole mesh is
436           plotted.
437           If inhibit&1, then lines at constant j are not drawn;
438           if inhibit&2, then lines at constant i are not drawn.  */
439 
440 PLUG_API int GaFillMesh(GaQuadMesh *mesh, int region, const GpColor *colors,
441                         long nColumns);
442        /* Fills each zone of the quadrilateral mesh according to the
443           (iMax-1)-by-(jMax-1) array of colors.  The colors array may
444           be a subarray of a larger rectangular array; therefore, you
445           must specify the actual length of a row of the colors array
446           using the nColumns parameter (nColumns>=iMax-1 for sensible
447           results).  Only the region specified is plotted, unless
448           region==0, in which case all non-zero regions are filled.
449           (As a special case, if colors==0, every zone is filled with
450           gistA.f.color.)  If gistA.e.type!=L_NONE, an edge is drawn
451           around each zone as it is drawn.  */
452 
453 PLUG_API int GaFillMarker(long n, const GpReal *px, const GpReal *py,
454                           GpReal x0, GpReal y0);
455        /* Fills (px,py)[n] in NDC with origin at (x0,y0) in world.  */
456 
457 PLUG_API int GaVectors(GaQuadMesh *mesh, int region,
458                        const GpReal *u, const GpReal *v, GpReal scale);
459        /* Plot a vector scale*(u,v) at each point of the current
460           mesh (gistA.mesh).  If region==0, the entire mesh is
461           drawn, otherwise only the specified region.  */
462 
463 PLUG_API int GaContourInit(GaQuadMesh *mesh, int region,
464                            const GpReal *z, GpReal level);
465        /* Find the edges cut by the current contour, remembering z, mesh
466           region, and level for the GaContour routine, which actually
467           walks the contour.  The z array represents function values at
468           the mesh points.  If region==0, contours are drawn on the
469           entire mesh, otherwise only on the specified region.
470           The mesh->triangle array is updated by GaContour as follows:
471           If a contour passes through an untriangulated saddle zone,
472           GaContour chooses a triangulation and marks the triangle
473           array approriately, so that subsequent calls to GaContour
474           will never produce intersecting contour curves.
475           If mesh->triangle==0 on input to GaContourInit, the
476           curves returned by GaContour may intersect the curves
477           returned after a subsequent call to GaContourInit with a
478           new contour level.  */
479 
480 PLUG_API int GaContour(long *cn, GpReal **cx, GpReal **cy, int *closed);
481        /* After a call to GaContourInit, GaContour must be called
482           repeatedly to generate the sequence of curves obtained by
483           walking the edges cut by the contour level plane.  GaContour
484           returns 1 until there are no more contours to be plotted,
485           when it returns 0.  GaContour signals an error by returning
486           0, but setting *cn!=0.  The curve coordinates (*cx,*cy)
487           use internal scratch space and the associated storage must
488           not be freed.  (*cx, *cy) are valid only until the next
489           GaContour or GaMesh call.  */
490 
491 PLUG_API int GaTicks(GaTickStyle *ticks, int xIsLog, int yIsLog);
492        /* Draws a system of tick marks and labels for the current
493           transformation (gistT), according to the specified
494           tick style.  */
495 
496 PLUG_API int GaFreeScratch(void);
497        /* Frees scratch space required by GaMesh, GaContour,
498           and GaContourInit, and GaTicks.  Ordinarily, there is no reason
499           to call this, as the amount of scratch space required is modest
500           in comparison to the size of the mesh, and it is reused
501           in subsequent calls.  */
502 
503 typedef int GaAltTicks(GpReal lo, GpReal hi, GpReal nMajor, GpReal nMinor,
504                        GpReal *ticks, int nlevel[TICK_LEVELS]);
505       /* An alternative tick generator function accepts the lo and hi
506          axis limits (lo<hi) and the maximum total number of ticks
507          allowed for all levels of the hierarchy.  It is given space
508          ticks[ceil(nMinor)] to return the tick values, which are given
509          in order within each level -- that is, all level 0 ticks first,
510          followed by all level 1 ticks, then level 2, and so on.  The
511          elements of nlevel array should be set to the number of ticks
512          ticks returned in ticks up to that level.  On entry, nlevel[i]
513          is set to zero for each i.  On exit, max(nlevel)<=maxnum.
514          The function should return 0 if successful.  If it returns
515          non-zero, the default tick generation scheme will be used.  */
516 typedef int GaAltLabel(char *label, GpReal value);
517       /* An alternative label generator stores label (<=31 characters)
518          in label, which is to represent the given value.  The function
519          should return 0 on success, non-zero to drop back to the default
520          scheme.  If label==0 on input, the function should return the
521          correct success value without actually computing the label;
522          it will be called once in this mode for every value, and if it
523          fails for any value, the default scheme will be used instead.  */
524 
525 PLUG_API int Base60Ticks(GpReal lo, GpReal hi, GpReal nMajor, GpReal nMinor,
526                          GpReal *ticks, int nlevel[TICK_LEVELS]);
527      /* Puts ticks at multiples of 30, failing if lo<=-3600 or hi>=+3600.
528         For ticks at multiples of 10 or less, the subdivisions are
529         identical to the default decimal tick scheme.  */
530 PLUG_API int DegreeLabels(char *label, GpReal value);
531      /* Prints (value+180)%360-180 instead of just value.  */
532 PLUG_API int HourLabels(char *label, GpReal value);
533      /* Prints hh:mm (or mm:ss) for value 60*hh+mm (or 60*mm+ss).  */
534 
535 PLUG_API int GaAltTick(GaTickStyle *ticks, int xIsLog, int yIsLog,
536                        GaAltTicks *xtick, GaAltLabel *xlabel,
537                        GaAltTicks *ytick, GaAltLabel *ylabel);
538        /* Like GaTicks, but uses the specified ticker and labeler for
539           non-log axes.  Log axes always use the defaults.  Either
540           ticker or labeler or both may be zero to use the default.  */
541 
542 /* ------------------------------------------------------------------------ */
543 
544 /* These general purpose contouring routines actually have nothing to
545  * do with graphics; I provide them as a convenience for computing
546  * inputs to the GaLines and GpFill routines.
547  * GcInit1 takes the same inputs as GaContourInit.  It returns nparts,
548  * the number of disjoint contour curves, and its return value is the
549  * total number of points on all these parts.  (On closed curves, the
550  * start point will be repeated, and so has been counted twice.)
551  * GcInit2 accepts two level values instead of one; it returns the
552  * boundary of the region between these two contour levels, with
553  * slits cut as necessary to render each disjoint part simply connected,
554  * traced counterclockwise (in logical space) about the region between
555  * the levels.  If you specify a non-zero value for nchunk, then the
556  * mesh will be chunked into pieces of no more than nchunk^2 zones, which
557  * limits the number of sides of any returned polygon to about 4*nchunk^2.
558  * After you call GcInit1 or GcInit2, you must allocate px[ntotal],
559  * py[ntotal], and n[nparts] arrays, then call GcTrace to fill them.
560  */
561 PLUG_API long GcInit1(GaQuadMesh *mesh, int region, const GpReal *zz,
562                       GpReal lev, long *nparts);
563 PLUG_API long GcInit2(GaQuadMesh *mesh, int region, const GpReal *zz,
564                       GpReal levs[2], long nchunk, long *nparts);
565 PLUG_API long GcTrace(long *n, GpReal *px, GpReal *py);
566 
567 /* ------------------------------------------------------------------------ */
568 /* Display list routines */
569 
570 /* GIST maintains a list of drawings much like its list of engines.
571    Unlike engines, only one drawing is active at a time.  The
572    contents of the drawing can be rendered on all active engines by
573    calling GdDraw.  This clears each engine before it begins to draw,
574    so that each call to GdDraw results in one page of graphics output
575    on all active engines.  X window engines may remember the most recent
576    drawing rendered on them; they will then respond to the GdUpdate
577    command by repairing any damage or making any additions to the
578    window containing the drawing.  On metafile engines, GdUpdate is
579    a noop.
580    A drawing consists of a list of coordinate systems (a GKS normalization
581    transformation plus GIST ticks and labels and a list of elements to be
582    displayed), plus a list of graphical elements outside any coordinate
583    systems (such as plot titles or legends).  The general layout of the
584    coordinate systems (their viewport and tick and label style) can be
585    specified using GdNewSystem, but the preferred technique is to put
586    this data into a "style sheet", which is an ASCII file.  */
587 
588 typedef struct Drauing Drauing;
589 
590 PLUG_API Drauing *GdNewDrawing(char *gsFile);
591 PLUG_API void GdKillDrawing(Drauing *drawing);
592 
593 /* After GdNewDrawing, the new drawing becomes the current drawing.
594    GdSetDrawing can be used to change the current drawing.  This
595    action saves the state of the previous drawing (the current system,
596    element, etc.), which can be recalled using GdSetDrawing(0).
597    Otherwise, GdSetDrawing scans the drawing to find the latest
598    system, element, and mesh, and these become current.  */
599 PLUG_API int GdSetDrawing(Drauing *drawing);
600 
601 /* GdClear marks the drawing as cleared, but no action is taken until
602    something new is drawn, at which point the cleared display list
603    elements are discarded.  GpClear is not sent until the next
604    GdDraw.  If drawing is 0, the current drawing is assumed.  */
605 PLUG_API int GdClear(Drauing *drawing);
606 
607 /* If changesOnly is non-zero, only new elements or damaged areas
608    are redrawn.  The amount drawn may be recorded by each engine, and
609    may vary from engine to engine.
610    The Drauing* is also recorded on each engine.  */
611 PLUG_API int GdDraw(int changesOnly);
612 
613 /* Graphical elements are added to the current drawing by setting
614    attributes in gistA, then calling GdLines, GdDisjoint, GdCells, GdMesh,
615    GdFillMesh, GdVectors, or GdContours.  GdText puts the text outside
616    all coordinate systems unless toSys is non-0.  Each of these routines
617    returns a unique identification number (equal to the total number
618    of objects defined in the current drawing since the last GdClear).
619    They return -1 if an error occurs.  */
620 
621 PLUG_API int GdLines(long n, const GpReal *px, const GpReal *py);
622 PLUG_API int GdDisjoint(long n, const GpReal *px, const GpReal *py,
623                         const GpReal *qx, const GpReal *qy);
624 PLUG_API int GdText(GpReal x0, GpReal y0, const char *text, int toSys);
625 PLUG_API int GdCells(GpReal px, GpReal py, GpReal qx, GpReal qy,
626                      long width, long height, long nColumns,
627                      const GpColor *colors);
628 PLUG_API int GdFill(long n, const GpColor *colors, const GpReal *px,
629                     const GpReal *py, const long *pn);
630 
631 /* The other D level primitives involve mesh arrays.  It is often
632    convenient NOT to copy mesh data, so that several objects may
633    point to a single mesh array (strictly speaking, it is the mesh->x,
634    mesh->y, mesh->reg, and mesh->triangle arrays which will be copied
635    or not copied).  Therefore, a noCopy flag is provided, which can be
636    constructed by ORing together NOCOPY_MESH, etc.  If you set any of
637    these bits, you are promising that you will not free the corresponding
638    object for the lifetime of this display list object, conversely,
639    when Gist discards the object, it will not free the pointers (the
640    memory management responsibility is yours).  However, if you
641    supply a GdFree routine, Gist will call that for uncopied objects.  */
642 PLUG_API int GdMesh(int noCopy, GaQuadMesh *mesh, int region, int boundary,
643                     int inhibit);
644 PLUG_API int GdFillMesh(int noCopy, GaQuadMesh *mesh, int region,
645                         GpColor *colors, long nColumns);
646 PLUG_API int GdVectors(int noCopy, GaQuadMesh *mesh, int region,
647                        GpReal *u, GpReal *v, GpReal scale);
648 PLUG_API int GdContours(int noCopy, GaQuadMesh *mesh, int region,
649                         GpReal *z, const GpReal *levels, int nLevels);
650 #define NOCOPY_MESH 1
651 #define NOCOPY_COLORS 2
652 #define NOCOPY_UV 4
653 #define NOCOPY_Z 8
654 
655 /* graphical element types */
656 #define E_NONE 0
657 #define E_LINES 1
658 #define E_DISJOINT 2
659 #define E_TEXT 3
660 #define E_MESH 4
661 #define E_FILLED 5
662 #define E_VECTORS 6
663 #define E_CONTOURS 7
664 #define E_CELLS 8
665 #define E_POLYS 9
666 #define E_SYSTEM 10
667 
668 /* Properties of drawing elements are similar to attributes of
669    graphical primitives.  The properties include everything passed
670    in the parameter lists to the primitives.  The global property
671    list gistD is used to inquire about or change these values in
672    the drawing elements-- i.e.- to edit the drawing.  */
673 
674 typedef struct GdProperties GdProperties;
675 struct GdProperties {
676   /* Properties of all elements */
677   int hidden;           /* 1 if element should not be plotted */
678   char *legend;         /* description of this element */
679 
680   /* Properties of coordinate systems */
681   GaTickStyle ticks;    /* for GaTicks to produce ticks and labels */
682   GpTransform trans;    /* transform for GpSetTrans for current system */
683   int flags;            /* flags for computing the limits */
684 #define D_XMIN 0x001
685 #define D_XMAX 0x002
686 #define D_YMIN 0x004
687 #define D_YMAX 0x008
688 #define D_RESTRICT 0x010
689 #define D_NICE 0x020
690 #define D_SQUARE 0x040
691 #define D_LOGX 0x080
692 #define D_LOGY 0x100
693 #define D_ZOOMED 0x200
694   GpBox limits;         /* current trans->window or exp10(trans->window) */
695 
696   /* Properties of elements */
697   /* --- GdLines- also uses gistA.l, gistA.dl, gistA.m, GdFill */
698   int n;
699   GpReal *x, *y;
700   /* --- GdDisjoint */
701   GpReal *xq, *yq;
702   /* --- GdText- also uses gistA.t */
703   GpReal x0, y0;
704   char *text;
705   /* --- GdCells */
706   GpReal px, py, qx, qy;
707   long width, height;
708   /* --- GdCells, GdFillMesh */
709   long nColumns;         /* if colors copied, this is width or iMax-1 */
710   GpColor *colors;       /* also GdFill */
711   /* --- GdMesh, GdFillMesh, GdVectors, GdContours */
712   int noCopy;  /* if bit is set, Gist will not free corresponding array
713                   -- however, if non-0, GdFree will be called */
714 /* if NOCOPY_MESH was set, but reg or triangle was 0, then gist
715    owns the reg or triangle array, and the following bits are NOT set: */
716 #define NOCOPY_REG 16
717 #define NOCOPY_TRI 32
718   GaQuadMesh mesh;
719   int region;
720   /* --- GdMesh- also uses gistA.l */
721   int boundary, inhibit;
722   /* --- GdVectors- also uses gistA.l, gistA.f, gistA.vect */
723   GpReal *u, *v, scale;
724   /* --- GdContours- individual level curves are like GdLines
725           contour itself uses gistA.l, gistA.dl, gistA.m as defaults */
726   GpReal *z, *levels;
727   int nLevels;
728   /* --- GdFill */
729   long *pn;
730 };
731 
732 PLUG_API GdProperties gistD;
733 
734 /* GdSetSystem, GdSetElement, and GdSetContour cause the contents
735    of one drawing element to be copied into gistD and gistA for
736    examination or editing (with GdEdit or GdRemove).
737    GdNewSystem does an automatic GdSetSystem, and GdLines,
738    GdText, GdCells, GdMesh, GdFillMesh, GdVectors, and GdContours
739    do an automatic GdSetElement to the newly created element.
740    The return values are E_LINES, ... E_SYSTEM; E_NONE on failure.  */
741 PLUG_API int GdSetSystem(int sysIndex);
742 PLUG_API int GdSetElement(int elIndex);
743 PLUG_API int GdSetContour(int levIndex);
744 
745 /* return current sysIndex, or <0 if unavailable */
746 PLUG_API int GdGetSystem(void);
747 
748 /* The elIndex required by GdSetElement is NOT the id number returned
749    by GdLines, GdMesh, etc.  Instead, elIndex begins at 0 and goes
750    up to 1 less than the number of elements in the current system.
751    To get the elIndex corresponding to a given id, use GdFindIndex(id).
752    The sysIndex varies from 0 (outside of all systems), up to the
753    total number of coordinate systems defined in the current Drauing.
754    To find the sysIndex for a given element id, use GdFindSystem(id).  */
755 PLUG_API int GdFindIndex(int id);  /* returns -1 if no such element
756                                       if current system */
757 PLUG_API int GdFindSystem(int id); /* returns -1 if no such element
758                                       anywhere in current Drauing */
759 
760 /* After you call one of the 3 GdSet... routines, you may
761    alter the contents of gistA and/or gistD, then call
762    GdEdit to write the changes back into the element.
763    If you change gistD.x, gistD.y, gistD.mesh->x, or gistD.mesh->y,
764    use GdEdit(CHANGE_XY) (this recomputes log coordinates if necessary),
765    otherwise, use GdEdit(0).  If you want to change any of the
766    pointers, you should first free the existing pointer (with free),
767    and be aware that GdKillDrawing, GdClear, or GdRemove will
768    free the pointer you are providing.  If the element is a set of
769    contours, and you change gistD.z or gistD.levels, gistD.nLevels, or
770    gistD.mesh->triangle, use GdEdit(CHANGE_Z).
771    Use GdEdit(CHANGE_XY | CHANGE_Z) if both apply.
772    GdRemove completely removes the element from the drawing.  */
773 PLUG_API int GdEdit(int xyzChanged);
774 #define CHANGE_XY 1
775 #define CHANGE_Z 2
776 PLUG_API int GdRemove(void);
777 
778 /* GdGetLimits copies the current coordinate systems limits into
779    gistD.limits and gistD.flags.  GdSetLimits sets the limits in
780    the current coordinate system to gistD.limits and gistD.flags
781    (if the various adjustment flags are set, the window limits
782    may be adjusted, but this will not happen until the drawing
783    is rendered on at least one engine).  GdSetPort sets the tick
784    style and viewport for the current coordinate system.  */
785 PLUG_API int GdGetLimits(void);
786 PLUG_API int GdSetLimits(void);
787 PLUG_API int GdSetPort(void);
788 
789 /* Each coordinate system keeps a "saved" set of limits, which
790    can be "reverted" to return the limits to the state at the time
791    of the last save operation.  (gistD plays no role in this operation.)
792    This is used by the fancy X Engine to save the limits prior to
793    a series of mouse-driven zoom or pan operations.
794    GdRevertLimits(1) reverts to the save limits only if the current
795    limits are marked D_ZOOMED, while GdRevertLimits(0) reverts
796    unconditionally.  GdSaveLimits(1) assures that D_ZOOMED is not
797    set in the saved flags.  */
798 PLUG_API int GdSaveLimits(int resetZoomed);
799 PLUG_API int GdRevertLimits(int ifZoomed);
800 
801 /* You can register an alternative tick and/or label generator for
802    each axis of the current corodinate system.  They will not be used
803    unless the ALT_TICK or ALT_LABEL limits flag is set.  Passing 0
804    to GdAltTick leaves the corresponding function unchanged -- there
805    is no way to unregister it (just turn off the limits flag).  */
806 PLUG_API int GdAltTick(GaAltTicks *xtick, GaAltLabel *xlabel,
807                        GaAltTicks *ytick, GaAltLabel *ylabel);
808 
809 /* Unlike the other `D' level drawing routines, GdDrawLegends acts
810    immediately.  If engine==0, all active engines are used.
811    The intent is that legends not be rendered in an X window or
812    other interactive device, but this optional routine can render
813    them on a hardcopy device.  */
814 PLUG_API int GdDrawLegends(Engine *engine);
815 
816 /* ------------------------------------------------------------------------ */
817 /* The following Gd routines are not intended for ordinary use:
818    GdReadStyle, GdNewSystem, GdLandscape, and GdLegendBox are
819    unnecessary if you use drawing style files (see gread.c).
820    GdDetach is provided here for completeness; several of the
821    other Gd routines use it (e.g.- GdClear).
822    GdClearSystem is required for the specialized animation mode
823    described in hlevel.c.  */
824 
825 /* GdReadStyle clears the drawing and removes all its current systems
826    as a side effect.  It is the worker for GdNewDrawing.  */
827 PLUG_API int GdReadStyle(Drauing *drawing, const char *gsFile);
828 
829 /* Coordinate systems are usually defined in the styleFile, but
830    a new coordinate system may be added with GdNewSystem, which
831    returns the index of the newly created system.  */
832 PLUG_API int GdNewSystem(GpBox *viewport, GaTickStyle *ticks);
833 
834 /* Set current drawing to landscape or portrait mode */
835 PLUG_API int GdLandscape(int landscape);
836 
837 /* Set location and properties of legends for output.   */
838 PLUG_API int GdLegendBox(int which, GpReal x, GpReal y, GpReal dx, GpReal dy,
839                          const GpTextAttribs *t, int nchars, int nlines,
840                          int nwrap);
841 
842 /* GdDetach detaches one or all (if drawing==0) drawings from one or all
843    (if engine==0) engines.  Whether an engine is active or not is
844    unimportant.  A drawing is attached to an engine by GdDraw.  */
845 PLUG_API void GdDetach(Drauing *drawing, Engine *engine);
846 
847 /* Clear the current coordinate system-- returns 0 if there is no
848    current system.  Damages viewport only if all limits fixed,
849    otherwise damages both ticks and viewport.  Returns damaged box.  */
850 PLUG_API GpBox *GdClearSystem(void);
851 
852 /* ------------------------------------------------------------------------ */
853 /* Color */
854 
855 /* GIST cell arrays and filled meshes are aimed at displaying pseudocolor
856    images, not true color images.  (Another primitive might be added to
857    handle true color images.  This is probably most useful for shading
858    projections of 3D objects, which requires additional primitives as
859    anyway.)  The colors arrays in the G*Cells and G*FillMesh primitives
860    are arrays of indices into a pseudocolor map.  The colors for the
861    various attribute lists may come from this pseudocolor map, or
862    they may be special values representing the foreground and background
863    colors, or a primary color.  */
864 
865 /* duplicate P_BG, P_FG, etc from play.h */
866 #define BG_COLOR (255UL)
867 #define FG_COLOR (254UL)
868 #define BLACK_COLOR (253UL)
869 #define WHITE_COLOR (252UL)
870 #define RED_COLOR (251UL)
871 #define GREEN_COLOR (250UL)
872 #define BLUE_COLOR (249UL)
873 #define CYAN_COLOR (248UL)
874 #define MAGENTA_COLOR (247UL)
875 #define YELLOW_COLOR (246UL)
876 
877 /* Each Engine maintains a list of colors for the pseudocolor
878    map.  These can be set or retrieved directly from the nColors and
879    palette Engine members.  The pseudocolor map is in addition to
880    the 10 standard colors defined in gist.h -- note that the meaning of
881    a colorcell need not be the same from one engine to another, although
882    the 4th component (gray) has been added to make it easier to control
883    both gray and color devices using the same GpColorCell array.  Note
884    that no Engine owns a GpColorCell array; allocating and freeing this
885    storage is the responsibility of the application program.
886 
887    A change in the colormap for an Engine will generally have no effect
888    until the next page of graphics output.  However, individual types
889    of engines may implement a function to try to make immediate
890    changes to the pseudocolor map.  */
891 
892 /* duplicate p_col_t from play.h */
893 typedef unsigned long GpColorCell;
894 
895 /* Two routines are provided to set the gray component of the cells in
896    a colormap--  GpPutGray for gray=(red+green+blue)/3 and GpPutNTSC
897    for gray=(30*red+59*green+11*blue).  The latter is the NTSC standard
898    for converting color TV signals to monochrome.  GpPutRGB copies the
899    gray entry into the red, green, and blue entries.  */
900 /* these all no-ops now */
901 PLUG_API void GpPutGray(int nColors, GpColorCell *palette);
902 PLUG_API void GpPutNTSC(int nColors, GpColorCell *palette);
903 PLUG_API void GpPutRGB(int nColors, GpColorCell *palette);
904 
905 /* Set the palette; the change takes place as soon as possible for
906    this engine and the effect on previously drawn objects is
907    engine dependent.  The maximum usable palette size is returned.  */
908 PLUG_API int GpSetPalette(Engine *engine, GpColorCell *palette, int nColors);
909 
910 /* GpGetPalette returns the number of colors in the palette-
911    this is the nColors passed to GpSetPalette.  */
912 PLUG_API int GpGetPalette(Engine *engine, GpColorCell **palette);
913 
914 /* GpReadPalette returns the number of colors found in the palette
915    file (see gread.c for format), as well as the palette itself.
916    If the number of colors in the palette exceeds maxColors, attempts
917    to scale to maxColors.  */
918 PLUG_API int GpReadPalette(Engine *engine, const char *gpFile,
919                            GpColorCell **palette, int maxColors);
920 
921 /* The PostScript and CGM formats, unlike Xlib, guarantee that
922    the color table from one page does not automatically carry over to
923    the next.  Additionally, color images cannot be rendered (and may be
924    inconvenient if they can be rendered) on most hardcopy devices.
925    Consequently, by default, Gist produces a simple gray scale for
926    PostScript or CGM output.  However, you can optionally force the
927    current palette to be dumped on each output page by setting the
928    color mode flag.  If any marks have been made on the current page,
929    the color table cannot be dumped until the next page.
930    For an X Engine, the colorMode is initially 0, which means to
931    use the best available shared colors.  Setting colorMode to 1
932    results in exact private colors, which may require a private
933    colormap.  */
934 PLUG_API int GpDumpColors(Engine *engine, int colorMode);
935 
936 /* ------------------------------------------------------------------------ */
937 /* Error handlers */
938 
939 /* The Xlib functions invoked by X engines will call exit unless you
940    set an alternative error recovery routine.  */
941 PLUG_API int GpSetXHandler(void (*ErrHandler)(char *errMsg));
942 
943 /* ------------------------------------------------------------------------ */
944 /* Memory management */
945 
946 /* GdFree, if non-0, will be called to free objects
947    marked with the noCopy flag.  */
948 PLUG_API void (*GdFree)(void *);
949 
950 #endif
951