~ubuntu-branches/ubuntu/lucid/python-scipy/lucid

« back to all changes in this revision

Viewing changes to Lib/xplt/src/gist/gread.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2007-01-07 14:12:12 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070107141212-mm0ebkh5b37hcpzn
* Remove build dependency on python-numpy-dev.
* python-scipy: Depend on python-numpy instead of python-numpy-dev.
* Package builds on other archs than i386. Closes: #402783.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * GREAD.C
3
 
 *
4
 
 * $Id: gread.c,v 1.1 2003/03/08 15:26:45 travo Exp $
5
 
 *
6
 
 * Define Drauing gread read routine for GIST
7
 
 *
8
 
 */
9
 
/*    Copyright (c) 1994.  The Regents of the University of California.
10
 
                    All rights reserved.  */
11
 
 
12
 
#include "gist.h"
13
 
#include "pstdio.h"
14
 
#include "pstdlib.h"
15
 
#include "play.h"
16
 
 
17
 
extern void GdKillSystems(void);  /* defined in draw.c */
18
 
 
19
 
#ifndef GISTPATH
20
 
#define GISTPATH "~/gist:~/Gist:/usr/local/lib/gist"
21
 
#endif
22
 
char *gistPathDefault= GISTPATH;
23
 
 
24
 
/* ------------------------------------------------------------------------ */
25
 
 
26
 
#include <string.h>
27
 
 
28
 
struct GsysRead {
29
 
  char *legend;
30
 
  GpBox viewport;
31
 
  GaTickStyle ticks;
32
 
} modelSystem, tempSystem;
33
 
 
34
 
struct GlegRead {
35
 
  GpReal x, y, dx, dy;
36
 
  GpTextAttribs textStyle;
37
 
  int nchars, nlines, nwrap;
38
 
} modelLegends;
39
 
 
40
 
static char *FormGistPath(void);
41
 
static char *FormFullName(char *gistPath, const char *name);
42
 
static void FormatError(p_file *fp, const char *name, const char *id);
43
 
static int SnarfColor(char *token);
44
 
static int SnarfRGB(char *token, GpColorCell *cell);
45
 
static int SnarfGray(GpColorCell *cell, int lookingFor4);
46
 
static char *WhiteSkip(char *input);
47
 
static char *DelimitRead(char *input, int *closed, int nlOK);
48
 
static char *ColRead(char *input, GpColorCell *dest);
49
 
static char *IntRead(char *input, int *dest);
50
 
static char *RealRead(char *input, GpReal *dest);
51
 
static char *StringRead(char *input, char **dest);
52
 
static char *MemberRead(char *input, char **member);
53
 
static char *ArrayRead(char *input, GpReal *dest, int narray);
54
 
static char *LineRead(char *input, GpLineAttribs *dest);
55
 
static char *TextRead(char *input, GpTextAttribs *dest);
56
 
static char *AxisRead(char *input, GaAxisStyle *dest);
57
 
static char *TickRead(char *input, GaTickStyle *dest);
58
 
static char *SystemRead(char *input, struct GsysRead *dest);
59
 
static char *LegendsRead(char *input, struct GlegRead *dest);
60
 
 
61
 
/* ------------------------------------------------------------------------ */
62
 
/* A palette file (.gp) or style file (.gs) will be found if it:
63
 
 
64
 
   1. Is in the current working directory.
65
 
   2. Is the first file of its name encountered in any of the directories
66
 
      named in the GISTPATH environment variable.
67
 
   3. Ditto for the GISTPATH default string built in at compile time.
68
 
      Note that the environment variable is in addition to the compile
69
 
      time variable, not in place of it.
70
 
 
71
 
   The path name list should consist of directory names (with or without
72
 
   trailing '/'), separated by ':' with no intervening whitespace.  The
73
 
   symbol '~', if it is the first symbol of a directory name, will be
74
 
   expanded to the value of the HOME environment variable, but other
75
 
   environment variable expansions are not recognized.
76
 
 
77
 
   If the given filename begins with '/' the path search is
78
 
   not done.  '~' is NOT recognized in the given filename.
79
 
 */
80
 
 
81
 
extern char *g_argv0;
82
 
char *g_argv0 = 0;
83
 
 
84
 
static char *scratch = 0;
85
 
static char *gist_path = 0;
86
 
 
87
 
static char *FormGistPath(void)
88
 
{
89
 
  if (!gist_path) {
90
 
    char *gistPath = getenv("GISTPATH");
91
 
    int len = gistPath? strlen(gistPath) : 0;
92
 
    int len0 = g_argv0? strlen(g_argv0) : 0;
93
 
    int lend = gistPathDefault? strlen(gistPathDefault) : 0;
94
 
    char *place;
95
 
 
96
 
    /* Get enough scratch space to hold
97
 
       the concatenation of the GISTPATH environment variable and the
98
 
       GISTPATH compile-time option, and a fallback computed from argv[0] */
99
 
    gist_path = p_malloc(len+len0+lend+4);
100
 
    if (!gist_path) return 0;
101
 
 
102
 
    place = gist_path;
103
 
    if (gistPath) {
104
 
      strcpy(place, gistPath);
105
 
      place += len;
106
 
      *(place++) = ':';
107
 
    }
108
 
    strcpy(place, gistPathDefault);
109
 
    place += lend;
110
 
    /* back up to sibling of directory containing executable */
111
 
    for (len=len0-1 ; len>0 ; len--) if (g_argv0[len]=='/') break;
112
 
    for (len-- ; len>0 ; len--) if (g_argv0[len]=='/') break;
113
 
    if (len > 0) {
114
 
      /* tack /g/ sibling of executable directory onto path */
115
 
      *(place++) = ':';
116
 
      strncpy(place, g_argv0, ++len);
117
 
      place += len;
118
 
      strcpy(place, "g");
119
 
    }
120
 
  }
121
 
 
122
 
  scratch = p_malloc(1028);
123
 
  if (!scratch) return 0;
124
 
  return gist_path;
125
 
}
126
 
 
127
 
static char *FormFullName(char *gistPath, const char *name)
128
 
{
129
 
  int nlen= strlen(name);
130
 
  int len, elen;
131
 
  char *now= scratch;
132
 
 
133
 
  for (;;) {
134
 
    /* Skip past any components of the GISTPATH which result in impossibly
135
 
       long path names */
136
 
    do len= strcspn(gistPath, ":"); while (!len);
137
 
    /* handle MS Windows drive letters */
138
 
    if (len==1 && gistPath[1]==':' &&
139
 
        ((gistPath[0]>='A' && gistPath[0]<='Z') ||
140
 
         (gistPath[0]>='a' && gistPath[0]<='z')))
141
 
      len = 2+strcspn(gistPath+2, ":");
142
 
    if (!len) break;
143
 
    elen= len;
144
 
 
145
 
    now= scratch;
146
 
    if (gistPath[0]=='~') {
147
 
      /* Get name of home directory from HOME environment variable */
148
 
      char *home= getenv("HOME");
149
 
      int hlen;
150
 
      if (home && (hlen= strlen(home))<1024) {
151
 
        strcpy(now, home);
152
 
        now+= hlen;
153
 
        gistPath++;
154
 
        len--;
155
 
        elen+= hlen-1;
156
 
      }
157
 
    }
158
 
 
159
 
    if (elen+nlen<1023) break;
160
 
 
161
 
    gistPath+= len+1;
162
 
  }
163
 
 
164
 
  if (len) {
165
 
    strncpy(now, gistPath, len);
166
 
    now+= len;
167
 
    if (now[-1]!='/') *now++= '/';
168
 
    strcpy(now, name);
169
 
  } else {
170
 
    scratch[0]= '\0';
171
 
  }
172
 
 
173
 
  return gistPath+len + strspn(gistPath+len, ":");
174
 
}
175
 
 
176
 
extern p_file *GistOpen(const char *name);
177
 
p_file *GistOpen(const char *name)
178
 
{
179
 
  p_file *f;
180
 
  if (!name) return 0;
181
 
 
182
 
  f= p_fopen(name, "r");
183
 
 
184
 
  if (!f && name[0]!='/') {
185
 
    /* Try to find relative file names somewhere on GISTPATH or, failing
186
 
       that, in the default directory specified at compile time.  */
187
 
    char *gistPath= FormGistPath();
188
 
    if (gistPath) {
189
 
      do {
190
 
        gistPath= FormFullName(gistPath, name);
191
 
        f= p_fopen(scratch, "r");
192
 
      } while (!f && gistPath[0]);
193
 
      p_free(scratch);
194
 
    }
195
 
  }
196
 
 
197
 
  if (!f) {
198
 
    strcpy(gistError, "unable to open file ");
199
 
    strncat(gistError, name, 100);
200
 
  }
201
 
  return f;
202
 
}
203
 
 
204
 
static void FormatError(p_file *fp, const char *name, const char *id)
205
 
{
206
 
  p_fclose(fp);
207
 
  strcpy(gistError, id);
208
 
  strcat(gistError, " file format error in ");
209
 
  strncat(gistError, name, 127-strlen(gistError));
210
 
}
211
 
 
212
 
static char line[137];  /* longest allowed line is 136 characters */
213
 
 
214
 
/* ------------------------------------------------------------------------ */
215
 
 
216
 
static int SnarfColor(char *token)
217
 
     /* returns -1 if not unsigned char, -2 if missing */
218
 
{
219
 
  int color;
220
 
  char *suffix;
221
 
 
222
 
  if (!token) token= strtok(0, " \t\n");
223
 
  if (token) color= (int)strtol(token, &suffix, 0);
224
 
  else return -2;
225
 
  if (suffix==token || color<0 || color>255) return -1;
226
 
  else return color;
227
 
}
228
 
 
229
 
static int SnarfRGB(char *token, GpColorCell *cell)
230
 
{
231
 
  int red, blue, green;
232
 
  red= SnarfColor(token);
233
 
  if (red<0) return 1;
234
 
  green= SnarfColor(0);
235
 
  if (green<0) return 1;
236
 
  blue= SnarfColor(0);
237
 
  if (blue<0) return 1;
238
 
  cell[0] = P_RGB(red, green, blue);
239
 
  return 0;
240
 
}
241
 
 
242
 
/* ARGSUSED */
243
 
static int SnarfGray(GpColorCell *cell, int lookingFor4)
244
 
{
245
 
  int gray= SnarfColor(0);
246
 
  if (gray==-2) return lookingFor4;
247
 
  else if (gray<0 || !lookingFor4) return 1;
248
 
  /* cell->gray= gray; */
249
 
  return 0;
250
 
}
251
 
 
252
 
int GpReadPalette(Engine *engine, const char *gpFile,
253
 
                  GpColorCell **palette, int maxColors)
254
 
{
255
 
  char *token, *suffix;
256
 
  GpColorCell *pal= 0;
257
 
  int iColor= -1,  nColors= 0,  ntsc= 0,  lookingFor4= 0;
258
 
  p_file *gp= GistOpen(gpFile);
259
 
 
260
 
  *palette= 0;
261
 
  if (!gp) return 0;
262
 
 
263
 
  for (;;) {  /* loop on lines in file */
264
 
    token= p_fgets(gp, line, 137);
265
 
    if (!token) break;                      /* eof (or error) */
266
 
 
267
 
    token= strtok(token, " =\t\n");
268
 
    if (!token || token[0]=='#') continue;  /* blank or comment line */
269
 
 
270
 
    if (iColor<=0) {
271
 
      int *dest= 0;
272
 
      if (strcmp(token, "ncolors")==0) dest= &nColors;
273
 
      else if (strcmp(token, "ntsc")==0) dest= &ntsc;
274
 
 
275
 
      if (dest) {
276
 
        /* this is ncolors=... or ntsc=... line */
277
 
        token= strtok(0, " =\t\n");
278
 
        if (token) *dest= (int)strtol(token, &suffix, 0);
279
 
        else goto err;
280
 
        if (suffix==token || strtok(0, " \t\n")) goto err;
281
 
 
282
 
      } else {
283
 
        /* this must be the first rgb line */
284
 
        int gray;
285
 
 
286
 
        /* previous ncolors= is mandatory so palette can be allocated */
287
 
        if (nColors<=0) goto err;
288
 
        pal= p_malloc(sizeof(GpColorCell)*nColors);
289
 
        if (!pal) goto merr;
290
 
 
291
 
        /* if first rgb line has 4 numbers, all must have 4, else 3 */
292
 
        if (SnarfRGB(token, pal)) goto err;
293
 
        gray= SnarfColor(0);
294
 
        if (gray==-1) goto err;
295
 
        if (gray>=0) {
296
 
          lookingFor4= 1;
297
 
          /* pal->gray= gray; */
298
 
          if (SnarfGray(pal, 0)) goto err;  /* just check for eol */
299
 
        } else {
300
 
          lookingFor4= 0;
301
 
          /* already got eol */
302
 
        }
303
 
 
304
 
        iColor= 1;
305
 
      }
306
 
 
307
 
    } else if (iColor<nColors) {
308
 
      /* read next rgb line */
309
 
      if (SnarfRGB(token, pal+iColor)) goto err;
310
 
      if (SnarfGray(pal+iColor, lookingFor4)) goto err;
311
 
      iColor++;
312
 
 
313
 
    } else {
314
 
      goto err;                  /* too many rgb for specified ncolors */
315
 
    }
316
 
  }
317
 
  if (iColor<nColors) goto err;  /* too few rgb for specified ncolors */
318
 
 
319
 
  p_fclose(gp);
320
 
 
321
 
  if (nColors>maxColors && maxColors>1) {
322
 
    /* attempt to rescale the palette to maxColors */
323
 
    int oldCell, newCell, nextCell, r, g, b;
324
 
    double ratio= ((double)(nColors-1))/((double)(maxColors-1));
325
 
    double frac, frac1, old= 0.0;
326
 
    for (newCell=0 ; newCell<maxColors ; newCell++) {
327
 
      oldCell= (int)old;
328
 
      nextCell= oldCell+1;
329
 
      if (nextCell>=nColors) nextCell= oldCell;
330
 
      frac= old-(double)oldCell;
331
 
      frac1= 1.0-frac;
332
 
      r = (int)(frac1*P_R(pal[oldCell]) + frac*P_R(pal[nextCell]));
333
 
      g = (int)(frac1*P_G(pal[oldCell]) + frac*P_G(pal[nextCell]));
334
 
      b = (int)(frac1*P_B(pal[oldCell]) + frac*P_B(pal[nextCell]));
335
 
      pal[newCell] = P_RGB(r, g, b);
336
 
      /*if (!lookingFor4)
337
 
        pal[newCell].gray= frac1*pal[oldCell].gray+frac*pal[nextCell].gray;*/
338
 
      old+= ratio;
339
 
    }
340
 
    nColors= maxColors;
341
 
  }
342
 
 
343
 
  if (!lookingFor4) {
344
 
    /* gray values were not explicitly specified */
345
 
    if (ntsc) GpPutNTSC(nColors, pal);
346
 
    else GpPutGray(nColors, pal);
347
 
  }
348
 
 
349
 
  *palette= pal;
350
 
  iColor= GpSetPalette(engine, pal, nColors);
351
 
  return iColor>nColors? nColors : iColor;
352
 
 
353
 
 err:
354
 
  FormatError(gp, gpFile, "palette");
355
 
  if (pal) p_free(pal);
356
 
  return 0;
357
 
 
358
 
 merr:
359
 
  strcpy(gistError, "memory manager failed to get space for palette");
360
 
  p_fclose(gp);
361
 
  return 0;
362
 
}
363
 
 
364
 
/* ------------------------------------------------------------------------ */
365
 
 
366
 
#define OPEN_BRACE '{'
367
 
#define CLOSE_BRACE '}'
368
 
 
369
 
static p_file *gs= 0;
370
 
 
371
 
static char *WhiteSkip(char *input)
372
 
{
373
 
  input+= strspn(input, " \t\n");
374
 
 
375
 
  while (!input[0] || input[0]=='#') { /* rest of line missing or comment */
376
 
    input= p_fgets(gs, line, 137);
377
 
    if (input) input= line + strspn(line, " \t\n");
378
 
    else break;
379
 
  }
380
 
 
381
 
  return input;
382
 
}
383
 
 
384
 
static char *DelimitRead(char *input, int *closed, int nlOK)
385
 
{
386
 
  int nlFound= 0;
387
 
 
388
 
  if (nlOK) {
389
 
    input+= strspn(input, " \t");
390
 
    if (*input=='\n' || *input=='\0') nlFound= 1;
391
 
  }
392
 
 
393
 
  input= WhiteSkip(input);
394
 
  if (input) {
395
 
    if (*input == CLOSE_BRACE) {
396
 
      *closed= 1;
397
 
      input++;
398
 
    } else {
399
 
      *closed= 0;
400
 
      if (*input == ',') {
401
 
        input++;
402
 
      } else {
403
 
        if (!nlOK || !nlFound) input= 0;
404
 
      }
405
 
    }
406
 
 
407
 
  } else {
408
 
    /* distinguish end-of-file from comma not found */
409
 
    *closed= 1;
410
 
  }
411
 
 
412
 
  return input;
413
 
}
414
 
 
415
 
static char *
416
 
ColRead(char *input, GpColorCell *dest)
417
 
{
418
 
  long value;
419
 
  char *suffix;
420
 
 
421
 
  input = WhiteSkip(input);  /* may be on a new line */
422
 
  value = strtol(input, &suffix, 0);
423
 
  if (suffix==input) return 0;
424
 
 
425
 
  if (value<0) value += 256;
426
 
  *dest = value;
427
 
  return suffix;
428
 
}
429
 
 
430
 
static char *IntRead(char *input, int *dest)
431
 
{
432
 
  int value;
433
 
  char *suffix;
434
 
 
435
 
  input= WhiteSkip(input);  /* may be on a new line */
436
 
  value= (int)strtol(input, &suffix, 0);
437
 
  if (suffix==input) return 0;
438
 
 
439
 
  *dest= value;
440
 
  return suffix;
441
 
}
442
 
 
443
 
static char *RealRead(char *input, GpReal *dest)
444
 
{
445
 
  GpReal value;
446
 
  char *suffix;
447
 
 
448
 
  input= WhiteSkip(input);  /* may be on a new line */
449
 
  value= (GpReal)strtod(input, &suffix);
450
 
  if (suffix==input) return 0;
451
 
 
452
 
  *dest= value;
453
 
  return suffix;
454
 
}
455
 
 
456
 
char legendString[41];
457
 
 
458
 
static char *StringRead(char *input, char **dest)
459
 
{
460
 
  input= WhiteSkip(input);
461
 
  if (input) {
462
 
    if (*input=='0') {
463
 
      *dest= 0;
464
 
      input++;
465
 
    } else if (*input=='\"') {
466
 
      long len= strcspn(++input, "\"");
467
 
      int nc= len>40? 40 : len;
468
 
      strncpy(legendString, input, nc);
469
 
      input+= len;
470
 
      if (*input=='\"') { *dest= legendString;  input++; }
471
 
      else input= 0;
472
 
    } else {
473
 
      input= 0;
474
 
    }
475
 
  }
476
 
  return input;
477
 
}
478
 
 
479
 
static char *MemberRead(char *input, char **member)
480
 
{
481
 
  input= WhiteSkip(input);
482
 
  *member= input;
483
 
  if (input) {
484
 
    int gotEqual= 0;
485
 
    input+= strcspn(input, "= \t\n");
486
 
    if (*input == '=') gotEqual= 1;
487
 
    if (*input) *input++= '\0';
488
 
    if (!gotEqual) {
489
 
      input= WhiteSkip(input);
490
 
      if (input && *input++!='=') input= 0;
491
 
    }
492
 
  }
493
 
  return input;
494
 
}
495
 
 
496
 
static char *ArrayRead(char *input, GpReal *dest, int narray)
497
 
{
498
 
  int foundClose;
499
 
 
500
 
  input= WhiteSkip(input);
501
 
  if (!input) return 0;
502
 
 
503
 
  if (*input++ != OPEN_BRACE) return 0;  /* no open brace */
504
 
  input= WhiteSkip(input);
505
 
  if (!input) return 0;                  /* eof after open brace */
506
 
 
507
 
  for (narray-- ; ; narray--) {
508
 
    if (narray<0) return 0;           /* too many numbers in aggregate */
509
 
 
510
 
    input= RealRead(input, dest++);
511
 
    if (!input) return 0;             /* token was not a number */
512
 
 
513
 
    input= DelimitRead(input, &foundClose, 0);
514
 
    if (!input) return 0;             /* neither comma nor close brace */
515
 
    if (foundClose) break;
516
 
  }
517
 
 
518
 
  return input;
519
 
}
520
 
 
521
 
static char *LineRead(char *input, GpLineAttribs *dest)
522
 
{
523
 
  int foundClose;
524
 
  char *member;
525
 
 
526
 
  input= WhiteSkip(input);
527
 
  if (!input || *input++!=OPEN_BRACE) return 0;
528
 
 
529
 
  for (;;) {
530
 
    input= MemberRead(input, &member);
531
 
    if (!input) return 0;             /* couldn't find member = */
532
 
 
533
 
    if (strcmp(member, "color")==0) {
534
 
      input= ColRead(input, &dest->color);
535
 
    } else if (strcmp(member, "type")==0) {
536
 
      input= IntRead(input, &dest->type);
537
 
    } else if (strcmp(member, "width")==0) {
538
 
      input= RealRead(input, &dest->width);
539
 
    } else {
540
 
      return 0;                       /* unknown member */
541
 
    }
542
 
    if (!input) return 0;             /* illegal format */
543
 
 
544
 
    input= DelimitRead(input, &foundClose, 1);
545
 
    if (!input) return 0;             /* not comma, nl, or close brace */
546
 
    if (foundClose) break;
547
 
  }
548
 
 
549
 
  return input;
550
 
}
551
 
 
552
 
static char *TextRead(char *input, GpTextAttribs *dest)
553
 
{
554
 
  int foundClose;
555
 
  char *member;
556
 
  int ijunk;
557
 
  GpReal rjunk;
558
 
 
559
 
  input= WhiteSkip(input);
560
 
  if (!input || *input++!=OPEN_BRACE) return 0;
561
 
 
562
 
  for (;;) {
563
 
    input= MemberRead(input, &member);
564
 
    if (!input) return 0;             /* couldn't find member = */
565
 
 
566
 
    if (strcmp(member, "color")==0) {
567
 
      input= ColRead(input, &dest->color);
568
 
    } else if (strcmp(member, "font")==0) {
569
 
      input= IntRead(input, &dest->font);
570
 
    } else if (strcmp(member, "prec")==0) {
571
 
      input= IntRead(input, &ijunk);
572
 
    } else if (strcmp(member, "height")==0) {
573
 
      input= RealRead(input, &dest->height);
574
 
    } else if (strcmp(member, "expand")==0) {
575
 
      input= RealRead(input, &rjunk);
576
 
    } else if (strcmp(member, "spacing")==0) {
577
 
      input= RealRead(input, &rjunk);
578
 
    } else if (strcmp(member, "upX")==0) {
579
 
      input= RealRead(input, &rjunk);
580
 
    } else if (strcmp(member, "upY")==0) {
581
 
      input= RealRead(input, &rjunk);
582
 
    } else if (strcmp(member, "path")==0 || strcmp(member, "orient")==0) {
583
 
      input= IntRead(input, &dest->orient);
584
 
    } else if (strcmp(member, "alignH")==0) {
585
 
      input= IntRead(input, &dest->alignH);
586
 
    } else if (strcmp(member, "alignV")==0) {
587
 
      input= IntRead(input, &dest->alignV);
588
 
    } else if (strcmp(member, "opaque")==0) {
589
 
      input= IntRead(input, &dest->opaque);
590
 
    } else {
591
 
      return 0;                       /* unknown member */
592
 
    }
593
 
    if (!input) return 0;             /* illegal format */
594
 
 
595
 
    input= DelimitRead(input, &foundClose, 1);
596
 
    if (!input) return 0;             /* not comma, nl, or close brace */
597
 
    if (foundClose) break;
598
 
  }
599
 
 
600
 
  return input;
601
 
}
602
 
 
603
 
static char *AxisRead(char *input, GaAxisStyle *dest)
604
 
{
605
 
  int foundClose;
606
 
  char *member;
607
 
 
608
 
  input= WhiteSkip(input);
609
 
  if (!input || *input++!=OPEN_BRACE) return 0;
610
 
 
611
 
  for (;;) {
612
 
    input= MemberRead(input, &member);
613
 
    if (!input) return 0;             /* couldn't find member = */
614
 
 
615
 
    if (strcmp(member, "nMajor")==0) {
616
 
      input= RealRead(input, &dest->nMajor);
617
 
    } else if (strcmp(member, "nMinor")==0) {
618
 
      input= RealRead(input, &dest->nMinor);
619
 
    } else if (strcmp(member, "logAdjMajor")==0) {
620
 
      input= RealRead(input, &dest->logAdjMajor);
621
 
    } else if (strcmp(member, "logAdjMinor")==0) {
622
 
      input= RealRead(input, &dest->logAdjMinor);
623
 
    } else if (strcmp(member, "nDigits")==0) {
624
 
      input= IntRead(input, &dest->nDigits);
625
 
    } else if (strcmp(member, "gridLevel")==0) {
626
 
      input= IntRead(input, &dest->gridLevel);
627
 
    } else if (strcmp(member, "flags")==0) {
628
 
      input= IntRead(input, &dest->flags);
629
 
    } else if (strcmp(member, "tickOff")==0) {
630
 
      input= RealRead(input, &dest->tickOff);
631
 
    } else if (strcmp(member, "labelOff")==0) {
632
 
      input= RealRead(input, &dest->labelOff);
633
 
    } else if (strcmp(member, "tickLen")==0) {
634
 
      input= ArrayRead(input, dest->tickLen, 5);
635
 
    } else if (strcmp(member, "tickStyle")==0) {
636
 
      input= LineRead(input, &dest->tickStyle);
637
 
    } else if (strcmp(member, "gridStyle")==0) {
638
 
      input= LineRead(input, &dest->gridStyle);
639
 
    } else if (strcmp(member, "textStyle")==0) {
640
 
      input= TextRead(input, &dest->textStyle);
641
 
    } else if (strcmp(member, "xOver")==0) {
642
 
      input= RealRead(input, &dest->xOver);
643
 
    } else if (strcmp(member, "yOver")==0) {
644
 
      input= RealRead(input, &dest->yOver);
645
 
    } else {
646
 
      return 0;                       /* unknown member */
647
 
    }
648
 
    if (!input) return 0;             /* illegal format */
649
 
 
650
 
    input= DelimitRead(input, &foundClose, 1);
651
 
    if (!input) return 0;             /* not comma, nl, or close brace */
652
 
    if (foundClose) break;
653
 
  }
654
 
 
655
 
  return input;
656
 
}
657
 
 
658
 
static char *TickRead(char *input, GaTickStyle *dest)
659
 
{
660
 
  int foundClose;
661
 
  char *member;
662
 
 
663
 
  input= WhiteSkip(input);
664
 
  if (!input || *input++!=OPEN_BRACE) return 0;
665
 
 
666
 
  for (;;) {
667
 
    input= MemberRead(input, &member);
668
 
    if (!input) return 0;             /* couldn't find member = */
669
 
 
670
 
    if (strcmp(member, "horiz")==0) {
671
 
      input= AxisRead(input, &dest->horiz);
672
 
    } else if (strcmp(member, "vert")==0) {
673
 
      input= AxisRead(input, &dest->vert);
674
 
    } else if (strcmp(member, "frame")==0) {
675
 
      input= IntRead(input, &dest->frame);
676
 
    } else if (strcmp(member, "frameStyle")==0) {
677
 
      input= LineRead(input, &dest->frameStyle);
678
 
    } else {
679
 
      return 0;                       /* unknown member */
680
 
    }
681
 
    if (!input) return 0;             /* illegal format */
682
 
 
683
 
    input= DelimitRead(input, &foundClose, 1);
684
 
    if (!input) return 0;             /* not comma, nl, or close brace */
685
 
    if (foundClose) break;
686
 
  }
687
 
 
688
 
  return input;
689
 
}
690
 
 
691
 
/* defaultSystem is initialized to reasonable value for portrait mode */
692
 
#define DEF_XMIN 0.25
693
 
#define DEF_XMAX 0.60
694
 
#define DEF_YMIN 0.50
695
 
#define DEF_YMAX 0.85
696
 
struct GsysRead defaultSystem= {
697
 
  0, { DEF_XMIN, DEF_XMAX, DEF_YMIN, DEF_YMAX },
698
 
  {
699
 
 
700
 
    {7.5, 50., 1.2, 1.2, 3, 1, TICK_L|TICK_U|TICK_OUT|LABEL_L,
701
 
     0.0, 14.0*ONE_POINT,
702
 
     {12.*ONE_POINT, 8.*ONE_POINT, 5.*ONE_POINT, 3.*ONE_POINT, 2.*ONE_POINT},
703
 
     {FG_COLOR, L_SOLID, DEFAULT_LINE_WIDTH},
704
 
     {FG_COLOR, L_DOT, DEFAULT_LINE_WIDTH},
705
 
     {FG_COLOR, T_HELVETICA, 14.*ONE_POINT, TX_RIGHT, TH_NORMAL, TV_NORMAL, 1},
706
 
     0.5*(DEF_XMIN+DEF_XMAX), DEF_YMIN-52.*ONE_POINT},
707
 
 
708
 
    {7.5, 50., 1.2, 1.2, 4, 1, TICK_L|TICK_U|TICK_OUT|LABEL_L,
709
 
     0.0, 14.0*ONE_POINT,
710
 
     {12.*ONE_POINT, 8.*ONE_POINT, 5.*ONE_POINT, 3.*ONE_POINT, 2.*ONE_POINT},
711
 
     {FG_COLOR, L_SOLID, DEFAULT_LINE_WIDTH},
712
 
     {FG_COLOR, L_DOT, DEFAULT_LINE_WIDTH},
713
 
     {FG_COLOR, T_HELVETICA, 14.*ONE_POINT, TX_RIGHT, TH_NORMAL, TV_NORMAL, 1},
714
 
     DEF_XMIN, DEF_YMIN-52.*ONE_POINT},
715
 
 
716
 
  0, {FG_COLOR, L_SOLID, DEFAULT_LINE_WIDTH}
717
 
  }
718
 
};
719
 
 
720
 
struct GlegRead defaultLegends[2]= {
721
 
  /* Ordinary legends form two 36x22 character columns below viewport */
722
 
  { 0.5*ONE_INCH, DEF_YMIN-64.*ONE_POINT, 3.875*ONE_INCH, 0.0,
723
 
    {FG_COLOR, T_COURIER, 12.*ONE_POINT, TX_RIGHT, TH_LEFT, TV_TOP, 1},
724
 
    36, 22, 2 },
725
 
  /* Contour legends get a single 14x28 column to left of viewport */
726
 
  { DEF_XMAX+14.*ONE_POINT, DEF_YMAX+12.*ONE_POINT, 0.0, 0.0,
727
 
    {FG_COLOR, T_COURIER, 12.*ONE_POINT, TX_RIGHT, TH_LEFT, TV_TOP, 1},
728
 
    14, 28, 1 },
729
 
};
730
 
 
731
 
static char *SystemRead(char *input, struct GsysRead *dest)
732
 
{
733
 
  int foundClose;
734
 
  char *member;
735
 
 
736
 
  input= WhiteSkip(input);
737
 
  if (!input || *input++!=OPEN_BRACE) return 0;
738
 
 
739
 
  for (;;) {
740
 
    input= MemberRead(input, &member);
741
 
    if (!input) return 0;             /* couldn't find member = */
742
 
 
743
 
    if (strcmp(member, "viewport")==0) {
744
 
      GpReal box[4];
745
 
      box[0]= box[1]= box[2]= box[3]= -1.0;
746
 
      input= ArrayRead(input, box, 4);
747
 
      if (box[3]<0.0) input= 0;       /* all four required */
748
 
      else {
749
 
        dest->viewport.xmin= box[0];
750
 
        dest->viewport.xmax= box[1];
751
 
        dest->viewport.ymin= box[2];
752
 
        dest->viewport.ymax= box[3];
753
 
      }
754
 
    } else if (strcmp(member, "ticks")==0) {
755
 
      input= TickRead(input, &dest->ticks);
756
 
    } else if (strcmp(member, "legend")==0) {
757
 
      input= StringRead(input, &dest->legend);
758
 
    } else {
759
 
      return 0;                       /* unknown member */
760
 
    }
761
 
    if (!input) return 0;             /* illegal format */
762
 
 
763
 
    input= DelimitRead(input, &foundClose, 1);
764
 
    if (!input) return 0;             /* not comma, nl, or close brace */
765
 
    if (foundClose) break;
766
 
  }
767
 
 
768
 
  return input;
769
 
}
770
 
 
771
 
static char *LegendsRead(char *input, struct GlegRead *dest)
772
 
{
773
 
  int foundClose;
774
 
  char *member;
775
 
 
776
 
  input= WhiteSkip(input);
777
 
  if (!input || *input++!=OPEN_BRACE) return 0;
778
 
 
779
 
  for (;;) {
780
 
    input= MemberRead(input, &member);
781
 
    if (!input) return 0;             /* couldn't find member = */
782
 
 
783
 
    if (strcmp(member, "x")==0) {
784
 
      input= RealRead(input, &dest->x);
785
 
    } else if (strcmp(member, "y")==0) {
786
 
      input= RealRead(input, &dest->y);
787
 
    } else if (strcmp(member, "dx")==0) {
788
 
      input= RealRead(input, &dest->dx);
789
 
    } else if (strcmp(member, "dy")==0) {
790
 
      input= RealRead(input, &dest->dy);
791
 
    } else if (strcmp(member, "textStyle")==0) {
792
 
      input= TextRead(input, &dest->textStyle);
793
 
    } else if (strcmp(member, "nchars")==0) {
794
 
      input= IntRead(input, &dest->nchars);
795
 
    } else if (strcmp(member, "nlines")==0) {
796
 
      input= IntRead(input, &dest->nlines);
797
 
    } else if (strcmp(member, "nwrap")==0) {
798
 
      input= IntRead(input, &dest->nwrap);
799
 
    } else {
800
 
      return 0;                       /* unknown member */
801
 
    }
802
 
    if (!input) return 0;             /* illegal format */
803
 
 
804
 
    input= DelimitRead(input, &foundClose, 1);
805
 
    if (!input) return 0;             /* not comma, nl, or close brace */
806
 
    if (foundClose) break;
807
 
  }
808
 
 
809
 
  return input;
810
 
}
811
 
 
812
 
int GdReadStyle(Drauing *drawing, const char *gsFile)
813
 
{
814
 
  int foundClose, sysIndex, landscape;
815
 
  char *input, *keyword;
816
 
 
817
 
  if (!gsFile) return 0;
818
 
 
819
 
  gs= GistOpen(gsFile);
820
 
  if (!gs) return 1;
821
 
 
822
 
  tempSystem= defaultSystem;
823
 
  landscape= 0;
824
 
 
825
 
  input= p_fgets(gs, line, 137);
826
 
  if (!input) goto err;                      /* eof (or error) */
827
 
 
828
 
  GdKillSystems();
829
 
 
830
 
  for (;;) {
831
 
    input= WhiteSkip(input);
832
 
    if (!input) break;
833
 
 
834
 
    input= MemberRead(input, &keyword);
835
 
    if (!input) goto err;             /* couldn't find keyword = */
836
 
 
837
 
    if (strcmp(keyword, "default")==0) {
838
 
      input= SystemRead(input, &tempSystem);
839
 
    } else if (strcmp(keyword, "system")==0) {
840
 
      modelSystem= tempSystem;
841
 
      input= SystemRead(input, &modelSystem);
842
 
      gistD.hidden= 0;
843
 
      gistD.legend= modelSystem.legend;
844
 
      sysIndex= GdNewSystem(&modelSystem.viewport, &modelSystem.ticks);
845
 
      if (sysIndex<0) return 1;
846
 
    } else if (strcmp(keyword, "landscape")==0) {
847
 
      input= IntRead(input, &landscape);
848
 
    } else if (strcmp(keyword, "legends")==0) {
849
 
      modelLegends= defaultLegends[0];
850
 
      input= LegendsRead(input, &modelLegends);
851
 
      if (input) GdLegendBox(0, modelLegends.x, modelLegends.y,
852
 
                             modelLegends.dx, modelLegends.dy,
853
 
                             &modelLegends.textStyle, modelLegends.nchars,
854
 
                             modelLegends.nlines, modelLegends.nwrap);
855
 
    } else if (strcmp(keyword, "clegends")==0) {
856
 
      modelLegends= defaultLegends[1];
857
 
      input= LegendsRead(input, &modelLegends);
858
 
      if (input) GdLegendBox(1, modelLegends.x, modelLegends.y,
859
 
                             modelLegends.dx, modelLegends.dy,
860
 
                             &modelLegends.textStyle, modelLegends.nchars,
861
 
                             modelLegends.nlines, modelLegends.nwrap);
862
 
    } else {
863
 
      goto err;                       /* unknown keyword */
864
 
    }
865
 
    if (!input) goto err;             /* illegal format */
866
 
 
867
 
    input= DelimitRead(input, &foundClose, 1);
868
 
    if (!input) {
869
 
      if (foundClose) break;
870
 
      goto err;                       /* not comma, nl, or eof */
871
 
    }
872
 
    if (foundClose) goto err;         /* close brace not legal here */
873
 
  }
874
 
 
875
 
  if (landscape) GdLandscape(1);
876
 
  p_fclose(gs);
877
 
  return 0;
878
 
 
879
 
 err:
880
 
  FormatError(gs, gsFile, "drawing style");
881
 
  return 1;
882
 
}
883
 
 
884
 
/* ------------------------------------------------------------------------ */