[gimp] app: add support for subpixel image grids
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add support for subpixel image grids
- Date: Sun, 19 Feb 2017 23:15:29 +0000 (UTC)
commit 1572bccc9f1f781b720bb030730f34a1f59c498b
Author: Ell <ell_se yahoo com>
Date: Sun Feb 19 18:03:02 2017 -0500
app: add support for subpixel image grids
In particular, this enables grids whose points of intersection
are at the middle of the image's pixels, which is useful for
undistorted painting with odd-sized brushes using tools other than
the pencil.
This commit also changes the grid visibility behavior, so that the
the visibiltiy of horizontal and vertical grid lines (depending on
the zoom level) is independent.
app/core/gimpgrid.c | 14 ++--
app/core/gimpimage-snap.c | 56 ++++++---------
app/display/gimpcanvasgrid.c | 162 +++++++++++++++++++++++-------------------
app/widgets/gimpgrideditor.c | 14 +++-
4 files changed, 126 insertions(+), 120 deletions(-)
---
diff --git a/app/core/gimpgrid.c b/app/core/gimpgrid.c
index 3b8109a..7893a02 100644
--- a/app/core/gimpgrid.c
+++ b/app/core/gimpgrid.c
@@ -108,14 +108,14 @@ gimp_grid_class_init (GimpGridClass *klass)
"xspacing",
_("Spacing X"),
_("Horizontal spacing of grid lines."),
- 1.0, GIMP_MAX_IMAGE_SIZE, 10.0,
+ 0.0, GIMP_MAX_IMAGE_SIZE, 10.0,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_DOUBLE (object_class, PROP_YSPACING,
"yspacing",
_("Spacing Y"),
_("Vertical spacing of grid lines."),
- 1.0, GIMP_MAX_IMAGE_SIZE, 10.0,
+ 0.0, GIMP_MAX_IMAGE_SIZE, 10.0,
GIMP_PARAM_STATIC_STRINGS);
GIMP_CONFIG_PROP_UNIT (object_class, PROP_SPACING_UNIT,
@@ -283,9 +283,8 @@ gimp_grid_get_spacing (GimpGrid *grid,
{
g_return_if_fail (GIMP_IS_GRID (grid));
- /* FIXME subpixel grid */
- if (xspacing) *xspacing = RINT (grid->xspacing);
- if (yspacing) *yspacing = RINT (grid->yspacing);
+ if (xspacing) *xspacing = grid->xspacing;
+ if (yspacing) *yspacing = grid->yspacing;
}
void
@@ -295,9 +294,8 @@ gimp_grid_get_offset (GimpGrid *grid,
{
g_return_if_fail (GIMP_IS_GRID (grid));
- /* FIXME subpixel grid */
- if (xoffset) *xoffset = RINT (grid->xoffset);
- if (yoffset) *yoffset = RINT (grid->yoffset);
+ if (xoffset) *xoffset = grid->xoffset;
+ if (yoffset) *yoffset = grid->yoffset;
}
const gchar *
diff --git a/app/core/gimpimage-snap.c b/app/core/gimpimage-snap.c
index 5934704..4e67ae6 100644
--- a/app/core/gimpimage-snap.c
+++ b/app/core/gimpimage-snap.c
@@ -100,21 +100,17 @@ gimp_image_snap_x (GimpImage *image,
GimpGrid *grid = gimp_image_get_grid (image);
gdouble xspacing;
gdouble xoffset;
- gdouble i;
gimp_grid_get_spacing (grid, &xspacing, NULL);
gimp_grid_get_offset (grid, &xoffset, NULL);
- /* the snap-to-grid part could probably be rewritten */
- while (xoffset > xspacing)
- xoffset -= xspacing;
-
- for (i = xoffset; i <= gimp_image_get_width (image); i += xspacing)
+ if (xspacing > 0.0)
{
- if (i < 0)
- continue;
+ gdouble nearest;
+
+ nearest = xoffset + RINT ((x - xoffset) / xspacing) * xspacing;
- snapped |= gimp_image_snap_distance (x, i,
+ snapped |= gimp_image_snap_distance (x, nearest,
epsilon_x,
&mindist, tx);
}
@@ -183,22 +179,19 @@ gimp_image_snap_y (GimpImage *image,
if (snap_to_grid)
{
GimpGrid *grid = gimp_image_get_grid (image);
- gdouble yspacing;
- gdouble yoffset;
- gdouble i;
+ gdouble yspacing;
+ gdouble yoffset;
gimp_grid_get_spacing (grid, NULL, &yspacing);
gimp_grid_get_offset (grid, NULL, &yoffset);
- while (yoffset > yspacing)
- yoffset -= yspacing;
-
- for (i = yoffset; i <= gimp_image_get_height (image); i += yspacing)
+ if (yspacing > 0.0)
{
- if (i < 0)
- continue;
+ gdouble nearest;
+
+ nearest = yoffset + RINT ((y - yoffset) / yspacing) * yspacing;
- snapped |= gimp_image_snap_distance (y, i,
+ snapped |= gimp_image_snap_distance (y, nearest,
epsilon_y,
&mindist, ty);
}
@@ -291,33 +284,28 @@ gimp_image_snap_point (GimpImage *image,
GimpGrid *grid = gimp_image_get_grid (image);
gdouble xspacing, yspacing;
gdouble xoffset, yoffset;
- gdouble i;
gimp_grid_get_spacing (grid, &xspacing, &yspacing);
gimp_grid_get_offset (grid, &xoffset, &yoffset);
- while (xoffset > xspacing)
- xoffset -= xspacing;
-
- while (yoffset > yspacing)
- yoffset -= yspacing;
-
- for (i = xoffset; i <= gimp_image_get_width (image); i += xspacing)
+ if (xspacing > 0.0)
{
- if (i < 0)
- continue;
+ gdouble nearest;
- snapped |= gimp_image_snap_distance (x, i,
+ nearest = xoffset + RINT ((x - xoffset) / xspacing) * xspacing;
+
+ snapped |= gimp_image_snap_distance (x, nearest,
epsilon_x,
&mindist_x, tx);
}
- for (i = yoffset; i <= gimp_image_get_height (image); i += yspacing)
+ if (yspacing > 0.0)
{
- if (i < 0)
- continue;
+ gdouble nearest;
+
+ nearest = yoffset + RINT ((y - yoffset) / yspacing) * yspacing;
- snapped |= gimp_image_snap_distance (y, i,
+ snapped |= gimp_image_snap_distance (y, nearest,
epsilon_y,
&mindist_y, ty);
}
diff --git a/app/display/gimpcanvasgrid.c b/app/display/gimpcanvasgrid.c
index ed32977..0a7bada 100644
--- a/app/display/gimpcanvasgrid.c
+++ b/app/display/gimpcanvasgrid.c
@@ -20,6 +20,8 @@
#include "config.h"
+#include <math.h>
+
#include <gegl.h>
#include <gtk/gtk.h>
@@ -191,6 +193,7 @@ gimp_canvas_grid_draw (GimpCanvasItem *item,
GimpImage *image = gimp_canvas_item_get_image (item);
gdouble xspacing, yspacing;
gdouble xoffset, yoffset;
+ gboolean vert, horz;
gdouble x, y;
gdouble dx1, dy1, dx2, dy2;
gint x0, x1, x2, x3;
@@ -203,14 +206,16 @@ gimp_canvas_grid_draw (GimpCanvasItem *item,
gimp_grid_get_spacing (private->grid, &xspacing, &yspacing);
gimp_grid_get_offset (private->grid, &xoffset, &yoffset);
- g_return_if_fail (xspacing > 0.0 &&
- yspacing > 0.0);
+ g_return_if_fail (xspacing >= 0.0 &&
+ yspacing >= 0.0);
/* skip grid drawing when the space between grid lines starts
* disappearing, see bug #599267.
*/
- if (xspacing * shell->scale_x < 2.0 ||
- yspacing * shell->scale_y < 2.0)
+ vert = (xspacing * shell->scale_x >= 2.0);
+ horz = (yspacing * shell->scale_y >= 2.0);
+
+ if (! vert && ! horz)
return;
cairo_clip_extents (cr, &dx1, &dy1, &dx2, &dy2);
@@ -223,84 +228,87 @@ gimp_canvas_grid_draw (GimpCanvasItem *item,
width = gimp_image_get_width (image);
height = gimp_image_get_height (image);
- while (xoffset > 0)
- xoffset -= xspacing;
-
- while (yoffset > 0)
- yoffset -= yspacing;
+ xoffset = fmod (xoffset, xspacing);
+ yoffset = fmod (yoffset, yspacing);
switch (gimp_grid_get_style (private->grid))
{
case GIMP_GRID_DOTS:
- for (x = xoffset; x <= width; x += xspacing)
+ if (vert && horz)
{
- if (x < 0)
- continue;
-
- gimp_canvas_item_transform_xy (item, x, 0, &x_real, &y_real);
-
- if (x_real < x1 || x_real >= x2)
- continue;
-
- for (y = yoffset; y <= height; y += yspacing)
+ for (x = xoffset; x <= width; x += xspacing)
{
- if (y < 0)
+ if (x < 0)
continue;
- gimp_canvas_item_transform_xy (item, x, y, &x_real, &y_real);
+ gimp_canvas_item_transform_xy (item, x, 0, &x_real, &y_real);
- if (y_real >= y1 && y_real < y2)
+ if (x_real < x1 || x_real >= x2)
+ continue;
+
+ for (y = yoffset; y <= height; y += yspacing)
{
- cairo_move_to (cr, x_real, y_real + 0.5);
- cairo_line_to (cr, x_real + 1, y_real + 0.5);
+ if (y < 0)
+ continue;
+
+ gimp_canvas_item_transform_xy (item, x, y, &x_real, &y_real);
+
+ if (y_real >= y1 && y_real < y2)
+ {
+ cairo_move_to (cr, x_real, y_real + 0.5);
+ cairo_line_to (cr, x_real + 1, y_real + 0.5);
+ }
}
}
}
break;
case GIMP_GRID_INTERSECTIONS:
- for (x = xoffset; x <= width; x += xspacing)
+ if (vert && horz)
{
- if (x < 0)
- continue;
-
- gimp_canvas_item_transform_xy (item, x, 0, &x_real, &y_real);
-
- if (x_real + CROSSHAIR < x1 || x_real - CROSSHAIR >= x2)
- continue;
-
- for (y = yoffset; y <= height; y += yspacing)
+ for (x = xoffset; x <= width; x += xspacing)
{
- if (y < 0)
+ if (x < 0)
continue;
- gimp_canvas_item_transform_xy (item, x, y, &x_real, &y_real);
+ gimp_canvas_item_transform_xy (item, x, 0, &x_real, &y_real);
- if (y_real + CROSSHAIR < y1 || y_real - CROSSHAIR >= y2)
+ if (x_real + CROSSHAIR < x1 || x_real - CROSSHAIR >= x2)
continue;
- if (x_real >= x1 && x_real < x2)
- {
- cairo_move_to (cr,
- x_real + 0.5,
- CLAMP (y_real - CROSSHAIR,
- y1, y2 - 1));
- cairo_line_to (cr,
- x_real + 0.5,
- CLAMP (y_real + CROSSHAIR,
- y1, y2 - 1) + 1);
- }
-
- if (y_real >= y1 && y_real < y2)
+ for (y = yoffset; y <= height; y += yspacing)
{
- cairo_move_to (cr,
- CLAMP (x_real - CROSSHAIR,
- x1, x2 - 1),
- y_real + 0.5);
- cairo_line_to (cr,
- CLAMP (x_real + CROSSHAIR,
- x1, x2 - 1) + 1,
- y_real + 0.5);
+ if (y < 0)
+ continue;
+
+ gimp_canvas_item_transform_xy (item, x, y, &x_real, &y_real);
+
+ if (y_real + CROSSHAIR < y1 || y_real - CROSSHAIR >= y2)
+ continue;
+
+ if (x_real >= x1 && x_real < x2)
+ {
+ cairo_move_to (cr,
+ x_real + 0.5,
+ CLAMP (y_real - CROSSHAIR,
+ y1, y2 - 1));
+ cairo_line_to (cr,
+ x_real + 0.5,
+ CLAMP (y_real + CROSSHAIR,
+ y1, y2 - 1) + 1);
+ }
+
+ if (y_real >= y1 && y_real < y2)
+ {
+ cairo_move_to (cr,
+ CLAMP (x_real - CROSSHAIR,
+ x1, x2 - 1),
+ y_real + 0.5);
+ cairo_line_to (cr,
+ CLAMP (x_real + CROSSHAIR,
+ x1, x2 - 1) + 1,
+ y_real + 0.5);
+ }
}
}
}
@@ -312,31 +320,37 @@ gimp_canvas_grid_draw (GimpCanvasItem *item,
gimp_canvas_item_transform_xy (item, 0, 0, &x0, &y0);
gimp_canvas_item_transform_xy (item, width, height, &x3, &y3);
- for (x = xoffset; x < width; x += xspacing)
+ if (vert)
{
- if (x < 0)
- continue;
+ for (x = xoffset; x < width; x += xspacing)
+ {
+ if (x < 0)
+ continue;
- gimp_canvas_item_transform_xy (item, x, 0, &x_real, &y_real);
+ gimp_canvas_item_transform_xy (item, x, 0, &x_real, &y_real);
- if (x_real >= x1 && x_real < x2)
- {
- cairo_move_to (cr, x_real + 0.5, y0);
- cairo_line_to (cr, x_real + 0.5, y3 + 1);
+ if (x_real >= x1 && x_real < x2)
+ {
+ cairo_move_to (cr, x_real + 0.5, y0);
+ cairo_line_to (cr, x_real + 0.5, y3 + 1);
+ }
}
}
- for (y = yoffset; y < height; y += yspacing)
+ if (horz)
{
- if (y < 0)
- continue;
+ for (y = yoffset; y < height; y += yspacing)
+ {
+ if (y < 0)
+ continue;
- gimp_canvas_item_transform_xy (item, 0, y, &x_real, &y_real);
+ gimp_canvas_item_transform_xy (item, 0, y, &x_real, &y_real);
- if (y_real >= y1 && y_real < y2)
- {
- cairo_move_to (cr, x0, y_real + 0.5);
- cairo_line_to (cr, x3 + 1, y_real + 0.5);
+ if (y_real >= y1 && y_real < y2)
+ {
+ cairo_move_to (cr, x0, y_real + 0.5);
+ cairo_line_to (cr, x3 + 1, y_real + 0.5);
+ }
}
}
break;
diff --git a/app/widgets/gimpgrideditor.c b/app/widgets/gimpgrideditor.c
index 1895127..0ba5406 100644
--- a/app/widgets/gimpgrideditor.c
+++ b/app/widgets/gimpgrideditor.c
@@ -192,12 +192,15 @@ gimp_grid_editor_constructed (GObject *object)
gtk_table_set_row_spacings (GTK_TABLE (sizeentry), 2);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (sizeentry),
- _("Width"), 0, 1, 0.0);
+ _("Horizontal"), 0, 1, 0.0);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (sizeentry),
- _("Height"), 0, 2, 0.0);
+ _("Vertical"), 0, 2, 0.0);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (sizeentry),
_("Pixels"), 1, 4, 0.0);
+ gimp_size_entry_set_refval_digits (GIMP_SIZE_ENTRY (sizeentry), 0, 2);
+ gimp_size_entry_set_refval_digits (GIMP_SIZE_ENTRY (sizeentry), 1, 2);
+
gtk_box_pack_start (GTK_BOX (hbox), sizeentry, FALSE, FALSE, 0);
gtk_widget_show (sizeentry);
@@ -224,12 +227,15 @@ gimp_grid_editor_constructed (GObject *object)
gtk_table_set_row_spacings (GTK_TABLE (sizeentry), 2);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (sizeentry),
- _("Width"), 0, 1, 0.0);
+ _("Horizontal"), 0, 1, 0.0);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (sizeentry),
- _("Height"), 0, 2, 0.0);
+ _("Vertical"), 0, 2, 0.0);
gimp_size_entry_attach_label (GIMP_SIZE_ENTRY (sizeentry),
_("Pixels"), 1, 4, 0.0);
+ gimp_size_entry_set_refval_digits (GIMP_SIZE_ENTRY (sizeentry), 0, 2);
+ gimp_size_entry_set_refval_digits (GIMP_SIZE_ENTRY (sizeentry), 1, 2);
+
gtk_box_pack_start (GTK_BOX (hbox), sizeentry, FALSE, FALSE, 0);
gtk_widget_show (sizeentry);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]