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

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    csrcoord.c (Cursor Coordinates)
  6.  * Purpose:    Calculate coordinates for cursor functions
  7.  * Subroutine:    set_cursor_file_coords()    returns: void    
  8.  * Subroutine:    adjust_cursor_coords()        returns: void    
  9.  * Subroutine:    set_cursor_from_file_coords()    returns: void    
  10.  * Subroutine:    set_annuli_from_file_coords()    returns: void
  11.  * Subroutine:    note_current_disp_transform()    returns: void    
  12.  * Subroutine:    report_cursor_info()        returns: void    
  13.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  14.  *        You may do anything you like with this file except remove
  15.  *        this copyright.  The Smithsonian Astrophysical Observatory
  16.  *        makes no representations about the suitability of this
  17.  *        software for any purpose.  It is provided "as is" without
  18.  *        express or implied warranty.
  19.  * Modified:    {0} Michael VanHilst    initial version          4 June 1989
  20.  *        {1} MVH added text cursor support           1 Jan 1991
  21.  *        {n} <who> -- <does what> -- <when>
  22.  */
  23.  
  24. #include <stdio.h>        /* stderr, NULL, etc. */
  25. #include <X11/Xlib.h>        /* X window stuff */
  26. #include <X11/Xutil.h>        /* X window manager stuff */
  27. #include "hfiles/color.h"    /* cursor colors needed by Cursor.h */
  28. #include "hfiles/constant.h"    /* define codes */
  29. #include "hfiles/coord.h"    /* coord structs */
  30. #include "hfiles/cursor.h"    /* define cursor parameter structures */
  31.  
  32. /*  Saved transform to see if it changed  */
  33. static Transform ftod;
  34.  
  35.  
  36. #ifdef ANSIC
  37. /*  Exported declarations must be centralized before ANSI C can be used  */
  38.  
  39. void        set_cursor_file_coords(    struct cursorRec *cursor,
  40.                     Transform *disptofile, int setcen);
  41. void        adjust_cursor_coords(    struct cursorRec *cursor,
  42.                     struct coordRec *coord);
  43. void        set_cursor_from_file_coords(    struct cursorRec *cursor,
  44.                         Transform *filetodisp);
  45. void        set_annuli_from_file_coords(    struct cursorRec *cursor,
  46.                         Transform *filetodisp);
  47. void        note_current_disp_transform(    Transform *filetodisp);
  48. void        report_cursor_info(    struct cursorRec *cursor);
  49.  
  50. static int    disp_coords_changed(    Transform *filetodisp);
  51.  
  52. #else
  53.  
  54. void d_transform(), make_cursor(), reset_textcursor_coords();
  55. double cursor_area();
  56. void set_polygon_from_file_coords(), set_annuli_from_file_coords();
  57. void set_cursor_from_file_coords(), note_current_disp_transform();
  58. static int disp_coords_changed();
  59.  
  60. #endif
  61.  
  62.  
  63. /*  Subroutine:    set_cursor_file_coords
  64.  *  Purpose:    Set img coords of cursor
  65.  */
  66. #ifdef ANSIC
  67. void set_cursor_file_coords( struct cursorRec *cursor, Transform *disptofile,
  68.                  int setcen )
  69. #else
  70. void set_cursor_file_coords ( cursor, disptofile, setcen )
  71.      struct cursorRec *cursor;
  72.      Transform *disptofile;
  73.      int setcen;    /* i: set-center-after-move, else set dim after size */
  74. #endif
  75. {
  76.   double ratio;
  77.  
  78.   if( setcen ) {
  79.     d_transform(disptofile, cursor->win.X, cursor->win.Y,
  80.         &cursor->file.X, &cursor->file.Y);
  81.   } else {
  82.     if( (ratio = disptofile->inx_outx + disptofile->inx_outy) < 0.0 )
  83.       ratio = -ratio;
  84.     cursor->file.Xdim = cursor->win.rayX * ratio;
  85.     cursor->file.Ydim = cursor->win.rayY * ratio;
  86.   }
  87. }
  88.  
  89.  
  90. /*  Subroutine:    adjust_cursor_coords
  91.  *  Purpose:    If the display image has been altered, change the cursor
  92.  *        parameters in the same way, so that the cursor has the same
  93.  *        relationship to the image.  old cursor is not erased, image
  94.  *        redraw usually does that
  95.  */
  96. #ifdef ANSIC
  97. void adjust_cursor_coords ( struct cursorRec *cursor, struct coordRec *coord )
  98. #else
  99. void adjust_cursor_coords ( cursor, coord )
  100.      struct cursorRec *cursor;
  101.      struct coordRec *coord;
  102. #endif
  103. {
  104.   int maincursor = 1;
  105.  
  106.   if( disp_coords_changed(&coord->filetodisp) ) {
  107.     /*  Remake the window coordinates and line drawing records  */
  108.     while( cursor != NULL ) {
  109.       if( cursor->type == COP_Polygon )
  110.     set_polygon_from_file_coords(cursor, &coord->filetodisp, maincursor);
  111.       else {
  112.     if( cursor->annuli )
  113.       set_annuli_from_file_coords(cursor, &coord->filetodisp);
  114.     else
  115.       set_cursor_from_file_coords(cursor, &coord->filetodisp);
  116.       }
  117.       /*  Loop on saved cursors  */
  118.       maincursor = 0;
  119.       cursor = cursor->next_region;
  120.     }
  121.     note_current_disp_transform(&coord->filetodisp);
  122.   }
  123. }
  124.  
  125.  
  126. /*  Subroutine:    set_cursor_from_file_coords
  127.  *  Purpose:    Set cursor window coordinates from its file coordinates
  128.  */
  129. #ifdef ANSIC
  130. void set_cursor_from_file_coords( struct cursorRec *cursor,
  131.                   Transform *filetodisp )
  132. #else
  133. void set_cursor_from_file_coords ( cursor, filetodisp )
  134.      struct cursorRec *cursor;
  135.      Transform *filetodisp;
  136. #endif
  137. {
  138.   float X, Y, ratio;
  139.  
  140.   /*  Get new window coordinates  */
  141.   d_transform(filetodisp,
  142.           (double)cursor->file.X, (double)cursor->file.Y, &X, &Y);
  143.   cursor->win.X = X;
  144.   cursor->win.Y = Y;
  145.   cursor->win.x = (int)X;
  146.   cursor->win.y = (int)Y;
  147.   /*  Get new window dimensions  */
  148.   if( (ratio = filetodisp->inx_outx + filetodisp->inx_outy) < 0.0 )
  149.     ratio = -ratio;
  150.   cursor->win.rayX = ratio * cursor->file.Xdim;
  151.   cursor->win.rayY = ratio * cursor->file.Ydim;
  152.   /*  Make new drawing vertices  */
  153.   if( cursor->type == COP_Text )
  154.     reset_textcursor_coords(cursor);
  155.   else
  156.     make_cursor(cursor);
  157. }
  158.  
  159.  
  160. /*  Subroutine:    set_annuli_from_file_coords
  161.  *  Purpose:    Set annuli window coordinates from their file coordinates
  162.  */
  163. #ifdef ANSIC
  164. void set_annuli_from_file_coords ( struct cursorRec *cursor,
  165.                    Transform *filetodisp )
  166. #else
  167. void set_annuli_from_file_coords ( cursor, filetodisp )
  168.      struct cursorRec *cursor;
  169.      Transform *filetodisp;
  170. #endif
  171. {
  172.   struct cursorRec *annulus;
  173.   float X, Y, ratio;
  174.  
  175.   /*  Get new window coordinates  */
  176.   d_transform(filetodisp,
  177.           (double)cursor->file.X, (double)cursor->file.Y, &X, &Y);
  178.   cursor->win.X = X;
  179.   cursor->win.Y = Y;
  180.   cursor->win.x = (int)X;
  181.   cursor->win.y = (int)Y;
  182.   /*  Get new window dimensions  */
  183.   if( (ratio = filetodisp->inx_outx + filetodisp->inx_outy) < 0.0 )
  184.     ratio = -ratio;
  185.   annulus = cursor->next_annulus;
  186.   while( annulus != 0 ) {
  187.     annulus->win.X = cursor->win.X;
  188.     annulus->win.Y = cursor->win.Y;
  189.     annulus->win.x = cursor->win.x;
  190.     annulus->win.y = cursor->win.y;
  191.     annulus->win.rayX = ratio * annulus->file.Xdim;
  192.     annulus->win.rayY = ratio * annulus->file.Ydim;
  193.     /*  Make new drawing vertices  */
  194.     make_cursor(annulus);
  195.     annulus = annulus->next_annulus;
  196.   }
  197. }
  198.  
  199.  
  200. /*  Subroutine:    note_current_disp_transform
  201.  *  Purpose:    Note current transform
  202.  */
  203. #ifdef ANSIC
  204. void note_current_disp_transform ( Transform *filetodisp )
  205. #else
  206. void note_current_disp_transform ( filetodisp )
  207.      Transform *filetodisp;
  208. #endif
  209. {
  210.   ftod.inx_outx = filetodisp->inx_outx;
  211.   ftod.inx_outy = filetodisp->inx_outy;
  212.   ftod.add_outx = filetodisp->add_outx;
  213.   ftod.add_outy = filetodisp->add_outy;
  214. }
  215.  
  216.  
  217. /*  Subroutine:    disp_params_changed
  218.  *  Purpose:    Check if current transform has changed
  219.  */
  220. #ifdef ANSIC
  221. static int disp_coords_changed ( Transform *filetodisp )
  222. #else
  223. static int disp_coords_changed ( filetodisp )
  224.      Transform *filetodisp;
  225. #endif
  226. {
  227.   if( (filetodisp->inx_outx != ftod.inx_outx) ||
  228.       (filetodisp->inx_outy != ftod.inx_outy) ||
  229.       (filetodisp->add_outx != ftod.add_outx) ||
  230.       (filetodisp->add_outy != ftod.add_outy) )
  231.     return( 1 );
  232.   else
  233.     return( 0 );
  234. }
  235.  
  236.  
  237. /*  Subroutine:    report_cursor_info
  238.  *  Purpose:    Calculate and report curosr params in file coordinates
  239.  */
  240. #ifdef ANSIC
  241. void report_cursor_info ( struct cursorRec *cursor )
  242. #endif
  243. void report_cursor_info ( cursor )
  244.      struct cursorRec *cursor;
  245. {
  246.   double area;
  247.   int i;
  248.  
  249.   /*  Calculate the new coords  */
  250.   /*  Now tell what and where  */
  251.   (void)printf("cursor window position: x=%d, y=%d\n",
  252.            cursor->win.x, cursor->win.y);
  253.   (void)printf("cursor file position: X=%.3f, Y=%.3f\n",
  254.            cursor->file.X, cursor->file.Y);
  255.   switch( cursor->type ) {
  256.   case COP_Circle:
  257.     (void)printf("Circle cursor\n");
  258.     (void)printf("radius: %.2f, ", cursor->file.Xdim);
  259.     (void)printf("geometric area: %.2f\n", cursor_area(cursor, 1));
  260.     break;
  261.   case COP_Ellipse:
  262.     (void)printf("Rotatable ellipse\n");
  263.     (void)printf("angle in radians: %6.3f\n", cursor->rot.angle);
  264.     (void)printf("X radius: w=%.2f, Y radius: h=%.2f\n",
  265.          cursor->file.Xdim, cursor->file.Ydim);
  266.     (void)printf("geometric area: %.2f\n", cursor_area(cursor, 1));
  267.     break;
  268.   case COP_Box:
  269.     if( cursor->rot.angle == 0.0 ) {
  270.       (void)printf("Orthogonal box cursor\n");
  271.       (void)printf("width and height in file pixels: w=%.2f, h=%.2f\n",
  272.            cursor->file.Xdim * 2.0, cursor->file.Ydim * 2.0);
  273.       (void)printf("geometric area: %.2f\n", cursor_area(cursor, 1));
  274.     } else {
  275.       (void)printf("Rotated box cursor\n");
  276.       (void)printf("angle in radians: %6.3f\n", cursor->rot.angle);
  277.       (void)printf("width and height in file pixels: w=%.2f, h=%.2f\n",
  278.            cursor->file.Xdim * 2.0, cursor->file.Ydim * 2.0);
  279.       (void)printf("geometric area: %.2f\n", cursor_area(cursor, 1));
  280.     }
  281.     break;
  282.   case COP_Polygon:
  283.     (void)printf("Polygon cursor with ");
  284.     (void)printf("%d vertices:\n", cursor->poly_cnt);
  285.     for( i=0; i<cursor->poly_cnt; i++ ) {
  286.       (void)printf("  (x=%.2f, y=%.2f)\n",
  287.            cursor->poly[i].fileX, cursor->poly[i].fileY);
  288.     }
  289.     if( (area = cursor_area(cursor, 1)) > 0.0 )
  290.       (void)printf("geometric area: %.2f\n", area );
  291.     else
  292.       (void)printf("Note: polygon is twisted.\n");
  293.     break;
  294.   case COP_Point:
  295.   default:
  296.     break;
  297.   }
  298.   (void)printf("\n");    
  299. }
  300.