diff --git a/app/core/gimp-utils.c b/app/core/gimp-utils.c index c6726e80c0..ec9d2982c2 100644 --- a/app/core/gimp-utils.c +++ b/app/core/gimp-utils.c @@ -546,42 +546,6 @@ gimp_get_fill_params (GimpContext *context, return TRUE; } -/** - * gimp_utils_point_to_line_distance: - * @point: The point to calculate the distance for. - * @point_on_line: A point on the line. - * @line_direction: Normalized line direction vector. - * @closest_line_point: Gets set to the point on the line that is - * closest to @point. - * - * Returns: The shortest distance from @point to the line defined by - * @point_on_line and @normalized_line_direction. - **/ -static gdouble -gimp_utils_point_to_line_distance (const GimpVector2 *point, - const GimpVector2 *point_on_line, - const GimpVector2 *line_direction, - GimpVector2 *closest_line_point) -{ - GimpVector2 distance_vector; - GimpVector2 tmp_a; - GimpVector2 tmp_b; - gdouble d; - - gimp_vector2_sub (&tmp_a, point, point_on_line); - - d = gimp_vector2_inner_product (&tmp_a, line_direction); - - tmp_b = gimp_vector2_mul_val (*line_direction, d); - - *closest_line_point = gimp_vector2_add_val (*point_on_line, - tmp_b); - - gimp_vector2_sub (&distance_vector, closest_line_point, point); - - return gimp_vector2_length (&distance_vector); -} - /** * gimp_constrain_line: * @start_x: @@ -590,6 +554,8 @@ gimp_utils_point_to_line_distance (const GimpVector2 *point, * @end_y: * @n_snap_lines: Number evenly disributed lines to snap to. * @offset_angle: The angle by which to offset the lines, in degrees. + * @xres: The horizontal resolution. + * @yres: The vertical resolution. * * Projects a line onto the specified subset of evenly radially * distributed lines. @n_lines of 2 makes the line snap horizontally @@ -602,38 +568,29 @@ gimp_constrain_line (gdouble start_x, gdouble *end_x, gdouble *end_y, gint n_snap_lines, - gdouble offset_angle) + gdouble offset_angle, + gdouble xres, + gdouble yres) { - GimpVector2 line_point = { start_x, start_y }; - GimpVector2 point = { *end_x, *end_y }; - GimpVector2 constrained_point; - GimpVector2 line_dir; - gdouble shortest_dist_moved = G_MAXDOUBLE; - gdouble dist_moved; + GimpVector2 diff; + GimpVector2 dir; gdouble angle; - gint i; - for (i = 0; i < n_snap_lines; i++) - { - angle = i * G_PI / n_snap_lines; - angle += offset_angle * G_PI / 180.0; + offset_angle *= G_PI / 180.0; - gimp_vector2_set (&line_dir, - cos (angle), - sin (angle)); + diff.x = (*end_x - start_x) / xres; + diff.y = (*end_y - start_y) / yres; - dist_moved = gimp_utils_point_to_line_distance (&point, - &line_point, - &line_dir, - &constrained_point); - if (dist_moved < shortest_dist_moved) - { - shortest_dist_moved = dist_moved; + angle = (atan2 (diff.y, diff.x) - offset_angle) * n_snap_lines / G_PI; + angle = RINT (angle) * G_PI / n_snap_lines + offset_angle; - *end_x = constrained_point.x; - *end_y = constrained_point.y; - } - } + dir.x = cos (angle); + dir.y = sin (angle); + + gimp_vector2_mul (&dir, gimp_vector2_inner_product (&dir, &diff)); + + *end_x = start_x + dir.x * xres; + *end_y = start_y + dir.y * yres; } gint diff --git a/app/core/gimp-utils.h b/app/core/gimp-utils.h index 50868c898c..956216e82b 100644 --- a/app/core/gimp-utils.h +++ b/app/core/gimp-utils.h @@ -74,7 +74,9 @@ void gimp_constrain_line (gdouble start_x, gdouble *end_x, gdouble *end_y, gint n_snap_lines, - gdouble offset_angle); + gdouble offset_angle, + gdouble xres, + gdouble yres); gint gimp_file_compare (GFile *file1, GFile *file2); diff --git a/app/display/gimpdisplayshell-utils.c b/app/display/gimpdisplayshell-utils.c index 88719a6616..1d4854f93f 100644 --- a/app/display/gimpdisplayshell-utils.c +++ b/app/display/gimpdisplayshell-utils.c @@ -35,15 +35,32 @@ #include "gimp-intl.h" -gdouble -gimp_display_shell_get_constrained_line_offset_angle (GimpDisplayShell *shell) +void +gimp_display_shell_get_constrained_line_params (GimpDisplayShell *shell, + gdouble *offset_angle, + gdouble *xres, + gdouble *yres) { - g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), 0.0); + 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) - return +shell->rotate_angle; + *offset_angle = +shell->rotate_angle; else - return -shell->rotate_angle; + *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); + } } void @@ -54,14 +71,22 @@ gimp_display_shell_constrain_line (GimpDisplayShell *shell, 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, - gimp_display_shell_get_constrained_line_offset_angle (shell)); + offset_angle, + xres, yres); } /** diff --git a/app/display/gimpdisplayshell-utils.h b/app/display/gimpdisplayshell-utils.h index 254815fd0a..d397ed6a18 100644 --- a/app/display/gimpdisplayshell-utils.h +++ b/app/display/gimpdisplayshell-utils.h @@ -19,20 +19,23 @@ #define __GIMP_DISPLAY_SHELL_UTILS_H__ -gdouble gimp_display_shell_get_constrained_line_offset_angle (GimpDisplayShell *shell); -void gimp_display_shell_constrain_line (GimpDisplayShell *shell, - gdouble start_x, - gdouble start_y, - gdouble *end_x, - gdouble *end_y, - gint n_snap_lines); -gchar * gimp_display_shell_get_line_status (GimpDisplayShell *shell, - const gchar *status, - const gchar *separator, - gdouble x1, - gdouble y1, - gdouble x2, - gdouble y2); +void gimp_display_shell_get_constrained_line_params (GimpDisplayShell *shell, + gdouble *offset_angle, + gdouble *xres, + gdouble *yres); +void gimp_display_shell_constrain_line (GimpDisplayShell *shell, + gdouble start_x, + gdouble start_y, + gdouble *end_x, + gdouble *end_y, + gint n_snap_lines); +gchar * gimp_display_shell_get_line_status (GimpDisplayShell *shell, + const gchar *status, + const gchar *separator, + gdouble x1, + gdouble y1, + gdouble x2, + gdouble y2); #endif /* __GIMP_DISPLAY_SHELL_UTILS_H__ */ diff --git a/app/paint/gimppaintcore.c b/app/paint/gimppaintcore.c index 2ff8fd0fb6..ceedd16844 100644 --- a/app/paint/gimppaintcore.c +++ b/app/paint/gimppaintcore.c @@ -673,9 +673,12 @@ gimp_paint_core_get_last_coords (GimpPaintCore *core, /** * gimp_paint_core_round_line: - * @core: the #GimpPaintCore - * @options: the #GimpPaintOptions to use - * @constrain_15_degrees: the modifier state + * @core: the #GimpPaintCore + * @options: the #GimpPaintOptions to use + * @constrain_15_degrees: the modifier state + * @constrain_offset_angle: the angle by which to offset the lines, in degrees + * @constrain_xres: the horizontal resolution + * @constrain_yres: the vertical resolution * * Adjusts core->last_coords and core_cur_coords in preparation to * drawing a straight line. If @center_pixels is TRUE the endpoints @@ -689,7 +692,9 @@ void gimp_paint_core_round_line (GimpPaintCore *core, GimpPaintOptions *paint_options, gboolean constrain_15_degrees, - gdouble constrain_offset_angle) + gdouble constrain_offset_angle, + gdouble constrain_xres, + gdouble constrain_yres) { g_return_if_fail (GIMP_IS_PAINT_CORE (core)); g_return_if_fail (GIMP_IS_PAINT_OPTIONS (paint_options)); @@ -706,7 +711,8 @@ gimp_paint_core_round_line (GimpPaintCore *core, gimp_constrain_line (core->last_coords.x, core->last_coords.y, &core->cur_coords.x, &core->cur_coords.y, GIMP_CONSTRAIN_LINE_15_DEGREES, - constrain_offset_angle); + constrain_offset_angle, + constrain_xres, constrain_yres); } diff --git a/app/paint/gimppaintcore.h b/app/paint/gimppaintcore.h index ba788982fa..350c7b0d8b 100644 --- a/app/paint/gimppaintcore.h +++ b/app/paint/gimppaintcore.h @@ -160,7 +160,9 @@ void gimp_paint_core_get_last_coords (GimpPaintCore *core, void gimp_paint_core_round_line (GimpPaintCore *core, GimpPaintOptions *options, gboolean constrain_15_degrees, - gdouble constrain_offset_angle); + gdouble constrain_offset_angle, + gdouble constrain_xres, + gdouble constrain_yres); /* protected functions */ diff --git a/app/tools/gimpeditselectiontool.c b/app/tools/gimpeditselectiontool.c index cd39065e08..42332a1663 100644 --- a/app/tools/gimpeditselectiontool.c +++ b/app/tools/gimpeditselectiontool.c @@ -531,7 +531,7 @@ gimp_edit_selection_tool_update_motion (GimpEditSelectionTool *edit_select, { gimp_constrain_line (edit_select->start_x, edit_select->start_y, &new_x, &new_y, - GIMP_CONSTRAIN_LINE_45_DEGREES, 0.0); + GIMP_CONSTRAIN_LINE_45_DEGREES, 0.0, 1.0, 1.0); } gimp_edit_selection_tool_calc_coords (edit_select, image, diff --git a/app/tools/gimppainttool-paint.c b/app/tools/gimppainttool-paint.c index 39ce1ec1be..51fb4bce2e 100644 --- a/app/tools/gimppainttool-paint.c +++ b/app/tools/gimppainttool-paint.c @@ -289,13 +289,18 @@ gimp_paint_tool_paint_start (GimpPaintTool *paint_tool, } else if (paint_tool->draw_line) { + gdouble offset_angle; + gdouble xres, yres; + + gimp_display_shell_get_constrained_line_params (shell, + &offset_angle, + &xres, &yres); + /* If shift is down and this is not the first paint * stroke, then draw a line from the last coords to the pointer */ - gimp_paint_core_round_line ( - core, paint_options, - constrain, - gimp_display_shell_get_constrained_line_offset_angle (shell)); + gimp_paint_core_round_line (core, paint_options, + constrain, offset_angle, xres, yres); } /* Notify subclasses */ diff --git a/app/tools/gimppainttool.c b/app/tools/gimppainttool.c index ce85abef39..335904dfaa 100644 --- a/app/tools/gimppainttool.c +++ b/app/tools/gimppainttool.c @@ -570,11 +570,16 @@ gimp_paint_tool_oper_update (GimpTool *tool, * draw a line. */ gchar *status_help; + gdouble offset_angle; + gdouble xres, yres; - gimp_paint_core_round_line ( - core, paint_options, - (state & constrain_mask) != 0, - gimp_display_shell_get_constrained_line_offset_angle (shell)); + gimp_display_shell_get_constrained_line_params (shell, + &offset_angle, + &xres, &yres); + + gimp_paint_core_round_line (core, paint_options, + (state & constrain_mask) != 0, + offset_angle, xres, yres); status_help = gimp_suggest_modifiers (paint_tool->status_line, constrain_mask & ~state,