/** * gimp_display_shell_rotate_xy: * @shell: * @x: * @y: * @nx: * @ny: * * Rotates an unrotated display coordinate to a rotated shell coordinate. **/ void gimp_display_shell_rotate_xy (const GimpDisplayShell *shell, gdouble x, gdouble y, gint *nx, gint *ny) { gint64 tx; gint64 ty; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (nx != NULL); g_return_if_fail (ny != NULL); if (shell->rotate_transform) cairo_matrix_transform_point (shell->rotate_transform, &x, &y); tx = x; ty = y; /* The projected coordinates might overflow a gint in the case of * big images at high zoom levels, so we clamp them here to avoid * problems. */ *nx = CLAMP (tx, G_MININT, G_MAXINT); *ny = CLAMP (ty, G_MININT, G_MAXINT); }
/** * gimp_display_shell_scroll_set_offsets: * @shell: * @offset_x: * @offset_y: * * This function scrolls the image in the shell's viewport. It redraws * the entire canvas. * * Use it for setting the scroll offset on freshly scaled images or * when the window is resized. For panning, use * gimp_display_shell_scroll(). **/ void gimp_display_shell_scroll_set_offset (GimpDisplayShell *shell, gint offset_x, gint offset_y) { g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); if (shell->offset_x == offset_x && shell->offset_y == offset_y) return; gimp_display_shell_scale_save_revert_values (shell); /* freeze the active tool */ gimp_display_shell_pause (shell); shell->offset_x = offset_x; shell->offset_y = offset_y; gimp_display_shell_scroll_clamp_and_update (shell); gimp_display_shell_scrolled (shell); gimp_display_shell_expose_full (shell); /* re-enable the active tool */ gimp_display_shell_resume (shell); }
void gimp_display_shell_layer_select_init (GimpDisplayShell *shell, gint move, guint32 time) { LayerSelect *layer_select; GimpImage *image; GimpLayer *layer; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); image = gimp_display_get_image (shell->display); layer = gimp_image_get_active_layer (image); if (! layer) return; layer_select = layer_select_new (image, layer, image->gimp->config->layer_preview_size); layer_select_advance (layer_select, move); gtk_window_set_screen (GTK_WINDOW (layer_select->window), gtk_widget_get_screen (GTK_WIDGET (shell))); gtk_widget_show (layer_select->window); gdk_keyboard_grab (gtk_widget_get_window (layer_select->window), FALSE, time); }
/** * gimp_display_shell_scale_image_is_within_viewport: * @shell: * * Returns: %TRUE if the (scaled) image is smaller than and within the * viewport. **/ gboolean gimp_display_shell_scale_image_is_within_viewport (GimpDisplayShell *shell, gboolean *horizontally, gboolean *vertically) { gint sw, sh; gboolean horizontally_dummy, vertically_dummy; g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE); if (! horizontally) horizontally = &horizontally_dummy; if (! vertically) vertically = &vertically_dummy; gimp_display_shell_scale_get_image_size (shell, &sw, &sh); *horizontally = sw <= shell->disp_width && shell->offset_x <= 0 && shell->offset_x >= sw - shell->disp_width; *vertically = sh <= shell->disp_height && shell->offset_y <= 0 && shell->offset_y >= sh - shell->disp_height; return *vertically && *horizontally; }
/** * gimp_display_shell_scale_by_values: * @shell: the #GimpDisplayShell * @scale: the new scale * @offset_x: the new X offset * @offset_y: the new Y offset * @resize_window: whether the display window should be resized * * Directly sets the image scale and image offsets used by the display. If * @resize_window is %TRUE then the display window is resized to better * accommodate the image, see gimp_display_shell_shrink_wrap(). **/ void gimp_display_shell_scale_by_values (GimpDisplayShell *shell, gdouble scale, gint offset_x, gint offset_y, gboolean resize_window) { g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); /* Abort early if the values are all setup already. We don't * want to inadvertently resize the window (bug #164281). */ if (SCALE_EQUALS (gimp_zoom_model_get_factor (shell->zoom), scale) && shell->offset_x == offset_x && shell->offset_y == offset_y) return; gimp_display_shell_scale_save_revert_values (shell); /* freeze the active tool */ gimp_display_shell_pause (shell); gimp_zoom_model_zoom (shell->zoom, GIMP_ZOOM_TO, scale); shell->offset_x = offset_x; shell->offset_y = offset_y; gimp_display_shell_scale_resize (shell, resize_window, FALSE); /* re-enable the active tool */ gimp_display_shell_resume (shell); }
void gimp_display_shell_filter_set (GimpDisplayShell *shell, GimpColorDisplayStack *stack) { g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (stack == NULL || GIMP_IS_COLOR_DISPLAY_STACK (stack)); if (stack == shell->filter_stack) return; if (shell->filter_stack) { g_signal_handlers_disconnect_by_func (shell->filter_stack, gimp_display_shell_filter_changed, shell); g_object_unref (shell->filter_stack); } shell->filter_stack = stack; if (shell->filter_stack) { g_object_ref (shell->filter_stack); g_signal_connect (shell->filter_stack, "changed", G_CALLBACK (gimp_display_shell_filter_changed), shell); } gimp_display_shell_filter_changed (NULL, shell); }
/** * gimp_display_shell_scale_can_revert: * @shell: the #GimpDisplayShell * * Return value: %TRUE if a previous display scale exists, otherwise %FALSE. **/ gboolean gimp_display_shell_scale_can_revert (GimpDisplayShell *shell) { g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE); return (shell->last_scale > SCALE_EPSILON); }
/** * gimp_display_shell_transform_xy: * @shell: * @x: * @y: * @nx: * @ny: * * Transforms an image coordinate to a shell coordinate. **/ void gimp_display_shell_transform_xy (const GimpDisplayShell *shell, gdouble x, gdouble y, gint *nx, gint *ny) { gint64 tx; gint64 ty; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (nx != NULL); g_return_if_fail (ny != NULL); tx = ((gint64) x * shell->x_src_dec) / shell->x_dest_inc; ty = ((gint64) y * shell->y_src_dec) / shell->y_dest_inc; tx -= shell->offset_x; ty -= shell->offset_y; /* The projected coordinates might overflow a gint in the case of big images at high zoom levels, so we clamp them here to avoid problems. */ *nx = CLAMP (tx, G_MININT, G_MAXINT); *ny = CLAMP (ty, G_MININT, G_MAXINT); }
/** * gimp_display_shell_untransform_xy: * @shell: a #GimpDisplayShell * @x: x coordinate in display coordinates * @y: y coordinate in display coordinates * @nx: returns x oordinate in image coordinates * @ny: returns y coordinate in image coordinates * @round: if %TRUE, round the results to the nearest integer; * if %FALSE, simply cast them to @gint. * * Transform from display coordinates to image coordinates, so that * points on the display can be mapped to the corresponding points * in the image. **/ void gimp_display_shell_untransform_xy (const GimpDisplayShell *shell, gint x, gint y, gint *nx, gint *ny, gboolean round) { gint64 tx; gint64 ty; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (nx != NULL); g_return_if_fail (ny != NULL); tx = (gint64) x + shell->offset_x; ty = (gint64) y + shell->offset_y; tx *= shell->x_dest_inc; ty *= shell->y_dest_inc; tx += round ? shell->x_dest_inc : shell->x_dest_inc >> 1; ty += round ? shell->y_dest_inc : shell->y_dest_inc >> 1; tx /= shell->x_src_dec; ty /= shell->y_src_dec; *nx = CLAMP (tx, G_MININT, G_MAXINT); *ny = CLAMP (ty, G_MININT, G_MAXINT); }
void gimp_display_shell_constrain_line (GimpDisplayShell *shell, gdouble start_x, gdouble start_y, gdouble *end_x, gdouble *end_y, gint n_snap_lines) { gdouble offset_angle; gdouble xres, yres; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (end_x != NULL); g_return_if_fail (end_y != NULL); gimp_display_shell_get_constrained_line_params (shell, &offset_angle, &xres, &yres); gimp_constrain_line (start_x, start_y, end_x, end_y, n_snap_lines, offset_angle, xres, yres); }
/** * gimp_display_shell_scale_to: * @shell: * @scale: * @viewport_x: * @viewport_y: * * Zooms. The display offsets are adjusted so that the point specified * by @x and @y doesn't change it's position on screen. **/ static void gimp_display_shell_scale_to (GimpDisplayShell *shell, gdouble scale, gint viewport_x, gint viewport_y) { gdouble scale_x, scale_y; gdouble image_focus_x, image_focus_y; gint target_offset_x, target_offset_y; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); if (! shell->display) return; gimp_display_shell_untransform_xy_f (shell, viewport_x, viewport_y, &image_focus_x, &image_focus_y); gimp_display_shell_calculate_scale_x_and_y (shell, scale, &scale_x, &scale_y); target_offset_x = scale_x * image_focus_x - viewport_x; target_offset_y = scale_y * image_focus_y - viewport_y; /* Note that we never come here if we need to * resize_windows_on_zoom */ gimp_display_shell_scale_by_values (shell, scale, target_offset_x, target_offset_y, FALSE); }
void gimp_display_shell_get_constrained_line_params (GimpDisplayShell *shell, gdouble *offset_angle, gdouble *xres, gdouble *yres) { g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (offset_angle != NULL); g_return_if_fail (xres != NULL); g_return_if_fail (yres != NULL); if (shell->flip_horizontally ^ shell->flip_vertically) *offset_angle = +shell->rotate_angle; else *offset_angle = -shell->rotate_angle; *xres = 1.0; *yres = 1.0; if (! shell->dot_for_dot) { GimpImage *image = gimp_display_get_image (shell->display); if (image) gimp_image_get_resolution (image, xres, yres); } }
/** * gimp_display_shell_untransform_coords: * @shell: a #GimpDisplayShell * @display_coords: display coordinates * @image_coords: returns the corresponding image coordinates * * Transforms from display coordinates to image coordinates, so that * points on the display can be mapped to points in the image. **/ void gimp_display_shell_untransform_coords (const GimpDisplayShell *shell, const GimpCoords *display_coords, GimpCoords *image_coords) { g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (display_coords != NULL); g_return_if_fail (image_coords != NULL); *image_coords = *display_coords; if (shell->rotate_untransform) cairo_matrix_transform_point (shell->rotate_untransform, &image_coords->x, &image_coords->y); image_coords->x += shell->offset_x; image_coords->y += shell->offset_y; image_coords->x /= shell->scale_x; image_coords->y /= shell->scale_y; image_coords->xscale = shell->scale_x; image_coords->yscale = shell->scale_y; }
/** * gimp_display_shell_unrotate_xy: * @shell: a #GimpDisplayShell * @x: x coordinate in rotated display coordinates * @y: y coordinate in rotated display coordinates * @nx: returns x oordinate in unrotated display coordinates * @ny: returns y coordinate in unrotated display coordinates * * Rotate from rotated display coordinates to unrotated display * coordinates. **/ void gimp_display_shell_unrotate_xy (const GimpDisplayShell *shell, gint x, gint y, gint *nx, gint *ny) { g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (nx != NULL); g_return_if_fail (ny != NULL); if (shell->rotate_untransform) { gdouble fx = x; gdouble fy = y; cairo_matrix_transform_point (shell->rotate_untransform, &fy, &fy); *nx = CLAMP (fx, G_MININT, G_MAXINT); *ny = CLAMP (fy, G_MININT, G_MAXINT); } else { *nx = x; *ny = y; } }
void gimp_display_shell_scale_drag (GimpDisplayShell *shell, gdouble start_x, gdouble start_y, gdouble delta_x, gdouble delta_y) { gdouble scale; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); scale = gimp_zoom_model_get_factor (shell->zoom); gimp_display_shell_push_zoom_focus_pointer_pos (shell, start_x, start_y); if (delta_y > 0) { gimp_display_shell_scale (shell, GIMP_ZOOM_TO, scale * 1.1, GIMP_ZOOM_FOCUS_POINTER); } else if (delta_y < 0) { gimp_display_shell_scale (shell, GIMP_ZOOM_TO, scale * 0.9, GIMP_ZOOM_FOCUS_POINTER); } }
/** * gimp_display_shell_transform_segments: * @shell: a #GimpDisplayShell * @src_segs: array of segments in image coordinates * @dest_segs: returns the corresponding segments in display coordinates * @n_segs: number of segments * * Transforms from image coordinates to display coordinates, so that * objects can be rendered at the correct points on the display. **/ void gimp_display_shell_transform_segments (const GimpDisplayShell *shell, const GimpBoundSeg *src_segs, GimpSegment *dest_segs, gint n_segs, gdouble offset_x, gdouble offset_y) { gint i; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); for (i = 0; i < n_segs ; i++) { gdouble x1, x2; gdouble y1, y2; x1 = src_segs[i].x1 + offset_x; x2 = src_segs[i].x2 + offset_x; y1 = src_segs[i].y1 + offset_y; y2 = src_segs[i].y2 + offset_y; dest_segs[i].x1 = SCALEX (shell, x1) - shell->offset_x; dest_segs[i].x2 = SCALEX (shell, x2) - shell->offset_x; dest_segs[i].y1 = SCALEY (shell, y1) - shell->offset_y; dest_segs[i].y2 = SCALEY (shell, y2) - shell->offset_y; } }
/** * gimp_display_shell_get_rotated_scale: * @shell: the #GimpDisplayShell * @scale_x: horizontal scale output * @scale_y: vertical scale output * * Returns the screen space horizontal and vertical scaling * factors, taking rotation into account. **/ void gimp_display_shell_get_rotated_scale (GimpDisplayShell *shell, gdouble *scale_x, gdouble *scale_y) { g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); if (shell->rotate_angle == 0.0 || shell->scale_x == shell->scale_y) { if (scale_x) *scale_x = shell->scale_x; if (scale_y) *scale_y = shell->scale_y; } else { gdouble a = G_PI * shell->rotate_angle / 180.0; gdouble cos_a = cos (a); gdouble sin_a = sin (a); if (scale_x) *scale_x = 1.0 / sqrt (SQR (cos_a / shell->scale_x) + SQR (sin_a / shell->scale_y)); if (scale_y) *scale_y = 1.0 / sqrt (SQR (cos_a / shell->scale_y) + SQR (sin_a / shell->scale_x)); } }
/** * gimp_display_shell_scroll_center_image: * @shell: * @horizontally: * @vertically: * * Centers the image in the display shell on the desired axes. * **/ void gimp_display_shell_scroll_center_image (GimpDisplayShell *shell, gboolean horizontally, gboolean vertically) { gint sw, sh; gint target_offset_x, target_offset_y; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); if (! shell->display || ! gimp_display_get_image (shell->display) || (! vertically && ! horizontally)) return; target_offset_x = shell->offset_x; target_offset_y = shell->offset_y; gimp_display_shell_scale_get_image_size (shell, &sw, &sh); if (horizontally) { target_offset_x = (sw - shell->disp_width) / 2; } if (vertically) { target_offset_y = (sh - shell->disp_height) / 2; } gimp_display_shell_scroll_set_offset (shell, target_offset_x, target_offset_y); }
GimpColorDisplayStack * gimp_display_shell_filter_new (GimpDisplayShell *shell, GimpColorConfig *config) { g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL); g_return_val_if_fail (GIMP_IS_COLOR_CONFIG (config), NULL); if (config->display_module) { GType type = g_type_from_name (config->display_module); if (g_type_is_a (type, GIMP_TYPE_COLOR_DISPLAY)) { GimpColorDisplay *display; GimpColorDisplayStack *stack; display = g_object_new (type, "color-config", config, "color-managed", shell, NULL); stack = gimp_color_display_stack_new (); gimp_color_display_stack_add (stack, display); g_object_unref (display); return stack; } } return NULL; }
/** * gimp_display_shell_scroll_setup_vscrollbar: * @shell: * @value: * * Setup the limits of the vertical scrollbar * **/ void gimp_display_shell_scroll_setup_vscrollbar (GimpDisplayShell *shell, gdouble value) { gint sh; gdouble lower; gdouble upper; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); if (! shell->display || ! gimp_display_get_image (shell->display)) return; gimp_display_shell_scale_get_image_size (shell, NULL, &sh); if (shell->disp_height < sh) { lower = MIN (value, 0); upper = MAX (value + shell->disp_height, sh); } else { lower = MIN (value, -(shell->disp_height - sh) / 2); upper = MAX (value + shell->disp_height, sh + (shell->disp_height - sh) / 2); } g_object_set (shell->vsbdata, "lower", lower, "upper", upper, "step-increment", (gdouble) MAX (shell->scale_y, MINIMUM_STEP_AMOUNT), NULL); }
/** * gimp_display_shell_scale_set_dot_for_dot: * @shell: the #GimpDisplayShell * @dot_for_dot: whether "Dot for Dot" should be enabled * * If @dot_for_dot is set to %TRUE then the "Dot for Dot" mode (where image and * screen pixels are of the same size) is activated. Dually, the mode is * disabled if @dot_for_dot is %FALSE. **/ void gimp_display_shell_scale_set_dot_for_dot (GimpDisplayShell *shell, gboolean dot_for_dot) { g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); if (dot_for_dot != shell->dot_for_dot) { GimpDisplayConfig *config = shell->display->config; gboolean resize_window; /* Resize windows only in multi-window mode */ resize_window = (config->resize_windows_on_zoom && ! GIMP_GUI_CONFIG (config)->single_window_mode); /* freeze the active tool */ gimp_display_shell_pause (shell); shell->dot_for_dot = dot_for_dot; gimp_display_shell_scale_update (shell); gimp_display_shell_scale_resize (shell, resize_window, FALSE); /* re-enable the active tool */ gimp_display_shell_resume (shell); } }
void gimp_display_shell_expose_region (GimpDisplayShell *shell, cairo_region_t *region) { GdkRegion *gdk_region; gint n_rectangles; gint i; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (region != NULL); if (! gtk_widget_get_realized (shell->canvas)) return; gdk_region = gdk_region_new (); n_rectangles = cairo_region_num_rectangles (region); for (i = 0; i < n_rectangles; i++) { cairo_rectangle_int_t rectangle; cairo_region_get_rectangle (region, i, &rectangle); gdk_region_union_with_rect (gdk_region, (GdkRectangle *) &rectangle); } gdk_window_invalidate_region (gtk_widget_get_window (shell->canvas), gdk_region, TRUE); gdk_region_destroy (gdk_region); }
/** * gimp_display_shell_scale_fill: * @shell: the #GimpDisplayShell * * Sets the scale such that the entire display area is precisely * filled by the image. **/ void gimp_display_shell_scale_fill (GimpDisplayShell *shell) { GimpImage *image; gint image_width; gint image_height; gdouble xres; gdouble yres; gdouble zoom_factor; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); image = gimp_display_get_image (shell->display); image_width = gimp_image_get_width (image); image_height = gimp_image_get_height (image); gimp_image_get_resolution (image, &xres, &yres); if (! shell->dot_for_dot) { image_width = ROUND (image_width * shell->monitor_xres / xres); image_height = ROUND (image_height * shell->monitor_yres / yres); } zoom_factor = MAX ((gdouble) shell->disp_width / (gdouble) image_width, (gdouble) shell->disp_height / (gdouble) image_height); gimp_display_shell_scale (shell, GIMP_ZOOM_TO, zoom_factor, GIMP_ZOOM_FOCUS_BEST_GUESS); gimp_display_shell_scroll_center_image (shell, TRUE, TRUE); }
void gimp_display_shell_expose_full (GimpDisplayShell *shell) { g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); gtk_widget_queue_draw (shell->canvas); }
/** * gimp_display_shell_scale_resize: * @shell: the #GimpDisplayShell * @resize_window: whether the display window should be resized * @grow_only: whether shrinking of the window is allowed or not * * Function commonly called after a change in display scale to make the changes * visible to the user. If @resize_window is %TRUE then the display window is * resized to accommodate the display image as per * gimp_display_shell_shrink_wrap(). **/ void gimp_display_shell_scale_resize (GimpDisplayShell *shell, gboolean resize_window, gboolean grow_only) { g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); /* freeze the active tool */ gimp_display_shell_pause (shell); if (resize_window) { GimpImageWindow *window = gimp_display_shell_get_window (shell); if (window && gimp_image_window_get_active_shell (window) == shell) { gimp_image_window_shrink_wrap (window, grow_only); } } gimp_display_shell_scroll_clamp_and_update (shell); gimp_display_shell_scaled (shell); gimp_display_shell_expose_full (shell); /* re-enable the active tool */ gimp_display_shell_resume (shell); }
void gimp_display_shell_clear_software_cursor (GimpDisplayShell *shell) { GimpStatusbar *statusbar; GimpSessionInfo *session_info; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); gimp_canvas_item_set_visible (shell->cursor, FALSE); statusbar = gimp_display_shell_get_statusbar (shell); gimp_statusbar_clear_cursor (statusbar); session_info = gimp_dialog_factory_find_session_info (gimp_dialog_factory_get_singleton (), "gimp-cursor-view"); if (session_info && gimp_session_info_get_widget (session_info)) { GtkWidget *cursor_view; cursor_view = gtk_bin_get_child (GTK_BIN (gimp_session_info_get_widget (session_info))); if (cursor_view) gimp_cursor_view_clear_cursor (GIMP_CURSOR_VIEW (cursor_view)); } }
void gimp_display_shell_selection_free (GimpDisplayShell *shell) { g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); if (shell->selection) { Selection *selection = shell->selection; selection_stop (selection); g_signal_handlers_disconnect_by_func (shell, selection_window_state_event, selection); g_signal_handlers_disconnect_by_func (shell, selection_visibility_notify_event, selection); selection_free_segs (selection); g_slice_free (Selection, selection); shell->selection = NULL; } }
/** * gimp_display_shell_scale_get_image_bounds: * @shell: * @x: * @y: * @w: * @h: * * Gets the screen-space boudning box of the image, after it has * been transformed (i.e., scaled, rotated, and scrolled). **/ void gimp_display_shell_scale_get_image_bounds (GimpDisplayShell *shell, gint *x, gint *y, gint *w, gint *h) { GimpImage *image; gdouble x1, y1; gdouble x2, y2; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); image = gimp_display_get_image (shell->display); gimp_display_shell_transform_bounds (shell, 0, 0, gimp_image_get_width (image), gimp_image_get_height (image), &x1, &y1, &x2, &y2); x1 = ceil (x1); y1 = ceil (y1); x2 = floor (x2); y2 = floor (y2); if (x) *x = x1 + shell->offset_x; if (y) *y = y1 + shell->offset_y; if (w) *w = x2 - x1; if (h) *h = y2 - y1; }
void gimp_display_shell_close (GimpDisplayShell *shell, gboolean kill_it) { GimpImage *image; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); image = shell->display->image; /* FIXME: gimp_busy HACK not really appropriate here because we only * want to prevent the busy image and display to be closed. --Mitch */ if (image->gimp->busy) return; /* If the image has been modified, give the user a chance to save * it before nuking it--this only applies if its the last view * to an image canvas. (a image with disp_count = 1) */ if (! kill_it && image->disp_count == 1 && image->dirty && GIMP_DISPLAY_CONFIG (image->gimp->config)->confirm_on_close) { gimp_display_shell_close_dialog (shell, image); } else { gimp_display_delete (shell->display); } }
/** * gimp_display_shell_unzoom_xy: * @shell: a #GimpDisplayShell * @x: x coordinate in display coordinates * @y: y coordinate in display coordinates * @nx: returns x oordinate in image coordinates * @ny: returns y coordinate in image coordinates * @round: if %TRUE, round the results to the nearest integer; * if %FALSE, simply cast them to @gint. * * Zoom from display coordinates to image coordinates, so that * points on the display can be mapped to the corresponding points * in the image. **/ void gimp_display_shell_unzoom_xy (const GimpDisplayShell *shell, gint x, gint y, gint *nx, gint *ny, gboolean round) { gint64 tx; gint64 ty; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (nx != NULL); g_return_if_fail (ny != NULL); if (round) { tx = SIGNED_ROUND (((gdouble) x + shell->offset_x) / shell->scale_x); ty = SIGNED_ROUND (((gdouble) y + shell->offset_y) / shell->scale_y); } else { tx = ((gint64) x + shell->offset_x) / shell->scale_x; ty = ((gint64) y + shell->offset_y) / shell->scale_y; } *nx = CLAMP (tx, G_MININT, G_MAXINT); *ny = CLAMP (ty, G_MININT, G_MAXINT); }