[gimp] app: round layer bounds to global pixel grid when scaling image/group
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: round layer bounds to global pixel grid when scaling image/group
- Date: Sun, 25 Mar 2018 15:48:50 +0000 (UTC)
commit 5763b50d452a52ffb7e9fc2ec30dcde7ba9b5957
Author: Ell <ell_se yahoo com>
Date: Sun Mar 25 11:20:14 2018 -0400
app: round layer bounds to global pixel grid when scaling image/group
Add gimp_item_scale_by_factors_with_origin(), which is an extension
of gimp_item_scale_by_factors(), taking the input/output points of
origin for the transformation (both of which are (0, 0) in the case
of gimp_item_scale_by_factors()). Implement
gimp_item_scale_by_factors() in terms of the new function, and Use
the new function when scaling group layers, instead of manually
calculating the children boundaries, so that the behavior is
uniform across whole-image scaling and group-layer scaling.
The new function rounds all four edges of the boundary to the
image-global pixel grid, instead of only rounding the top/left
edges to the global grid, and the bottom/right edges to the item-
local grid. This preserves layer-adjacency when scaling.
app/core/gimpgrouplayer.c | 46 ++++++++--------------
app/core/gimpitem.c | 93 +++++++++++++++++++++++++++++++++++----------
app/core/gimpitem.h | 10 +++++
3 files changed, 100 insertions(+), 49 deletions(-)
---
diff --git a/app/core/gimpgrouplayer.c b/app/core/gimpgrouplayer.c
index b78ecee..e81ba8e 100644
--- a/app/core/gimpgrouplayer.c
+++ b/app/core/gimpgrouplayer.c
@@ -810,42 +810,30 @@ gimp_group_layer_scale (GimpLayer *layer,
while (list)
{
GimpItem *child = list->data;
- gint child_width;
- gint child_height;
- gint child_offset_x;
- gint child_offset_y;
list = g_list_next (list);
if (queue)
gimp_object_queue_pop (queue);
- child_width = ROUND (width_factor * gimp_item_get_width (child));
- child_height = ROUND (height_factor * gimp_item_get_height (child));
- child_offset_x = ROUND (width_factor * (gimp_item_get_offset_x (child) -
- old_offset_x));
- child_offset_y = ROUND (height_factor * (gimp_item_get_offset_y (child) -
- old_offset_y));
-
- child_offset_x += new_offset_x;
- child_offset_y += new_offset_y;
-
- if (child_width > 0 && child_height > 0)
- {
- gimp_item_scale (child,
- child_width, child_height,
- child_offset_x, child_offset_y,
- interpolation_type, progress);
- }
- else if (gimp_item_is_attached (item))
+ if (! gimp_item_scale_by_factors_with_origin (child,
+ width_factor, height_factor,
+ old_offset_x, old_offset_y,
+ new_offset_x, new_offset_y,
+ interpolation_type,
+ progress))
{
- gimp_image_remove_layer (gimp_item_get_image (item),
- GIMP_LAYER (child),
- TRUE, NULL);
- }
- else
- {
- gimp_container_remove (private->children, GIMP_OBJECT (child));
+ /* new width or height are 0; remove item */
+ if (gimp_item_is_attached (item))
+ {
+ gimp_image_remove_layer (gimp_item_get_image (item),
+ GIMP_LAYER (child),
+ TRUE, NULL);
+ }
+ else
+ {
+ gimp_container_remove (private->children, GIMP_OBJECT (child));
+ }
}
}
diff --git a/app/core/gimpitem.c b/app/core/gimpitem.c
index 1fbf375..29dfbcc 100644
--- a/app/core/gimpitem.c
+++ b/app/core/gimpitem.c
@@ -1261,22 +1261,32 @@ gimp_item_check_scaling (GimpItem *item,
gint new_width,
gint new_height)
{
- GimpImage *image;
- gdouble img_scale_w;
- gdouble img_scale_h;
- gint new_item_width;
- gint new_item_height;
+ GimpItemPrivate *private;
+ GimpImage *image;
+ gdouble img_scale_w;
+ gdouble img_scale_h;
+ gint new_item_offset_x;
+ gint new_item_offset_y;
+ gint new_item_width;
+ gint new_item_height;
g_return_val_if_fail (GIMP_IS_ITEM (item), FALSE);
- image = gimp_item_get_image (item);
-
- img_scale_w = ((gdouble) new_width /
- (gdouble) gimp_image_get_width (image));
- img_scale_h = ((gdouble) new_height /
- (gdouble) gimp_image_get_height (image));
- new_item_width = ROUND (img_scale_w * (gdouble) gimp_item_get_width (item));
- new_item_height = ROUND (img_scale_h * (gdouble) gimp_item_get_height (item));
+ private = GET_PRIVATE (item);
+ image = gimp_item_get_image (item);
+
+ img_scale_w = ((gdouble) new_width /
+ (gdouble) gimp_image_get_width (image));
+ img_scale_h = ((gdouble) new_height /
+ (gdouble) gimp_image_get_height (image));
+ new_item_offset_x = SIGNED_ROUND (img_scale_w * private->offset_x);
+ new_item_offset_y = SIGNED_ROUND (img_scale_h * private->offset_y);
+ new_item_width = SIGNED_ROUND (img_scale_w * (private->offset_x +
+ gimp_item_get_width (item))) -
+ new_item_offset_x;
+ new_item_height = SIGNED_ROUND (img_scale_h * (private->offset_y +
+ gimp_item_get_height (item))) -
+ new_item_offset_y;
return (new_item_width > 0 && new_item_height > 0);
}
@@ -1360,6 +1370,41 @@ gimp_item_scale_by_factors (GimpItem *item,
GimpInterpolationType interpolation,
GimpProgress *progress)
{
+ return gimp_item_scale_by_factors_with_origin (item,
+ w_factor, h_factor,
+ 0, 0, 0, 0,
+ interpolation, progress);
+}
+
+/**
+ * gimp_item_scale_by_factors:
+ * @item: Item to be transformed by explicit width and height factors.
+ * @w_factor: scale factor to apply to width and horizontal offset
+ * @h_factor: scale factor to apply to height and vertical offset
+ * @origin_x: x-coordinate of the transformation input origin
+ * @origin_y: y-coordinate of the transformation input origin
+ * @new_origin_x: x-coordinate of the transformation output origin
+ * @new_origin_y: y-coordinate of the transformation output origin
+ * @interpolation:
+ * @progress:
+ *
+ * Same as gimp_item_scale_by_factors(), but with the option to specify
+ * custom input and output points of origin for the transformation.
+ *
+ * Returns: #TRUE, if the scaled item has positive dimensions
+ * #FALSE if the scaled item has at least one zero dimension
+ **/
+gboolean
+gimp_item_scale_by_factors_with_origin (GimpItem *item,
+ gdouble w_factor,
+ gdouble h_factor,
+ gint origin_x,
+ gint origin_y,
+ gint new_origin_x,
+ gint new_origin_y,
+ GimpInterpolationType interpolation,
+ GimpProgress *progress)
+{
GimpItemPrivate *private;
gint new_width, new_height;
gint new_offset_x, new_offset_y;
@@ -1369,18 +1414,26 @@ gimp_item_scale_by_factors (GimpItem *item,
private = GET_PRIVATE (item);
- if (w_factor == 0.0 || h_factor == 0.0)
+ if (w_factor <= 0.0 || h_factor <= 0.0)
{
- g_warning ("%s: requested width or height scale equals zero", G_STRFUNC);
+ g_warning ("%s: requested width or height scale is non-positive",
+ G_STRFUNC);
return FALSE;
}
- new_offset_x = SIGNED_ROUND (w_factor * (gdouble) private->offset_x);
- new_offset_y = SIGNED_ROUND (h_factor * (gdouble) private->offset_y);
- new_width = ROUND (w_factor * (gdouble) gimp_item_get_width (item));
- new_height = ROUND (h_factor * (gdouble) gimp_item_get_height (item));
+ new_offset_x = SIGNED_ROUND (w_factor * (private->offset_x - origin_x));
+ new_offset_y = SIGNED_ROUND (h_factor * (private->offset_y - origin_y));
+ new_width = SIGNED_ROUND (w_factor * (private->offset_x - origin_x +
+ gimp_item_get_width (item))) -
+ new_offset_x;
+ new_height = SIGNED_ROUND (h_factor * (private->offset_y - origin_y +
+ gimp_item_get_height (item))) -
+ new_offset_y;
+
+ new_offset_x += new_origin_x;
+ new_offset_y += new_origin_y;
- if (new_width != 0 && new_height != 0)
+ if (new_width > 0 && new_height > 0)
{
gimp_item_scale (item,
new_width, new_height,
diff --git a/app/core/gimpitem.h b/app/core/gimpitem.h
index b9023cf..783d07a 100644
--- a/app/core/gimpitem.h
+++ b/app/core/gimpitem.h
@@ -236,6 +236,16 @@ gboolean gimp_item_scale_by_factors (GimpItem *item,
gdouble h_factor,
GimpInterpolationType interpolation,
GimpProgress *progress);
+gboolean
+ gimp_item_scale_by_factors_with_origin (GimpItem *item,
+ gdouble w_factor,
+ gdouble h_factor,
+ gint origin_x,
+ gint origin_y,
+ gint new_origin_x,
+ gint new_origin_y,
+ GimpInterpolationType interpolation,
+ GimpProgress *progress);
void gimp_item_scale_by_origin (GimpItem *item,
gint new_width,
gint new_height,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]