home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / saoimage / sao1_07.tar / rgnwpros.c < prev    next >
C/C++ Source or Header  |  1991-01-08  |  9KB  |  330 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    rgnwpros.c (Region Write Pros)
  6.  * Purpose:    Write regions to a file readable by the IRAF PROS system
  7.  * Subroutine:    write_regions_pros()        returns: void
  8.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  9.  *        You may do anything you like with this file except remove
  10.  *        this copyright.  The Smithsonian Astrophysical Observatory
  11.  *        makes no representations about the suitability of this
  12.  *        software for any purpose.  It is provided "as is" without
  13.  *        express or implied warranty.
  14.  * Modified:    {0} Michael VanHilst    initial version          9 July 1989
  15.  *        {1} MVH made boxes write diameter, not radius      7 Dec 1989
  16.  *              {2} MVH BSDonly strings.h compatability           19 Feb 1990
  17.  *        {3} MVH if center, point are int, write as int      22 Feb 1990
  18.  *        {n} <who> -- <does what> -- <when>
  19.  */
  20.  
  21. #include <stdio.h>        /* stderr, NULL, etc. */
  22.  
  23. #ifndef VMS
  24. #ifdef SYSV
  25. #include <string.h>        /* strlen, strcat, strcpy, strrchr */
  26. #else
  27. #include <strings.h>        /* strlen, strcat, strcpy, rindex */
  28. #endif
  29. #else
  30. #include <string.h>        /* strlen, strcat, strcpy, strrchr */
  31. #endif
  32.  
  33. #include <X11/Xlib.h>        /* get X types and constants */
  34. #include <X11/Xutil.h>        /* X window manager stuff, visuals */
  35. #include "hfiles/color.h"    /* gcset needed by cursor */
  36. #include "hfiles/constant.h"    /* define codes */
  37. #include "hfiles/cursor.h"    /* define cursor parameter structures */
  38. #include "hfiles/define.h"    /* define PI */
  39.  
  40. #define DEG(r) ((360.0 / TWO_PI) * (r))
  41. #define RAD(d) ((TWO_PI / 360.0) * (d))
  42.  
  43. /*
  44.  * Subroutine:    write_region_pros
  45.  * Purpose:    Write ROSAT PROS style region description to file
  46.  * Method:    Recurse first to start writing from end of link list
  47.  */
  48. void write_region_pros ( fd, region )
  49.      FILE *fd;
  50.      struct cursorRec *region;
  51. {
  52.   static void cat_annulus(), write_annuli(), cat_shape();
  53.  
  54.   /*  Check for pointer before doing anything  */
  55.   if( region == NULL )
  56.     return;
  57.   /*  Recurse for higher regions so as to reverse order  */
  58.   if( region->next_region != NULL )
  59.     write_region_pros(fd, region->next_region);
  60.   {
  61.     /*  Declare locals here so as not to put them on stack while recursing  */
  62.     char line[512];
  63.     if( region->exclude_region )
  64.       line[0] = '-';
  65.     else
  66.       line[0] = ' ';
  67.     line[1] = '\0';
  68.     if( region->annuli ) {
  69.       if( region->type == COP_Circle ) {
  70.     cat_annulus (region, line);
  71.       } else {
  72.     write_annuli(region, line, fd);
  73.       }
  74.     } else {
  75.       cat_shape(region, line);
  76.     }
  77.     (void)strcat(line, "\n");
  78.     /*  And write it out  */
  79.     fputs(line, fd);
  80.   }
  81. }
  82.  
  83.  
  84. /*  Subroutine:    cat_shape
  85.  *  Purpose:    Put simple PROS description of given cursor in line buffer
  86.  */     
  87. static void cat_shape ( region, line )
  88.      struct cursorRec *region;
  89.      char *line;
  90. {
  91.   int params;
  92.   void write_text_region();
  93.   static void cat_polypts(), cat_cen(), cat_params();
  94.  
  95.   switch( region->type ) {
  96.   case COP_Box:
  97.     (void)strcat(line, "BOX(");
  98.     if( region->rot.angle == 0.0 )
  99.       params = 2;
  100.     else
  101.       params = 3;
  102.     break;
  103.   case COP_Circle:
  104.     (void)strcat(line, "CIRCLE(");
  105.     params = 1;
  106.     break;
  107.   case COP_Ellipse:
  108.     (void)strcat(line, "ELLIPSE(");
  109.     params = 3;
  110.     break;
  111.   case COP_Point:
  112.     (void)strcat(line, "POINT(");
  113.     params = 0;
  114.     break;
  115.   case COP_Polygon:
  116.     if( region->poly_cnt >= 3 ) {
  117.       (void)strcat(line, "POLYGON(");
  118.       cat_polypts(region, line);
  119.       (void)strcat(line, ")");
  120.     }
  121.     return;
  122.   case COP_Arrow:
  123.     /*  Make regionless cursor appear as a comment to most region parsers  */
  124.     line[1] = line[0];
  125.     line[0] = '#';
  126.     (void)strcpy(&line[2], "ARROW(");
  127.     params = 3;
  128.     break;
  129.   case COP_Text:
  130.     /*  Make regionless cursor appear as a comment to most region parsers  */
  131.     line[1] = line[0];
  132.     line[0] = '#';
  133.     (void)strcpy(&line[2], "TEXT(");
  134.     cat_cen(region, line);
  135.     write_text_region(region, line);
  136.     return;
  137.   default:
  138.     return;
  139.   }
  140.   /*  Put it all together  */
  141.   cat_cen(region, line);
  142.   cat_params(region, line, params);
  143.   (void)strcat(line, ")");
  144. }
  145.  
  146.  
  147. /*  Subroutine:    cat_params
  148.  *  Purpose:    Add appropriate number of cursor shape parameters to
  149.  *        line buffer
  150.  */
  151. static void cat_params ( region, line, count )
  152.      struct cursorRec *region;
  153.      char *line;
  154.      int count;            /* i: number of shape parameters wanted */
  155. {
  156.   char params[32];
  157.   switch( count ) {
  158.   case 1:
  159.     sprintf(params, ",%.2f", region->file.Xdim);
  160.     break;
  161.   case 2:
  162.     if( region->type == COP_Box )
  163.       /* PROS software expects boxes to use diameter instead of radius */
  164.       sprintf(params, ",%.2f,%.2f",
  165.           region->file.Xdim * 2.0, region->file.Ydim * 2.0);
  166.     else
  167.       sprintf(params, ",%.2f,%.2f", region->file.Xdim, region->file.Ydim);
  168.     break;
  169.   case 3:
  170.     if( region->type == COP_Box )
  171.       sprintf(params, ",%.2f,%.2f,%.3f", region->file.Xdim * 2.0,
  172.           region->file.Ydim * 2.0, DEG(region->rot.angle));
  173.     else
  174.       sprintf(params, ",%.2f,%.2f,%.3f", region->file.Xdim,
  175.           region->file.Ydim, DEG(region->rot.angle));
  176.     break;
  177.   default:
  178.     return;
  179.   }
  180.   (void)strcat(line, params);
  181. }
  182.  
  183. /*
  184.  * Subroutine:    cat_cen
  185.  * Purpose:    Add center coordinates to line buffer
  186.  */
  187. static void cat_cen ( region, line )
  188.      struct cursorRec *region;
  189.      char *line;
  190. {
  191.   int ix, iy;
  192.   char center[20];
  193.  
  194.   ix = (int)region->file.X;
  195.   iy = (int)region->file.Y;
  196.   /* print the center */
  197.   if( ((double)ix == region->file.X) && ((double)iy == region->file.Y) )
  198.     sprintf(center, "%d,%d", ix, iy);
  199.   else
  200.     sprintf(center, "%.2f,%.2f", region->file.X, region->file.Y);
  201.   (void)strcat(line, center);
  202. }
  203.  
  204. /*
  205.  * Subroutine:    cat_polypts
  206.  * Purpose:    Add list of point coordinates to line buffer (for polygon)
  207.  */
  208. static void cat_polypts ( region, line )
  209.      struct cursorRec *region;
  210.      char *line;
  211. {
  212.   int i;
  213.   static void cat_pt();
  214.  
  215.   cat_pt((double)region->poly[0].fileX, (double)region->poly[0].fileY,
  216.      line, 0);
  217.   for( i=1; i<region->poly_cnt; i++ ) {
  218.     cat_pt((double)region->poly[i].fileX, (double)region->poly[i].fileY,
  219.        line, 1);
  220.   }
  221. }
  222.  
  223. /*
  224.  * Subroutine:    cat_pt
  225.  * Purpose:    Add given coordinates in parentheses to line buffer
  226.  */
  227. static void cat_pt ( x, y, line, comma )
  228.      double x, y;
  229.      char *line;
  230.      int comma;
  231. {
  232.   int ix, iy;
  233.   char point[20];
  234.  
  235.   ix = (int)x;
  236.   iy = (int)y;
  237.   /* print the point's coords */
  238.   if( ((double)ix == x) && ((double)iy == y) ) {
  239.     if( comma )
  240.       sprintf(point, ",%d,%d", ix, iy);
  241.     else
  242.       sprintf(point, "%d,%d", ix, iy);
  243.   } else {
  244.     if( comma )
  245.       sprintf(point, ",%.2f,%.2f", x, y);
  246.     else
  247.       sprintf(point, "%.2f,%.2f", x, y);
  248.   }
  249.   (void)strcat(line, point);
  250. }
  251.  
  252. /*
  253.  * Subroutine:    cat_annulus
  254.  * Purpose:    Put a PROS style description of circular annuli on the
  255.  *        line buffer
  256.  */
  257. static void cat_annulus ( region, line )
  258.      struct cursorRec *region;
  259.      char *line;
  260. {
  261.   char radius[16];
  262.   static void cat_cen();
  263.  
  264.   (void)strcat(line, "ANNULUS(");
  265.   cat_cen(region, line);
  266.   /* first region is not one of the annuli */
  267.   while( (region = region->next_annulus) != NULL ) {
  268.     sprintf(radius, ",%.2f", region->file.Xdim);
  269.     (void)strcat(line, radius);
  270.   }
  271.   (void)strcat(line, ")");
  272. }
  273.  
  274. /*
  275.  * Subroutine:    write_annuli
  276.  * Purpose:    Write PROS type description to produce annuli of given shapes
  277.  */
  278. static void write_annuli ( region, line, fd )
  279.      struct cursorRec *region;
  280.      char *line;
  281.      FILE *fd;
  282. {
  283.   struct cursorRec *annulus;
  284.   static struct cursorRec *cat_annular();
  285.   static void cat_shape();
  286.  
  287.   /* annuli start with next_annulus (base region is not one of them) */ 
  288.   if( (annulus = region->next_annulus) != NULL ) {
  289.     /* first line is the inner ring */
  290.     cat_shape(annulus, line);
  291.     (void)strcat(line, "\n");
  292.     fputs(line, fd);
  293.     line[0] = 0;
  294.     while( annulus != NULL ) {
  295.       annulus = cat_annular(annulus, line);
  296.       /* write if there is a line, and it's not the last one */
  297.       if( (annulus != NULL) && (annulus->next_annulus != NULL) ) {
  298.     (void)strcat(line, "\n");
  299.     /* and write it out */
  300.     fputs(line, fd);
  301.     line[0] = 0;
  302.       }
  303.     }
  304.   }
  305. }
  306.  
  307. /*
  308.  * Subroutine:    cat_annular
  309.  * Purpose:    Add outer shape anded with not of inner shape to make
  310.  *        an annular ring
  311.  */
  312. static struct cursorRec *cat_annular ( region, line )
  313.      struct cursorRec *region;
  314.      char *line;
  315. {
  316.   static void cat_shape();
  317.  
  318.   if( region->next_annulus != NULL ) {
  319.     if( region->exclude_region )
  320.       line[0] = '-';
  321.     else
  322.       line[0] = ' ';
  323.     line[1] = '\0';
  324.     cat_shape(region->next_annulus, line);
  325.     (void)strcat (line, " & !");
  326.     cat_shape(region, line);
  327.   }
  328.   return( region->next_annulus );
  329. }
  330.