[gimp/gimp-2-10] app: fix line-angle constraint when xres != yres
- From: Ell <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/gimp-2-10] app: fix line-angle constraint when xres != yres
- Date: Sun, 15 Jul 2018 23:10:23 +0000 (UTC)
commit 4cb91320a4ba162c72bdc5866963cbafe9529a9a
Author: Ell <ell_se yahoo com>
Date: Sun Jul 15 17:58:55 2018 -0400
app: fix line-angle constraint when xres != yres
Fix gimp_constrain_line() and friends to properly constrain line
angles when the image's horizontal and vertical resolutions are
different, and dot-for-dot is disabled.
(cherry picked from commit 4fefab1798a1f1b29d9b94b1fa95fb249d233284)
app/core/gimp-utils.c | 85 +++++++++---------------------------
app/core/gimp-utils.h | 4 +-
app/display/gimpdisplayshell-utils.c | 37 +++++++++++++---
app/display/gimpdisplayshell-utils.h | 31 +++++++------
app/paint/gimppaintcore.c | 16 ++++---
app/paint/gimppaintcore.h | 4 +-
app/tools/gimpeditselectiontool.c | 2 +-
app/tools/gimppainttool-paint.c | 13 ++++--
app/tools/gimppainttool.c | 13 ++++--
9 files changed, 105 insertions(+), 100 deletions(-)
---
diff --git a/app/core/gimp-utils.c b/app/core/gimp-utils.c
index 625fce6ede..8be6c3c5d8 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;
-
- gimp_vector2_set (&line_dir,
- cos (angle),
- sin (angle));
-
- 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;
+ offset_angle *= G_PI / 180.0;
- *end_x = constrained_point.x;
- *end_y = constrained_point.y;
- }
- }
+ diff.x = (*end_x - start_x) / xres;
+ diff.y = (*end_y - start_y) / yres;
+
+ angle = (atan2 (diff.y, diff.x) - offset_angle) * n_snap_lines / G_PI;
+ angle = RINT (angle) * G_PI / n_snap_lines + offset_angle;
+
+ 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 8320f5492a..9c37a40e3e 100644
--- a/app/tools/gimpeditselectiontool.c
+++ b/app/tools/gimpeditselectiontool.c
@@ -530,7 +530,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,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]