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

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    mgfyctrl.c (Magnify Control)
  6.  * Purpose:    Initialize params and organize drawing the magnifier window
  7.  * Subroutine:    magnify_disp()            returns: void
  8.  * Subroutine:    magnify_pan()            returns: void
  9.  * Subroutine:    clear_coord_area()        returns: void
  10.  * Subroutine:    redraw_magnifier()        returns: void
  11.  * Xlib calls:    XCheckWindowEvent(), XSync()
  12.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  13.  *        You may do anything you like with this file except remove
  14.  *        this copyright.  The Smithsonian Astrophysical Observatory
  15.  *        makes no representations about the suitability of this
  16.  *        software for any purpose.  It is provided "as is" without
  17.  *        express or implied warranty.
  18.  * Modified:    {0} Michael VanHilst    initial version         6 June 1989
  19.  *        {1} MVH added support for second set of coords      7 Nov 1989
  20.  *        {n} <who> -- <does what> -- <when>
  21.  */
  22.  
  23. #include <stdio.h>
  24. #include <X11/Xlib.h>        /* X window stuff */
  25. #include <X11/Xutil.h>        /* X window manager stuff */
  26. #include "hfiles/struct.h"    /* declare structure types */
  27. #include "hfiles/extern.h"    /* extern main SAOimage parameter structures */
  28. #include "hfiles/constant.h"    /* codes */
  29. #include "hfiles/magnify.h"    /* magnifier quick access structure */
  30.  
  31. extern struct windowRec desktop;
  32. extern struct magRec magset;
  33.  
  34. #define VAL_SZ 10
  35. /*
  36.  * Subroutine:    magnify_disp
  37.  * Purpose:    Magnify location of a dispbox event
  38.  * Xlib calls:    XCheckWindowEvent(), XSync()
  39.  */
  40. void magnify_disp ( event, view, text )
  41.      XEvent *event;        /* i: XEvent for location of mouse */
  42.      int view, text;
  43. {
  44.   void draw_magnifier();
  45.   static void label_file_coords(), label_file_coords_proportional();
  46.  
  47.   /* get only the most recent mouse moved event */
  48.   XSync(dispbox.display, 0);
  49.   while( XCheckWindowEvent(dispbox.display, dispbox.ID,
  50.                PointerMotionMask, event) );
  51.   /* draw image fragment in scope magnibox if desired */
  52.   if( view ) {
  53.     /* get buffer coordinates */
  54.     magset.buf.X = ((float)event->xmotion.x * coord.disptobuf.inx_outx) +
  55.       coord.disptobuf.iadd_outx;
  56.     magset.buf.Y = ((float)event->xmotion.y * coord.disptobuf.iny_outy) +
  57.       coord.disptobuf.iadd_outy;
  58.     draw_magnifier((double)magset.buf.X, (double)magset.buf.Y);
  59.     if( text ) {
  60.       if( magset.text.proportional )
  61.     label_file_coords_proportional((double)magset.buf.X,
  62.                        (double)magset.buf.Y);
  63.       else
  64.     label_file_coords((double)magset.buf.X, (double)magset.buf.Y);
  65.     }
  66.   } else if( text ) {
  67.     float bufx, bufy;
  68.  
  69.     /* get buffer coordinates */
  70.     bufx = ((float)event->xmotion.x * coord.disptobuf.inx_outx) +
  71.       coord.disptobuf.iadd_outx;
  72.     bufy = ((float)event->xmotion.y * coord.disptobuf.iny_outy) +
  73.       coord.disptobuf.iadd_outy;
  74.     if( magset.text.proportional )
  75.     label_file_coords_proportional((double)bufx, (double)bufy);
  76.     else
  77.       label_file_coords((double)bufx, (double)bufy);
  78.   }
  79. }
  80.  
  81. /*
  82.  * Subroutine:    magnify_pan
  83.  * Purpose:    Magnify location of a panbox event
  84.  * Xlib calls:    XCheckWindowEvent(), XSync()
  85.  */
  86. void magnify_pan ( event )
  87.      XEvent *event;        /* i: XEvent for location of mouse */
  88. {
  89.   void draw_magnifier();
  90.  
  91.   /* get only the most recent mouse moved event */
  92.   XSync(panbox.display, 0);
  93.   while( XCheckWindowEvent(panbox.display, panbox.ID,
  94.                PointerMotionMask, event) );
  95.   /* draw image fragment in scope magnibox */
  96.   /* get buffer coordinates */
  97.   magset.buf.X = (coord.imgtobuf.inx_outx *
  98.          (((float)event->xmotion.x * coord.pantoimg.inx_outx) +
  99.           coord.pantoimg.iadd_outx)) + coord.imgtobuf.add_outx;
  100.   magset.buf.Y = (coord.imgtobuf.iny_outy *
  101.          (((float)event->xmotion.y * coord.pantoimg.iny_outy) +
  102.           coord.pantoimg.iadd_outy)) + coord.imgtobuf.add_outy;
  103.   draw_magnifier((double)magset.buf.X, (double)magset.buf.Y);
  104. }
  105.  
  106. /*
  107.  * Subroutine:    redraw_magnifier
  108.  * Purpose:    Draw image piece in zoombox window, using last coords or
  109.  *        dispbox center
  110.  */
  111. void redraw_magnifier ( )
  112. {
  113.   void draw_magnifier(), d_transform();
  114.  
  115.   /* if called by a window redraw event, redraw as it last was */
  116.   if( magset.buf.X < 0 )
  117.     d_transform(&coord.disptobuf, (double)coord.disp.cenX,
  118.          (double)coord.disp.cenY, &magset.buf.X, &magset.buf.Y);
  119.   draw_magnifier((double)magset.buf.X, (double)magset.buf.Y);
  120. }
  121.  
  122. /*
  123.  * Subroutine:    label_file_coords
  124.  * Purpose:    Show pointer coordinates and image value in display window
  125.  * Xlib calls:    XDrawImageString()
  126.  */
  127. static void label_file_coords ( bufX, bufY )
  128.      double bufX, bufY;
  129. {
  130.   int val;
  131.   static char string[48];
  132.   float fileX, fileY;
  133.   GC gc, set_edit_gc();
  134.   void d_transform();
  135.   static void draw_proportional_coord();
  136.  
  137.   gc = set_edit_gc(magset.text.font,
  138.            magset.text.foreground, magset.text.background);
  139.   d_transform(&coord.buftofile, bufX, bufY, &fileX, &fileY);
  140.   if( (bufX < coord.buf.X1) || (bufX > coord.buf.X2) ||
  141.       (bufY < coord.buf.Y1) || (bufY > coord.buf.Y2) ) {
  142.     sprintf(string, " %6.1f %6.1f       x   ", fileX, fileY);
  143.     if( img.fiscaled )
  144.       XDrawImageString(desktop.display, desktop.ID, gc, magset.text.x_x,
  145.                magset.text.y, string, 26);
  146.     else
  147.       XDrawImageString(desktop.display, desktop.ID, gc, magset.text.x_x,
  148.                magset.text.y, string, 23);
  149.   } else if( img.fiscaled ) {
  150.     double rval;
  151.     if( (buffer.filebuf == NULL) ||
  152.         (buffer.filebuf == (char *)buffer.shortbuf) ) {
  153.       /* values scaled, originals not available */
  154.       val = buffer.shortbuf[(int)bufX + ((int)bufY * coord.buf.width)];
  155.       rval = ((double)val * img.fiscale) + img.fibias;
  156.       /* print strings with spaces padding out the end */
  157.       if( val <= buffer.clipmin )
  158.     sprintf(string, " %6.1f %6.1f  <%.4g         ", fileX, fileY, rval);
  159.       else if( val >= buffer.clipmax )
  160.     sprintf(string, " %6.1f %6.1f  >%.4g         ", fileX, fileY, rval);
  161.       else
  162.     sprintf(string, " %6.1f %6.1f   %.4g         ", fileX, fileY, rval);
  163.     } else {
  164.       /* values scaled, originals in filebuf */
  165.       float fbX, fbY;
  166.       d_transform(&coord.buftofbuf, bufX, bufY, &fbX, &fbY);
  167.       if( img.storage_type == ARR_I4 ) {
  168.     rval = (double)
  169.       *((int *)(buffer.filebuf +
  170.             (((int)fbX + ((int)fbY * coord.fbuf.width)) *
  171.              sizeof(int))));
  172.       } else if( img.storage_type == ARR_R4 ) {
  173.     rval = (double)
  174.       *((float *)(buffer.filebuf +
  175.               (((int)fbX + ((int)fbY * coord.fbuf.width)) *
  176.                sizeof(float))));
  177.       } else if( img.storage_type == ARR_R8 ) {
  178.     rval = *((double *)(buffer.filebuf +
  179.                 (((int)fbX + ((int)fbY * coord.fbuf.width)) *
  180.                  sizeof(double))));
  181.       } else
  182.     rval = 0.0;
  183.       if( img.fscaled )
  184.     rval = img.fbias + (rval * img.fscale);
  185.       sprintf(string, " %6.1f %6.1f   %.4g         ", fileX, fileY, rval);
  186.     }
  187.     XDrawImageString(desktop.display, desktop.ID, gc, magset.text.x_x,
  188.              magset.text.y, string, 26);
  189.   } else {
  190.     val = buffer.shortbuf[(int)bufX + ((int)bufY * coord.buf.width)];
  191.     sprintf(string, " %6.1f %6.1f  %6d ", fileX, fileY, val);
  192.     XDrawImageString(desktop.display, desktop.ID, gc, magset.text.x_x,
  193.              magset.text.y, string, 23);
  194.   }
  195. }
  196.  
  197. /*
  198.  * Subroutine:    clear_coord_area
  199.  * Purpose:    Erase area of coords, esp. when imtool_aux is no longer used
  200.  */
  201. void clear_coord_area ()
  202. {
  203.   int height;
  204.   height = magset.text.yoff * 2 + 1;
  205.   XClearArea(desktop.display, desktop.ID, btnbox.y - (height + 1), 1,
  206.          panbox.x - 2, height, False);
  207. }
  208.  
  209. /*
  210.  * Subroutine:    label_file_coords_proportional
  211.  * Purpose:    Show pointer coordinates and image value in display window
  212.  *        Special handling for proporitonal fonts is good for the coords,
  213.  *        but has not been refined for the val section.
  214.  * Xlib call:    XDrawImageString()
  215.  */
  216. static void label_file_coords_proportional ( bufX, bufY )
  217.      double bufX, bufY;
  218. {
  219.   int val;
  220.   static char string[48];
  221.   float fileX, fileY;
  222.   GC gc, set_edit_gc();
  223.   void d_transform();
  224.   static void draw_proportional_number();
  225.  
  226.   gc = set_edit_gc(magset.text.font,
  227.            magset.text.foreground, magset.text.background);
  228.   d_transform(&coord.buftofile, bufX, bufY, &fileX, &fileY);
  229.   sprintf(string, "        %6.1f    ", fileX);
  230.   draw_proportional_number(string, 8, magset.text.x_x, magset.text.width, gc);
  231.   sprintf(string, "        %6.1f    ", fileY);
  232.   draw_proportional_number(string, 8, magset.text.y_x, magset.text.width, gc);
  233.   if( (bufX < coord.buf.X1) || (bufX > coord.buf.X2) ||
  234.       (bufY < coord.buf.Y1) || (bufY > coord.buf.Y2) ) {
  235.     sprintf(string, "                        x    ");
  236.     draw_proportional_number(string, 24, magset.text.val_x,
  237.                  2 * magset.text.width, gc);
  238.   } else {
  239.     double dval;
  240.     int ival, clip, i;
  241.     if( get_pixel_val((int)bufX, (int)bufY, &ival, &dval, &clip) ) {
  242.       /* value is an integer */
  243.       integer_string(ival, clip, &(string[16]), VAL_SZ);
  244.     } else {
  245.       real_string(dval, &string[17], VAL_SZ - 1);
  246.       if( clip ) {
  247.     if( clip > 0 )
  248.       string[16] = '>';
  249.     else
  250.       string[16] = '<';
  251.       } else
  252.     string[16] = ' ';
  253.     }
  254.     for( i = 0; i < 16; i++ )
  255.       string[i] = ' ';
  256.     for( i = 16 + VAL_SZ; i < (VAL_SZ + 20); i++ )
  257.       string[i] = ' ';
  258.     draw_proportional_number(string, 16, magset.text.val_x,
  259.                  2 * magset.text.width, gc);
  260.   }
  261. }
  262.  
  263. /*
  264.  * Subroutine:    draw_proportional_coord
  265.  * Purpose:    Draw proportional text to cover area and place decimal point
  266.  */
  267. static void draw_proportional_number ( string, first_num, x, width, gc )
  268.      char *string;
  269.      int first_num;    /* i: where number begins (after leading spaces) */
  270.      int x;
  271.      int width;        /* i: pixel width to fill with label */
  272.      GC gc;
  273. {
  274.   int size, count, offset;
  275.   int letter, leading, not_done;
  276.  
  277.   leading = 1;
  278.   not_done = 1;
  279.   /* do a quick XTextWidth using a restricted table */
  280.   for( count = 0, size = 0; not_done; count++ ) {
  281.     letter = string[count + first_num];
  282.     if( letter == ' ' ) {
  283.       if( leading )
  284.     size += magset.text.space;
  285.       else
  286.     /* label ends at first space after text */
  287.     not_done = 0;
  288.     } else {
  289.       leading = 0;
  290.       if( (letter >= '0') && (letter <= '9') )
  291.     /* sizes of numbers */
  292.     size += magset.text.numsz[letter - '0'];
  293.       else if( letter == '.' )
  294.     size += magset.text.dot;
  295.       else if( (letter == '-') || (letter == '+') )
  296.     size += magset.text.dash;
  297.       else if( letter == '\0' ) {
  298.     char *space;
  299.     /* oops, no trailing spaces - put them in */
  300.     space = &(string[count + first_num]);
  301.     *space = ' ';
  302.     *(space + 1) = ' ';
  303.     *(space + 2) = '\0';
  304.     not_done = 0;
  305.       } else
  306.     /* this covers whatever else ('e', 'E', '<'. '>') */
  307.     size += magset.text.e;
  308.     }
  309.   }
  310.   /* determine number of extra spaces to cover area and their x offset */
  311.   offset = (width - size) / magset.text.space;
  312.   x += (width - (size + (offset * magset.text.space)));
  313.   if( (first_num -= offset) < 0 ) {
  314.     /* move starting posisiont forward, shorten string */
  315.     x -= (first_num * magset.text.space);
  316.     count += first_num;
  317.     first_num = 0;
  318.   }
  319.   count += (offset + 2);
  320.   XDrawImageString(desktop.display, desktop.ID, gc, x,
  321.            magset.text.y, &(string[first_num]), count);
  322. }
  323.  
  324. /*
  325.  * Subroutine:    blank_scope
  326.  * Purpose:    Fill scope with blank data
  327.  */
  328. void blank_scope()
  329. {
  330.   GC gc, set_gc();
  331.   void mark_Zmagnifier();
  332.  
  333.   /* blank field */
  334.   bzero(magset.data, magset.data_size);
  335.   if( !magset.halftone ) {
  336.     /* install the sighting mark */
  337.     mark_Zmagnifier();
  338.   } else {
  339. #ifdef NOTYET /* %% */
  340.     mark_XYmagnifier();
  341. #endif
  342.   }
  343.   gc = set_gc(magset.gcset_disp);
  344.   XPutImage(magset.win.display, magset.win.ID, gc, magset.image,
  345.         0, 0, magset.win.x, magset.win.y,
  346.         magset.win.width, magset.win.height);
  347. }
  348.