Commit 9127a54d authored by Pedro Gimeno's avatar Pedro Gimeno Committed by Pedro Gimeno Fortea

Fixed several off-by-one problems in display:

2004-03-20  Pedro Gimeno  <pggimeno@wanadoo.es>

	Fixed several off-by-one problems in display:

	* app/display/gimpdisplayshell.h (PROJ_ROUND): New macro to apply
	to a float the same rounding method as the one used when rendering.
	(SCALEX, SCALEY): Use PROJ_ROUND instead of truncating.

	* app/display/gimpdisplayshell-transform.c
	(gimp_display_shell_transform_xy): Accept gdouble image coordinates
	even if the returned screen coordinates are integer. Use PROJ_ROUND
	instead of (gint) to apply proper rounding. Fixes bug #137566.

	* app/display/gimpdisplayshell-transform.h
	(gimp_display_shell_transform_xy): changed accordingly.

	* app/display/gimpdisplayshell-draw.c
	* app/tools/gimpdrawtool.c: make sure everywhere that PROJ_ROUND
	is used either directly or through gimp_display_shell_transform_xy,
	instead of using arbitrary rounding methods.
parent f97ae7d7
2004-03-20 Pedro Gimeno <pggimeno@wanadoo.es>
Fixed several off-by-one problems in display:
* app/display/gimpdisplayshell.h (PROJ_ROUND): New macro to apply
to a float the same rounding method as the one used when rendering.
(SCALEX, SCALEY): Use PROJ_ROUND instead of truncating.
* app/display/gimpdisplayshell-transform.c
(gimp_display_shell_transform_xy): Accept gdouble image coordinates
even if the returned screen coordinates are integer. Use PROJ_ROUND
instead of (gint) to apply proper rounding. Fixes bug #137566.
* app/display/gimpdisplayshell-transform.h
(gimp_display_shell_transform_xy): changed accordingly.
* app/display/gimpdisplayshell-draw.c
* app/tools/gimpdrawtool.c: make sure everywhere that PROJ_ROUND
is used either directly or through gimp_display_shell_transform_xy,
instead of using arbitrary rounding methods.
2004-03-20 Sven Neumann <sven@gimp.org>
* configure.in: set version number to 2.0.0, version string to
......@@ -259,7 +259,7 @@ gimp_display_shell_draw_vector (GimpDisplayShell *shell,
GimpCoords *coord;
GdkPoint *gdk_coords;
gint i;
gdouble sx, sy;
gint sx, sy;
gdk_coords = g_new (GdkPoint, coords->len);
......@@ -267,12 +267,12 @@ gimp_display_shell_draw_vector (GimpDisplayShell *shell,
{
coord = &g_array_index (coords, GimpCoords, i);
gimp_display_shell_transform_xy_f (shell,
coord->x, coord->y,
&sx, &sy,
FALSE);
gdk_coords[i].x = ROUND (sx);
gdk_coords[i].y = ROUND (sy);
gimp_display_shell_transform_xy (shell,
coord->x, coord->y,
&sx, &sy,
FALSE);
gdk_coords[i].x = sx;
gdk_coords[i].y = sy;
}
gimp_canvas_draw_lines (GIMP_CANVAS (shell->canvas),
......
......@@ -80,8 +80,8 @@ gimp_display_shell_untransform_coords (GimpDisplayShell *shell,
void
gimp_display_shell_transform_xy (GimpDisplayShell *shell,
gint x,
gint y,
gdouble x,
gdouble y,
gint *nx,
gint *ny,
gboolean use_offsets)
......@@ -103,11 +103,16 @@ gimp_display_shell_transform_xy (GimpDisplayShell *shell,
gimp_item_offsets (GIMP_ITEM (gimp_image_active_drawable (shell->gdisp->gimage)),
&offset_x, &offset_y);
*nx = (gint) (scalex * (x + offset_x) - shell->offset_x);
*ny = (gint) (scaley * (y + offset_y) - shell->offset_y);
x = (scalex * (x + offset_x) - shell->offset_x);
y = (scaley * (y + offset_y) - shell->offset_y);
*nx += shell->disp_xoffset;
*ny += shell->disp_yoffset;
/* The projected coordinates can easily overflow a gint in the case of big
images at high zoom levels, so we clamp them here to avoid problems. */
x = CLAMP (x, G_MININT, G_MAXINT);
y = CLAMP (y, G_MININT, G_MAXINT);
*nx = PROJ_ROUND (x) + shell->disp_xoffset;
*ny = PROJ_ROUND (y) + shell->disp_yoffset;
}
void
......
......@@ -28,8 +28,8 @@ void gimp_display_shell_untransform_coords (GimpDisplayShell *shell,
GimpCoords *image_coords);
void gimp_display_shell_transform_xy (GimpDisplayShell *shell,
gint x,
gint y,
gdouble x,
gdouble y,
gint *nx,
gint *ny,
gboolean use_offsets);
......
......@@ -27,6 +27,9 @@
#include "gui/gui-types.h"
/* Apply to a float the same rounding mode used in the renderer */
#define PROJ_ROUND(coord) ((gint) ceil (coord))
/* finding the effective screen resolution (double) */
#define SCREEN_XRES(s) (s->dot_for_dot ? \
s->gdisp->gimage->xresolution : s->monitor_xres)
......@@ -40,8 +43,8 @@
s->gdisp->gimage->yresolution)
/* scale values */
#define SCALEX(s,x) ((gint) (x * SCALEFACTOR_X(s)))
#define SCALEY(s,y) ((gint) (y * SCALEFACTOR_Y(s)))
#define SCALEX(s,x) PROJ_ROUND (x * SCALEFACTOR_X(s))
#define SCALEY(s,y) PROJ_ROUND (y * SCALEFACTOR_Y(s))
/* unscale values */
#define UNSCALEX(s,x) ((gint) (x / SCALEFACTOR_X(s)))
......
......@@ -401,25 +401,25 @@ gimp_draw_tool_draw_line (GimpDrawTool *draw_tool,
gboolean use_offsets)
{
GimpDisplayShell *shell;
gdouble tx1, ty1;
gdouble tx2, ty2;
gint tx1, ty1;
gint tx2, ty2;
g_return_if_fail (GIMP_IS_DRAW_TOOL (draw_tool));
shell = GIMP_DISPLAY_SHELL (draw_tool->gdisp->shell);
gimp_display_shell_transform_xy_f (shell,
x1, y1,
&tx1, &ty1,
use_offsets);
gimp_display_shell_transform_xy_f (shell,
x2, y2,
&tx2, &ty2,
use_offsets);
gimp_display_shell_transform_xy (shell,
x1, y1,
&tx1, &ty1,
use_offsets);
gimp_display_shell_transform_xy (shell,
x2, y2,
&tx2, &ty2,
use_offsets);
gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas), GIMP_CANVAS_STYLE_XOR,
RINT (tx1), RINT (ty1),
RINT (tx2), RINT (ty2));
tx1, ty1,
tx2, ty2);
}
void
......@@ -431,26 +431,26 @@ gimp_draw_tool_draw_dashed_line (GimpDrawTool *draw_tool,
gboolean use_offsets)
{
GimpDisplayShell *shell;
gdouble tx1, ty1;
gdouble tx2, ty2;
gint tx1, ty1;
gint tx2, ty2;
g_return_if_fail (GIMP_IS_DRAW_TOOL (draw_tool));
shell = GIMP_DISPLAY_SHELL (draw_tool->gdisp->shell);
gimp_display_shell_transform_xy_f (shell,
x1, y1,
&tx1, &ty1,
use_offsets);
gimp_display_shell_transform_xy_f (shell,
x2, y2,
&tx2, &ty2,
use_offsets);
gimp_display_shell_transform_xy (shell,
x1, y1,
&tx1, &ty1,
use_offsets);
gimp_display_shell_transform_xy (shell,
x2, y2,
&tx2, &ty2,
use_offsets);
gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas),
GIMP_CANVAS_STYLE_XOR_DASHED,
RINT (tx1), RINT (ty1),
RINT (tx2), RINT (ty2));
tx1, ty1,
tx2, ty2);
}
void
......@@ -463,27 +463,22 @@ gimp_draw_tool_draw_rectangle (GimpDrawTool *draw_tool,
gboolean use_offsets)
{
GimpDisplayShell *shell;
gdouble tx1, ty1;
gdouble tx2, ty2;
gint tx1, ty1;
gint tx2, ty2;
guint w, h;
g_return_if_fail (GIMP_IS_DRAW_TOOL (draw_tool));
shell = GIMP_DISPLAY_SHELL (draw_tool->gdisp->shell);
tx1 = MIN (x, x + width);
ty1 = MIN (y, y + height);
tx2 = MAX (x, x + width);
ty2 = MAX (y, y + height);
gimp_display_shell_transform_xy_f (shell,
tx1, ty1,
&tx1, &ty1,
use_offsets);
gimp_display_shell_transform_xy_f (shell,
tx2, ty2,
&tx2, &ty2,
use_offsets);
gimp_display_shell_transform_xy (shell,
MIN (x, x + width), MIN (y, y + height),
&tx1, &ty1,
use_offsets);
gimp_display_shell_transform_xy (shell,
MAX (x, x + width), MAX (y, y + height),
&tx2, &ty2,
use_offsets);
tx1 = CLAMP (tx1, -1, shell->disp_width + 1);
ty1 = CLAMP (ty1, -1, shell->disp_height + 1);
......@@ -492,14 +487,14 @@ gimp_draw_tool_draw_rectangle (GimpDrawTool *draw_tool,
tx2 -= tx1;
ty2 -= ty1;
w = (tx2 >= 0.0) ? RINT (tx2) : 0;
h = (ty2 >= 0.0) ? RINT (ty2) : 0;
w = MAX (0, tx2);
h = MAX (0, ty2);
if (w > 0 && h > 0)
gimp_canvas_draw_rectangle (GIMP_CANVAS (shell->canvas),
GIMP_CANVAS_STYLE_XOR,
filled,
RINT (tx1), RINT (ty1),
tx1, ty1,
w - 1, h - 1);
}
......@@ -515,32 +510,27 @@ gimp_draw_tool_draw_arc (GimpDrawTool *draw_tool,
gboolean use_offsets)
{
GimpDisplayShell *shell;
gdouble tx1, ty1;
gdouble tx2, ty2;
gint tx1, ty1;
gint tx2, ty2;
guint w, h;
g_return_if_fail (GIMP_IS_DRAW_TOOL (draw_tool));
shell = GIMP_DISPLAY_SHELL (draw_tool->gdisp->shell);
tx1 = MIN (x, x + width);
ty1 = MIN (y, y + height);
tx2 = MAX (x, x + width);
ty2 = MAX (y, y + height);
gimp_display_shell_transform_xy_f (shell,
tx1, ty1,
&tx1, &ty1,
use_offsets);
gimp_display_shell_transform_xy_f (shell,
tx2, ty2,
&tx2, &ty2,
use_offsets);
gimp_display_shell_transform_xy (shell,
MIN (x, x + width), MIN (y, y + height),
&tx1, &ty1,
use_offsets);
gimp_display_shell_transform_xy (shell,
MAX (x, x + width), MAX (y, y + height),
&tx2, &ty2,
use_offsets);
tx2 -= tx1;
ty2 -= ty1;
w = (tx2 >= 0.0) ? RINT (tx2) : 0;
h = (ty2 >= 0.0) ? RINT (ty2) : 0;
w = MAX (0, tx2);
h = MAX (0, ty2);
if (w > 0 && h > 0)
{
......@@ -549,7 +539,7 @@ gimp_draw_tool_draw_arc (GimpDrawTool *draw_tool,
gimp_canvas_draw_arc (GIMP_CANVAS (shell->canvas),
GIMP_CANVAS_STYLE_XOR,
filled,
RINT (tx1), RINT (ty1),
tx1, ty1,
w - 1, h - 1,
angle1, angle2);
}
......@@ -560,7 +550,7 @@ gimp_draw_tool_draw_arc (GimpDrawTool *draw_tool,
gimp_canvas_draw_rectangle (GIMP_CANVAS (shell->canvas),
GIMP_CANVAS_STYLE_XOR,
filled,
RINT (tx1), RINT (ty1),
tx1, ty1,
w - 1, h - 1);
}
}
......@@ -602,7 +592,7 @@ gimp_draw_tool_draw_rectangle_by_anchor (GimpDrawTool *draw_tool,
gimp_canvas_draw_rectangle (GIMP_CANVAS (shell->canvas),
GIMP_CANVAS_STYLE_XOR,
filled,
RINT (tx), RINT (ty),
PROJ_ROUND (tx), PROJ_ROUND (ty),
width, height);
}
......@@ -647,7 +637,7 @@ gimp_draw_tool_draw_arc_by_anchor (GimpDrawTool *draw_tool,
gimp_canvas_draw_arc (GIMP_CANVAS (shell->canvas), GIMP_CANVAS_STYLE_XOR,
filled,
RINT (tx), RINT (ty),
PROJ_ROUND (tx), PROJ_ROUND (ty),
radius_x, radius_y,
angle1, angle2);
}
......@@ -679,11 +669,11 @@ gimp_draw_tool_draw_cross_by_anchor (GimpDrawTool *draw_tool,
&tx, &ty);
gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas), GIMP_CANVAS_STYLE_XOR,
RINT (tx), RINT (ty) - (height >> 1),
RINT (tx), RINT (ty) + (height >> 1));
PROJ_ROUND (tx), PROJ_ROUND (ty) - (height >> 1),
PROJ_ROUND (tx), PROJ_ROUND (ty) + (height >> 1));
gimp_canvas_draw_line (GIMP_CANVAS (shell->canvas), GIMP_CANVAS_STYLE_XOR,
RINT (tx) - (width >> 1), RINT (ty),
RINT (tx) + (width >> 1), RINT (ty));
PROJ_ROUND (tx) - (width >> 1), PROJ_ROUND (ty),
PROJ_ROUND (tx) + (width >> 1), PROJ_ROUND (ty));
}
void
......@@ -1079,7 +1069,7 @@ gimp_draw_tool_draw_lines (GimpDrawTool *draw_tool,
GimpDisplayShell *shell;
GdkPoint *coords;
gint i;
gdouble sx, sy;
gint sx, sy;
g_return_if_fail (GIMP_IS_DRAW_TOOL (draw_tool));
......@@ -1089,12 +1079,12 @@ gimp_draw_tool_draw_lines (GimpDrawTool *draw_tool,
for (i = 0; i < n_points ; i++)
{
gimp_display_shell_transform_xy_f (shell,
points[i*2], points[i*2+1],
&sx, &sy,
use_offsets);
coords[i].x = ROUND (sx);
coords[i].y = ROUND (sy);
gimp_display_shell_transform_xy (shell,
points[i*2], points[i*2+1],
&sx, &sy,
use_offsets);
coords[i].x = sx;
coords[i].y = sy;
}
if (filled)
......@@ -1123,7 +1113,7 @@ gimp_draw_tool_draw_strokes (GimpDrawTool *draw_tool,
GimpDisplayShell *shell;
GdkPoint *coords;
gint i;
gdouble sx, sy;
gint sx, sy;
g_return_if_fail (GIMP_IS_DRAW_TOOL (draw_tool));
......@@ -1133,12 +1123,12 @@ gimp_draw_tool_draw_strokes (GimpDrawTool *draw_tool,
for (i = 0; i < n_points ; i++)
{
gimp_display_shell_transform_xy_f (shell,
points[i].x, points[i].y,
&sx, &sy,
use_offsets);
coords[i].x = ROUND (sx);
coords[i].y = ROUND (sy);
gimp_display_shell_transform_xy (shell,
points[i].x, points[i].y,
&sx, &sy,
use_offsets);
coords[i].x = sx;
coords[i].y = sy;
}
if (filled)
......@@ -1169,7 +1159,7 @@ gimp_draw_tool_draw_boundary (GimpDrawTool *draw_tool,
GdkSegment *gdk_segs;
gint n_gdk_segs;
gint xmax, ymax;
gdouble x, y;
gint x, y;
gint i;
g_return_if_fail (GIMP_IS_DRAW_TOOL (draw_tool));
......@@ -1185,23 +1175,23 @@ gimp_draw_tool_draw_boundary (GimpDrawTool *draw_tool,
for (i = 0; i < n_bound_segs; i++)
{
gimp_display_shell_transform_xy_f (shell,
bound_segs[i].x1 + offset_x,
bound_segs[i].y1 + offset_y,
&x, &y,
use_offsets);
gdk_segs[n_gdk_segs].x1 = RINT (CLAMP (x, -1, xmax));
gdk_segs[n_gdk_segs].y1 = RINT (CLAMP (y, -1, ymax));
gimp_display_shell_transform_xy_f (shell,
bound_segs[i].x2 + offset_x,
bound_segs[i].y2 + offset_y,
&x, &y,
use_offsets);
gdk_segs[n_gdk_segs].x2 = RINT (CLAMP (x, -1, xmax));
gdk_segs[n_gdk_segs].y2 = RINT (CLAMP (y, -1, ymax));
gimp_display_shell_transform_xy (shell,
bound_segs[i].x1 + offset_x,
bound_segs[i].y1 + offset_y,
&x, &y,
use_offsets);
gdk_segs[n_gdk_segs].x1 = CLAMP (x, -1, xmax);
gdk_segs[n_gdk_segs].y1 = CLAMP (y, -1, ymax);
gimp_display_shell_transform_xy (shell,
bound_segs[i].x2 + offset_x,
bound_segs[i].y2 + offset_y,
&x, &y,
use_offsets);
gdk_segs[n_gdk_segs].x2 = CLAMP (x, -1, xmax);
gdk_segs[n_gdk_segs].y2 = CLAMP (y, -1, ymax);
if (gdk_segs[n_gdk_segs].x1 == gdk_segs[n_gdk_segs].x2 &&
gdk_segs[n_gdk_segs].y1 == gdk_segs[n_gdk_segs].y2)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment