new utility function which takes GimpZoomType and zooms "scalesrc" and

2003-05-05  Michael Natterer  <mitch@gimp.org>

	* app/display/gimpdisplayshell-scale.[ch]
	(gimp_display_shell_scale_zoom_fraction): new utility function
	which takes GimpZoomType and zooms "scalesrc" and "scaledest".
	(gimp_display_shell_scale_calc_fraction): new utility function
	which takes an exact double scale factor and calculates "scalesrc"
	and "scaledest".

	(gimp_display_shell_scale): use the first.
	(gimp_display_shell_scale_fit): use the second.

	* app/tools/gimpmagnifytool.[ch]: use the first to click-zoom and
	the second to area-zoom. Fixes bug #112115. Removed zoom_in() and
	zoom_out() utiliy functions. Removed "GimpZoomType op" from the
	GimpMagnifyTool struct. Cleanup.
This commit is contained in:
Michael Natterer 2003-05-05 14:48:15 +00:00 committed by Michael Natterer
parent 5067bec93b
commit 1204865d04
5 changed files with 183 additions and 177 deletions

View File

@ -1,3 +1,20 @@
2003-05-05 Michael Natterer <mitch@gimp.org>
* app/display/gimpdisplayshell-scale.[ch]
(gimp_display_shell_scale_zoom_fraction): new utility function
which takes GimpZoomType and zooms "scalesrc" and "scaledest".
(gimp_display_shell_scale_calc_fraction): new utility function
which takes an exact double scale factor and calculates "scalesrc"
and "scaledest".
(gimp_display_shell_scale): use the first.
(gimp_display_shell_scale_fit): use the second.
* app/tools/gimpmagnifytool.[ch]: use the first to click-zoom and
the second to area-zoom. Fixes bug #112115. Removed zoom_in() and
zoom_out() utiliy functions. Removed "GimpZoomType op" from the
GimpMagnifyTool struct. Cleanup.
2003-05-05 Michael Natterer <mitch@gimp.org> 2003-05-05 Michael Natterer <mitch@gimp.org>
* app/display/gimpdisplayshell.c (gimp_display_shell_snap_coords): * app/display/gimpdisplayshell.c (gimp_display_shell_snap_coords):

View File

@ -62,6 +62,112 @@ static gdouble img2real (GimpDisplayShell *shell,
/* public functions */ /* public functions */
void
gimp_display_shell_scale_zoom_fraction (GimpZoomType zoom_type,
gint *scalesrc,
gint *scaledest)
{
gint src, dest;
g_return_if_fail (scalesrc != NULL);
g_return_if_fail (scaledest != NULL);
src = *scalesrc;
dest = *scaledest;
switch (zoom_type)
{
case GIMP_ZOOM_IN:
if (src > 1)
src--;
else if (dest < 0xFF)
dest++;
break;
case GIMP_ZOOM_OUT:
if (dest > 1)
dest--;
else if (src < 0xFF)
src++;
break;
default:
src = CLAMP (zoom_type % 100, 1, 0xFF);
dest = CLAMP (zoom_type / 100, 1, 0xFF);
break;
}
*scalesrc = src;
*scaledest = dest;
}
void
gimp_display_shell_scale_calc_fraction (gdouble zoom_factor,
gint *scalesrc,
gint *scaledest)
{
gdouble zoom_delta;
gdouble min_zoom_delta = G_MAXFLOAT;
gint best_i = 0xFF;
gint i;
g_return_if_fail (scalesrc != NULL);
g_return_if_fail (scaledest != NULL);
if (zoom_factor < 1.0)
{
for (i = 0xFF; i > 0; i--)
{
*scalesrc = i;
*scaledest = floor ((gdouble) *scalesrc * zoom_factor);
if (*scaledest < 0x1)
*scaledest = 0x1;
zoom_delta = ABS ((gdouble) *scaledest / (gdouble) *scalesrc -
zoom_factor);
if (zoom_delta <= min_zoom_delta)
{
min_zoom_delta = zoom_delta;
best_i = i;
}
}
*scalesrc = best_i;
*scaledest = floor ((gdouble) *scalesrc * zoom_factor);
if (*scaledest < 0x1)
*scaledest = 0x1;
}
else
{
for (i = 0xFF; i > 0; i--)
{
*scaledest = i;
*scalesrc = ceil ((gdouble) *scaledest / zoom_factor);
if (*scalesrc < 0x1)
*scalesrc = 0x1;
zoom_delta = ABS ((gdouble) *scaledest / (gdouble) *scalesrc -
zoom_factor);
if (zoom_delta <= min_zoom_delta)
{
min_zoom_delta = zoom_delta;
best_i = i;
}
}
*scaledest = best_i;
*scalesrc = ceil ((gdouble) *scaledest / zoom_factor);
if (*scalesrc < 0x1)
*scalesrc = 0x1;
}
}
void void
gimp_display_shell_scale_setup (GimpDisplayShell *shell) gimp_display_shell_scale_setup (GimpDisplayShell *shell)
{ {
@ -204,9 +310,8 @@ gimp_display_shell_scale (GimpDisplayShell *shell,
GimpZoomType zoom_type) GimpZoomType zoom_type)
{ {
GimpDisplayConfig *config; GimpDisplayConfig *config;
gint scalesrc, scaledest;
guchar scalesrc, scaledest; gdouble offset_x, offset_y;
gdouble offset_x, offset_y;
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
@ -220,40 +325,13 @@ gimp_display_shell_scale (GimpDisplayShell *shell,
offset_x *= ((gdouble) scalesrc / (gdouble) scaledest); offset_x *= ((gdouble) scalesrc / (gdouble) scaledest);
offset_y *= ((gdouble) scalesrc / (gdouble) scaledest); offset_y *= ((gdouble) scalesrc / (gdouble) scaledest);
switch (zoom_type) gimp_display_shell_scale_zoom_fraction (zoom_type, &scalesrc, &scaledest);
{
case GIMP_ZOOM_IN:
if (scalesrc > 1)
scalesrc--;
else
if (scaledest < 0xFF)
scaledest++;
else
return;
break;
case GIMP_ZOOM_OUT:
if (scaledest > 1)
scaledest--;
else
if (scalesrc < 0xFF)
scalesrc++;
else
return;
break;
default:
scalesrc = CLAMP (zoom_type % 100, 1, 0xFF);
scaledest = CLAMP (zoom_type / 100, 1, 0xFF);
break;
}
/* set the offsets */
offset_x *= ((gdouble) scaledest / (gdouble) scalesrc); offset_x *= ((gdouble) scaledest / (gdouble) scalesrc);
offset_y *= ((gdouble) scaledest / (gdouble) scalesrc); offset_y *= ((gdouble) scaledest / (gdouble) scalesrc);
config = GIMP_DISPLAY_CONFIG (shell->gdisp->gimage->gimp->config); config = GIMP_DISPLAY_CONFIG (shell->gdisp->gimage->gimp->config);
gimp_display_shell_scale_by_values (shell, gimp_display_shell_scale_by_values (shell,
(scaledest << 8) + scalesrc, (scaledest << 8) + scalesrc,
(offset_x - (shell->disp_width / 2)), (offset_x - (shell->disp_width / 2)),
@ -270,12 +348,8 @@ gimp_display_shell_scale_fit (GimpDisplayShell *shell)
gdouble zoom_x; gdouble zoom_x;
gdouble zoom_y; gdouble zoom_y;
gdouble zoom_factor; gdouble zoom_factor;
gdouble zoom_delta; gint scalesrc;
gdouble min_zoom_delta = G_MAXFLOAT; gint scaledest;
gint scalesrc = 1;
gint scaledest = 1;
gint i;
gint best_i = 0xFF;
g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell));
@ -298,74 +372,12 @@ gimp_display_shell_scale_fit (GimpDisplayShell *shell)
zoom_y = (gdouble) shell->disp_height / (gdouble) image_height; zoom_y = (gdouble) shell->disp_height / (gdouble) image_height;
if ((gdouble) image_height * zoom_x <= (gdouble) shell->disp_height) if ((gdouble) image_height * zoom_x <= (gdouble) shell->disp_height)
{ zoom_factor = zoom_x;
zoom_factor = zoom_x;
}
else else
{ zoom_factor = zoom_y;
zoom_factor = zoom_y;
}
if (zoom_factor < 1.0) gimp_display_shell_scale_calc_fraction (zoom_factor,
{ &scalesrc, &scaledest);
for (i = 0xFF; i > 0; i--)
{
scalesrc = i;
scaledest = floor ((gdouble) scalesrc * zoom_factor);
if (scaledest < 0x1)
{
scaledest = 0x1;
}
zoom_delta = ABS ((gdouble) scaledest / (gdouble) scalesrc -
zoom_factor);
if (zoom_delta <= min_zoom_delta)
{
min_zoom_delta = zoom_delta;
best_i = i;
}
}
scalesrc = best_i;
scaledest = floor ((gdouble) scalesrc * zoom_factor);
if (scaledest < 0x1)
{
scaledest = 0x1;
}
}
else
{
for (i = 0xFF; i > 0; i--)
{
scaledest = i;
scalesrc = ceil ((gdouble) scaledest / zoom_factor);
if (scalesrc < 0x1)
{
scalesrc = 0x1;
}
zoom_delta = ABS ((gdouble) scaledest / (gdouble) scalesrc -
zoom_factor);
if (zoom_delta <= min_zoom_delta)
{
min_zoom_delta = zoom_delta;
best_i = i;
}
}
scaledest = best_i;
scalesrc = ceil ((gdouble) scaledest / zoom_factor);
if (scalesrc < 0x1)
{
scalesrc = 0x1;
}
}
gimp_display_shell_scale_by_values (shell, gimp_display_shell_scale_by_values (shell,
(scaledest << 8) + scalesrc, (scaledest << 8) + scalesrc,

View File

@ -20,6 +20,13 @@
#define __GIMP_DISPLAY_SHELL_SCALE_H__ #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);
void gimp_display_shell_scale_setup (GimpDisplayShell *shell); void gimp_display_shell_scale_setup (GimpDisplayShell *shell);
void gimp_display_shell_scale_set_dot_for_dot (GimpDisplayShell *gdisp, void gimp_display_shell_scale_set_dot_for_dot (GimpDisplayShell *gdisp,

View File

@ -77,13 +77,6 @@ static void gimp_magnify_tool_cursor_update (GimpTool *tool,
static void gimp_magnify_tool_draw (GimpDrawTool *draw_tool); static void gimp_magnify_tool_draw (GimpDrawTool *draw_tool);
static void zoom_in (gint *src,
gint *dest,
gint scale);
static void zoom_out (gint *src,
gint *dest,
gint scale);
static GimpDrawToolClass *parent_class = NULL; static GimpDrawToolClass *parent_class = NULL;
@ -220,11 +213,6 @@ gimp_magnify_tool_button_release (GimpTool *tool,
GimpMagnifyTool *magnify; GimpMagnifyTool *magnify;
GimpMagnifyOptions *options; GimpMagnifyOptions *options;
GimpDisplayShell *shell; GimpDisplayShell *shell;
gint win_width, win_height;
gint width, height;
gint scalesrc, scaledest;
gint scale;
gint x1, y1, x2, y2, w, h;
magnify = GIMP_MAGNIFY_TOOL (tool); magnify = GIMP_MAGNIFY_TOOL (tool);
options = GIMP_MAGNIFY_OPTIONS (tool->tool_info->tool_options); options = GIMP_MAGNIFY_OPTIONS (tool->tool_info->tool_options);
@ -238,8 +226,13 @@ gimp_magnify_tool_button_release (GimpTool *tool,
/* First take care of the case where the user "cancels" the action */ /* First take care of the case where the user "cancels" the action */
if (! (state & GDK_BUTTON3_MASK)) if (! (state & GDK_BUTTON3_MASK))
{ {
x1 = (magnify->w < 0) ? magnify->x + magnify->w : magnify->x; gint x1, y1, x2, y2, w, h;
y1 = (magnify->h < 0) ? magnify->y + magnify->h : magnify->y; gint scalesrc, scaledest;
gint win_width, win_height;
gint offset_x, offset_y;
x1 = (magnify->w < 0) ? magnify->x + magnify->w : magnify->x;
y1 = (magnify->h < 0) ? magnify->y + magnify->h : magnify->y;
w = (magnify->w < 0) ? -magnify->w : magnify->w; w = (magnify->w < 0) ? -magnify->w : magnify->w;
h = (magnify->h < 0) ? -magnify->h : magnify->h; h = (magnify->h < 0) ? -magnify->h : magnify->h;
x2 = x1 + w; x2 = x1 + w;
@ -253,34 +246,47 @@ gimp_magnify_tool_button_release (GimpTool *tool,
win_width = shell->disp_width; win_width = shell->disp_width;
win_height = shell->disp_height; win_height = shell->disp_height;
width = (win_width * scalesrc) / scaledest;
height = (win_height * scalesrc) / scaledest;
/* we need to compute the mouse movement in screen coordinates */ /* we need to compute the mouse movement in screen coordinates */
if ( (SCALEX (shell, w) < options->threshold) || if ((SCALEX (shell, w) < options->threshold) ||
(SCALEY (shell, h) < options->threshold) ) (SCALEY (shell, h) < options->threshold))
scale = 1; {
gimp_display_shell_scale_zoom_fraction (options->zoom_type,
&scalesrc, &scaledest);
}
else else
scale = MIN ((width / w), (height / h)); {
gint width, height;
gdouble scale;
magnify->op = options->zoom_type; width = UNSCALEX (shell, win_width);
height = UNSCALEY (shell, win_height);
switch (magnify->op) switch (options->zoom_type)
{ {
case GIMP_ZOOM_IN: case GIMP_ZOOM_IN:
zoom_in (&scalesrc, &scaledest, scale); scale = MIN (((gdouble) width / (gdouble) w),
break; ((gdouble) height / (gdouble) h));
case GIMP_ZOOM_OUT: break;
zoom_out (&scalesrc, &scaledest, scale);
break; case GIMP_ZOOM_OUT:
} scale = MIN (((gdouble) w / (gdouble) width),
((gdouble) h / (gdouble) height));
break;
}
scale = scale * (gdouble) scaledest / (gdouble) scalesrc;
gimp_display_shell_scale_calc_fraction (scale,
&scalesrc, &scaledest);
}
offset_x = (scaledest * ((x1 + x2) / 2)) / scalesrc - (win_width / 2);
offset_y = (scaledest * ((y1 + y2) / 2)) / scalesrc - (win_height / 2);
gimp_display_shell_scale_by_values (shell, gimp_display_shell_scale_by_values (shell,
(scaledest << 8) + scalesrc, (scaledest << 8) + scalesrc,
((scaledest * ((x1 + x2) / 2)) / scalesrc - offset_x, offset_y,
(win_width / 2)),
((scaledest * ((y1 + y2) / 2)) / scalesrc -
(win_height / 2)),
options->allow_resize); options->allow_resize);
} }
} }
@ -369,37 +375,3 @@ gimp_magnify_tool_draw (GimpDrawTool *draw_tool)
magnify->h, magnify->h,
FALSE); FALSE);
} }
/* magnify utility functions */
static void
zoom_in (gint *src,
gint *dest,
gint scale)
{
while (scale--)
{
if (*src > 1)
(*src)--;
else
if (*dest < 0x10)
(*dest)++;
}
}
static void
zoom_out (gint *src,
gint *dest,
gint scale)
{
while (scale--)
{
if (*dest > 1)
(*dest)--;
else
if (*src < 0x10)
(*src)++;
}
}

View File

@ -38,10 +38,8 @@ struct _GimpMagnifyTool
{ {
GimpDrawTool parent_instance; GimpDrawTool parent_instance;
gint x, y; /* upper left hand coordinate */ gint x, y; /* upper left hand coordinate */
gint w, h; /* width and height */ gint w, h; /* width and height */
GimpZoomType op; /* magnify operation */
}; };
struct _GimpMagnifyToolClass struct _GimpMagnifyToolClass