#ifndef lint static char SccsId[] = "%W% %G%"; #endif /* Module: mgfyctrl.c (Magnify Control) * Purpose: Initialize params and organize drawing the magnifier window * Subroutine: magnify_disp() returns: void * Subroutine: magnify_pan() returns: void * Subroutine: clear_coord_area() returns: void * Subroutine: redraw_magnifier() returns: void * Xlib calls: XCheckWindowEvent(), XSync() * Copyright: 1999 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. * Modified: {0} Michael VanHilst initial version 6 June 1989 * {1} MVH added support for second set of coords 7 Nov 1989 * {2} Doug Mink added support for WCS 18 Oct 1994 * {3} DJM changed WCS arguments 6 Jul 1995 * {4} DJM overwrite excess chars in WCS area 17 Aug 1995 * {5} DJM overwrite excess chars in pixel area 2 Feb 1996 * {6} DJM write image number if 3D 13 Jul 1998 * {6} DJM write face number if quad cube 23 Feb 1999 * {6} Doug Mink bump WCS strin from 32 to 48 char 6 May 1999 * {n} -- -- */ #include #include /* strlen */ #include /* X window stuff */ #include /* X window manager stuff */ #include "hfiles/struct.h" /* declare structure types */ #include "hfiles/extern.h" /* extern main SAOimage parameter structures */ #include "hfiles/constant.h" /* codes */ #include "hfiles/magnify.h" /* magnifier quick access structure */ extern struct windowRec desktop; extern struct magRec magset; #define VAL_SZ 10 /* * Subroutine: magnify_disp * Purpose: Magnify location of a dispbox event * Xlib calls: XCheckWindowEvent(), XSync() */ void magnify_disp ( event, view, text ) XEvent *event; /* i: XEvent for location of mouse */ int view, text; { void draw_magnifier(); static void label_file_coords(), label_file_coords_proportional(); /* get only the most recent mouse moved event */ XSync(dispbox.display, 0); while( XCheckWindowEvent(dispbox.display, dispbox.ID, PointerMotionMask, event) ); /* draw image fragment in scope magnibox if desired */ if( view ) { /* get buffer coordinates */ magset.buf.X = ((float)event->xmotion.x * coord.disptobuf.inx_outx) + coord.disptobuf.iadd_outx; magset.buf.Y = ((float)event->xmotion.y * coord.disptobuf.iny_outy) + coord.disptobuf.iadd_outy; draw_magnifier((double)magset.buf.X, (double)magset.buf.Y); if( text ) { if( magset.text.proportional ) label_file_coords_proportional((double)magset.buf.X, (double)magset.buf.Y); else label_file_coords((double)magset.buf.X, (double)magset.buf.Y); } } else if( text ) { float bufx, bufy; /* get buffer coordinates */ bufx = ((float)event->xmotion.x * coord.disptobuf.inx_outx) + coord.disptobuf.iadd_outx; bufy = ((float)event->xmotion.y * coord.disptobuf.iny_outy) + coord.disptobuf.iadd_outy; if( magset.text.proportional ) label_file_coords_proportional((double)bufx, (double)bufy); else label_file_coords((double)bufx, (double)bufy); } } /* * Subroutine: magnify_pan * Purpose: Magnify location of a panbox event * Xlib calls: XCheckWindowEvent(), XSync() */ void magnify_pan ( event ) XEvent *event; /* i: XEvent for location of mouse */ { void draw_magnifier(); /* get only the most recent mouse moved event */ XSync(panbox.display, 0); while( XCheckWindowEvent(panbox.display, panbox.ID, PointerMotionMask, event) ); /* draw image fragment in scope magnibox */ /* get buffer coordinates */ magset.buf.X = (coord.imgtobuf.inx_outx * (((float)event->xmotion.x * coord.pantoimg.inx_outx) + coord.pantoimg.iadd_outx)) + coord.imgtobuf.add_outx; magset.buf.Y = (coord.imgtobuf.iny_outy * (((float)event->xmotion.y * coord.pantoimg.iny_outy) + coord.pantoimg.iadd_outy)) + coord.imgtobuf.add_outy; draw_magnifier((double)magset.buf.X, (double)magset.buf.Y); } /* * Subroutine: redraw_magnifier * Purpose: Draw image piece in zoombox window, using last coords or * dispbox center */ void redraw_magnifier ( ) { void draw_magnifier(), d_transform(); /* if called by a window redraw event, redraw as it last was */ if( magset.buf.X < 0 ) d_transform(&coord.disptobuf, (double)coord.disp.cenX, (double)coord.disp.cenY, &magset.buf.X, &magset.buf.Y); draw_magnifier((double)magset.buf.X, (double)magset.buf.Y); } /* * Subroutine: label_file_coords * Purpose: Show pointer coordinates and image value in display window * Xlib calls: XDrawImageString() */ static void label_file_coords ( bufX, bufY ) double bufX, bufY; { int val; static char string[48], cstring[64]; int lstr = 48; int lwcs, lpix; float fileX, fileY; GC gc, set_edit_gc(); void d_transform(); static void draw_proportional_coord(); static int lwcs0 = 0; static int lpix0 = 0; int i; int iswcs(); gc = set_edit_gc(magset.text.font, magset.text.foreground, magset.text.background); d_transform(&coord.buftofile, bufX, bufY, &fileX, &fileY); if (img.filenimg > 1) { if (iswcs(wcs) && (wcs->prjcode == WCS_CSC || wcs->prjcode == WCS_QSC || wcs->prjcode == WCS_TSC)) sprintf(cstring, " %6.1f %6.1f f%d", fileX, fileY, img.nimage-1); else sprintf(cstring, " %6.1f %6.1f %d", fileX, fileY, img.nimage); } else sprintf(cstring, " %6.1f %6.1f", fileX, fileY); /* Cursor is not on the image */ if( (bufX < coord.buf.X1) || (bufX > coord.buf.X2) || (bufY < coord.buf.Y1) || (bufY > coord.buf.Y2) ) { sprintf(string, "%s x ", cstring); lpix = strlen (string); if (lpix < lpix0) { for (i=lpix; i= buffer.clipmax ) sprintf(string, "%s >%.4g ", cstring, rval); else sprintf(string, "%s %.4g ", cstring, rval); } else { /* values scaled, originals in filebuf */ float fbX, fbY; d_transform(&coord.buftofbuf, bufX, bufY, &fbX, &fbY); if( img.storage_type == ARR_I4 ) { rval = (double) *((int *)(buffer.filebuf + (((int)fbX + ((int)fbY * coord.fbuf.width)) * sizeof(int)))); } else if( img.storage_type == ARR_R4 ) { rval = (double) *((float *)(buffer.filebuf + (((int)fbX + ((int)fbY * coord.fbuf.width)) * sizeof(float)))); } else if( img.storage_type == ARR_R8 ) { rval = *((double *)(buffer.filebuf + (((int)fbX + ((int)fbY * coord.fbuf.width)) * sizeof(double)))); } else rval = 0.0; if( img.fscaled ) rval = img.fbias + (rval * img.fscale); sprintf(string, "%s %.4g ", cstring, rval); } lpix = strlen (string); if (lpix < lpix0) { for (i=lpix; i coord.buf.X2) || (bufY < coord.buf.Y1) || (bufY > coord.buf.Y2) ) { sprintf(string, " x "); draw_proportional_number(string, 24, magset.text.val_x, 2 * magset.text.width, gc); } else { double dval; int ival, clip, i; if( get_pixel_val((int)bufX, (int)bufY, &ival, &dval, &clip) ) { /* value is an integer */ integer_string(ival, clip, &(string[16]), VAL_SZ); } else { real_string(dval, &string[17], VAL_SZ - 1); if( clip ) { if( clip > 0 ) string[16] = '>'; else string[16] = '<'; } else string[16] = ' '; } for( i = 0; i < 16; i++ ) string[i] = ' '; for( i = 16 + VAL_SZ; i < (VAL_SZ + 20); i++ ) string[i] = ' '; draw_proportional_number(string, 16, magset.text.val_x, 2 * magset.text.width, gc); } } /* * Subroutine: draw_proportional_coord * Purpose: Draw proportional text to cover area and place decimal point */ static void draw_proportional_number ( string, first_num, x, width, gc ) char *string; int first_num; /* i: where number begins (after leading spaces) */ int x; int width; /* i: pixel width to fill with label */ GC gc; { int size, count, offset; int letter, leading, not_done; leading = 1; not_done = 1; /* do a quick XTextWidth using a restricted table */ for( count = 0, size = 0; not_done; count++ ) { letter = string[count + first_num]; if( letter == ' ' ) { if( leading ) size += magset.text.space; else /* label ends at first space after text */ not_done = 0; } else { leading = 0; if( (letter >= '0') && (letter <= '9') ) /* sizes of numbers */ size += magset.text.numsz[letter - '0']; else if( letter == '.' ) size += magset.text.dot; else if( (letter == '-') || (letter == '+') ) size += magset.text.dash; else if( letter == '\0' ) { char *space; /* oops, no trailing spaces - put them in */ space = &(string[count + first_num]); *space = ' '; *(space + 1) = ' '; *(space + 2) = '\0'; not_done = 0; } else /* this covers whatever else ('e', 'E', '<'. '>') */ size += magset.text.e; } } /* determine number of extra spaces to cover area and their x offset */ offset = (width - size) / magset.text.space; x += (width - (size + (offset * magset.text.space))); if( (first_num -= offset) < 0 ) { /* move starting posisiont forward, shorten string */ x -= (first_num * magset.text.space); count += first_num; first_num = 0; } count += (offset + 2); XDrawImageString(desktop.display, desktop.ID, gc, x, magset.text.y, &(string[first_num]), count); } /* * Subroutine: blank_scope * Purpose: Fill scope with blank data */ void blank_scope() { GC gc, set_gc(); void mark_Zmagnifier(); /* blank field */ bzero(magset.data, magset.data_size); if( !magset.halftone ) { /* install the sighting mark */ mark_Zmagnifier(); } else { #ifdef NOTYET /* %% */ mark_XYmagnifier(); #endif } gc = set_gc(magset.gcset_disp); XPutImage(magset.win.display, magset.win.ID, gc, magset.image, 0, 0, magset.win.x, magset.win.y, magset.win.width, magset.win.height); }