/** * 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); }
/** * 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, gdouble viewport_x, gdouble viewport_y) { gdouble image_x, image_y; gdouble new_viewport_x, new_viewport_y; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); if (! shell->display) return; /* freeze the active tool */ gimp_display_shell_pause (shell); gimp_display_shell_untransform_xy_f (shell, viewport_x, viewport_y, &image_x, &image_y); /* Note that we never come here if we need to resize_windows_on_zoom */ gimp_display_shell_scale_by_values (shell, scale, shell->offset_x, shell->offset_y, FALSE); gimp_display_shell_transform_xy_f (shell, image_x, image_y, &new_viewport_x, &new_viewport_y); gimp_display_shell_scroll (shell, new_viewport_x - viewport_x, new_viewport_y - viewport_y); /* re-enable the active tool */ gimp_display_shell_resume (shell); }
/** * gimp_display_shell_scale_revert: * @shell: the #GimpDisplayShell * * Reverts the display to the previously used scale. If no previous * scale exist, then the call does nothing. * * Return value: %TRUE if the scale was reverted, otherwise %FALSE. **/ gboolean gimp_display_shell_scale_revert (GimpDisplayShell *shell) { g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), FALSE); /* don't bother if no scale has been set */ if (shell->last_scale < SCALE_EPSILON) return FALSE; shell->last_scale_time = 0; gimp_display_shell_scale_by_values (shell, shell->last_scale, shell->last_offset_x, shell->last_offset_y, FALSE); /* don't resize the window */ return TRUE; }
/** * gimp_display_shell_scale_to_rectangle: * @shell: the #GimpDisplayShell * @zoom_type: whether to zoom in or out * @x: retangle's x in image coordinates * @y: retangle's y in image coordinates * @width: retangle's width in image coordinates * @height: retangle's height in image coordinates * @resize_window: whether the display window should be resized * * Scales and scrolls to a specific image rectangle **/ void gimp_display_shell_scale_to_rectangle (GimpDisplayShell *shell, GimpZoomType zoom_type, gdouble x, gdouble y, gdouble width, gdouble height, gboolean resize_window) { GimpImage *image; gdouble current_scale; gdouble new_scale; gdouble display_width; gdouble display_height; gdouble factor = 1.0; gint offset_x = 0; gint offset_y = 0; gdouble xres; gdouble yres; gdouble screen_xres; gdouble screen_yres; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); image = gimp_display_get_image (shell->display); width = MAX (1.0, width); height = MAX (1.0, height); current_scale = gimp_zoom_model_get_factor (shell->zoom); display_width = FUNSCALEX (shell, shell->disp_width); display_height = FUNSCALEY (shell, shell->disp_height); switch (zoom_type) { case GIMP_ZOOM_IN: factor = MIN ((display_width / width), (display_height / height)); break; case GIMP_ZOOM_OUT: factor = MAX ((width / display_width), (height / display_height)); break; default: g_return_if_reached (); break; } new_scale = current_scale * factor; gimp_image_get_resolution (image, &xres, &yres); gimp_display_shell_scale_get_screen_resolution (shell, &screen_xres, &screen_yres); switch (zoom_type) { case GIMP_ZOOM_IN: /* move the center of the rectangle to the center of the * viewport: * * new_offset = center of rectangle in new scale screen coords * including offset * - * center of viewport in screen coords without * offset */ offset_x = RINT (new_scale * (x + width / 2.0) * screen_xres / xres - (shell->disp_width / 2.0)); offset_y = RINT (new_scale * (y + height / 2.0) * screen_yres / yres - (shell->disp_height / 2.0)); break; case GIMP_ZOOM_OUT: /* move the center of the viewport to the center of the * rectangle: * * new_offset = center of viewport in new scale screen coords * including offset * - * center of rectangle in screen coords without * offset */ offset_x = RINT (new_scale * UNSCALEX (shell, shell->offset_x + shell->disp_width / 2.0) * screen_xres / xres - (SCALEX (shell, x + width / 2.0) - shell->offset_x)); offset_y = RINT (new_scale * UNSCALEY (shell, shell->offset_y + shell->disp_height / 2.0) * screen_yres / yres - (SCALEY (shell, y + height / 2.0) - shell->offset_y)); break; default: break; } if (new_scale != current_scale || offset_x != shell->offset_x || offset_y != shell->offset_y) { gimp_display_shell_scale_by_values (shell, new_scale, offset_x, offset_y, resize_window); } }
/** * gimp_display_shell_scale_to_rectangle: * @shell: the #GimpDisplayShell * @zoom_type: whether to zoom in or out * @x: retangle's x in image coordinates * @y: retangle's y in image coordinates * @width: retangle's width in image coordinates * @height: retangle's height in image coordinates * @resize_window: whether the display window should be resized * * Scales and scrolls to a specific image rectangle **/ void gimp_display_shell_scale_to_rectangle (GimpDisplayShell *shell, GimpZoomType zoom_type, gdouble x, gdouble y, gdouble width, gdouble height, gboolean resize_window) { gdouble current_scale; gdouble new_scale; gdouble factor = 1.0; gint offset_x = 0; gint offset_y = 0; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); gimp_display_shell_transform_bounds (shell, x, y, x + width, y + height, &x, &y, &width, &height); /* Convert scrolled (x1, y1, x2, y2) to unscrolled (x, y, width, height). */ width -= x; height -= y; x += shell->offset_x; y += shell->offset_y; width = MAX (1.0, width); height = MAX (1.0, height); current_scale = gimp_zoom_model_get_factor (shell->zoom); switch (zoom_type) { case GIMP_ZOOM_IN: factor = MIN ((shell->disp_width / width), (shell->disp_height / height)); break; case GIMP_ZOOM_OUT: factor = MAX ((width / shell->disp_width), (height / shell->disp_height)); break; default: g_return_if_reached (); break; } new_scale = current_scale * factor; switch (zoom_type) { case GIMP_ZOOM_IN: /* move the center of the rectangle to the center of the * viewport: * * new_offset = center of rectangle in new scale screen coords * including offset * - * center of viewport in screen coords without * offset */ offset_x = RINT (factor * (x + width / 2.0) - (shell->disp_width / 2)); offset_y = RINT (factor * (y + height / 2.0) - (shell->disp_height / 2)); break; case GIMP_ZOOM_OUT: /* move the center of the viewport to the center of the * rectangle: * * new_offset = center of viewport in new scale screen coords * including offset * - * center of rectangle in screen coords without * offset */ offset_x = RINT (factor * (shell->offset_x + shell->disp_width / 2) - ((x + width / 2.0) - shell->offset_x)); offset_y = RINT (factor * (shell->offset_y + shell->disp_height / 2) - ((y + height / 2.0) - shell->offset_y)); break; default: break; } if (new_scale != current_scale || offset_x != shell->offset_x || offset_y != shell->offset_y) { gimp_display_shell_scale_by_values (shell, new_scale, offset_x, offset_y, resize_window); } }