ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/mgflib/parser.c
(Generate patch)

Comparing ray/src/cv/mgflib/parser.c (file contents):
Revision 1.12 by greg, Fri Jul 22 09:58:49 1994 UTC vs.
Revision 1.27 by greg, Fri Feb 28 20:11:29 2003 UTC

# Line 1 | Line 1
1 /* Copyright (c) 1994 Regents of the University of California */
2
1   #ifndef lint
2 < static char SCCSid[] = "$SunId$ LBL";
2 > static const char       RCSid[] = "$Id$";
3   #endif
6
4   /*
5   * Parse an MGF file, converting or discarding unsupported entities
6   */
7  
8   #include <stdio.h>
9 + #include <stdlib.h>
10   #include <math.h>
11   #include <ctype.h>
12   #include <string.h>
# Line 27 | Line 25 | char   mg_ename[MG_NENTITIES][MG_MAXELEN] = MG_NAMELIST;
25  
26   int     (*mg_ehand[MG_NENTITIES])();
27  
28 +                        /* Handler routine for unknown entities */
29 +
30 + int     (*mg_uhand)() = mg_defuhand;
31 +
32 + unsigned        mg_nunknown;    /* count of unknown entities */
33 +
34                          /* error messages */
35  
36   char    *mg_err[MG_NERRS] = MG_ERRLIST;
# Line 57 | Line 61 | int    mg_nqcdivs = MG_NQCD;   /* number of divisions per q
61  
62   static int      e_any_toss(),           /* discard unneeded entity */
63                  e_ies(),                /* IES luminaire file */
64 <                e_include(),            /* include file */
61 <                e_sph(),                /* sphere */
64 >                e_cct(),                /* color temperature */
65                  e_cmix(),               /* color mixtures */
66 <                e_cspec(),              /* color spectra */
64 <                e_cyl(),                /* cylinder */
65 <                e_cone(),               /* cone */
66 <                e_prism(),              /* prism */
67 <                e_ring(),               /* ring */
68 <                e_torus();              /* torus */
66 >                e_cspec();              /* color spectra */
67  
68                                  /* alternate handler support functions */
69  
# Line 88 | Line 86 | mg_init()                      /* initialize alternate entity handlers */
86                  mg_ehand[MG_E_INCLUDE] = e_include;
87          if (mg_ehand[MG_E_SPH] == NULL) {
88                  mg_ehand[MG_E_SPH] = e_sph;
89 <                ineed |= 1<<MG_E_POINT|1<<MG_E_VERTEX;
89 >                ineed |= 1L<<MG_E_POINT|1L<<MG_E_VERTEX;
90          } else
91 <                uneed |= 1<<MG_E_POINT|1<<MG_E_VERTEX|1<<MG_E_XF;
91 >                uneed |= 1L<<MG_E_POINT|1L<<MG_E_VERTEX|1L<<MG_E_XF;
92          if (mg_ehand[MG_E_CYL] == NULL) {
93                  mg_ehand[MG_E_CYL] = e_cyl;
94 <                ineed |= 1<<MG_E_POINT|1<<MG_E_VERTEX;
94 >                ineed |= 1L<<MG_E_POINT|1L<<MG_E_VERTEX;
95          } else
96 <                uneed |= 1<<MG_E_POINT|1<<MG_E_VERTEX|1<<MG_E_XF;
96 >                uneed |= 1L<<MG_E_POINT|1L<<MG_E_VERTEX|1L<<MG_E_XF;
97          if (mg_ehand[MG_E_CONE] == NULL) {
98                  mg_ehand[MG_E_CONE] = e_cone;
99 <                ineed |= 1<<MG_E_POINT|1<<MG_E_VERTEX;
99 >                ineed |= 1L<<MG_E_POINT|1L<<MG_E_VERTEX;
100          } else
101 <                uneed |= 1<<MG_E_POINT|1<<MG_E_VERTEX|1<<MG_E_XF;
101 >                uneed |= 1L<<MG_E_POINT|1L<<MG_E_VERTEX|1L<<MG_E_XF;
102          if (mg_ehand[MG_E_RING] == NULL) {
103                  mg_ehand[MG_E_RING] = e_ring;
104 <                ineed |= 1<<MG_E_POINT|1<<MG_E_NORMAL|1<<MG_E_VERTEX;
104 >                ineed |= 1L<<MG_E_POINT|1L<<MG_E_NORMAL|1L<<MG_E_VERTEX;
105          } else
106 <                uneed |= 1<<MG_E_POINT|1<<MG_E_NORMAL|1<<MG_E_VERTEX|1<<MG_E_XF;
106 >                uneed |= 1L<<MG_E_POINT|1L<<MG_E_NORMAL|1L<<MG_E_VERTEX|1L<<MG_E_XF;
107          if (mg_ehand[MG_E_PRISM] == NULL) {
108                  mg_ehand[MG_E_PRISM] = e_prism;
109 <                ineed |= 1<<MG_E_POINT|1<<MG_E_VERTEX;
109 >                ineed |= 1L<<MG_E_POINT|1L<<MG_E_VERTEX;
110          } else
111 <                uneed |= 1<<MG_E_POINT|1<<MG_E_VERTEX|1<<MG_E_XF;
111 >                uneed |= 1L<<MG_E_POINT|1L<<MG_E_VERTEX|1L<<MG_E_XF;
112          if (mg_ehand[MG_E_TORUS] == NULL) {
113                  mg_ehand[MG_E_TORUS] = e_torus;
114 <                ineed |= 1<<MG_E_POINT|1<<MG_E_NORMAL|1<<MG_E_VERTEX;
114 >                ineed |= 1L<<MG_E_POINT|1L<<MG_E_NORMAL|1L<<MG_E_VERTEX;
115          } else
116 <                uneed |= 1<<MG_E_POINT|1<<MG_E_NORMAL|1<<MG_E_VERTEX|1<<MG_E_XF;
116 >                uneed |= 1L<<MG_E_POINT|1L<<MG_E_NORMAL|1L<<MG_E_VERTEX|1L<<MG_E_XF;
117 >        if (mg_ehand[MG_E_FACE] == NULL)
118 >                mg_ehand[MG_E_FACE] = mg_ehand[MG_E_FACEH];
119 >        else if (mg_ehand[MG_E_FACEH] == NULL)
120 >                mg_ehand[MG_E_FACEH] = e_faceh;
121          if (mg_ehand[MG_E_COLOR] != NULL) {
122                  if (mg_ehand[MG_E_CMIX] == NULL) {
123                          mg_ehand[MG_E_CMIX] = e_cmix;
124 <                        ineed |= 1<<MG_E_COLOR|1<<MG_E_CXY|1<<MG_E_CSPEC|1<<MG_E_CMIX;
124 >                        ineed |= 1L<<MG_E_COLOR|1L<<MG_E_CXY|1L<<MG_E_CSPEC|1L<<MG_E_CMIX|1L<<MG_E_CCT;
125                  }
126                  if (mg_ehand[MG_E_CSPEC] == NULL) {
127                          mg_ehand[MG_E_CSPEC] = e_cspec;
128 <                        ineed |= 1<<MG_E_COLOR|1<<MG_E_CXY|1<<MG_E_CSPEC|1<<MG_E_CMIX;
128 >                        ineed |= 1L<<MG_E_COLOR|1L<<MG_E_CXY|1L<<MG_E_CSPEC|1L<<MG_E_CMIX|1L<<MG_E_CCT;
129                  }
130 +                if (mg_ehand[MG_E_CCT] == NULL) {
131 +                        mg_ehand[MG_E_CCT] = e_cct;
132 +                        ineed |= 1L<<MG_E_COLOR|1L<<MG_E_CXY|1L<<MG_E_CSPEC|1L<<MG_E_CMIX|1L<<MG_E_CCT;
133 +                }
134          }
135                                          /* check for consistency */
136          if (mg_ehand[MG_E_FACE] != NULL)
137 <                uneed |= 1<<MG_E_POINT|1<<MG_E_VERTEX|1<<MG_E_XF;
137 >                uneed |= 1L<<MG_E_POINT|1L<<MG_E_VERTEX|1L<<MG_E_XF;
138          if (mg_ehand[MG_E_CXY] != NULL || mg_ehand[MG_E_CSPEC] != NULL ||
139                          mg_ehand[MG_E_CMIX] != NULL)
140 <                uneed |= 1<<MG_E_COLOR;
140 >                uneed |= 1L<<MG_E_COLOR;
141          if (mg_ehand[MG_E_RD] != NULL || mg_ehand[MG_E_TD] != NULL ||
142 +                        mg_ehand[MG_E_IR] != NULL ||
143                          mg_ehand[MG_E_ED] != NULL ||
144                          mg_ehand[MG_E_RS] != NULL ||
145                          mg_ehand[MG_E_TS] != NULL ||
146                          mg_ehand[MG_E_SIDES] != NULL)
147 <                uneed |= 1<<MG_E_MATERIAL;
147 >                uneed |= 1L<<MG_E_MATERIAL;
148          for (i = 0; i < MG_NENTITIES; i++)
149 <                if (uneed & 1<<i && mg_ehand[i] == NULL) {
149 >                if (uneed & 1L<<i && mg_ehand[i] == NULL) {
150                          fprintf(stderr, "Missing support for \"%s\" entity\n",
151                                          mg_ename[i]);
152                          exit(1);
153                  }
154                                          /* add support as needed */
155 <        if (ineed & 1<<MG_E_VERTEX && mg_ehand[MG_E_VERTEX] != c_hvertex)
155 >        if (ineed & 1L<<MG_E_VERTEX && mg_ehand[MG_E_VERTEX] != c_hvertex)
156                  e_supp[MG_E_VERTEX] = c_hvertex;
157 <        if (ineed & 1<<MG_E_POINT && mg_ehand[MG_E_POINT] != c_hvertex)
157 >        if (ineed & 1L<<MG_E_POINT && mg_ehand[MG_E_POINT] != c_hvertex)
158                  e_supp[MG_E_POINT] = c_hvertex;
159 <        if (ineed & 1<<MG_E_NORMAL && mg_ehand[MG_E_NORMAL] != c_hvertex)
159 >        if (ineed & 1L<<MG_E_NORMAL && mg_ehand[MG_E_NORMAL] != c_hvertex)
160                  e_supp[MG_E_NORMAL] = c_hvertex;
161 <        if (ineed & 1<<MG_E_COLOR && mg_ehand[MG_E_COLOR] != c_hcolor)
161 >        if (ineed & 1L<<MG_E_COLOR && mg_ehand[MG_E_COLOR] != c_hcolor)
162                  e_supp[MG_E_COLOR] = c_hcolor;
163 <        if (ineed & 1<<MG_E_CXY && mg_ehand[MG_E_CXY] != c_hcolor)
163 >        if (ineed & 1L<<MG_E_CXY && mg_ehand[MG_E_CXY] != c_hcolor)
164                  e_supp[MG_E_CXY] = c_hcolor;
165 <        if (ineed & 1<<MG_E_CSPEC && mg_ehand[MG_E_CSPEC] != c_hcolor)
165 >        if (ineed & 1L<<MG_E_CSPEC && mg_ehand[MG_E_CSPEC] != c_hcolor)
166                  e_supp[MG_E_CSPEC] = c_hcolor;
167 <        if (ineed & 1<<MG_E_CMIX && mg_ehand[MG_E_CMIX] != c_hcolor)
167 >        if (ineed & 1L<<MG_E_CMIX && mg_ehand[MG_E_CMIX] != c_hcolor)
168                  e_supp[MG_E_CMIX] = c_hcolor;
169 +        if (ineed & 1L<<MG_E_CCT && mg_ehand[MG_E_CCT] != c_hcolor)
170 +                e_supp[MG_E_CCT] = c_hcolor;
171                                          /* discard remaining entities */
172          for (i = 0; i < MG_NENTITIES; i++)
173                  if (mg_ehand[i] == NULL)
# Line 166 | Line 175 | mg_init()                      /* initialize alternate entity handlers */
175   }
176  
177  
169
178   int
179   mg_entity(name)                 /* get entity number from its name */
180   char    *name;
# Line 196 | Line 204 | char   **av;
204   {
205          int     rv;
206  
207 <        if (en < 0 && (en = mg_entity(av[0])) < 0)
207 >        if (en < 0 && (en = mg_entity(av[0])) < 0) {    /* unknown entity */
208 >                if (mg_uhand != NULL)
209 >                        return((*mg_uhand)(ac, av));
210                  return(MG_EUNK);
211 <        if (e_supp[en] != NULL) {
211 >        }
212 >        if (e_supp[en] != NULL) {                       /* support handler */
213                  if ((rv = (*e_supp[en])(ac, av)) != MG_OK)
214                          return(rv);
215          }
216 <        return((*mg_ehand[en])(ac, av));
216 >        return((*mg_ehand[en])(ac, av));                /* assigned handler */
217   }
218  
219  
# Line 212 | Line 223 | register MG_FCTXT      *ctx;
223   char    *fn;
224   {
225          static int      nfids;
215        int     olen;
226          register char   *cp;
227  
228          ctx->fid = ++nfids;
# Line 225 | Line 235 | char   *fn;
235                  return(MG_OK);
236          }
237                                          /* get name relative to this context */
238 <        if (mg_file != NULL &&
239 <                        (cp = strrchr(mg_file->fname, '/')) != NULL)
230 <                olen = cp - mg_file->fname + 1;
231 <        else
232 <                olen = 0;
233 <        if (olen)
238 >        if (fn[0] != '/' && mg_file != NULL &&
239 >                        (cp = strrchr(mg_file->fname, '/')) != NULL) {
240                  strcpy(ctx->fname, mg_file->fname);
241 <        strcpy(ctx->fname+olen, fn);
241 >                strcpy(ctx->fname+(cp-mg_file->fname+1), fn);
242 >        } else
243 >                strcpy(ctx->fname, fn);
244          ctx->fp = fopen(ctx->fname, "r");
245          if (ctx->fp == NULL)
246                  return(MG_ENOFILE);
# Line 248 | Line 256 | mg_close()                     /* close input file */
256          register MG_FCTXT       *ctx = mg_file;
257  
258          mg_file = ctx->prev;            /* restore enclosing context */
259 <        if (ctx->fp == stdin)
260 <                return;                 /* don't close standard input */
253 <        fclose(ctx->fp);
259 >        if (ctx->fp != stdin)           /* close file if it's a file */
260 >                fclose(ctx->fp);
261   }
262  
263  
# Line 258 | Line 265 | void
265   mg_fgetpos(pos)                 /* get current position in input file */
266   register MG_FPOS        *pos;
267   {
261        extern long     ftell();
262
268          pos->fid = mg_file->fid;
269          pos->lineno = mg_file->lineno;
270          pos->offset = ftell(mg_file->fp);
# Line 292 | Line 297 | mg_read()                      /* read next line from file */
297                  if (fgets(mg_file->inpline+len,
298                                  MG_MAXLINE-len, mg_file->fp) == NULL)
299                          return(len);
295                mg_file->lineno++;
300                  len += strlen(mg_file->inpline+len);
301 <                if (len > 1 && mg_file->inpline[len-2] == '\\')
302 <                        mg_file->inpline[--len-1] = ' ';
303 <        } while (mg_file->inpline[len]);
301 >                if (len >= MG_MAXLINE-1)
302 >                        return(len);
303 >                mg_file->lineno++;
304 >        } while (len > 1 && mg_file->inpline[len-2] == '\\');
305  
306          return(len);
307   }
# Line 307 | Line 312 | mg_parse()                     /* parse current input line */
312   {
313          char    abuf[MG_MAXLINE];
314          char    *argv[MG_MAXARGC];
315 <        int     en;
316 <        register char   *cp, **ap;
317 <
318 <        strcpy(cp=abuf, mg_file->inpline);
319 <        ap = argv;                      /* break into words */
315 >        register char   *cp, *cp2, **ap;
316 >                                        /* copy line, removing escape chars */
317 >        cp = abuf; cp2 = mg_file->inpline;
318 >        while ((*cp++ = *cp2++))
319 >                if (cp2[0] == '\n' && cp2[-1] == '\\')
320 >                        cp--;
321 >        cp = abuf; ap = argv;           /* break into words */
322          for ( ; ; ) {
323                  while (isspace(*cp))
324                          *cp++ = '\0';
# Line 337 | Line 344 | char   *fn;
344   {
345          MG_FCTXT        cntxt;
346          int     rval;
347 +        register int    nbr;
348  
349          if ((rval = mg_open(&cntxt, fn)) != MG_OK) {
350                  fprintf(stderr, "%s: %s\n", fn, mg_err[rval]);
351                  return(rval);
352          }
353 <        while (mg_read())               /* parse each line */
353 >        while ((nbr = mg_read()) > 0) { /* parse each line */
354 >                if (nbr >= MG_MAXLINE-1) {
355 >                        fprintf(stderr, "%s: %d: %s\n", cntxt.fname,
356 >                                        cntxt.lineno, mg_err[rval=MG_ELINE]);
357 >                        break;
358 >                }
359                  if ((rval = mg_parse()) != MG_OK) {
360                          fprintf(stderr, "%s: %d: %s:\n%s", cntxt.fname,
361                                          cntxt.lineno, mg_err[rval],
362                                          cntxt.inpline);
363                          break;
364                  }
365 +        }
366          mg_close();
367          return(rval);
368   }
369  
370  
371 + int
372 + mg_defuhand(ac, av)             /* default handler for unknown entities */
373 + int     ac;
374 + char    **av;
375 + {
376 +        if (mg_nunknown++ == 0)         /* report first incident */
377 +                fprintf(stderr, "%s: %d: %s: %s\n", mg_file->fname,
378 +                                mg_file->lineno, mg_err[MG_EUNK], av[0]);
379 +        return(MG_OK);
380 + }
381 +
382 +
383   void
384   mg_clear()                      /* clear parser history */
385   {
386          c_clearall();                   /* clear context tables */
387 <        mg_file = NULL;                 /* reset our context */
387 >        while (mg_file != NULL)         /* reset our file context */
388 >                mg_close();
389   }
390  
391  
# Line 376 | Line 403 | char   **av;
403   }
404  
405  
406 < static int
406 > int
407   e_include(ac, av)               /* include file */
408   int     ac;
409   char    **av;
410   {
411          char    *xfarg[MG_MAXARGC];
412          MG_FCTXT        ictx;
413 <        int     rv;
413 >        XF_SPEC *xf_orig = xf_context;
414 >        register int    rv;
415  
416          if (ac < 2)
417                  return(MG_EARGC);
# Line 396 | Line 424 | char   **av;
424                  for (i = 1; i < ac-1; i++)
425                          xfarg[i] = av[i+1];
426                  xfarg[ac-1] = NULL;
427 <                if ((rv = mg_handle(MG_E_XF, ac-1, xfarg)) != MG_OK)
427 >                if ((rv = mg_handle(MG_E_XF, ac-1, xfarg)) != MG_OK) {
428 >                        mg_close();
429                          return(rv);
430 +                }
431          }
432 <        while (!feof(mg_file->fp)) {
433 <                while (mg_read())
432 >        do {
433 >                while ((rv = mg_read()) > 0) {
434 >                        if (rv >= MG_MAXLINE-1) {
435 >                                fprintf(stderr, "%s: %d: %s\n", ictx.fname,
436 >                                                ictx.lineno, mg_err[MG_ELINE]);
437 >                                mg_close();
438 >                                return(MG_EINCL);
439 >                        }
440                          if ((rv = mg_parse()) != MG_OK) {
441                                  fprintf(stderr, "%s: %d: %s:\n%s", ictx.fname,
442                                                  ictx.lineno, mg_err[rv],
# Line 408 | Line 444 | char   **av;
444                                  mg_close();
445                                  return(MG_EINCL);
446                          }
447 +                }
448                  if (ac > 2)
449 <                        if ((rv = mg_handle(MG_E_XF, 1, xfarg)) != MG_OK)
449 >                        if ((rv = mg_handle(MG_E_XF, 1, xfarg)) != MG_OK) {
450 >                                mg_close();
451                                  return(rv);
452 <        }
452 >                        }
453 >        } while (xf_context != xf_orig);
454          mg_close();
455          return(MG_OK);
456   }
457  
458  
459 + int
460 + e_faceh(ac, av)                 /* replace face+holes with single contour */
461 + int     ac;
462 + char    **av;
463 + {
464 +        char    *newav[MG_MAXARGC];
465 +        int     lastp = 0;
466 +        register int    i, j;
467 +
468 +        newav[0] = mg_ename[MG_E_FACE];
469 +        for (i = 1; i < ac; i++)
470 +                if (av[i][0] == '-') {
471 +                        if (i < 4)
472 +                                return(MG_EARGC);
473 +                        if (i >= ac-1)
474 +                                break;
475 +                        if (!lastp)
476 +                                lastp = i-1;
477 +                        for (j = i+1; j < ac-1 && av[j+1][0] != '-'; j++)
478 +                                ;
479 +                        if (j - i < 3)
480 +                                return(MG_EARGC);
481 +                        newav[i] = av[j];       /* connect hole loop */
482 +                } else
483 +                        newav[i] = av[i];       /* hole or perimeter vertex */
484 +        if (lastp)
485 +                newav[i++] = av[lastp];         /* finish seam to outside */
486 +        newav[i] = NULL;
487 +        return(mg_handle(MG_E_FACE, i, newav));
488 + }
489 +
490 +
491   static void
492   make_axes(u, v, w)              /* compute u and v given w (normalized) */
493   FVECT   u, v, w;
# Line 434 | Line 505 | FVECT  u, v, w;
505   }
506  
507  
508 < static int
508 > int
509   e_sph(ac, av)                   /* expand a sphere into cones */
510   int     ac;
511   char    **av;
# Line 486 | Line 557 | char   **av;
557   }
558  
559  
560 < static int
560 > int
561   e_torus(ac, av)                 /* expand a torus into cones */
562   int     ac;
563   char    **av;
# Line 578 | Line 649 | char   **av;
649   }
650  
651  
652 < static int
652 > int
653   e_cyl(ac, av)                   /* replace a cylinder with equivalent cone */
654   int     ac;
655   char    **av;
# Line 595 | Line 666 | char   **av;
666   }
667  
668  
669 < static int
669 > int
670   e_ring(ac, av)                  /* turn a ring into polygons */
671   int     ac;
672   char    **av;
# Line 693 | Line 764 | char   **av;
764   }
765  
766  
767 < static int
767 > int
768   e_cone(ac, av)                  /* turn a cone into polygons */
769   int     ac;
770   char    **av;
# Line 708 | Line 779 | char   **av;
779          static char     *p4ent[5] = {mg_ename[MG_E_POINT],p4[0],p4[1],p4[2]};
780          static char     *n4ent[5] = {mg_ename[MG_E_NORMAL],n4[0],n4[1],n4[2]};
781          static char     *fent[6] = {mg_ename[MG_E_FACE],"_cv1","_cv2","_cv3","_cv4"};
782 +        char    *v1n;
783          register C_VERTEX       *cv1, *cv2;
784          register int    i, j;
785          FVECT   u, v, w;
# Line 723 | Line 795 | char   **av;
795          if ((cv1 = c_getvert(av[1])) == NULL ||
796                          (cv2 = c_getvert(av[3])) == NULL)
797                  return(MG_EUNDEF);
798 +        v1n = av[1];
799          if (!isflt(av[2]) || !isflt(av[4]))
800                  return(MG_ETYPE);
801          rad1 = atof(av[2]);
# Line 733 | Line 806 | char   **av;
806                  if (rad2 == 0.)
807                          return(MG_EILL);
808          } else if (rad2 != 0.) {
809 <                if (rad1 < 0. ^ rad2 < 0.)
809 >                if ((rad1 < 0.) ^ (rad2 < 0.))
810                          return(MG_EILL);
811          } else {                        /* swap */
812                  C_VERTEX        *cv;
# Line 741 | Line 814 | char   **av;
814                  cv = cv1;
815                  cv1 = cv2;
816                  cv2 = cv;
817 +                v1n = av[3];
818                  d = rad1;
819                  rad1 = rad2;
820                  rad2 = d;
# Line 774 | Line 848 | char   **av;
848          if ((rv = mg_handle(MG_E_NORMAL, 4, n3ent)) != MG_OK)
849                  return(rv);
850          if (rad1 == 0.) {               /* triangles */
851 <                v1ent[3] = av[1];
851 >                v1ent[3] = v1n;
852                  if ((rv = mg_handle(MG_E_VERTEX, 4, v1ent)) != MG_OK)
853                          return(rv);
854                  for (j = 0; j < 3; j++)
# Line 860 | Line 934 | char   **av;
934   }
935  
936  
937 < static int
937 > int
938   e_prism(ac, av)                 /* turn a prism into polygons */
939   int     ac;
940   char    **av;
# Line 968 | Line 1042 | char   **av;
1042  
1043  
1044   static int
1045 < e_cspec(ac, av)                 /* handle spectral color */
972 < int     ac;
973 < char    **av;
1045 > put_cxy()                       /* put out current xy chromaticities */
1046   {
1047          static char     xbuf[24], ybuf[24];
1048          static char     *ccom[4] = {mg_ename[MG_E_CXY], xbuf, ybuf};
977        int     rv;
1049  
1050 +        sprintf(xbuf, "%.4f", c_ccolor->cx);
1051 +        sprintf(ybuf, "%.4f", c_ccolor->cy);
1052 +        return(mg_handle(MG_E_CXY, 3, ccom));
1053 + }
1054 +
1055 +
1056 + static int
1057 + put_cspec()                     /* put out current color spectrum */
1058 + {
1059 +        char    wl[2][6], vbuf[C_CNSS][24];
1060 +        char    *newav[C_CNSS+4];
1061 +        double  sf;
1062 +        register int    i;
1063 +
1064 +        if (mg_ehand[MG_E_CSPEC] != c_hcolor) {
1065 +                sprintf(wl[0], "%d", C_CMINWL);
1066 +                sprintf(wl[1], "%d", C_CMAXWL);
1067 +                newav[0] = mg_ename[MG_E_CSPEC];
1068 +                newav[1] = wl[0];
1069 +                newav[2] = wl[1];
1070 +                sf = (double)C_CNSS / c_ccolor->ssum;
1071 +                for (i = 0; i < C_CNSS; i++) {
1072 +                        sprintf(vbuf[i], "%.4f", sf*c_ccolor->ssamp[i]);
1073 +                        newav[i+3] = vbuf[i];
1074 +                }
1075 +                newav[C_CNSS+3] = NULL;
1076 +                if ((i = mg_handle(MG_E_CSPEC, C_CNSS+3, newav)) != MG_OK)
1077 +                        return(i);
1078 +        }
1079 +        return(MG_OK);
1080 + }
1081 +
1082 +
1083 + static int
1084 + e_cspec(ac, av)                 /* handle spectral color */
1085 + int     ac;
1086 + char    **av;
1087 + {
1088 +                                /* convert to xy chromaticity */
1089          c_ccvt(c_ccolor, C_CSXY);
1090                                  /* if it's really their handler, use it */
1091 <        if (mg_ehand[MG_E_CXY] != c_hcolor) {
1092 <                sprintf(xbuf, "%.4f", c_ccolor->cx);
983 <                sprintf(ybuf, "%.4f", c_ccolor->cy);
984 <                if ((rv = mg_handle(MG_E_CXY, 3, ccom)) != MG_OK)
985 <                        return(rv);
986 <        }
1091 >        if (mg_ehand[MG_E_CXY] != c_hcolor)
1092 >                return(put_cxy());
1093          return(MG_OK);
1094   }
1095  
# Line 993 | Line 1099 | e_cmix(ac, av)                 /* handle mixing of colors */
1099   int     ac;
1100   char    **av;
1101   {
996        char    wl[2][6], vbuf[C_CNSS][24];
997        char    *newav[C_CNSS+4];
998        int     rv;
999        register int    i;
1102          /*
1103           * Contorted logic works as follows:
1104           *      1. the colors are already mixed in c_hcolor() support function
# Line 1007 | Line 1109 | char   **av;
1109           */
1110          if (mg_ehand[MG_E_CSPEC] == e_cspec)
1111                  c_ccvt(c_ccolor, C_CSXY);
1112 <        else if (c_ccolor->flags & C_CDSPEC) {
1113 <                if (mg_ehand[MG_E_CSPEC] != c_hcolor) {
1114 <                        sprintf(wl[0], "%d", C_CMINWL);
1115 <                        sprintf(wl[1], "%d", C_CMAXWL);
1116 <                        newav[0] = mg_ename[MG_E_CSPEC];
1117 <                        newav[1] = wl[0];
1118 <                        newav[2] = wl[1];
1119 <                        for (i = 0; i < C_CNSS; i++) {
1120 <                                sprintf(vbuf[i], "%.6f",
1121 <                                                (double)c_ccolor->ssamp[i] /
1122 <                                                c_ccolor->ssum);
1123 <                                newav[i+3] = vbuf[i];
1124 <                        }
1125 <                        newav[C_CNSS+3] = NULL;
1126 <                        if ((rv = mg_handle(MG_E_CSPEC, C_CNSS+3, newav)) != MG_OK)
1127 <                                return(rv);
1128 <                }
1129 <                return(MG_OK);
1130 <        }
1131 <        if (mg_ehand[MG_E_CXY] != c_hcolor) {
1132 <                sprintf(vbuf[0], "%.4f", c_ccolor->cx);
1133 <                sprintf(vbuf[1], "%.4f", c_ccolor->cy);
1134 <                newav[0] = mg_ename[MG_E_CXY];
1135 <                newav[1] = vbuf[0];
1034 <                newav[2] = vbuf[1];
1035 <                newav[3] = NULL;
1036 <                if ((rv = mg_handle(MG_E_CXY, 3, newav)) != MG_OK)
1037 <                        return(rv);
1038 <        }
1112 >        else if (c_ccolor->flags & C_CDSPEC)
1113 >                return(put_cspec());
1114 >        if (mg_ehand[MG_E_CXY] != c_hcolor)
1115 >                return(put_cxy());
1116 >        return(MG_OK);
1117 > }
1118 >
1119 >
1120 > static int
1121 > e_cct(ac, av)                   /* handle color temperature */
1122 > int     ac;
1123 > char    **av;
1124 > {
1125 >        /*
1126 >         * Logic is similar to e_cmix here.  Support handler has already
1127 >         * converted temperature to spectral color.  Put it out as such
1128 >         * if they support it, otherwise convert to xy chromaticity and
1129 >         * put it out if they handle it.
1130 >         */
1131 >        if (mg_ehand[MG_E_CSPEC] != e_cspec)
1132 >                return(put_cspec());
1133 >        c_ccvt(c_ccolor, C_CSXY);
1134 >        if (mg_ehand[MG_E_CXY] != c_hcolor)
1135 >                return(put_cxy());
1136          return(MG_OK);
1137   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines