Logo Search packages:      
Sourcecode: saoimage version File versions

rgndraw.c

#ifndef lint
static char SccsId[] = "%W%  %G%";
#endif

/* Module:  rgndraw.c (Region Draw)
 * Purpose: Draw regions and their labels
 * Subroutine:    init_region_draw()            returns: void
 * Subroutine:    toggle_region_visibility()    returns: void
 * Subroutine:    toggle_region_labeling()      returns: void
 * Subroutine:    disp_regions()                returns: void
 * Subroutine:    disp_region()                 returns: void
 * Subroutine:    label_region_cycle_magnifier()      returns: void
 * Xlib calls:    XDrawImageString(), XDrawString(), XDrawLine(), XTextWidth()
 * Copyright:     1989-1998 Smithsonian Astrophysical Observatory
 *          You may do anything you like with this file except remove
 *          this copyright.  The Smithsonian Astrophysical Observatory
 *          makes no representations about the suitability of this
 *          software for any purpose.  It is provided "as is" without
 *          express or implied warranty.
 */

#include <stdio.h>            /* define stderr, NULL */

#ifndef VMS
#ifdef SYSV
#include <string.h>           /* strlen, strcat, strcpy, strrchr */
#else
#include <strings.h>          /* strlen, etc. for unenlightened BSD's */
#endif
#else
#include <string.h>           /* strlen, strcat, strcpy, strrchr */
#endif

#include <X11/Xlib.h>         /* X window stuff */
#include <X11/Xutil.h>        /* X window manager stuff */
#include "hfiles/define.h"    /* define MIN, MAX, U_DONT_CARE, etc. */
#include "hfiles/constant.h"  /* define codes */
#include "hfiles/struct.h"    /* declare structure types */
#include "hfiles/extern.h"    /* extern main parameter structures */
#define REGION_MAIN
#include "hfiles/region.h"    /* regdrawRec region drawing parameters */

struct regdrawRec rgdraw;

/*
 * Subroutine:    init_region_draw
 */
void init_region_draw ( view, label )
{
  XFontStruct *get_fontstruct();
  void set_submenu_toggle();

  /* set button panel buttons */
  if( (rgdraw.visible = view) )
    set_submenu_toggle (ROP, ROP_View, 1);
  if( (rgdraw.label = label) )
    set_submenu_toggle (ROP, ROP_Label, 1);
  /* get the medium font for legible numbers but limited size */
  rgdraw.fontstruct = get_fontstruct(1);
  rgdraw.label_xoff = 1;
  if( rgdraw.filled_label ) {
    rgdraw.label_yoff = -rgdraw.fontstruct->descent;
    rgdraw.label_height =
      rgdraw.fontstruct->descent + rgdraw.fontstruct->ascent;
  } else {
    rgdraw.label_yoff = 0;
    rgdraw.label_height = rgdraw.fontstruct->ascent + 1;
  }
}

/*
 * Subroutine:    toggle_region_visibility
 */
void toggle_region_visibility ( )
{
  void disp_dispbox();

  rgdraw.visible ^= 1;
  /* redraw the image, (it will call disp_regions) */
  disp_dispbox();
}

/*
 * Subroutine:    toggle_region_labeling
 */
void toggle_region_labeling ( )
{
  void disp_dispbox();

  rgdraw.label ^= 1;
  /* redraw the image, (it will call disp_regions) */
  disp_dispbox();
}

/*
 * Subroutine:    disp_regions
 * Purpose: Draw all saved cursor regions
 */
void disp_regions ( cursor )
     struct cursorRec *cursor;
{
  struct cursorRec *region;
  void disp_region();

  if( rgdraw.visible ) {
    region = cursor->next_region;
    while( region != NULL ) {
      disp_region (region);
      region = region->next_region;
    }
  }
}

/*
 * Subroutine:    disp_region
 * Purpose: Draw one saved cursor region and its labels
 */
void disp_region ( region )
     struct cursorRec *region;
{
  GC gc;
  static GC set_region_gc();
  static void label_annuli(), label_region(), draw_region();

  if( rgdraw.visible && (region != NULL) ) {
    gc = set_region_gc(region);
    draw_region(region, gc);
    if( rgdraw.label ) {
      if( region->annuli )
      label_annuli(region, gc);
      else
      label_region(region, gc);
    }
  }
}

/*
 * Subroutine:    label_region_cycle_magnifier
 * Purpose: Label cycle zoombox display
 * Xlib calls:    XDrawImageString(), XTextWidth()
 */
void label_region_cycle_magnifier ( region, do_index )
     struct cursorRec *region;
     int do_index;
{
  int text_y, index_x, center_x;
  char index[4], center[32];
  GC gc, set_edit_gc();

  /* make center label (round to correct integer pixel coordinate) */
  if( img.index_base )
    (void)sprintf(center, "(%d,%d)", RND(region->file.X), RND(region->file.Y));
  else
    (void)sprintf(center, "(%d,%d)", (int)region->file.X, (int)region->file.Y);
  text_y = magnibox.height -
    (rgdraw.fontstruct->ascent + rgdraw.fontstruct->descent);
  index_x = rgdraw.fontstruct->max_bounds.rbearing;
  center_x = magnibox.width -
    (XTextWidth(rgdraw.fontstruct, center, strlen(center)) + index_x);
  gc = set_edit_gc(rgdraw.fontstruct->fid,
               region->draw->foreground, region->draw->background);
  XDrawImageString(magnibox.display, magnibox.ID, gc,
               center_x, text_y, center, strlen(center));
  if( do_index ) {
    (void)sprintf(index, " %d ", region->index);
    XDrawImageString(magnibox.display, magnibox.ID, gc,
                 index_x, text_y, index, strlen(index));
  }
}

/*
 * Subroutine:    set_region_gc
 * Purpose: Set up the gc with only as much detail as needed
 */
static GC set_region_gc ( region )
     struct cursorRec *region;
{
  GC gc, set_edit_gc(), set_text_gc(), set_gc();

  if( rgdraw.label ) {
    if( rgdraw.filled_label )
      gc = set_edit_gc(rgdraw.fontstruct->fid,
                   region->draw->foreground, region->draw->background);
    else
      gc = set_text_gc(rgdraw.fontstruct->fid, region->draw->foreground,
                   U_DONT_CARE, GXcopy, AllPlanes);
  } else
    gc = set_gc(region->draw);
  return( gc );
}

/*
 * Subroutine:    draw_region_label
 * Xlib calls:    XDrawImageString(), XDrawString()
 */
static void draw_region_label ( string, cnt, gc, x, y )
     char *string;
     int cnt;
     GC gc;
     int x, y;
{
  if( (x > 0) &&
      (x <= (dispbox.width - rgdraw.fontstruct->max_bounds.rbearing)) &&
      (y >= rgdraw.fontstruct->max_bounds.ascent) &&
      (y <= (dispbox.height - rgdraw.fontstruct->max_bounds.descent)) ) {
    if( rgdraw.filled_label )
      XDrawImageString(dispbox.display, dispbox.ID, gc, x, y, string, cnt);
    else
      XDrawString(dispbox.display, dispbox.ID, gc, x, y, string, cnt);
  }
}

/*
 * Subroutine:    draw_region
 * Purpose: Draw one saved cursor region outline or point index
 * Note:    gc is already set, hence NULL GCspec in draw calls
 */
static void draw_region ( region, gc )
     struct cursorRec *region;
     GC gc;
{
  static void draw_region_label();
  void draw_annuli(), draw_cursor();

  if( region->type != COP_Point ) {
    if( region->annuli )
      /* if there are annuli, draw them (GC is already set) */
      draw_annuli(region, (GCspec *)NULL);
    else
      draw_cursor(region, (GCspec *)NULL);
  } else {
#ifdef LBLPNT
    if( !rgdraw.label ) {
      char label[32];

      sprintf(label, "%d", region->index);
      draw_region_label(label, strlen(label), gc,
                  region->win.x + rgdraw.label_xoff,
                  region->win.y + rgdraw.label_yoff);
    }
#endif
    XDrawPoint(dispbox.display, dispbox.ID, gc, region->win.x, region->win.y);
  }
}

/*
 * Subroutine:    label_annuli
 */
static void label_annuli ( region, gc )
     struct cursorRec *region;
     GC gc;
{
  struct cursorRec *annulus;
  static void label_region();

  /* apply label to outer annulus */
  annulus = region;
  while( annulus->next_annulus != NULL )
    annulus = annulus->next_annulus;
  annulus->index = region->index;
  annulus->draw = region->draw;
  annulus->exclude_region = region->exclude_region;
  label_region(annulus, gc);
}

/*
 * Subroutine:    label_region
 * Purpose: Draw one region's label line and text for center and edge
 * Xlib calls:    XDrawLine()
 */
static void label_region ( region, gc )
     struct cursorRec *region;
     GC gc;
{
  int x0, y0, x1, y1, yt;
  char center_string[16];
  char edge_string[132];
  int len;
  int exclude;
  static int mark_include();
  static void draw_region_label();

  /* if label not requested or don't know how to label or will another part */
  if( (!rgdraw.label) || (region->type == COP_Polygon) )
    return;

  /* make center label (round to correct integer pixel coordinate) */
  if( img.index_base )
    sprintf(center_string, "(%d,%d)",
              RND(region->file.X), RND(region->file.Y));
  else
    sprintf(center_string, "(%d,%d)",
              (int)region->file.X,(int)region->file.Y);
  x0 = region->win.x;
  y0 = region->win.y;
  if( region->type == COP_Point ) {
    if (region->label != NULL)
      sprintf(center_string, "%s", region->label);
    len = mark_include(center_string, region->exclude_region);
    draw_region_label(center_string, len, gc,
                  x0 + rgdraw.label_xoff, y0 + rgdraw.label_yoff);

    /* prepare and draw a line between center and edge of region */
  } else {
    switch( region->type ) {
    case COP_Circle:
    case COP_Square:
    case COP_Diamond:
    case COP_Cross:
    case COP_Ex:
      x1 = region->win.x;
      y1 = region->win.y - (int)(region->win.rayX + 0.5);
      sprintf(edge_string, "%d", (int)(region->file.Xdim + 0.5));
      break;
    case COP_Box:
    case COP_Ellipse:
      if( region->rot.angle == 0.0 ) {
      x1 = region->win.x;
      y1 = region->win.y - (int)(region->win.rayY + 0.5);
      } else {
      /* transform back to unrotated coords */
      x1 = region->win.x - RND(region->win.rayY * region->rot.sin);
      y1 = region->win.y + RND(region->win.rayY * region->rot.cos);
      }
      sprintf(edge_string, "%d", (int)(region->file.Ydim + 0.5));
      break;
    default:
      return;
    }

    if (region->label != NULL) {
      center_string[0] = (char) 0;
      sprintf(edge_string, "%s", region->label);
      exclude = -1;
      }
    else
      exclude = region->exclude_region;

    /* place text at end of line, but not over other label */
    if( y1 <= y0 ) {
      if( y1 > (y0 - rgdraw.label_height) )
      yt = y0 - rgdraw.label_height;
      else
      yt = y1;
    } else {
      if( y1 < (y0 + rgdraw.label_height) )
      yt = y0 + rgdraw.label_height;
      else
      yt = y1;
    }
    if( ((x0 >= 0) && (x0 < dispbox.width) &&
       (y0 >= 0) && (y0 < dispbox.height)) ||
        ((x1 >= 0) && (x1 < dispbox.width) &&
       (yt >= 0) && (yt < dispbox.height)) ) {

      /* draw the line if it is in the window */
      if (region->label == NULL)
      XDrawLine(dispbox.display, dispbox.ID, gc, x0, y0, x1, y1);

      /* make label indicate function of region */
      len = mark_include(edge_string, exclude);
      draw_region_label(edge_string, len, gc,
                  x1 + 1, yt + rgdraw.label_yoff);
      draw_region_label(center_string, strlen(center_string), gc,
                  x0 + 1, y0 + rgdraw.label_yoff);
    }
  }
}

/*
 * Subroutine:    mark_include
 * Purpose: Add include symbol to string
 */
static int mark_include ( string, exclude )
     char *string;
     int exclude;
{
  int len;
  
  len = strlen(string);
  if( exclude > 0 ) {
    string[len] = '-';
  } else if( exclude == 0 ) {
    string[len] = '+';
  } else
    return( len );
  string[++len] = '\0';
  return( len );
}
/* May 26 1989    Michael VanHilst  initial version
 *
 * Feb 19 1990    MVH  BSDonly strings.h compatability
 *
 * Oct 13 1998    Doug Mink  Add option to print region labels
 * Oct 19 1998    Doug Mink  Add 4 more centered shapes
 * Nov 30 1998    Paul Sydney  set REGION_MAIN flag so region.h declares structure
 */

Generated by  Doxygen 1.6.0   Back to index