diff --git a/ChangeLog b/ChangeLog index 21db1f2857..da46f558d4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,40 @@ +2004-01-29 Simon Budig + + * app/display/gimpdisplayshell.[ch]: Store the zoom factor as + float, not as a ratio. + + * app/display/gimpdisplayshell-scale.[ch]: change the API to + expose the Float instead a weirdly encoded integer. Implement + functions to get a ratio from the scale factor. Implement a set + as presets as discussed on the mailinglist. Changed Zoom->Other + dialog to enable entering a float. + + * app/display/gimpdisplayshell-title.c + * app/display/gimpnavigationview.c + * app/gui/image-menu.c + * app/gui/info-window.c + * app/tools/gimpmagnifytool.c: changed accordingly. + + * app/core/gimp.[ch] + * app/display/gimpdisplay.[ch] + * app/gui/gui-vtable.c + * app/widgets/widgets-enums.h: Made the various display-creating + functions accept a float for the scale. Introduce a new + GimpZoomType: GIMP_ZOOM_TO. Generally adjust the API to use + floats instead of weird integers. + + * app/core/gimp-edit.c + * app/core/gimptemplate.c + * app/display/gimpdisplayshell-callbacks.c + * app/file/file-open.c + * app/gui/image-commands.c + * app/gui/view-commands.[ch] + * tools/pdbgen/pdb/display.pdb + * app/widgets/gimpimageview.c + * app/widgets/gimptoolbox-dnd.c: changed accordingly + + * app/pdb/display_cmds.c: regenerated + 2004-01-29 Michael Natterer * app/core/gimpcontext.[ch]: removed the last artefact of context diff --git a/app/actions/image-commands.c b/app/actions/image-commands.c index 2d7a5b1cb5..e6534a0305 100644 --- a/app/actions/image-commands.c +++ b/app/actions/image-commands.c @@ -279,7 +279,7 @@ image_duplicate_cmd_callback (GtkWidget *widget, new_gimage = gimp_image_duplicate (gimage); - gimp_create_display (new_gimage->gimp, new_gimage, 0x0101); + gimp_create_display (new_gimage->gimp, new_gimage, 1.0); g_object_unref (new_gimage); } diff --git a/app/actions/view-commands.c b/app/actions/view-commands.c index a0fa7367f5..919086072e 100644 --- a/app/actions/view-commands.c +++ b/app/actions/view-commands.c @@ -68,7 +68,8 @@ view_zoom_out_cmd_callback (GtkWidget *widget, GimpDisplay *gdisp; return_if_no_display (gdisp, data); - gimp_display_shell_scale (GIMP_DISPLAY_SHELL (gdisp->shell), GIMP_ZOOM_OUT); + gimp_display_shell_scale (GIMP_DISPLAY_SHELL (gdisp->shell), + GIMP_ZOOM_OUT, 0.0); } void @@ -78,7 +79,8 @@ view_zoom_in_cmd_callback (GtkWidget *widget, GimpDisplay *gdisp; return_if_no_display (gdisp, data); - gimp_display_shell_scale (GIMP_DISPLAY_SHELL (gdisp->shell), GIMP_ZOOM_IN); + gimp_display_shell_scale (GIMP_DISPLAY_SHELL (gdisp->shell), + GIMP_ZOOM_IN, 0.0); } void @@ -94,12 +96,10 @@ view_zoom_fit_cmd_callback (GtkWidget *widget, void view_zoom_cmd_callback (GtkWidget *widget, gpointer data, - guint action) + guint scale) { GimpDisplay *gdisp; GimpDisplayShell *shell; - guchar scalesrc; - guchar scaledest; return_if_no_display (gdisp, data); if (! GTK_CHECK_MENU_ITEM (widget)->active) @@ -107,11 +107,8 @@ view_zoom_cmd_callback (GtkWidget *widget, shell = GIMP_DISPLAY_SHELL (gdisp->shell); - scalesrc = CLAMP (action % 100, 1, 0xFF); - scaledest = CLAMP (action / 100, 1, 0xFF); - - if (scalesrc != SCALESRC (shell) || scaledest != SCALEDEST (shell)) - gimp_display_shell_scale (shell, action); + if (fabs (scale - shell->scale) > 0.0001) + gimp_display_shell_scale (shell, GIMP_ZOOM_TO, (gdouble) scale / 10000); } void diff --git a/app/actions/view-commands.h b/app/actions/view-commands.h index 29511cf17e..5dc8a8ed8e 100644 --- a/app/actions/view-commands.h +++ b/app/actions/view-commands.h @@ -28,7 +28,7 @@ void view_zoom_fit_cmd_callback (GtkWidget *widget, gpointer data); void view_zoom_cmd_callback (GtkWidget *widget, gpointer data, - guint action); + guint scale); void view_zoom_other_cmd_callback (GtkWidget *widget, gpointer data); void view_dot_for_dot_cmd_callback (GtkWidget *widget, diff --git a/app/core/gimp-edit.c b/app/core/gimp-edit.c index 7d58863a49..665951acec 100644 --- a/app/core/gimp-edit.c +++ b/app/core/gimp-edit.c @@ -237,7 +237,7 @@ gimp_edit_paste_as_new (Gimp *gimp, gimp_image_undo_enable (gimage); - gimp_create_display (gimp, gimage, 0x0101); + gimp_create_display (gimp, gimage, 1.0); g_object_unref (gimage); return gimage; diff --git a/app/core/gimp.c b/app/core/gimp.c index 36497c6070..3f6d48e0ae 100644 --- a/app/core/gimp.c +++ b/app/core/gimp.c @@ -1217,8 +1217,8 @@ gimp_create_image (Gimp *gimp, GimpObject * gimp_create_display (Gimp *gimp, - GimpImage *gimage, - guint scale) + GimpImage *gimage, + gdouble scale) { GimpObject *display = NULL; diff --git a/app/core/gimp.h b/app/core/gimp.h index dc6922f093..1e9cffe5ac 100644 --- a/app/core/gimp.h +++ b/app/core/gimp.h @@ -26,7 +26,7 @@ typedef void (* GimpThreadEnterFunc) (Gimp *gimp); typedef void (* GimpThreadLeaveFunc) (Gimp *gimp); typedef GimpObject * (* GimpCreateDisplayFunc) (GimpImage *gimage, - guint scale); + gdouble scale); typedef void (* GimpSetBusyFunc) (Gimp *gimp); typedef void (* GimpUnsetBusyFunc) (Gimp *gimp); typedef void (* GimpMessageFunc) (Gimp *gimp, @@ -280,8 +280,8 @@ GimpImage * gimp_create_image (Gimp *gimp, gboolean attach_comment); GimpObject * gimp_create_display (Gimp *gimp, - GimpImage *gimage, - guint scale); + GimpImage *gimage, + gdouble scale); GimpContext * gimp_get_standard_context (Gimp *gimp); diff --git a/app/core/gimpprojection.c b/app/core/gimpprojection.c index d27f340af0..3f29417935 100644 --- a/app/core/gimpprojection.c +++ b/app/core/gimpprojection.c @@ -201,7 +201,7 @@ gimp_display_get_property (GObject *object, GimpDisplay * gimp_display_new (GimpImage *gimage, - guint scale, + gdouble scale, GimpMenuFactory *menu_factory, GimpItemFactory *popup_factory) { diff --git a/app/core/gimpprojection.h b/app/core/gimpprojection.h index a790ea669a..7e94471962 100644 --- a/app/core/gimpprojection.h +++ b/app/core/gimpprojection.h @@ -74,7 +74,7 @@ struct _GimpDisplayClass GType gimp_display_get_type (void) G_GNUC_CONST; GimpDisplay * gimp_display_new (GimpImage *gimage, - guint scale, + gdouble scale, GimpMenuFactory *menu_factory, GimpItemFactory *popup_factory); void gimp_display_delete (GimpDisplay *gdisp); diff --git a/app/core/gimptemplate.c b/app/core/gimptemplate.c index b67688a6a5..5a6eaffa60 100644 --- a/app/core/gimptemplate.c +++ b/app/core/gimptemplate.c @@ -442,7 +442,7 @@ gimp_template_create_image (Gimp *gimp, gimp_image_undo_enable (gimage); gimp_image_clean_all (gimage); - gimp_create_display (gimp, gimage, 0x0101); + gimp_create_display (gimp, gimage, 1.0); g_object_unref (gimage); diff --git a/app/dialogs/info-window.c b/app/dialogs/info-window.c index 6a63f676ec..9e2d5f4d94 100644 --- a/app/dialogs/info-window.c +++ b/app/dialogs/info-window.c @@ -521,8 +521,7 @@ info_window_update (GimpDisplay *gdisp) res_unit == GIMP_UNIT_INCH ? _("dpi") : format_buf); /* user zoom ratio */ - g_snprintf (iwd->scale_str, MAX_BUF, "%d:%d", - SCALEDEST (shell), SCALESRC (shell)); + g_snprintf (iwd->scale_str, MAX_BUF, "%.2f", shell->scale * 100); /* number of layers */ g_snprintf (iwd->num_layers_str, MAX_BUF, "%d", diff --git a/app/display/gimpdisplay.c b/app/display/gimpdisplay.c index d27f340af0..3f29417935 100644 --- a/app/display/gimpdisplay.c +++ b/app/display/gimpdisplay.c @@ -201,7 +201,7 @@ gimp_display_get_property (GObject *object, GimpDisplay * gimp_display_new (GimpImage *gimage, - guint scale, + gdouble scale, GimpMenuFactory *menu_factory, GimpItemFactory *popup_factory) { diff --git a/app/display/gimpdisplay.h b/app/display/gimpdisplay.h index a790ea669a..7e94471962 100644 --- a/app/display/gimpdisplay.h +++ b/app/display/gimpdisplay.h @@ -74,7 +74,7 @@ struct _GimpDisplayClass GType gimp_display_get_type (void) G_GNUC_CONST; GimpDisplay * gimp_display_new (GimpImage *gimage, - guint scale, + gdouble scale, GimpMenuFactory *menu_factory, GimpItemFactory *popup_factory); void gimp_display_delete (GimpDisplay *gdisp); diff --git a/app/display/gimpdisplayshell-callbacks.c b/app/display/gimpdisplayshell-callbacks.c index bda0054439..2232ae2171 100644 --- a/app/display/gimpdisplayshell-callbacks.c +++ b/app/display/gimpdisplayshell-callbacks.c @@ -823,11 +823,11 @@ gimp_display_shell_canvas_tool_events (GtkWidget *canvas, switch (direction) { case GDK_SCROLL_UP: - gimp_display_shell_scale (shell, GIMP_ZOOM_IN); + gimp_display_shell_scale (shell, GIMP_ZOOM_IN, 0.0); break; case GDK_SCROLL_DOWN: - gimp_display_shell_scale (shell, GIMP_ZOOM_OUT); + gimp_display_shell_scale (shell, GIMP_ZOOM_OUT, 0.0); break; default: diff --git a/app/display/gimpdisplayshell-draw.c b/app/display/gimpdisplayshell-draw.c index ac60116ca3..2cc7ab4443 100644 --- a/app/display/gimpdisplayshell-draw.c +++ b/app/display/gimpdisplayshell-draw.c @@ -210,8 +210,8 @@ gimp_display_shell_init (GimpDisplayShell *shell) shell->popup_factory = NULL; shell->qmask_factory = NULL; - shell->scale = 0x101; - shell->other_scale = 0; + shell->scale = 1.0; + shell->other_scale = 0.0; shell->dot_for_dot = TRUE; shell->offset_x = 0; @@ -486,7 +486,7 @@ gimp_display_shell_real_scaled (GimpDisplayShell *shell) GtkWidget * gimp_display_shell_new (GimpDisplay *gdisp, - guint scale, + gdouble scale, GimpMenuFactory *menu_factory, GimpItemFactory *popup_factory) { @@ -504,7 +504,7 @@ gimp_display_shell_new (GimpDisplay *gdisp, gint image_width, image_height; gint n_width, n_height; gint s_width, s_height; - gint scalesrc, scaledest; + gdouble new_scale; g_return_val_if_fail (GIMP_IS_DISPLAY (gdisp), NULL); g_return_val_if_fail (GIMP_IS_MENU_FACTORY (menu_factory), NULL); @@ -548,33 +548,31 @@ gimp_display_shell_new (GimpDisplay *gdisp, s_width = gdk_screen_get_width (screen) * 0.75; s_height = gdk_screen_get_height (screen) * 0.75; - scalesrc = SCALESRC (shell); - scaledest = SCALEDEST (shell); - n_width = SCALEX (shell, image_width); - n_height = SCALEX (shell, image_height); + n_height = SCALEY (shell, image_height); if (config->initial_zoom_to_fit) { /* Limit to the size of the screen... */ - while (n_width > s_width || n_height > s_height) + if (n_width > s_width || n_height > s_height) { - if (scaledest > 1) - scaledest--; - else - if (scalesrc < 0xFF) - scalesrc++; + new_scale = shell->scale * MIN (((gdouble) s_height) / n_height, + ((gdouble) s_width) / n_width); + + new_scale = gimp_display_shell_scale_zoom_step (GIMP_ZOOM_OUT, + new_scale); - n_width = (image_width * - (scaledest * SCREEN_XRES (shell)) / - (scalesrc * gdisp->gimage->xresolution)); + /* since zooming out might skip a zoom step we zoom in again + * and test if we are small enough. */ + shell->scale = gimp_display_shell_scale_zoom_step (GIMP_ZOOM_IN, + new_scale); - n_height = (image_height * - (scaledest * SCREEN_XRES (shell)) / - (scalesrc * gdisp->gimage->xresolution)); + if (SCALEX (shell, image_width) > s_width || + SCALEY (shell, image_height) > s_height) + shell->scale = new_scale; - if (scaledest == 1 && scalesrc == 0xFF) - break; + n_width = SCALEX (shell, image_width); + n_height = SCALEY (shell, image_height); } } else @@ -589,7 +587,6 @@ gimp_display_shell_new (GimpDisplay *gdisp, n_height = s_height; } - shell->scale = (scaledest << 8) + scalesrc; shell->menubar_factory = gimp_menu_factory_menu_new (menu_factory, "", diff --git a/app/display/gimpdisplayshell-draw.h b/app/display/gimpdisplayshell-draw.h index 944250fd6a..dae3d37560 100644 --- a/app/display/gimpdisplayshell-draw.h +++ b/app/display/gimpdisplayshell-draw.h @@ -33,15 +33,11 @@ #define SCREEN_YRES(s) (s->dot_for_dot ? \ s->gdisp->gimage->yresolution : s->monitor_yres) -/* unpacking the user scale level (char) */ -#define SCALESRC(s) (s->scale & 0x00ff) -#define SCALEDEST(s) (s->scale >> 8) - /* calculate scale factors (double) */ -#define SCALEFACTOR_X(s) ((SCALEDEST(s) * SCREEN_XRES(s)) / \ - (SCALESRC(s) * s->gdisp->gimage->xresolution)) -#define SCALEFACTOR_Y(s) ((SCALEDEST(s) * SCREEN_YRES(s)) / \ - (SCALESRC(s) * s->gdisp->gimage->yresolution)) +#define SCALEFACTOR_X(s) (s->scale * SCREEN_XRES(s) / \ + s->gdisp->gimage->xresolution) +#define SCALEFACTOR_Y(s) (s->scale * SCREEN_YRES(s) / \ + s->gdisp->gimage->yresolution) /* scale values */ #define SCALEX(s,x) ((gint) (x * SCALEFACTOR_X(s))) @@ -78,8 +74,8 @@ struct _GimpDisplayShell gdouble monitor_xres; gdouble monitor_yres; - gint scale; /* scale factor from original raw image */ - gint other_scale; /* scale factor entered in Zoom->Other */ + gdouble scale; /* scale factor from original raw image */ + gdouble other_scale; /* scale factor entered in Zoom->Other */ gboolean dot_for_dot; /* is monitor resolution being ignored? */ gint offset_x; /* offset of display image into raw image */ @@ -174,7 +170,7 @@ struct _GimpDisplayShellClass GType gimp_display_shell_get_type (void) G_GNUC_CONST; GtkWidget * gimp_display_shell_new (GimpDisplay *gdisp, - guint scale, + gdouble scale, GimpMenuFactory *menu_factory, GimpItemFactory *popup_factory); diff --git a/app/display/gimpdisplayshell-scale.c b/app/display/gimpdisplayshell-scale.c index 8eac2cdd21..e12e0d3c9f 100644 --- a/app/display/gimpdisplayshell-scale.c +++ b/app/display/gimpdisplayshell-scale.c @@ -50,8 +50,9 @@ typedef struct _ScaleDialogData ScaleDialogData; struct _ScaleDialogData { GimpDisplayShell *shell; - GtkObject *src_adj; - GtkObject *dest_adj; + GtkObject *scale_adj; + GtkObject *num_adj; + GtkObject *denom_adj; }; @@ -60,6 +61,8 @@ struct _ScaleDialogData static void gimp_display_shell_scale_dialog_response (GtkWidget *widget, gint response_id, ScaleDialogData *dialog); +static void update_zoom_values (GtkAdjustment *adj, + ScaleDialogData *dialog); static gdouble img2real (GimpDisplayShell *shell, gboolean xdir, gdouble a); @@ -67,51 +70,82 @@ static gdouble img2real (GimpDisplayShell *shell, /* public functions */ -void -gimp_display_shell_scale_zoom_fraction (GimpZoomType zoom_type, - gint *scalesrc, - gint *scaledest) +gdouble +gimp_display_shell_scale_zoom_step (GimpZoomType zoom_type, + gdouble scale) { - gdouble ratio; + gint i, n_presets; + gdouble new_scale; - g_return_if_fail (scalesrc != NULL); - g_return_if_fail (scaledest != NULL); + /* This table is constructed to have fractions, that approximate + * sqrt(2)^k. This gives a smooth feeling regardless of the starting + * zoom level. + * + * Zooming in/out always jumps to a zoom step from the list above. + * However, we try to guarantee a certain size of the step, to + * avoid silly jumps from 101% to 100%. + * The factor 1.1 is chosen a bit arbitrary, but feels better + * than the geometric median of the zoom steps (2^(1/4)). + */ - ratio = (double) *scaledest/ *scalesrc; +#define ZOOM_MIN_STEP 1.1 + gdouble presets[] = { + 1.0 / 256, 1.0 / 180, 1.0 / 128, 1.0 / 90, + 1.0 / 64, 1.0 / 45, 1.0 / 32, 1.0 / 23, + 1.0 / 16, 1.0 / 11, 1.0 / 8, 2.0 / 11, + 1.0 / 4, 1.0 / 3, 1.0 / 2, 2.0 / 3, + 1.0, + 3.0 / 2, 2.0, 3.0, + 4.0, 11.0 / 2, 8.0, 11.0, + 16.0, 23.0, 32.0, 45.0, + 64.0, 90.0, 128.0, 180.0, + 256.0, + }; + + n_presets = G_N_ELEMENTS (presets); + switch (zoom_type) { case GIMP_ZOOM_IN: - ratio *= G_SQRT2; + scale *= ZOOM_MIN_STEP; + + new_scale = presets[n_presets-1]; + + for (i = n_presets - 1; i >= 0 && presets[i] > scale; i--) + new_scale = presets[i]; + break; case GIMP_ZOOM_OUT: - ratio /= G_SQRT2; + scale /= ZOOM_MIN_STEP; + + new_scale = presets[0]; + + for (i = 0; i < n_presets && presets[i] < scale; i++) + new_scale = presets[i]; + break; - default: - *scalesrc = CLAMP (zoom_type % 100, 1, 0xFF); - *scaledest = CLAMP (zoom_type / 100, 1, 0xFF); - return; + case GIMP_ZOOM_TO: + new_scale = scale; break; } - /* set scalesrc and scaledest to a fraction close to ratio */ - gimp_display_shell_scale_calc_fraction (ratio, scalesrc, scaledest); + return CLAMP (new_scale, 1.0/256.0, 256.0); } void -gimp_display_shell_scale_calc_fraction (gdouble zoom_factor, - gint *scalesrc, - gint *scaledest) +gimp_display_shell_scale_get_fraction (gdouble zoom_factor, + gint *numerator, + gint *denominator) { gint p0, p1, p2; gint q0, q1, q2; gdouble remainder, next_cf; gboolean swapped = FALSE; - g_return_if_fail (scalesrc != NULL); - g_return_if_fail (scaledest != NULL); + g_return_if_fail (numerator != NULL && denominator != NULL); /* make sure that zooming behaves symmetrically */ if (zoom_factor < 1.0) @@ -139,9 +173,9 @@ gimp_display_shell_scale_calc_fraction (gdouble zoom_factor, p2 = next_cf * p1 + p0; q2 = next_cf * q1 + q0; - /* Numerator and Denominator are limited by 255 */ + /* Numerator and Denominator are limited by 256 */ /* also absurd ratios like 170:171 are excluded */ - if (p2 > 255 || q2 > 255 || (p2 > 1 && q2 > 1 && p2 * q2 > 200)) + if (p2 > 256 || q2 > 256 || (p2 > 1 && q2 > 1 && p2 * q2 > 200)) break; /* remember the last two fractions */ @@ -157,26 +191,26 @@ gimp_display_shell_scale_calc_fraction (gdouble zoom_factor, /* hard upper and lower bounds for zoom ratio */ - if (zoom_factor > 255.0) + if (zoom_factor > 256.0) { - p1 = 255; + p1 = 256; q1 = 1; } - else if (zoom_factor < 1.0 / 255.0) + else if (zoom_factor < 1.0 / 256.0) { p1 = 1; - q1 = 255; + q1 = 256; } if (swapped) { - *scalesrc = p1; - *scaledest = q1; + *numerator = q1; + *denominator = p1; } else { - *scalesrc = q1; - *scaledest = p1; + *numerator = p1; + *denominator = q1; } } @@ -319,35 +353,36 @@ gimp_display_shell_scale_set_dot_for_dot (GimpDisplayShell *shell, void gimp_display_shell_scale (GimpDisplayShell *shell, - GimpZoomType zoom_type) + GimpZoomType zoom_type, + gdouble new_scale) { GimpDisplayConfig *config; - gint scalesrc, scaledest; gdouble offset_x, offset_y; + gdouble scale; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); - /* user zoom control, so resolution versions not needed -- austin */ - scalesrc = SCALESRC (shell); - scaledest = SCALEDEST (shell); - offset_x = shell->offset_x + (shell->disp_width / 2.0); offset_y = shell->offset_y + (shell->disp_height / 2.0); - offset_x *= ((gdouble) scalesrc / (gdouble) scaledest); - offset_y *= ((gdouble) scalesrc / (gdouble) scaledest); + scale = shell->scale; - gimp_display_shell_scale_zoom_fraction (zoom_type, &scalesrc, &scaledest); + offset_x /= scale; + offset_y /= scale; - offset_x *= ((gdouble) scaledest / (gdouble) scalesrc); - offset_y *= ((gdouble) scaledest / (gdouble) scalesrc); + if (zoom_type == GIMP_ZOOM_TO) + scale = new_scale; + else + scale = gimp_display_shell_scale_zoom_step (zoom_type, scale); + + offset_x *= scale; + offset_y *= scale; config = GIMP_DISPLAY_CONFIG (shell->gdisp->gimage->gimp->config); - gimp_display_shell_scale_by_values (shell, - (scaledest << 8) + scalesrc, - (offset_x - (shell->disp_width / 2)), - (offset_y - (shell->disp_height / 2)), + gimp_display_shell_scale_by_values (shell, scale, + offset_x - (shell->disp_width / 2), + offset_y - (shell->disp_height / 2), config->resize_windows_on_zoom); } @@ -358,9 +393,6 @@ gimp_display_shell_scale_fit (GimpDisplayShell *shell) gint image_width; gint image_height; gdouble zoom_factor; - gint scalesrc; - gint scaledest; - gint a, b, gcd; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); @@ -380,42 +412,12 @@ gimp_display_shell_scale_fit (GimpDisplayShell *shell) zoom_factor = MIN ((gdouble) shell->disp_width / (gdouble) image_width, (gdouble) shell->disp_height / (gdouble) image_height); - /* choosing 240 because it has a lot of nice divisors and the - * chance of a nice fraction is bigger */ - - scalesrc = scaledest = 240; - - if (zoom_factor > 1.0) - scalesrc = CLAMP (ceil (1.0 / zoom_factor * 240.0), 1, 240); - else - scaledest = CLAMP (floor (zoom_factor * 240.0), 1, 240); - - /* determine gcd to shorten the fraction */ - a = MAX (scalesrc, scaledest); - b = MIN (scalesrc, scaledest); - - gcd = b; - - while (a % b != 0) - { - gcd = a % b; - a = b; - b = gcd; - } - - scalesrc /= gcd; - scaledest /= gcd; - - gimp_display_shell_scale_by_values (shell, - (scaledest << 8) + scalesrc, - 0, - 0, - FALSE); + gimp_display_shell_scale (shell, GIMP_ZOOM_TO, zoom_factor); } void gimp_display_shell_scale_by_values (GimpDisplayShell *shell, - gint scale, + gdouble scale, gint offset_x, gint offset_y, gboolean resize_window) @@ -480,8 +482,10 @@ gimp_display_shell_scale_dialog (GimpDisplayShell *shell) { ScaleDialogData *data; GtkWidget *hbox; + GtkWidget *table; GtkWidget *spin; GtkWidget *label; + gint num, denom, row; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); @@ -521,21 +525,29 @@ gimp_display_shell_scale_dialog (GimpDisplayShell *shell) G_CALLBACK (gimp_display_shell_scale_dialog_response), data); + table = gtk_table_new (2, 2, FALSE); + gtk_table_set_col_spacings (GTK_TABLE (table), 2); + gtk_table_set_row_spacings (GTK_TABLE (table), 4); + gtk_container_add (GTK_CONTAINER (GTK_DIALOG (shell->scale_dialog)->vbox), + table); + gtk_widget_show (table); + + row = 0; + hbox = gtk_hbox_new (FALSE, 4); gtk_container_set_border_width (GTK_CONTAINER (hbox), 6); - gtk_container_add (GTK_CONTAINER (GTK_DIALOG (shell->scale_dialog)->vbox), - hbox); - gtk_widget_show (hbox); + gimp_table_attach_aligned (GTK_TABLE (table), 0, row++, + _("Zoom Ratio:"), 1.0, 0.5, + hbox, 1, FALSE); - label = gtk_label_new (_("Zoom Ratio:")); - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - gtk_widget_show (label); + if (fabs (shell->other_scale) <= 0.0001) + shell->other_scale = shell->scale; /* other_scale not yet initialized */ - if ((shell->other_scale & 0xFFFF) == 0) - shell->other_scale = shell->scale; + gimp_display_shell_scale_get_fraction (fabs (shell->other_scale), + &num, &denom); - spin = gimp_spin_button_new (&data->dest_adj, - (shell->other_scale & 0xFF00) >> 8, 1, 0xFF, + spin = gimp_spin_button_new (&data->num_adj, + num, 1, 256, 1, 8, 1, 1, 0); gtk_box_pack_start (GTK_BOX (hbox), spin, TRUE, TRUE, 0); gtk_widget_show (spin); @@ -544,12 +556,27 @@ gimp_display_shell_scale_dialog (GimpDisplayShell *shell) gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); gtk_widget_show (label); - spin = gimp_spin_button_new (&data->src_adj, - (shell->other_scale & 0xFF), 1, 0xFF, + spin = gimp_spin_button_new (&data->denom_adj, + denom, 1, 256, 1, 8, 1, 1, 0); gtk_box_pack_start (GTK_BOX (hbox), spin, TRUE, TRUE, 0); gtk_widget_show (spin); + spin = gimp_spin_button_new (&data->scale_adj, + fabs (shell->other_scale) * 100, + 100.0 / 256.0, 25600.0, + 10, 50, 0, 1, 2); + gimp_table_attach_aligned (GTK_TABLE (table), 0, row++, + _("Zoom:"), 1.0, 0.5, + spin, 1, FALSE); + + g_signal_connect (data->scale_adj, "value-changed", + G_CALLBACK (update_zoom_values), data); + g_signal_connect (data->num_adj, "value-changed", + G_CALLBACK (update_zoom_values), data); + g_signal_connect (data->denom_adj, "value-changed", + G_CALLBACK (update_zoom_values), data); + gtk_widget_show (shell->scale_dialog); } @@ -563,13 +590,11 @@ gimp_display_shell_scale_dialog_response (GtkWidget *widget, { if (response_id == GTK_RESPONSE_OK) { - gint scale_src; - gint scale_dest; + gdouble scale; - scale_src = gtk_adjustment_get_value (GTK_ADJUSTMENT (dialog->src_adj)); - scale_dest = gtk_adjustment_get_value (GTK_ADJUSTMENT (dialog->dest_adj)); + scale = gtk_adjustment_get_value (GTK_ADJUSTMENT (dialog->scale_adj)); - gimp_display_shell_scale (dialog->shell, scale_dest * 100 + scale_src); + gimp_display_shell_scale (dialog->shell, GIMP_ZOOM_TO, scale / 100.0); } else { @@ -577,12 +602,61 @@ gimp_display_shell_scale_dialog_response (GtkWidget *widget, gimp_display_shell_scaled (dialog->shell); } - dialog->shell->other_scale |= (1 << 30); + dialog->shell->other_scale = - fabs (dialog->shell->other_scale); gtk_widget_destroy (dialog->shell->scale_dialog); } +static void +update_zoom_values (GtkAdjustment *adj, + ScaleDialogData *dialog) +{ + gint num, denom; + gdouble scale; + + g_signal_handlers_block_by_func (GTK_ADJUSTMENT (dialog->scale_adj), + G_CALLBACK (update_zoom_values), + dialog); + + g_signal_handlers_block_by_func (GTK_ADJUSTMENT (dialog->num_adj), + G_CALLBACK (update_zoom_values), + dialog); + + g_signal_handlers_block_by_func (GTK_ADJUSTMENT (dialog->denom_adj), + G_CALLBACK (update_zoom_values), + dialog); + + if (GTK_OBJECT (adj) == dialog->scale_adj) + { + scale = gtk_adjustment_get_value (GTK_ADJUSTMENT (dialog->scale_adj)); + + gimp_display_shell_scale_get_fraction (scale / 100.0, &num, &denom); + + gtk_adjustment_set_value (GTK_ADJUSTMENT (dialog->num_adj), num); + gtk_adjustment_set_value (GTK_ADJUSTMENT (dialog->denom_adj), denom); + } + else /* fraction adjustments */ + { + scale = (gtk_adjustment_get_value (GTK_ADJUSTMENT (dialog->num_adj)) / + gtk_adjustment_get_value (GTK_ADJUSTMENT (dialog->denom_adj))); + gtk_adjustment_set_value (GTK_ADJUSTMENT (dialog->scale_adj), + scale * 100); + } + + g_signal_handlers_unblock_by_func (GTK_ADJUSTMENT (dialog->scale_adj), + G_CALLBACK (update_zoom_values), + dialog); + + g_signal_handlers_unblock_by_func (GTK_ADJUSTMENT (dialog->num_adj), + G_CALLBACK (update_zoom_values), + dialog); + + g_signal_handlers_unblock_by_func (GTK_ADJUSTMENT (dialog->denom_adj), + G_CALLBACK (update_zoom_values), + dialog); +} + /* scale image coord to realworld units (cm, inches, pixels) * * 27/Feb/1999 I tried inlining this, but the result was slightly diff --git a/app/display/gimpdisplayshell-scale.h b/app/display/gimpdisplayshell-scale.h index 7bf7e8b685..0fde6cd280 100644 --- a/app/display/gimpdisplayshell-scale.h +++ b/app/display/gimpdisplayshell-scale.h @@ -20,12 +20,11 @@ #define __GIMP_DISPLAY_SHELL_SCALE_H__ -void gimp_display_shell_scale_zoom_fraction (GimpZoomType zoom_type, - gint *scalesrc, - gint *scaledest); -void gimp_display_shell_scale_calc_fraction (gdouble zoom_factor, - gint *scalesrc, - gint *scaledest); +gdouble gimp_display_shell_scale_zoom_step (GimpZoomType zoom_type, + gdouble scale); +void gimp_display_shell_scale_get_fraction (gdouble zoom_factor, + gint *numerator, + gint *denominator); void gimp_display_shell_scale_setup (GimpDisplayShell *shell); @@ -33,10 +32,11 @@ void gimp_display_shell_scale_set_dot_for_dot (GimpDisplayShell *gdisp, gboolean dot_for_dot); void gimp_display_shell_scale (GimpDisplayShell *gdisp, - GimpZoomType zoom_type); + GimpZoomType zoom_type, + gdouble new_scale); void gimp_display_shell_scale_fit (GimpDisplayShell *gdisp); void gimp_display_shell_scale_by_values (GimpDisplayShell *gdisp, - gint scale, + gdouble scale, gint offset_x, gint offset_y, gboolean resize_window); diff --git a/app/display/gimpdisplayshell-title.c b/app/display/gimpdisplayshell-title.c index a148340634..4613a4b887 100644 --- a/app/display/gimpdisplayshell-title.c +++ b/app/display/gimpdisplayshell-title.c @@ -45,6 +45,7 @@ #include "gimpdisplay.h" #include "gimpdisplayshell.h" +#include "gimpdisplayshell-scale.h" #include "gimpdisplayshell-title.h" #include "gimpstatusbar.h" @@ -148,12 +149,15 @@ gimp_display_shell_format_title (GimpDisplayShell *shell, const gchar *format) { GimpImage *gimage; + gint num, denom; gint i = 0; g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); gimage = shell->gdisp->gimage; + gimp_display_shell_scale_get_fraction (shell->scale, &num, &denom); + while (i < title_len && *format) { switch (*format) @@ -230,16 +234,17 @@ gimp_display_shell_format_title (GimpDisplayShell *shell, break; case 's': /* user source zoom factor */ - i += print (title, title_len, i, "%d", SCALESRC (shell)); + i += print (title, title_len, i, "%d", denom); break; case 'd': /* user destination zoom factor */ - i += print (title, title_len, i, "%d", SCALEDEST (shell)); + i += print (title, title_len, i, "%d", num); break; case 'z': /* user zoom factor (percentage) */ - i += print (title, title_len, i, "%d", - 100 * SCALEDEST (shell) / SCALESRC (shell)); + i += print (title, title_len, i, + shell->scale >= 0.15 ? "%.0f" : "%.2f", + 100 * shell->scale); break; case 'D': /* dirty flag */ diff --git a/app/display/gimpdisplayshell.c b/app/display/gimpdisplayshell.c index ac60116ca3..2cc7ab4443 100644 --- a/app/display/gimpdisplayshell.c +++ b/app/display/gimpdisplayshell.c @@ -210,8 +210,8 @@ gimp_display_shell_init (GimpDisplayShell *shell) shell->popup_factory = NULL; shell->qmask_factory = NULL; - shell->scale = 0x101; - shell->other_scale = 0; + shell->scale = 1.0; + shell->other_scale = 0.0; shell->dot_for_dot = TRUE; shell->offset_x = 0; @@ -486,7 +486,7 @@ gimp_display_shell_real_scaled (GimpDisplayShell *shell) GtkWidget * gimp_display_shell_new (GimpDisplay *gdisp, - guint scale, + gdouble scale, GimpMenuFactory *menu_factory, GimpItemFactory *popup_factory) { @@ -504,7 +504,7 @@ gimp_display_shell_new (GimpDisplay *gdisp, gint image_width, image_height; gint n_width, n_height; gint s_width, s_height; - gint scalesrc, scaledest; + gdouble new_scale; g_return_val_if_fail (GIMP_IS_DISPLAY (gdisp), NULL); g_return_val_if_fail (GIMP_IS_MENU_FACTORY (menu_factory), NULL); @@ -548,33 +548,31 @@ gimp_display_shell_new (GimpDisplay *gdisp, s_width = gdk_screen_get_width (screen) * 0.75; s_height = gdk_screen_get_height (screen) * 0.75; - scalesrc = SCALESRC (shell); - scaledest = SCALEDEST (shell); - n_width = SCALEX (shell, image_width); - n_height = SCALEX (shell, image_height); + n_height = SCALEY (shell, image_height); if (config->initial_zoom_to_fit) { /* Limit to the size of the screen... */ - while (n_width > s_width || n_height > s_height) + if (n_width > s_width || n_height > s_height) { - if (scaledest > 1) - scaledest--; - else - if (scalesrc < 0xFF) - scalesrc++; + new_scale = shell->scale * MIN (((gdouble) s_height) / n_height, + ((gdouble) s_width) / n_width); + + new_scale = gimp_display_shell_scale_zoom_step (GIMP_ZOOM_OUT, + new_scale); - n_width = (image_width * - (scaledest * SCREEN_XRES (shell)) / - (scalesrc * gdisp->gimage->xresolution)); + /* since zooming out might skip a zoom step we zoom in again + * and test if we are small enough. */ + shell->scale = gimp_display_shell_scale_zoom_step (GIMP_ZOOM_IN, + new_scale); - n_height = (image_height * - (scaledest * SCREEN_XRES (shell)) / - (scalesrc * gdisp->gimage->xresolution)); + if (SCALEX (shell, image_width) > s_width || + SCALEY (shell, image_height) > s_height) + shell->scale = new_scale; - if (scaledest == 1 && scalesrc == 0xFF) - break; + n_width = SCALEX (shell, image_width); + n_height = SCALEY (shell, image_height); } } else @@ -589,7 +587,6 @@ gimp_display_shell_new (GimpDisplay *gdisp, n_height = s_height; } - shell->scale = (scaledest << 8) + scalesrc; shell->menubar_factory = gimp_menu_factory_menu_new (menu_factory, "", diff --git a/app/display/gimpdisplayshell.h b/app/display/gimpdisplayshell.h index 944250fd6a..dae3d37560 100644 --- a/app/display/gimpdisplayshell.h +++ b/app/display/gimpdisplayshell.h @@ -33,15 +33,11 @@ #define SCREEN_YRES(s) (s->dot_for_dot ? \ s->gdisp->gimage->yresolution : s->monitor_yres) -/* unpacking the user scale level (char) */ -#define SCALESRC(s) (s->scale & 0x00ff) -#define SCALEDEST(s) (s->scale >> 8) - /* calculate scale factors (double) */ -#define SCALEFACTOR_X(s) ((SCALEDEST(s) * SCREEN_XRES(s)) / \ - (SCALESRC(s) * s->gdisp->gimage->xresolution)) -#define SCALEFACTOR_Y(s) ((SCALEDEST(s) * SCREEN_YRES(s)) / \ - (SCALESRC(s) * s->gdisp->gimage->yresolution)) +#define SCALEFACTOR_X(s) (s->scale * SCREEN_XRES(s) / \ + s->gdisp->gimage->xresolution) +#define SCALEFACTOR_Y(s) (s->scale * SCREEN_YRES(s) / \ + s->gdisp->gimage->yresolution) /* scale values */ #define SCALEX(s,x) ((gint) (x * SCALEFACTOR_X(s))) @@ -78,8 +74,8 @@ struct _GimpDisplayShell gdouble monitor_xres; gdouble monitor_yres; - gint scale; /* scale factor from original raw image */ - gint other_scale; /* scale factor entered in Zoom->Other */ + gdouble scale; /* scale factor from original raw image */ + gdouble other_scale; /* scale factor entered in Zoom->Other */ gboolean dot_for_dot; /* is monitor resolution being ignored? */ gint offset_x; /* offset of display image into raw image */ @@ -174,7 +170,7 @@ struct _GimpDisplayShellClass GType gimp_display_shell_get_type (void) G_GNUC_CONST; GtkWidget * gimp_display_shell_new (GimpDisplay *gdisp, - guint scale, + gdouble scale, GimpMenuFactory *menu_factory, GimpItemFactory *popup_factory); diff --git a/app/display/gimpnavigationeditor.c b/app/display/gimpnavigationeditor.c index cacd61546b..ee191e69a4 100644 --- a/app/display/gimpnavigationeditor.c +++ b/app/display/gimpnavigationeditor.c @@ -487,7 +487,7 @@ gimp_navigation_view_new_private (GimpDisplayShell *shell, /* the zoom scale */ view->zoom_adjustment = - GTK_ADJUSTMENT (gtk_adjustment_new (0.0, -15.0, 15.0, 1.0, 1.0, 0.0)); + GTK_ADJUSTMENT (gtk_adjustment_new (0.0, -8.0, 8.0, 0.5, 1.0, 0.0)); g_signal_connect (view->zoom_adjustment, "value_changed", G_CALLBACK (gimp_navigation_view_zoom_adj_changed), @@ -496,13 +496,13 @@ gimp_navigation_view_new_private (GimpDisplayShell *shell, hscale = gtk_hscale_new (GTK_ADJUSTMENT (view->zoom_adjustment)); gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_DELAYED); gtk_scale_set_draw_value (GTK_SCALE (hscale), FALSE); - gtk_scale_set_digits (GTK_SCALE (hscale), 0); + gtk_scale_set_digits (GTK_SCALE (hscale), 2); gtk_box_pack_end (GTK_BOX (view), hscale, FALSE, FALSE, 0); gtk_widget_show (hscale); /* the zoom label */ - view->zoom_label = gtk_label_new ("1:1"); + view->zoom_label = gtk_label_new ("100%"); gtk_box_pack_end (GTK_BOX (view), view->zoom_label, FALSE, FALSE, 0); gtk_widget_show (view->zoom_label); @@ -567,9 +567,11 @@ gimp_navigation_view_zoom (GimpNavigationPreview *preview, GimpZoomType direction, GimpNavigationView *view) { + g_return_if_fail (direction != GIMP_ZOOM_TO); + if (view->shell) { - gimp_display_shell_scale (view->shell, direction); + gimp_display_shell_scale (view->shell, direction, 0.0); } } @@ -623,27 +625,8 @@ static void gimp_navigation_view_zoom_adj_changed (GtkAdjustment *adj, GimpNavigationView *view) { - gint value; - gint scalesrc; - gint scaledest; - - value = RINT (adj->value); - - if (value < 0) - { - scalesrc = - value + 1; - scaledest = 1; - } - else - { - scalesrc = 1; - scaledest = value + 1; - } - - g_print ("zoom_adj_changed: %d : %d (%f)\n", scaledest, scalesrc, - adj->value); - - gimp_display_shell_scale (view->shell, (scaledest * 100) + scalesrc); + gimp_display_shell_scale (view->shell, GIMP_ZOOM_TO, + pow (2.0, adj->value)); } static void @@ -651,7 +634,7 @@ gimp_navigation_view_zoom_out_clicked (GtkWidget *widget, GimpNavigationView *view) { if (view->shell) - gimp_display_shell_scale (view->shell, GIMP_ZOOM_OUT); + gimp_display_shell_scale (view->shell, GIMP_ZOOM_OUT, 0.0); } static void @@ -659,7 +642,7 @@ gimp_navigation_view_zoom_in_clicked (GtkWidget *widget, GimpNavigationView *view) { if (view->shell) - gimp_display_shell_scale (view->shell, GIMP_ZOOM_IN); + gimp_display_shell_scale (view->shell, GIMP_ZOOM_IN, 0.0); } static void @@ -667,7 +650,7 @@ gimp_navigation_view_zoom_100_clicked (GtkWidget *widget, GimpNavigationView *view) { if (view->shell) - gimp_display_shell_scale (view->shell, 101); + gimp_display_shell_scale (view->shell, GIMP_ZOOM_TO, 1.0); } static void @@ -695,25 +678,18 @@ gimp_navigation_view_shell_scaled (GimpDisplayShell *shell, gchar scale_str[MAX_SCALE_BUF]; /* Update the zoom scale string */ - g_snprintf (scale_str, sizeof (scale_str), "%d:%d", - SCALEDEST (view->shell), - SCALESRC (view->shell)); + g_snprintf (scale_str, sizeof (scale_str), + shell->scale >= 0.15 ? "%.0f%%" : "%.2f%%", + view->shell->scale * 100); gtk_label_set_text (GTK_LABEL (view->zoom_label), scale_str); } if (view->zoom_adjustment) { - gdouble f; - gint val; - - f = (((gdouble) SCALEDEST (view->shell)) / - ((gdouble) SCALESRC (view->shell))); + gdouble val; - if (f < 1.0) - val = - RINT (1.0 / f) + 1; - else - val = RINT (f) - 1; + val = log (CLAMP (view->shell->scale, 1.0 / 256, 256.0) ) / G_LN2; g_signal_handlers_block_by_func (view->zoom_adjustment, gimp_navigation_view_zoom_adj_changed, diff --git a/app/display/gimpnavigationview.c b/app/display/gimpnavigationview.c index cacd61546b..ee191e69a4 100644 --- a/app/display/gimpnavigationview.c +++ b/app/display/gimpnavigationview.c @@ -487,7 +487,7 @@ gimp_navigation_view_new_private (GimpDisplayShell *shell, /* the zoom scale */ view->zoom_adjustment = - GTK_ADJUSTMENT (gtk_adjustment_new (0.0, -15.0, 15.0, 1.0, 1.0, 0.0)); + GTK_ADJUSTMENT (gtk_adjustment_new (0.0, -8.0, 8.0, 0.5, 1.0, 0.0)); g_signal_connect (view->zoom_adjustment, "value_changed", G_CALLBACK (gimp_navigation_view_zoom_adj_changed), @@ -496,13 +496,13 @@ gimp_navigation_view_new_private (GimpDisplayShell *shell, hscale = gtk_hscale_new (GTK_ADJUSTMENT (view->zoom_adjustment)); gtk_range_set_update_policy (GTK_RANGE (hscale), GTK_UPDATE_DELAYED); gtk_scale_set_draw_value (GTK_SCALE (hscale), FALSE); - gtk_scale_set_digits (GTK_SCALE (hscale), 0); + gtk_scale_set_digits (GTK_SCALE (hscale), 2); gtk_box_pack_end (GTK_BOX (view), hscale, FALSE, FALSE, 0); gtk_widget_show (hscale); /* the zoom label */ - view->zoom_label = gtk_label_new ("1:1"); + view->zoom_label = gtk_label_new ("100%"); gtk_box_pack_end (GTK_BOX (view), view->zoom_label, FALSE, FALSE, 0); gtk_widget_show (view->zoom_label); @@ -567,9 +567,11 @@ gimp_navigation_view_zoom (GimpNavigationPreview *preview, GimpZoomType direction, GimpNavigationView *view) { + g_return_if_fail (direction != GIMP_ZOOM_TO); + if (view->shell) { - gimp_display_shell_scale (view->shell, direction); + gimp_display_shell_scale (view->shell, direction, 0.0); } } @@ -623,27 +625,8 @@ static void gimp_navigation_view_zoom_adj_changed (GtkAdjustment *adj, GimpNavigationView *view) { - gint value; - gint scalesrc; - gint scaledest; - - value = RINT (adj->value); - - if (value < 0) - { - scalesrc = - value + 1; - scaledest = 1; - } - else - { - scalesrc = 1; - scaledest = value + 1; - } - - g_print ("zoom_adj_changed: %d : %d (%f)\n", scaledest, scalesrc, - adj->value); - - gimp_display_shell_scale (view->shell, (scaledest * 100) + scalesrc); + gimp_display_shell_scale (view->shell, GIMP_ZOOM_TO, + pow (2.0, adj->value)); } static void @@ -651,7 +634,7 @@ gimp_navigation_view_zoom_out_clicked (GtkWidget *widget, GimpNavigationView *view) { if (view->shell) - gimp_display_shell_scale (view->shell, GIMP_ZOOM_OUT); + gimp_display_shell_scale (view->shell, GIMP_ZOOM_OUT, 0.0); } static void @@ -659,7 +642,7 @@ gimp_navigation_view_zoom_in_clicked (GtkWidget *widget, GimpNavigationView *view) { if (view->shell) - gimp_display_shell_scale (view->shell, GIMP_ZOOM_IN); + gimp_display_shell_scale (view->shell, GIMP_ZOOM_IN, 0.0); } static void @@ -667,7 +650,7 @@ gimp_navigation_view_zoom_100_clicked (GtkWidget *widget, GimpNavigationView *view) { if (view->shell) - gimp_display_shell_scale (view->shell, 101); + gimp_display_shell_scale (view->shell, GIMP_ZOOM_TO, 1.0); } static void @@ -695,25 +678,18 @@ gimp_navigation_view_shell_scaled (GimpDisplayShell *shell, gchar scale_str[MAX_SCALE_BUF]; /* Update the zoom scale string */ - g_snprintf (scale_str, sizeof (scale_str), "%d:%d", - SCALEDEST (view->shell), - SCALESRC (view->shell)); + g_snprintf (scale_str, sizeof (scale_str), + shell->scale >= 0.15 ? "%.0f%%" : "%.2f%%", + view->shell->scale * 100); gtk_label_set_text (GTK_LABEL (view->zoom_label), scale_str); } if (view->zoom_adjustment) { - gdouble f; - gint val; - - f = (((gdouble) SCALEDEST (view->shell)) / - ((gdouble) SCALESRC (view->shell))); + gdouble val; - if (f < 1.0) - val = - RINT (1.0 / f) + 1; - else - val = RINT (f) - 1; + val = log (CLAMP (view->shell->scale, 1.0 / 256, 256.0) ) / G_LN2; g_signal_handlers_block_by_func (view->zoom_adjustment, gimp_navigation_view_zoom_adj_changed, diff --git a/app/file/file-open.c b/app/file/file-open.c index 1819e5777c..42283faf21 100644 --- a/app/file/file-open.c +++ b/app/file/file-open.c @@ -208,7 +208,7 @@ file_open_with_proc_and_display (Gimp *gimp, /* set the image to clean */ gimp_image_clean_all (gimage); - gimp_create_display (gimage->gimp, gimage, 0x0101); + gimp_create_display (gimage->gimp, gimage, 1.0); g_object_unref (gimage); diff --git a/app/gui/gui-vtable.c b/app/gui/gui-vtable.c index ec2ae403e2..d9d07fdce1 100644 --- a/app/gui/gui-vtable.c +++ b/app/gui/gui-vtable.c @@ -61,7 +61,7 @@ static void gui_message (Gimp *gimp, const gchar *domain, const gchar *message); static GimpObject * gui_display_new (GimpImage *gimage, - guint scale); + gdouble scale); static void gui_menus_init (Gimp *gimp, GSList *plug_in_defs, const gchar *plugins_domain); @@ -185,7 +185,7 @@ gui_message (Gimp *gimp, static GimpObject * gui_display_new (GimpImage *gimage, - guint scale) + gdouble scale) { GimpDisplayShell *shell; GimpDisplay *gdisp; diff --git a/app/gui/image-commands.c b/app/gui/image-commands.c index 2d7a5b1cb5..e6534a0305 100644 --- a/app/gui/image-commands.c +++ b/app/gui/image-commands.c @@ -279,7 +279,7 @@ image_duplicate_cmd_callback (GtkWidget *widget, new_gimage = gimp_image_duplicate (gimage); - gimp_create_display (new_gimage->gimp, new_gimage, 0x0101); + gimp_create_display (new_gimage->gimp, new_gimage, 1.0); g_object_unref (new_gimage); } diff --git a/app/gui/image-menu.c b/app/gui/image-menu.c index bd06d9d396..adeebf40b8 100644 --- a/app/gui/image-menu.c +++ b/app/gui/image-menu.c @@ -368,39 +368,39 @@ GimpItemFactoryEntry image_menu_entries[] = MENU_SEPARATOR ("/View/Zoom/---"), { { N_("/View/Zoom/16:1"), NULL, - view_zoom_cmd_callback, 1601, "" }, + view_zoom_cmd_callback, 160000, "" }, NULL, GIMP_HELP_VIEW_ZOOM_IN, NULL }, { { N_("/View/Zoom/8:1"), NULL, - view_zoom_cmd_callback, 801, "/View/Zoom/16:1" }, + view_zoom_cmd_callback, 80000, "/View/Zoom/16:1" }, NULL, GIMP_HELP_VIEW_ZOOM_IN, NULL }, { { N_("/View/Zoom/4:1"), NULL, - view_zoom_cmd_callback, 401, "/View/Zoom/16:1" }, + view_zoom_cmd_callback, 40000, "/View/Zoom/16:1" }, NULL, GIMP_HELP_VIEW_ZOOM_IN, NULL }, { { N_("/View/Zoom/2:1"), NULL, - view_zoom_cmd_callback, 201, "/View/Zoom/16:1" }, + view_zoom_cmd_callback, 20000, "/View/Zoom/16:1" }, NULL, GIMP_HELP_VIEW_ZOOM_IN, NULL }, { { N_("/View/Zoom/1:1"), "1", - view_zoom_cmd_callback, 101, "/View/Zoom/16:1" }, + view_zoom_cmd_callback, 10000, "/View/Zoom/16:1" }, NULL, GIMP_HELP_VIEW_ZOOM_100, NULL }, { { N_("/View/Zoom/1:2"), NULL, - view_zoom_cmd_callback, 102, "/View/Zoom/16:1" }, + view_zoom_cmd_callback, 5000, "/View/Zoom/16:1" }, NULL, GIMP_HELP_VIEW_ZOOM_OUT, NULL }, { { N_("/View/Zoom/1:4"), NULL, - view_zoom_cmd_callback, 104, "/View/Zoom/16:1" }, + view_zoom_cmd_callback, 2500, "/View/Zoom/16:1" }, NULL, GIMP_HELP_VIEW_ZOOM_OUT, NULL }, { { N_("/View/Zoom/1:8"), NULL, - view_zoom_cmd_callback, 108, "/View/Zoom/16:1" }, + view_zoom_cmd_callback, 1250, "/View/Zoom/16:1" }, NULL, GIMP_HELP_VIEW_ZOOM_OUT, NULL }, { { N_("/View/Zoom/1:16"), NULL, - view_zoom_cmd_callback, 116, "/View/Zoom/16:1" }, + view_zoom_cmd_callback, 625, "/View/Zoom/16:1" }, NULL, GIMP_HELP_VIEW_ZOOM_OUT, NULL }, @@ -1655,40 +1655,33 @@ image_menu_set_zoom (GtkItemFactory *item_factory, GimpDisplayShell *shell) { const gchar *menu = NULL; - guint scalesrc; - guint scaledest; + guint scale; gchar *label; - scalesrc = SCALESRC (shell); - scaledest = SCALEDEST (shell); + scale = ROUND (shell->scale * 1000); - if (scaledest == 1) + switch (scale) { - switch (scalesrc) - { - case 1: menu = "/View/Zoom/1:1"; break; - case 2: menu = "/View/Zoom/1:2"; break; - case 4: menu = "/View/Zoom/1:4"; break; - case 8: menu = "/View/Zoom/1:8"; break; - case 16: menu = "/View/Zoom/1:16"; break; - } - } - else if (scalesrc == 1) - { - switch (scaledest) - { - case 2: menu = "/View/Zoom/2:1"; break; - case 4: menu = "/View/Zoom/4:1"; break; - case 8: menu = "/View/Zoom/8:1"; break; - case 16: menu = "/View/Zoom/16:1"; break; - } + case 16000: menu = "/View/Zoom/16:1"; break; + case 8000: menu = "/View/Zoom/8:1"; break; + case 4000: menu = "/View/Zoom/4:1"; break; + case 2000: menu = "/View/Zoom/2:1"; break; + case 1000: menu = "/View/Zoom/1:1"; break; + case 500: menu = "/View/Zoom/1:2"; break; + case 250: menu = "/View/Zoom/1:4"; break; + case 125: menu = "/View/Zoom/1:8"; break; + case 63: + case 62: menu = "/View/Zoom/1:16"; break; } if (!menu) { menu = "/View/Zoom/Other..."; - label = g_strdup_printf (_("Other (%d:%d) ..."), scaledest, scalesrc); + label = g_strdup_printf (shell->scale >= 0.15 ? + _("Other (%.0f%%) ..."): + _("Other (%.2f%%) ..."), + shell->scale * 100.0); gimp_item_factory_set_label (item_factory, menu, label); g_free (label); @@ -1697,10 +1690,13 @@ image_menu_set_zoom (GtkItemFactory *item_factory, gimp_item_factory_set_active (item_factory, menu, TRUE); - label = g_strdup_printf (_("_Zoom (%d:%d)"), scaledest, scalesrc); + label = g_strdup_printf (shell->scale >= 0.15 ? + _("_Zoom (%.0f%%)") : + _("_Zoom (%.2f%%)"), + shell->scale * 100.0); gimp_item_factory_set_label (item_factory, "/View/Zoom", label); g_free (label); - /* flag as dirty */ - shell->other_scale |= (1 << 30); + /* flag as dirty */ + shell->other_scale = - fabs (shell->other_scale); } diff --git a/app/gui/info-window.c b/app/gui/info-window.c index 6a63f676ec..9e2d5f4d94 100644 --- a/app/gui/info-window.c +++ b/app/gui/info-window.c @@ -521,8 +521,7 @@ info_window_update (GimpDisplay *gdisp) res_unit == GIMP_UNIT_INCH ? _("dpi") : format_buf); /* user zoom ratio */ - g_snprintf (iwd->scale_str, MAX_BUF, "%d:%d", - SCALEDEST (shell), SCALESRC (shell)); + g_snprintf (iwd->scale_str, MAX_BUF, "%.2f", shell->scale * 100); /* number of layers */ g_snprintf (iwd->num_layers_str, MAX_BUF, "%d", diff --git a/app/gui/view-commands.c b/app/gui/view-commands.c index a0fa7367f5..919086072e 100644 --- a/app/gui/view-commands.c +++ b/app/gui/view-commands.c @@ -68,7 +68,8 @@ view_zoom_out_cmd_callback (GtkWidget *widget, GimpDisplay *gdisp; return_if_no_display (gdisp, data); - gimp_display_shell_scale (GIMP_DISPLAY_SHELL (gdisp->shell), GIMP_ZOOM_OUT); + gimp_display_shell_scale (GIMP_DISPLAY_SHELL (gdisp->shell), + GIMP_ZOOM_OUT, 0.0); } void @@ -78,7 +79,8 @@ view_zoom_in_cmd_callback (GtkWidget *widget, GimpDisplay *gdisp; return_if_no_display (gdisp, data); - gimp_display_shell_scale (GIMP_DISPLAY_SHELL (gdisp->shell), GIMP_ZOOM_IN); + gimp_display_shell_scale (GIMP_DISPLAY_SHELL (gdisp->shell), + GIMP_ZOOM_IN, 0.0); } void @@ -94,12 +96,10 @@ view_zoom_fit_cmd_callback (GtkWidget *widget, void view_zoom_cmd_callback (GtkWidget *widget, gpointer data, - guint action) + guint scale) { GimpDisplay *gdisp; GimpDisplayShell *shell; - guchar scalesrc; - guchar scaledest; return_if_no_display (gdisp, data); if (! GTK_CHECK_MENU_ITEM (widget)->active) @@ -107,11 +107,8 @@ view_zoom_cmd_callback (GtkWidget *widget, shell = GIMP_DISPLAY_SHELL (gdisp->shell); - scalesrc = CLAMP (action % 100, 1, 0xFF); - scaledest = CLAMP (action / 100, 1, 0xFF); - - if (scalesrc != SCALESRC (shell) || scaledest != SCALEDEST (shell)) - gimp_display_shell_scale (shell, action); + if (fabs (scale - shell->scale) > 0.0001) + gimp_display_shell_scale (shell, GIMP_ZOOM_TO, (gdouble) scale / 10000); } void diff --git a/app/gui/view-commands.h b/app/gui/view-commands.h index 29511cf17e..5dc8a8ed8e 100644 --- a/app/gui/view-commands.h +++ b/app/gui/view-commands.h @@ -28,7 +28,7 @@ void view_zoom_fit_cmd_callback (GtkWidget *widget, gpointer data); void view_zoom_cmd_callback (GtkWidget *widget, gpointer data, - guint action); + guint scale); void view_zoom_other_cmd_callback (GtkWidget *widget, gpointer data); void view_dot_for_dot_cmd_callback (GtkWidget *widget, diff --git a/app/menus/image-menu.c b/app/menus/image-menu.c index bd06d9d396..adeebf40b8 100644 --- a/app/menus/image-menu.c +++ b/app/menus/image-menu.c @@ -368,39 +368,39 @@ GimpItemFactoryEntry image_menu_entries[] = MENU_SEPARATOR ("/View/Zoom/---"), { { N_("/View/Zoom/16:1"), NULL, - view_zoom_cmd_callback, 1601, "" }, + view_zoom_cmd_callback, 160000, "" }, NULL, GIMP_HELP_VIEW_ZOOM_IN, NULL }, { { N_("/View/Zoom/8:1"), NULL, - view_zoom_cmd_callback, 801, "/View/Zoom/16:1" }, + view_zoom_cmd_callback, 80000, "/View/Zoom/16:1" }, NULL, GIMP_HELP_VIEW_ZOOM_IN, NULL }, { { N_("/View/Zoom/4:1"), NULL, - view_zoom_cmd_callback, 401, "/View/Zoom/16:1" }, + view_zoom_cmd_callback, 40000, "/View/Zoom/16:1" }, NULL, GIMP_HELP_VIEW_ZOOM_IN, NULL }, { { N_("/View/Zoom/2:1"), NULL, - view_zoom_cmd_callback, 201, "/View/Zoom/16:1" }, + view_zoom_cmd_callback, 20000, "/View/Zoom/16:1" }, NULL, GIMP_HELP_VIEW_ZOOM_IN, NULL }, { { N_("/View/Zoom/1:1"), "1", - view_zoom_cmd_callback, 101, "/View/Zoom/16:1" }, + view_zoom_cmd_callback, 10000, "/View/Zoom/16:1" }, NULL, GIMP_HELP_VIEW_ZOOM_100, NULL }, { { N_("/View/Zoom/1:2"), NULL, - view_zoom_cmd_callback, 102, "/View/Zoom/16:1" }, + view_zoom_cmd_callback, 5000, "/View/Zoom/16:1" }, NULL, GIMP_HELP_VIEW_ZOOM_OUT, NULL }, { { N_("/View/Zoom/1:4"), NULL, - view_zoom_cmd_callback, 104, "/View/Zoom/16:1" }, + view_zoom_cmd_callback, 2500, "/View/Zoom/16:1" }, NULL, GIMP_HELP_VIEW_ZOOM_OUT, NULL }, { { N_("/View/Zoom/1:8"), NULL, - view_zoom_cmd_callback, 108, "/View/Zoom/16:1" }, + view_zoom_cmd_callback, 1250, "/View/Zoom/16:1" }, NULL, GIMP_HELP_VIEW_ZOOM_OUT, NULL }, { { N_("/View/Zoom/1:16"), NULL, - view_zoom_cmd_callback, 116, "/View/Zoom/16:1" }, + view_zoom_cmd_callback, 625, "/View/Zoom/16:1" }, NULL, GIMP_HELP_VIEW_ZOOM_OUT, NULL }, @@ -1655,40 +1655,33 @@ image_menu_set_zoom (GtkItemFactory *item_factory, GimpDisplayShell *shell) { const gchar *menu = NULL; - guint scalesrc; - guint scaledest; + guint scale; gchar *label; - scalesrc = SCALESRC (shell); - scaledest = SCALEDEST (shell); + scale = ROUND (shell->scale * 1000); - if (scaledest == 1) + switch (scale) { - switch (scalesrc) - { - case 1: menu = "/View/Zoom/1:1"; break; - case 2: menu = "/View/Zoom/1:2"; break; - case 4: menu = "/View/Zoom/1:4"; break; - case 8: menu = "/View/Zoom/1:8"; break; - case 16: menu = "/View/Zoom/1:16"; break; - } - } - else if (scalesrc == 1) - { - switch (scaledest) - { - case 2: menu = "/View/Zoom/2:1"; break; - case 4: menu = "/View/Zoom/4:1"; break; - case 8: menu = "/View/Zoom/8:1"; break; - case 16: menu = "/View/Zoom/16:1"; break; - } + case 16000: menu = "/View/Zoom/16:1"; break; + case 8000: menu = "/View/Zoom/8:1"; break; + case 4000: menu = "/View/Zoom/4:1"; break; + case 2000: menu = "/View/Zoom/2:1"; break; + case 1000: menu = "/View/Zoom/1:1"; break; + case 500: menu = "/View/Zoom/1:2"; break; + case 250: menu = "/View/Zoom/1:4"; break; + case 125: menu = "/View/Zoom/1:8"; break; + case 63: + case 62: menu = "/View/Zoom/1:16"; break; } if (!menu) { menu = "/View/Zoom/Other..."; - label = g_strdup_printf (_("Other (%d:%d) ..."), scaledest, scalesrc); + label = g_strdup_printf (shell->scale >= 0.15 ? + _("Other (%.0f%%) ..."): + _("Other (%.2f%%) ..."), + shell->scale * 100.0); gimp_item_factory_set_label (item_factory, menu, label); g_free (label); @@ -1697,10 +1690,13 @@ image_menu_set_zoom (GtkItemFactory *item_factory, gimp_item_factory_set_active (item_factory, menu, TRUE); - label = g_strdup_printf (_("_Zoom (%d:%d)"), scaledest, scalesrc); + label = g_strdup_printf (shell->scale >= 0.15 ? + _("_Zoom (%.0f%%)") : + _("_Zoom (%.2f%%)"), + shell->scale * 100.0); gimp_item_factory_set_label (item_factory, "/View/Zoom", label); g_free (label); - /* flag as dirty */ - shell->other_scale |= (1 << 30); + /* flag as dirty */ + shell->other_scale = - fabs (shell->other_scale); } diff --git a/app/pdb/display_cmds.c b/app/pdb/display_cmds.c index d682f5b33a..c733128f26 100644 --- a/app/pdb/display_cmds.c +++ b/app/pdb/display_cmds.c @@ -64,7 +64,7 @@ display_new_invoker (Gimp *gimp, if (success) { - display = (GimpDisplay *) gimp_create_display (gimp, gimage, 0x0101); + display = (GimpDisplay *) gimp_create_display (gimp, gimage, 1.0); success = (display != NULL); diff --git a/app/tools/gimpmagnifytool.c b/app/tools/gimpmagnifytool.c index fa70496575..911c55f267 100644 --- a/app/tools/gimpmagnifytool.c +++ b/app/tools/gimpmagnifytool.c @@ -228,9 +228,9 @@ gimp_magnify_tool_button_release (GimpTool *tool, if (! (state & GDK_BUTTON3_MASK)) { gint x1, y1, x2, y2, w, h; - gint scalesrc, scaledest; gint win_width, win_height; gint offset_x, offset_y; + gdouble new_scale; x1 = (magnify->w < 0) ? magnify->x + magnify->w : magnify->x; y1 = (magnify->h < 0) ? magnify->y + magnify->h : magnify->y; @@ -239,12 +239,6 @@ gimp_magnify_tool_button_release (GimpTool *tool, x2 = x1 + w; y2 = y1 + h; - /* these change the user zoom level, so should not be changed to - * the resolution-aware scale macros -- austin - */ - scalesrc = SCALESRC (shell); - scaledest = SCALEDEST (shell); - win_width = shell->disp_width; win_height = shell->disp_height; @@ -252,8 +246,8 @@ gimp_magnify_tool_button_release (GimpTool *tool, if ((SCALEX (shell, w) < options->threshold) || (SCALEY (shell, h) < options->threshold)) { - gimp_display_shell_scale_zoom_fraction (options->zoom_type, - &scalesrc, &scaledest); + new_scale = gimp_display_shell_scale_zoom_step (options->zoom_type, + shell->scale); } else { @@ -274,19 +268,19 @@ gimp_magnify_tool_button_release (GimpTool *tool, scale = MIN (((gdouble) w / (gdouble) width), ((gdouble) h / (gdouble) height)); break; + + case GIMP_ZOOM_TO: + break; } - scale = scale * (gdouble) scaledest / (gdouble) scalesrc; - - gimp_display_shell_scale_calc_fraction (scale, - &scalesrc, &scaledest); + new_scale = shell->scale * scale; } - offset_x = (scaledest * ((x1 + x2) / 2)) / scalesrc - (win_width / 2); - offset_y = (scaledest * ((y1 + y2) / 2)) / scalesrc - (win_height / 2); + offset_x = (new_scale * (x1 + x2) / 2) - (win_width / 2); + offset_y = (new_scale * (y1 + y2) / 2) - (win_height / 2); gimp_display_shell_scale_by_values (shell, - (scaledest << 8) + scalesrc, + new_scale, offset_x, offset_y, options->allow_resize); } diff --git a/app/widgets/gimpimageview.c b/app/widgets/gimpimageview.c index 3c6b847eca..eb9b6e98da 100644 --- a/app/widgets/gimpimageview.c +++ b/app/widgets/gimpimageview.c @@ -206,7 +206,7 @@ gimp_image_view_new_clicked (GtkWidget *widget, if (image && gimp_container_have (editor->view->container, GIMP_OBJECT (image))) { - gimp_create_display (image->gimp, image, 0x0101); + gimp_create_display (image->gimp, image, 1.0); } } diff --git a/app/widgets/gimptoolbox-dnd.c b/app/widgets/gimptoolbox-dnd.c index 593ab6ad14..295816b60c 100644 --- a/app/widgets/gimptoolbox-dnd.c +++ b/app/widgets/gimptoolbox-dnd.c @@ -144,7 +144,7 @@ gimp_toolbox_drop_drawable (GtkWidget *widget, gimp_image_undo_enable (new_image); - gimp_create_display (gimage->gimp, new_image, 0x0101); + gimp_create_display (gimage->gimp, new_image, 1.0); g_object_unref (new_image); } diff --git a/app/widgets/widgets-enums.h b/app/widgets/widgets-enums.h index 45d25f177e..a11a361b9a 100644 --- a/app/widgets/widgets-enums.h +++ b/app/widgets/widgets-enums.h @@ -117,7 +117,8 @@ GType gimp_zoom_type_get_type (void) G_GNUC_CONST; typedef enum { GIMP_ZOOM_IN, /*< desc="Zoom in" >*/ - GIMP_ZOOM_OUT /*< desc="Zoom out" >*/ + GIMP_ZOOM_OUT, /*< desc="Zoom out" >*/ + GIMP_ZOOM_TO /*< skip >*/ } GimpZoomType; diff --git a/tools/pdbgen/pdb/display.pdb b/tools/pdbgen/pdb/display.pdb index a9e65620a2..6dcd7a4ea4 100644 --- a/tools/pdbgen/pdb/display.pdb +++ b/tools/pdbgen/pdb/display.pdb @@ -42,7 +42,7 @@ HELP %invoke = ( code => <<'CODE' { - display = (GimpDisplay *) gimp_create_display (gimp, gimage, 0x0101); + display = (GimpDisplay *) gimp_create_display (gimp, gimage, 1.0); success = (display != NULL);