summaryrefslogtreecommitdiffstats
path: root/app/display/gimpdisplayshell-utils.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--app/display/gimpdisplayshell-utils.c220
1 files changed, 220 insertions, 0 deletions
diff --git a/app/display/gimpdisplayshell-utils.c b/app/display/gimpdisplayshell-utils.c
new file mode 100644
index 0000000..8e85e71
--- /dev/null
+++ b/app/display/gimpdisplayshell-utils.c
@@ -0,0 +1,220 @@
+/* GIMP - The GNU Image Manipulation Program
+ * Copyright (C) 1995 Spencer Kimball and Peter Mattis
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+#include "config.h"
+
+#include <gegl.h>
+#include <gtk/gtk.h>
+
+#include "libgimpbase/gimpbase.h"
+#include "libgimpmath/gimpmath.h"
+
+#include "display-types.h"
+
+#include "core/gimp-utils.h"
+#include "core/gimpimage.h"
+#include "core/gimpunit.h"
+
+#include "gimpdisplay.h"
+#include "gimpdisplayshell.h"
+#include "gimpdisplayshell-utils.h"
+
+#include "gimp-intl.h"
+
+void
+gimp_display_shell_get_constrained_line_params (GimpDisplayShell *shell,
+ gdouble *offset_angle,
+ gdouble *xres,
+ gdouble *yres)
+{
+ 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)
+ *offset_angle = +shell->rotate_angle;
+ else
+ *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
+gimp_display_shell_constrain_line (GimpDisplayShell *shell,
+ gdouble start_x,
+ gdouble start_y,
+ gdouble *end_x,
+ 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,
+ offset_angle,
+ xres, yres);
+}
+
+gdouble
+gimp_display_shell_constrain_angle (GimpDisplayShell *shell,
+ gdouble angle,
+ gint n_snap_lines)
+{
+ gdouble x, y;
+
+ g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), 0.0);
+
+ x = cos (angle);
+ y = sin (angle);
+
+ gimp_display_shell_constrain_line (shell,
+ 0.0, 0.0,
+ &x, &y,
+ n_snap_lines);
+
+ return atan2 (y, x);
+}
+
+/**
+ * gimp_display_shell_get_line_status:
+ * @status: initial status text.
+ * @separator: separator text between the line information and @status.
+ * @shell: #GimpDisplayShell this status text will be displayed for.
+ * @x1: abscissa of first point.
+ * @y1: ordinate of first point.
+ * @x2: abscissa of second point.
+ * @y2: ordinate of second point.
+ *
+ * Utility function to prepend the status message with a distance and
+ * angle value. Obviously this is only to be used for tools when it
+ * makes sense, and in particular when there is a concept of line. For
+ * instance when shift-clicking a painting tool or in the blend tool,
+ * etc.
+ * This utility prevents code duplication but also ensures a common
+ * display for every tool where such a status is needed. It will take
+ * into account the shell unit settings and will use the ideal digit
+ * precision according to current image resolution.
+ *
+ * Return value: a newly allocated string containing the enhanced status.
+ **/
+gchar *
+gimp_display_shell_get_line_status (GimpDisplayShell *shell,
+ const gchar *status,
+ const gchar *separator,
+ gdouble x1,
+ gdouble y1,
+ gdouble x2,
+ gdouble y2)
+{
+ GimpImage *image;
+ gchar *enhanced_status;
+ gdouble xres;
+ gdouble yres;
+ gdouble dx, dy, pixel_dist;
+ gdouble angle;
+
+ image = gimp_display_get_image (shell->display);
+ if (! image)
+ {
+ /* This makes no sense to add line information when no image is
+ * attached to the display. */
+ return g_strdup (status);
+ }
+
+ if (shell->unit == GIMP_UNIT_PIXEL)
+ xres = yres = 1.0;
+ else
+ gimp_image_get_resolution (image, &xres, &yres);
+
+ dx = x2 - x1;
+ dy = y2 - y1;
+ pixel_dist = sqrt (SQR (dx) + SQR (dy));
+
+ if (dx)
+ {
+ angle = gimp_rad_to_deg (atan ((dy/yres) / (dx/xres)));
+ if (dx > 0)
+ {
+ if (dy > 0)
+ angle = 360.0 - angle;
+ else if (dy < 0)
+ angle = -angle;
+ }
+ else
+ {
+ angle = 180.0 - angle;
+ }
+ }
+ else if (dy)
+ {
+ angle = dy > 0 ? 270.0 : 90.0;
+ }
+ else
+ {
+ angle = 0.0;
+ }
+
+ if (shell->unit == GIMP_UNIT_PIXEL)
+ {
+ enhanced_status = g_strdup_printf ("%.1f %s, %.2f\302\260%s%s",
+ pixel_dist, _("pixels"), angle,
+ separator, status);
+ }
+ else
+ {
+ gdouble inch_dist;
+ gdouble unit_dist;
+ gint digits = 0;
+
+ /* The distance in unit. */
+ inch_dist = sqrt (SQR (dx / xres) + SQR (dy / yres));
+ unit_dist = gimp_unit_get_factor (shell->unit) * inch_dist;
+
+ /* The ideal digit precision for unit in current resolution. */
+ if (inch_dist)
+ digits = gimp_unit_get_scaled_digits (shell->unit,
+ pixel_dist / inch_dist);
+
+ enhanced_status = g_strdup_printf ("%.*f %s, %.2f\302\260%s%s",
+ digits, unit_dist,
+ gimp_unit_get_symbol (shell->unit),
+ angle, separator, status);
+
+ }
+
+ return enhanced_status;
+}