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