/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * filename: xzoom.c * * * * UTIL C-source: Medical Image Conversion Utility * * * * purpose : image zoom routines * * * * project : (X)MedCon by Erik Nolf * * * * Functions : XMdcImagesZoomIn() - Zoom image IN * * XMdcImagesZoomOut() - Zoom image OUT * * XMdcImagesZoomCallbackClicked() - Zoom Clicked callback * * XMdcImagesZoom() - Display zoomed image * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ /* $Id: xzoom.c,v 1.20 2007/05/21 20:16:20 enlf Exp $ */ /* Copyright (C) 1997-2007 by Erik Nolf This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Place - Suite 330, Boston, MA 02111-1307, USA. */ /**************************************************************************** H E A D E R S ****************************************************************************/ #include "m-depend.h" #include #ifdef HAVE_STDLIB_H #include #endif #include "xmedcon.h" /**************************************************************************** D E F I N E S ****************************************************************************/ typedef struct ZoomStruct_t { int type; Uint32 nr; GdkPixbuf *im, *cur; GtkWidget *darea; }ZoomStruct; /**************************************************************************** F U N C T I O N S ****************************************************************************/ /* local routine */ static int XMdcGetZoomFactor(ZoomStruct *zoom, int z) { zoom->type += z; /* incr/decr */ /* prevent zero (= not allowed) and -1 (= 1 original) */ if (zoom->type == 0 || zoom->type == -1) { switch (z) { case XMDC_ZOOM_IN : zoom->type = 1; break; case XMDC_ZOOM_OUT: zoom->type = -2; break; default : zoom->type = 1; } } return(zoom->type); } /* local routine */ static char *XMdcGetStrZoomFactor(int type) { if (type < 0) { sprintf(xmdcstr,"[1:%d]",-type); }else{ sprintf(xmdcstr,"[%d:1]",type); } return(xmdcstr); } /* local routine */ static void XMdcSetZoomWindowTitle(GtkWidget *window, ZoomStruct *zoom) { Uint32 nr = zoom->nr + 1; sprintf(mdcbufr,"%u %s",nr,XMdcGetStrZoomFactor(zoom->type)); gtk_window_set_title(GTK_WINDOW(window),mdcbufr); } /* local routine */ static void XMdcRemoveZoomStruct(GtkWidget *window, gpointer data) { ZoomStruct *zoom = (ZoomStruct *)data; if (zoom != NULL) { if (zoom->im != NULL) gdk_pixbuf_unref(zoom->im); if (zoom->cur != NULL) gdk_pixbuf_unref(zoom->cur); MdcFree(zoom); } } /* local routine */ static gboolean XMdcImagesZoomCallbackExpose(GtkWidget *widget, GdkEventExpose *event, gpointer window) { GdkGC *gc = widget->style->fg_gc[GTK_STATE_NORMAL]; ZoomStruct *zoom; zoom = (ZoomStruct *)gtk_object_get_data(GTK_OBJECT(window),"zoomstruct"); if (event->area.width <= gdk_pixbuf_get_width(zoom->cur) && event->area.height <= gdk_pixbuf_get_height(zoom->cur)) { gdk_pixbuf_render_to_drawable(zoom->cur, widget->window, gc, event->area.x, event->area.y, event->area.x, event->area.y, event->area.width, event->area.height, sRenderSelection.Dither, 0, 0); } return(TRUE); } void XMdcImagesZoomIn(GtkWidget *window) { GdkPixbuf *new; ZoomStruct *zoom; int w, h, z; #ifdef _WIN32 gtk_widget_hide(window); #endif zoom = (ZoomStruct *)gtk_object_get_data(GTK_OBJECT(window),"zoomstruct"); z = XMdcGetZoomFactor(zoom,XMDC_ZOOM_IN); w = gdk_pixbuf_get_width(zoom->im); h = gdk_pixbuf_get_height(zoom->im); if (z < 0) { w /= -z; h /= -z; }else{ w *= z; h *= z; } gtk_window_set_policy(GTK_WINDOW(window),TRUE,TRUE,TRUE); new = gdk_pixbuf_scale_simple(zoom->im,w,h,sRenderSelection.Interp); gdk_pixbuf_unref(zoom->cur); zoom->cur = new; gtk_drawing_area_size(GTK_DRAWING_AREA(zoom->darea),w,h); gdk_pixbuf_render_to_drawable(zoom->cur, zoom->darea->window, zoom->darea->style->fg_gc[GTK_STATE_NORMAL], 0,0,0,0,w,h,sRenderSelection.Dither,0,0); XMdcSetZoomWindowTitle(window,zoom); gtk_window_set_policy(GTK_WINDOW(window),FALSE,FALSE,FALSE); #ifdef _WIN32 gtk_widget_show(window); #endif } void XMdcImagesZoomOut(GtkWidget *window) { GdkPixbuf *new; ZoomStruct *zoom; int w, h, z; #ifdef _WIN32 gtk_widget_hide(window); #endif zoom = (ZoomStruct *)gtk_object_get_data(GTK_OBJECT(window),"zoomstruct"); z = XMdcGetZoomFactor(zoom,XMDC_ZOOM_OUT); w = gdk_pixbuf_get_width(zoom->im); h = gdk_pixbuf_get_height(zoom->im); if (z < 0) { w /= -z; h /= -z; }else{ w *= z; h *= z; } gtk_window_set_policy(GTK_WINDOW(window),TRUE,TRUE,TRUE); new = gdk_pixbuf_scale_simple(zoom->im,w,h,sRenderSelection.Interp); gdk_pixbuf_unref(zoom->cur); zoom->cur = new; gtk_drawing_area_size(GTK_DRAWING_AREA(zoom->darea),w,h); gdk_pixbuf_render_to_drawable(zoom->cur, zoom->darea->window, zoom->darea->style->fg_gc[GTK_STATE_NORMAL], 0,0,0,0,w,h,sRenderSelection.Dither,0,0); XMdcSetZoomWindowTitle(window,zoom); gtk_window_set_policy(GTK_WINDOW(window),FALSE,FALSE,FALSE); #ifdef _WIN32 gtk_widget_show(window); #endif } gboolean XMdcImagesZoomCallbackClicked(GtkWidget *widget, GdkEventButton *button, GtkWidget *window) { if (button->button == 3) gtk_widget_destroy(window); if (button->button == 1) XMdcImagesZoomIn(window); if (button->button == 2) XMdcImagesZoomOut(window); return(TRUE); } void XMdcImagesZoom(GtkWidget *widget, Uint32 nr) { GtkWidget *window; GtkWidget *tblbox; GtkWidget *darea; ZoomStruct *zoom=NULL; int w, h, z, w_zoom, h_zoom; /* allocate structure */ zoom = (ZoomStruct *)malloc(sizeof(ZoomStruct)); if (zoom == NULL) { XMdcDisplayErr("Couldn't allocate zoom struct"); return; }else{ zoom->nr = my.realnumber[nr]; zoom->type = sResizeSelection.CurType; zoom->im = NULL; zoom->cur = NULL; } w = (int)XMdcScaleW(my.fi->image[zoom->nr].width); w_zoom = w; h = (int)XMdcScaleH(my.fi->image[zoom->nr].height); h_zoom = h; z = XMdcGetZoomFactor(zoom,XMDC_ZOOM_NONE); if (z < 0) { w_zoom /= -z; h_zoom /= -z; }else{ w_zoom *= z; h_zoom *= z; } /* initial pixmap must be original image; so no resize here */ my.RESIZE = MDC_NO; zoom->im = XMdcBuildGdkPixbufFI(my.fi,zoom->nr,sGbc.mod.vgbc); my.RESIZE = MDC_YES; zoom->cur = gdk_pixbuf_scale_simple(zoom->im,w,h,sRenderSelection.Interp); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_policy(GTK_WINDOW(window),TRUE,TRUE,TRUE); gtk_container_set_border_width(GTK_CONTAINER(window),1); gtk_signal_connect(GTK_OBJECT(window),"destroy", GTK_SIGNAL_FUNC(XMdcRemoveZoomStruct),zoom); gtk_signal_connect(GTK_OBJECT(window),"destroy", GTK_SIGNAL_FUNC(gtk_widget_destroy),NULL); tblbox = gtk_table_new(1,1,TRUE); gtk_container_add(GTK_CONTAINER(window),tblbox); gtk_widget_show(tblbox); darea = gtk_drawing_area_new(); zoom->darea = darea; gtk_table_attach(GTK_TABLE(tblbox),darea,0,1,0,1,GTK_FILL,GTK_FILL,0,0); gtk_widget_show(darea); gtk_widget_set_events(darea, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK); gtk_drawing_area_size(GTK_DRAWING_AREA(darea),w,h); gtk_signal_connect(GTK_OBJECT(darea),"button_press_event", GTK_SIGNAL_FUNC(XMdcImagesZoomCallbackClicked), GTK_WIDGET(window)); gtk_signal_connect(GTK_OBJECT(darea),"expose_event", GTK_SIGNAL_FUNC(XMdcImagesZoomCallbackExpose), GTK_WIDGET(window)); XMdcShowWidget(window); gdk_window_set_cursor (window->window, fleurcursor); gtk_object_set_data(GTK_OBJECT(window),"zoomstruct",zoom); XMdcSetZoomWindowTitle(window,zoom); gtk_window_set_policy(GTK_WINDOW(window),FALSE,FALSE,FALSE); }