home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / saoimage / sao1_07.tar / rgndraw.c < prev    next >
C/C++ Source or Header  |  1990-05-02  |  11KB  |  371 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    rgndraw.c (Region Draw)
  6.  * Purpose:    Draw regions and their labels
  7.  * Subroutine:    init_region_draw()        returns: void
  8.  * Subroutine:    toggle_region_visibility()    returns: void
  9.  * Subroutine:    toggle_region_labeling()    returns: void
  10.  * Subroutine:    disp_regions()            returns: void
  11.  * Subroutine:    disp_region()            returns: void
  12.  * Subroutine:    label_region_cycle_magnifier()    returns: void
  13.  * Xlib calls:    XDrawImageString(), XDrawString(), XDrawLine(), XTextWidth()
  14.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  15.  *        You may do anything you like with this file except remove
  16.  *        this copyright.  The Smithsonian Astrophysical Observatory
  17.  *        makes no representations about the suitability of this
  18.  *        software for any purpose.  It is provided "as is" without
  19.  *        express or implied warranty.
  20.  * Modified:    {0} Michael VanHilst    initial version          26 May 1989
  21.  *              {1} MVH BSDonly strings.h compatability           19 Feb 1990
  22.  *        {n} <who> -- <does what> -- <when>
  23.  */
  24.  
  25. #include <stdio.h>        /* define stderr, NULL */
  26.  
  27. #ifndef VMS
  28. #ifdef SYSV
  29. #include <string.h>        /* strlen, strcat, strcpy, strrchr */
  30. #else
  31. #include <strings.h>        /* strlen, etc. for unenlightened BSD's */
  32. #endif
  33. #else
  34. #include <string.h>        /* strlen, strcat, strcpy, strrchr */
  35. #endif
  36.  
  37. #include <X11/Xlib.h>        /* X window stuff */
  38. #include <X11/Xutil.h>        /* X window manager stuff */
  39. #include "hfiles/define.h"    /* define MIN, MAX, U_DONT_CARE, etc. */
  40. #include "hfiles/constant.h"    /* define codes */
  41. #include "hfiles/struct.h"    /* declare structure types */
  42. #include "hfiles/extern.h"    /* extern main parameter structures */
  43. #include "hfiles/region.h"    /* regdrawRec region drawing parameters */
  44.  
  45. struct regdrawRec rgdraw;
  46.  
  47. /*
  48.  * Subroutine:    init_region_draw
  49.  */
  50. void init_region_draw ( view, label )
  51. {
  52.   XFontStruct *get_fontstruct();
  53.   void set_submenu_toggle();
  54.  
  55.   /* set button panel buttons */
  56.   if( (rgdraw.visible = view) )
  57.     set_submenu_toggle (ROP, ROP_View, 1);
  58.   if( (rgdraw.label = label) )
  59.     set_submenu_toggle (ROP, ROP_Label, 1);
  60.   /* get the medium font for legible numbers but limited size */
  61.   rgdraw.fontstruct = get_fontstruct(1);
  62.   rgdraw.label_xoff = 1;
  63.   if( rgdraw.filled_label ) {
  64.     rgdraw.label_yoff = -rgdraw.fontstruct->descent;
  65.     rgdraw.label_height =
  66.       rgdraw.fontstruct->descent + rgdraw.fontstruct->ascent;
  67.   } else {
  68.     rgdraw.label_yoff = 0;
  69.     rgdraw.label_height = rgdraw.fontstruct->ascent + 1;
  70.   }
  71. }
  72.  
  73. /*
  74.  * Subroutine:    toggle_region_visibility
  75.  */
  76. void toggle_region_visibility ( )
  77. {
  78.   void disp_dispbox();
  79.  
  80.   rgdraw.visible ^= 1;
  81.   /* redraw the image, (it will call disp_regions) */
  82.   disp_dispbox();
  83. }
  84.  
  85. /*
  86.  * Subroutine:    toggle_region_labeling
  87.  */
  88. void toggle_region_labeling ( )
  89. {
  90.   void disp_dispbox();
  91.  
  92.   rgdraw.label ^= 1;
  93.   /* redraw the image, (it will call disp_regions) */
  94.   disp_dispbox();
  95. }
  96.  
  97. /*
  98.  * Subroutine:    disp_regions
  99.  * Purpose:    Draw all saved cursor regions
  100.  */
  101. void disp_regions ( cursor )
  102.      struct cursorRec *cursor;
  103. {
  104.   struct cursorRec *region;
  105.   void disp_region();
  106.  
  107.   if( rgdraw.visible ) {
  108.     region = cursor->next_region;
  109.     while( region != NULL ) {
  110.       disp_region (region);
  111.       region = region->next_region;
  112.     }
  113.   }
  114. }
  115.  
  116. /*
  117.  * Subroutine:    disp_region
  118.  * Purpose:    Draw one saved cursor region and its labels
  119.  */
  120. void disp_region ( region )
  121.      struct cursorRec *region;
  122. {
  123.   GC gc;
  124.   static GC set_region_gc();
  125.   static void label_annuli(), label_region(), draw_region();
  126.  
  127.   if( rgdraw.visible && (region != NULL) ) {
  128.     gc = set_region_gc(region);
  129.     draw_region(region, gc);
  130.     if( rgdraw.label ) {
  131.       if( region->annuli )
  132.     label_annuli(region, gc);
  133.       else
  134.     label_region(region, gc);
  135.     }
  136.   }
  137. }
  138.  
  139. /*
  140.  * Subroutine:    label_region_cycle_magnifier
  141.  * Purpose:    Label cycle zoombox display
  142.  * Xlib calls:    XDrawImageString(), XTextWidth()
  143.  */
  144. void label_region_cycle_magnifier ( region, do_index )
  145.      struct cursorRec *region;
  146.      int do_index;
  147. {
  148.   int text_y, index_x, center_x;
  149.   char index[4], center[32];
  150.   GC gc, set_edit_gc();
  151.  
  152.   /* make center label (round to correct integer pixel coordinate) */
  153.   if( img.index_base )
  154.     (void)sprintf(center, "(%d,%d)", RND(region->file.X), RND(region->file.Y));
  155.   else
  156.     (void)sprintf(center, "(%d,%d)", (int)region->file.X, (int)region->file.Y);
  157.   text_y = magnibox.height -
  158.     (rgdraw.fontstruct->ascent + rgdraw.fontstruct->descent);
  159.   index_x = rgdraw.fontstruct->max_bounds.rbearing;
  160.   center_x = magnibox.width -
  161.     (XTextWidth(rgdraw.fontstruct, center, strlen(center)) + index_x);
  162.   gc = set_edit_gc(rgdraw.fontstruct->fid,
  163.            region->draw->foreground, region->draw->background);
  164.   XDrawImageString(magnibox.display, magnibox.ID, gc,
  165.            center_x, text_y, center, strlen(center));
  166.   if( do_index ) {
  167.     (void)sprintf(index, " %d ", region->index);
  168.     XDrawImageString(magnibox.display, magnibox.ID, gc,
  169.              index_x, text_y, index, strlen(index));
  170.   }
  171. }
  172.  
  173. /*
  174.  * Subroutine:    set_region_gc
  175.  * Purpose:    Set up the gc with only as much detail as needed
  176.  */
  177. static GC set_region_gc ( region )
  178.      struct cursorRec *region;
  179. {
  180.   GC gc, set_edit_gc(), set_text_gc(), set_gc();
  181.  
  182.   if( rgdraw.label ) {
  183.     if( rgdraw.filled_label )
  184.       gc = set_edit_gc(rgdraw.fontstruct->fid,
  185.                region->draw->foreground, region->draw->background);
  186.     else
  187.       gc = set_text_gc(rgdraw.fontstruct->fid, region->draw->foreground,
  188.                U_DONT_CARE, GXcopy, AllPlanes);
  189.   } else
  190.     gc = set_gc(region->draw);
  191.   return( gc );
  192. }
  193.  
  194. /*
  195.  * Subroutine:    draw_region_label
  196.  * Xlib calls:    XDrawImageString(), XDrawString()
  197.  */
  198. static void draw_region_label ( string, cnt, gc, x, y )
  199.      char *string;
  200.      int cnt;
  201.      GC gc;
  202.      int x, y;
  203. {
  204.   if( (x > 0) &&
  205.       (x <= (dispbox.width - rgdraw.fontstruct->max_bounds.rbearing)) &&
  206.       (y >= rgdraw.fontstruct->max_bounds.ascent) &&
  207.       (y <= (dispbox.height - rgdraw.fontstruct->max_bounds.descent)) ) {
  208.     if( rgdraw.filled_label )
  209.       XDrawImageString(dispbox.display, dispbox.ID, gc, x, y, string, cnt);
  210.     else
  211.       XDrawString(dispbox.display, dispbox.ID, gc, x, y, string, cnt);
  212.   }
  213. }
  214.  
  215. /*
  216.  * Subroutine:    draw_region
  217.  * Purpose:    Draw one saved cursor region outline or point index
  218.  * Note:    gc is already set, hence NULL GCspec in draw calls
  219.  */
  220. static void draw_region ( region, gc )
  221.      struct cursorRec *region;
  222.      GC gc;
  223. {
  224.   static void draw_region_label();
  225.   void draw_annuli(), draw_cursor();
  226.  
  227.   if( region->type != COP_Point ) {
  228.     if( region->annuli )
  229.       /* if there are annuli, draw them (GC is already set) */
  230.       draw_annuli(region, (GCspec *)NULL);
  231.     else
  232.       draw_cursor(region, (GCspec *)NULL);
  233.   } else {
  234. #ifdef LBLPNT
  235.     if( !rgdraw.label ) {
  236.       char label[32];
  237.  
  238.       sprintf(label, "%d", region->index);
  239.       draw_region_label(label, strlen(label), gc,
  240.             region->win.x + rgdraw.label_xoff,
  241.             region->win.y + rgdraw.label_yoff);
  242.     }
  243. #endif
  244.     XDrawPoint(dispbox.display, dispbox.ID, gc, region->win.x, region->win.y);
  245.   }
  246. }
  247.  
  248. /*
  249.  * Subroutine:    label_annuli
  250.  */
  251. static void label_annuli ( region, gc )
  252.      struct cursorRec *region;
  253.      GC gc;
  254. {
  255.   struct cursorRec *annulus;
  256.   static void label_region();
  257.  
  258.   /* apply label to outer annulus */
  259.   annulus = region;
  260.   while( annulus->next_annulus != NULL )
  261.     annulus = annulus->next_annulus;
  262.   annulus->index = region->index;
  263.   annulus->draw = region->draw;
  264.   annulus->exclude_region = region->exclude_region;
  265.   label_region(annulus, gc);
  266. }
  267.  
  268. /*
  269.  * Subroutine:    label_region
  270.  * Purpose:    Draw one region's label line and text for center and edge
  271.  * Xlib calls:    XDrawLine()
  272.  */
  273. static void label_region ( region, gc )
  274.      struct cursorRec *region;
  275.      GC gc;
  276. {
  277.   int x0, y0, x1, y1, yt;
  278.   char center_string[16];
  279.   char edge_string[132];
  280.   int len;
  281.   static int mark_include();
  282.   static void draw_region_label();
  283.  
  284.   /* if label not requested or don't know how to label or will another part */
  285.   if( (!rgdraw.label) || (region->type == COP_Polygon) )
  286.     return;
  287.   /* make center label (round to correct integer pixel coordinate) */
  288.   if( img.index_base )
  289.     sprintf(center_string, "(%d,%d)",
  290.           RND(region->file.X), RND(region->file.Y));
  291.   else
  292.     sprintf(center_string, "(%d,%d)",
  293.           (int)region->file.X,(int)region->file.Y);
  294.   x0 = region->win.x;
  295.   y0 = region->win.y;
  296.   if( region->type == COP_Point ) {
  297.     len = mark_include(center_string, region->exclude_region);
  298.     draw_region_label(center_string, len, gc,
  299.               x0 + rgdraw.label_xoff, y0 + rgdraw.label_yoff);
  300.   } else {
  301.     /* prepare and draw a line between center and edge of region */
  302.     switch( region->type ) {
  303.     case COP_Circle:
  304.       x1 = region->win.x;
  305.       y1 = region->win.y - (int)(region->win.rayX + 0.5);
  306.       sprintf(edge_string, "%d", (int)(region->file.Xdim + 0.5));
  307.       break;
  308.     case COP_Box:
  309.     case COP_Ellipse:
  310.       if( region->rot.angle == 0.0 ) {
  311.     x1 = region->win.x;
  312.     y1 = region->win.y - (int)(region->win.rayY + 0.5);
  313.       } else {
  314.     /* transform back to unrotated coords */
  315.     x1 = region->win.x - RND(region->win.rayY * region->rot.sin);
  316.     y1 = region->win.y + RND(region->win.rayY * region->rot.cos);
  317.       }
  318.       sprintf(edge_string, "%d", (int)(region->file.Ydim + 0.5));
  319.       break;
  320.     default:
  321.       return;
  322.     }
  323.     /* place text at end of line, but not over other label */
  324.     if( y1 <= y0 ) {
  325.       if( y1 > (y0 - rgdraw.label_height) )
  326.     yt = y0 - rgdraw.label_height;
  327.       else
  328.     yt = y1;
  329.     } else {
  330.       if( y1 < (y0 + rgdraw.label_height) )
  331.     yt = y0 + rgdraw.label_height;
  332.       else
  333.     yt = y1;
  334.     }
  335.     if( ((x0 >= 0) && (x0 < dispbox.width) &&
  336.      (y0 >= 0) && (y0 < dispbox.height)) ||
  337.         ((x1 >= 0) && (x1 < dispbox.width) &&
  338.      (yt >= 0) && (yt < dispbox.height)) ) {
  339.       /* draw the line if it is in the window */
  340.       XDrawLine(dispbox.display, dispbox.ID, gc, x0, y0, x1, y1);
  341.       /* make label indicate function of region */
  342.       len = mark_include(edge_string, region->exclude_region);
  343.       draw_region_label(edge_string, len, gc,
  344.             x1 + 1, yt + rgdraw.label_yoff);
  345.       draw_region_label(center_string, strlen(center_string), gc,
  346.             x0 + 1, y0 + rgdraw.label_yoff);
  347.     }
  348.   }
  349. }
  350.  
  351. /*
  352.  * Subroutine:    mark_include
  353.  * Purpose:    Add include symbol to string
  354.  */
  355. static int mark_include ( string, exclude )
  356.      char *string;
  357.      int exclude;
  358. {
  359.   int len;
  360.   
  361.   len = strlen(string);
  362.   if( exclude > 0 ) {
  363.     string[len] = '-';
  364.   } else if( exclude == 0 ) {
  365.     string[len] = '+';
  366.   } else
  367.     return( len );
  368.   string[++len] = '\0';
  369.   return( len );
  370. }
  371.