[gimp] app: add virtual transform/type-conversion functions to GimpLayer
- From: N/A <ell src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp] app: add virtual transform/type-conversion functions to GimpLayer
- Date: Sat, 17 Jun 2017 17:45:55 +0000 (UTC)
commit c83f0e88afa5575d7b19873175a98c9b2622719c
Author: Ell <ell_se yahoo com>
Date: Fri Jun 16 20:15:56 2017 -0400
app: add virtual transform/type-conversion functions to GimpLayer
The GimpLayer implementation of the GimpItem transform functions,
and the GimpDrawable convert_type() function, apply their operation
to both the layer and its mask. The subclasses of GimpLayer --
GimpGroupLayer and GimpTextLayer -- override some of these
functions, providing their own logic for the layer part, and
duplicating the mask part.
Avoid this duplication by adding a set of virtual transform and
type-conversion functions to GimpLayer. Have the GimpLayer
implementaion of the corresponding GimpItem and GimpDrawable
functions use these functions to apply the operation to the layer,
while taking care of the mask themselves. Have GimpLayer's
subclasses override the new virtual functions, instead of the
GimpItem and GimpDrawable ones.
Note that the existing implementation of convert_type() in
GimpTextLayer neglected to convert the mask, hence text layer masks
retained their old format after conversion. This issue is fixed as
a side effect of this commit.
app/core/gimpgrouplayer.c | 269 ++++++++++++++-----------------------
app/core/gimplayer.c | 322 +++++++++++++++++++++++++++++++++------------
app/core/gimplayer.h | 67 ++++++++--
app/text/gimptextlayer.c | 97 +++++++-------
4 files changed, 442 insertions(+), 313 deletions(-)
---
diff --git a/app/core/gimpgrouplayer.c b/app/core/gimpgrouplayer.c
index 2be8de7..331e872 100644
--- a/app/core/gimpgrouplayer.c
+++ b/app/core/gimpgrouplayer.c
@@ -96,48 +96,48 @@ static GimpItem * gimp_group_layer_duplicate (GimpItem *item,
static void gimp_group_layer_convert (GimpItem *item,
GimpImage *dest_image,
GType old_type);
-static void gimp_group_layer_translate (GimpItem *item,
+
+static gint64 gimp_group_layer_estimate_memsize (GimpDrawable *drawable,
+ GimpComponentType component_type,
+ gint width,
+ gint height);
+
+static void gimp_group_layer_translate (GimpLayer *layer,
gint offset_x,
- gint offset_y,
- gboolean push_undo);
-static void gimp_group_layer_scale (GimpItem *item,
+ gint offset_y);
+static void gimp_group_layer_scale (GimpLayer *layer,
gint new_width,
gint new_height,
gint new_offset_x,
gint new_offset_y,
GimpInterpolationType interp_type,
GimpProgress *progress);
-static void gimp_group_layer_resize (GimpItem *item,
+static void gimp_group_layer_resize (GimpLayer *layer,
GimpContext *context,
GimpFillType fill_type,
gint new_width,
gint new_height,
gint offset_x,
gint offset_y);
-static void gimp_group_layer_flip (GimpItem *item,
+static void gimp_group_layer_flip (GimpLayer *layer,
GimpContext *context,
GimpOrientationType flip_type,
gdouble axis,
gboolean clip_result);
-static void gimp_group_layer_rotate (GimpItem *item,
+static void gimp_group_layer_rotate (GimpLayer *layer,
GimpContext *context,
GimpRotationType rotate_type,
gdouble center_x,
gdouble center_y,
gboolean clip_result);
-static void gimp_group_layer_transform (GimpItem *item,
+static void gimp_group_layer_transform (GimpLayer *layer,
GimpContext *context,
const GimpMatrix3 *matrix,
GimpTransformDirection direction,
GimpInterpolationType interpolation_type,
GimpTransformResize clip_result,
- GimpProgress *progress);
-
-static gint64 gimp_group_layer_estimate_memsize (GimpDrawable *drawable,
- GimpComponentType component_type,
- gint width,
- gint height);
-static void gimp_group_layer_convert_type (GimpDrawable *drawable,
+ GimpProgress *progress);
+static void gimp_group_layer_convert_type (GimpLayer *layer,
GimpImage *dest_image,
const Babl *new_format,
GimpColorProfile *dest_profile,
@@ -201,6 +201,7 @@ gimp_group_layer_class_init (GimpGroupLayerClass *klass)
GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
GimpItemClass *item_class = GIMP_ITEM_CLASS (klass);
GimpDrawableClass *drawable_class = GIMP_DRAWABLE_CLASS (klass);
+ GimpLayerClass *layer_class = GIMP_LAYER_CLASS (klass);
object_class->set_property = gimp_group_layer_set_property;
object_class->get_property = gimp_group_layer_get_property;
@@ -217,12 +218,6 @@ gimp_group_layer_class_init (GimpGroupLayerClass *klass)
item_class->is_position_locked = gimp_group_layer_is_position_locked;
item_class->duplicate = gimp_group_layer_duplicate;
item_class->convert = gimp_group_layer_convert;
- item_class->translate = gimp_group_layer_translate;
- item_class->scale = gimp_group_layer_scale;
- item_class->resize = gimp_group_layer_resize;
- item_class->flip = gimp_group_layer_flip;
- item_class->rotate = gimp_group_layer_rotate;
- item_class->transform = gimp_group_layer_transform;
item_class->default_name = _("Layer Group");
item_class->rename_desc = C_("undo-type", "Rename Layer Group");
@@ -234,7 +229,14 @@ gimp_group_layer_class_init (GimpGroupLayerClass *klass)
item_class->transform_desc = C_("undo-type", "Transform Layer Group");
drawable_class->estimate_memsize = gimp_group_layer_estimate_memsize;
- drawable_class->convert_type = gimp_group_layer_convert_type;
+
+ layer_class->translate = gimp_group_layer_translate;
+ layer_class->scale = gimp_group_layer_scale;
+ layer_class->resize = gimp_group_layer_resize;
+ layer_class->flip = gimp_group_layer_flip;
+ layer_class->rotate = gimp_group_layer_rotate;
+ layer_class->transform = gimp_group_layer_transform;
+ layer_class->convert_type = gimp_group_layer_convert_type;
g_type_class_add_private (klass, sizeof (GimpGroupLayerPrivate));
}
@@ -520,39 +522,69 @@ gimp_group_layer_convert (GimpItem *item,
GIMP_ITEM_CLASS (parent_class)->convert (item, dest_image, old_type);
}
-static void
-gimp_group_layer_translate (GimpItem *item,
- gint offset_x,
- gint offset_y,
- gboolean push_undo)
+static gint64
+gimp_group_layer_estimate_memsize (GimpDrawable *drawable,
+ GimpComponentType component_type,
+ gint width,
+ gint height)
{
- GimpGroupLayer *group = GIMP_GROUP_LAYER (item);
- GimpGroupLayerPrivate *private = GET_PRIVATE (item);
- GimpLayerMask *mask;
+ GimpGroupLayerPrivate *private = GET_PRIVATE (drawable);
GList *list;
-
- /* don't push an undo here because undo will call us again */
- gimp_group_layer_suspend_resize (group, FALSE);
+ GimpImageBaseType base_type;
+ gint64 memsize = 0;
for (list = gimp_item_stack_get_item_iter (GIMP_ITEM_STACK (private->children));
list;
list = g_list_next (list))
{
- GimpItem *child = list->data;
+ GimpDrawable *child = list->data;
+ gint child_width;
+ gint child_height;
- gimp_item_translate (child, offset_x, offset_y, push_undo);
+ child_width = (gimp_item_get_width (GIMP_ITEM (child)) *
+ width /
+ gimp_item_get_width (GIMP_ITEM (drawable)));
+ child_height = (gimp_item_get_height (GIMP_ITEM (child)) *
+ height /
+ gimp_item_get_height (GIMP_ITEM (drawable)));
+
+ memsize += gimp_drawable_estimate_memsize (child,
+ component_type,
+ child_width,
+ child_height);
}
- mask = gimp_layer_get_mask (GIMP_LAYER (group));
+ base_type = gimp_drawable_get_base_type (drawable);
- if (mask)
- {
- gint off_x, off_y;
+ memsize += gimp_projection_estimate_memsize (base_type, component_type,
+ width, height);
+
+ return memsize +
+ GIMP_DRAWABLE_CLASS (parent_class)->estimate_memsize (drawable,
+ component_type,
+ width, height);
+}
+
+static void
+gimp_group_layer_translate (GimpLayer *layer,
+ gint offset_x,
+ gint offset_y)
+{
+ GimpGroupLayer *group = GIMP_GROUP_LAYER (layer);
+ GimpGroupLayerPrivate *private = GET_PRIVATE (layer);
+ GList *list;
- gimp_item_get_offset (item, &off_x, &off_y);
- gimp_item_set_offset (GIMP_ITEM (mask), off_x, off_y);
+ /* don't push an undo here because undo will call us again */
+ gimp_group_layer_suspend_resize (group, FALSE);
+
+ for (list = gimp_item_stack_get_item_iter (GIMP_ITEM_STACK (private->children));
+ list;
+ list = g_list_next (list))
+ {
+ GimpItem *child = list->data;
- gimp_viewable_invalidate_preview (GIMP_VIEWABLE (mask));
+ /* don't push an undo here because undo will call us again */
+ gimp_item_translate (child, offset_x, offset_y, FALSE);
}
/* don't push an undo here because undo will call us again */
@@ -560,7 +592,7 @@ gimp_group_layer_translate (GimpItem *item,
}
static void
-gimp_group_layer_scale (GimpItem *item,
+gimp_group_layer_scale (GimpLayer *layer,
gint new_width,
gint new_height,
gint new_offset_x,
@@ -568,9 +600,9 @@ gimp_group_layer_scale (GimpItem *item,
GimpInterpolationType interpolation_type,
GimpProgress *progress)
{
- GimpGroupLayer *group = GIMP_GROUP_LAYER (item);
- GimpGroupLayerPrivate *private = GET_PRIVATE (item);
- GimpLayerMask *mask;
+ GimpGroupLayer *group = GIMP_GROUP_LAYER (layer);
+ GimpGroupLayerPrivate *private = GET_PRIVATE (layer);
+ GimpItem *item = GIMP_ITEM (layer);
GList *list;
gdouble width_factor;
gdouble height_factor;
@@ -626,19 +658,11 @@ gimp_group_layer_scale (GimpItem *item,
}
}
- mask = gimp_layer_get_mask (GIMP_LAYER (group));
-
- if (mask)
- gimp_item_scale (GIMP_ITEM (mask),
- new_width, new_height,
- new_offset_x, new_offset_y,
- interpolation_type, progress);
-
gimp_group_layer_resume_resize (group, TRUE);
}
static void
-gimp_group_layer_resize (GimpItem *item,
+gimp_group_layer_resize (GimpLayer *layer,
GimpContext *context,
GimpFillType fill_type,
gint new_width,
@@ -646,14 +670,13 @@ gimp_group_layer_resize (GimpItem *item,
gint offset_x,
gint offset_y)
{
- GimpGroupLayer *group = GIMP_GROUP_LAYER (item);
- GimpGroupLayerPrivate *private = GET_PRIVATE (item);
- GimpLayerMask *mask;
+ GimpGroupLayer *group = GIMP_GROUP_LAYER (layer);
+ GimpGroupLayerPrivate *private = GET_PRIVATE (layer);
GList *list;
gint x, y;
- x = gimp_item_get_offset_x (item) - offset_x;
- y = gimp_item_get_offset_y (item) - offset_y;
+ x = gimp_item_get_offset_x (GIMP_ITEM (group)) - offset_x;
+ y = gimp_item_get_offset_y (GIMP_ITEM (group)) - offset_y;
gimp_group_layer_suspend_resize (group, TRUE);
@@ -689,9 +712,9 @@ gimp_group_layer_resize (GimpItem *item,
child_width, child_height,
child_offset_x, child_offset_y);
}
- else if (gimp_item_is_attached (item))
+ else if (gimp_item_is_attached (GIMP_ITEM (group)))
{
- gimp_image_remove_layer (gimp_item_get_image (item),
+ gimp_image_remove_layer (gimp_item_get_image (GIMP_ITEM (group)),
GIMP_LAYER (child),
TRUE, NULL);
}
@@ -701,25 +724,18 @@ gimp_group_layer_resize (GimpItem *item,
}
}
- mask = gimp_layer_get_mask (GIMP_LAYER (group));
-
- if (mask)
- gimp_item_resize (GIMP_ITEM (mask), context, GIMP_FILL_TRANSPARENT,
- new_width, new_height, offset_x, offset_y);
-
gimp_group_layer_resume_resize (group, TRUE);
}
static void
-gimp_group_layer_flip (GimpItem *item,
+gimp_group_layer_flip (GimpLayer *layer,
GimpContext *context,
GimpOrientationType flip_type,
gdouble axis,
gboolean clip_result)
{
- GimpGroupLayer *group = GIMP_GROUP_LAYER (item);
- GimpGroupLayerPrivate *private = GET_PRIVATE (item);
- GimpLayerMask *mask;
+ GimpGroupLayer *group = GIMP_GROUP_LAYER (layer);
+ GimpGroupLayerPrivate *private = GET_PRIVATE (layer);
GList *list;
gimp_group_layer_suspend_resize (group, TRUE);
@@ -734,26 +750,19 @@ gimp_group_layer_flip (GimpItem *item,
flip_type, axis, clip_result);
}
- mask = gimp_layer_get_mask (GIMP_LAYER (group));
-
- if (mask)
- gimp_item_flip (GIMP_ITEM (mask), context,
- flip_type, axis, clip_result);
-
gimp_group_layer_resume_resize (group, TRUE);
}
static void
-gimp_group_layer_rotate (GimpItem *item,
+gimp_group_layer_rotate (GimpLayer *layer,
GimpContext *context,
GimpRotationType rotate_type,
gdouble center_x,
gdouble center_y,
gboolean clip_result)
{
- GimpGroupLayer *group = GIMP_GROUP_LAYER (item);
- GimpGroupLayerPrivate *private = GET_PRIVATE (item);
- GimpLayerMask *mask;
+ GimpGroupLayer *group = GIMP_GROUP_LAYER (layer);
+ GimpGroupLayerPrivate *private = GET_PRIVATE (layer);
GList *list;
gimp_group_layer_suspend_resize (group, TRUE);
@@ -768,17 +777,11 @@ gimp_group_layer_rotate (GimpItem *item,
rotate_type, center_x, center_y, clip_result);
}
- mask = gimp_layer_get_mask (GIMP_LAYER (group));
-
- if (mask)
- gimp_item_rotate (GIMP_ITEM (mask), context,
- rotate_type, center_x, center_y, clip_result);
-
gimp_group_layer_resume_resize (group, TRUE);
}
static void
-gimp_group_layer_transform (GimpItem *item,
+gimp_group_layer_transform (GimpLayer *layer,
GimpContext *context,
const GimpMatrix3 *matrix,
GimpTransformDirection direction,
@@ -786,9 +789,8 @@ gimp_group_layer_transform (GimpItem *item,
GimpTransformResize clip_result,
GimpProgress *progress)
{
- GimpGroupLayer *group = GIMP_GROUP_LAYER (item);
- GimpGroupLayerPrivate *private = GET_PRIVATE (item);
- GimpLayerMask *mask;
+ GimpGroupLayer *group = GIMP_GROUP_LAYER (layer);
+ GimpGroupLayerPrivate *private = GET_PRIVATE (layer);
GList *list;
gimp_group_layer_suspend_resize (group, TRUE);
@@ -805,60 +807,9 @@ gimp_group_layer_transform (GimpItem *item,
clip_result, progress);
}
- mask = gimp_layer_get_mask (GIMP_LAYER (group));
-
- if (mask)
- gimp_item_transform (GIMP_ITEM (mask), context,
- matrix, direction,
- interpolation_type,
- clip_result, progress);
-
gimp_group_layer_resume_resize (group, TRUE);
}
-static gint64
-gimp_group_layer_estimate_memsize (GimpDrawable *drawable,
- GimpComponentType component_type,
- gint width,
- gint height)
-{
- GimpGroupLayerPrivate *private = GET_PRIVATE (drawable);
- GList *list;
- GimpImageBaseType base_type;
- gint64 memsize = 0;
-
- for (list = gimp_item_stack_get_item_iter (GIMP_ITEM_STACK (private->children));
- list;
- list = g_list_next (list))
- {
- GimpDrawable *child = list->data;
- gint child_width;
- gint child_height;
-
- child_width = (gimp_item_get_width (GIMP_ITEM (child)) *
- width /
- gimp_item_get_width (GIMP_ITEM (drawable)));
- child_height = (gimp_item_get_height (GIMP_ITEM (child)) *
- height /
- gimp_item_get_height (GIMP_ITEM (drawable)));
-
- memsize += gimp_drawable_estimate_memsize (child,
- component_type,
- child_width,
- child_height);
- }
-
- base_type = gimp_drawable_get_base_type (drawable);
-
- memsize += gimp_projection_estimate_memsize (base_type, component_type,
- width, height);
-
- return memsize +
- GIMP_DRAWABLE_CLASS (parent_class)->estimate_memsize (drawable,
- component_type,
- width, height);
-}
-
static const Babl *
get_projection_format (GimpProjectable *projectable,
GimpImageBaseType base_type,
@@ -882,7 +833,7 @@ get_projection_format (GimpProjectable *projectable,
}
static void
-gimp_group_layer_convert_type (GimpDrawable *drawable,
+gimp_group_layer_convert_type (GimpLayer *layer,
GimpImage *dest_image,
const Babl *new_format,
GimpColorProfile *dest_profile,
@@ -891,9 +842,8 @@ gimp_group_layer_convert_type (GimpDrawable *drawable,
gboolean push_undo,
GimpProgress *progress)
{
- GimpGroupLayer *group = GIMP_GROUP_LAYER (drawable);
- GimpGroupLayerPrivate *private = GET_PRIVATE (drawable);
- GimpLayerMask *mask;
+ GimpGroupLayer *group = GIMP_GROUP_LAYER (layer);
+ GimpGroupLayerPrivate *private = GET_PRIVATE (layer);
GeglBuffer *buffer;
if (push_undo)
@@ -908,37 +858,22 @@ gimp_group_layer_convert_type (GimpDrawable *drawable,
* depth
*/
private->convert_format =
- get_projection_format (GIMP_PROJECTABLE (drawable),
+ get_projection_format (GIMP_PROJECTABLE (group),
gimp_babl_format_get_base_type (new_format),
gimp_babl_format_get_precision (new_format));
- gimp_projectable_structure_changed (GIMP_PROJECTABLE (drawable));
+ gimp_projectable_structure_changed (GIMP_PROJECTABLE (group));
gimp_pickable_flush (GIMP_PICKABLE (private->projection));
buffer = gimp_pickable_get_buffer (GIMP_PICKABLE (private->projection));
- gimp_drawable_set_buffer_full (drawable,
+ gimp_drawable_set_buffer_full (GIMP_DRAWABLE (group),
FALSE, NULL,
buffer,
- gimp_item_get_offset_x (GIMP_ITEM (drawable)),
- gimp_item_get_offset_y (GIMP_ITEM (drawable)));
+ gimp_item_get_offset_x (GIMP_ITEM (group)),
+ gimp_item_get_offset_y (GIMP_ITEM (group)));
/* reset, the actual format is right now */
private->convert_format = NULL;
-
- mask = gimp_layer_get_mask (GIMP_LAYER (group));
-
- if (mask &&
- gimp_babl_format_get_precision (new_format) !=
- gimp_drawable_get_precision (GIMP_DRAWABLE (mask)))
- {
- gimp_drawable_convert_type (GIMP_DRAWABLE (mask), dest_image,
- GIMP_GRAY,
- gimp_babl_format_get_precision (new_format),
- gimp_drawable_has_alpha (GIMP_DRAWABLE (mask)),
- NULL,
- layer_dither_type, mask_dither_type,
- push_undo, progress);
- }
}
static const Babl *
diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c
index ff5a740..b8d61b4 100644
--- a/app/core/gimplayer.c
+++ b/app/core/gimplayer.c
@@ -210,6 +210,49 @@ static void gimp_layer_srgb_to_pixel (GimpPickable *pickable,
const Babl *format,
gpointer pixel);
+static void gimp_layer_real_translate (GimpLayer *layer,
+ gint offset_x,
+ gint offset_y);
+static void gimp_layer_real_scale (GimpLayer *layer,
+ gint new_width,
+ gint new_height,
+ gint new_offset_x,
+ gint new_offset_y,
+ GimpInterpolationType interp_type,
+ GimpProgress *progress);
+static void gimp_layer_real_resize (GimpLayer *layer,
+ GimpContext *context,
+ GimpFillType fill_type,
+ gint new_width,
+ gint new_height,
+ gint offset_x,
+ gint offset_y);
+static void gimp_layer_real_flip (GimpLayer *layer,
+ GimpContext *context,
+ GimpOrientationType flip_type,
+ gdouble axis,
+ gboolean clip_result);
+static void gimp_layer_real_rotate (GimpLayer *layer,
+ GimpContext *context,
+ GimpRotationType rotate_type,
+ gdouble center_x,
+ gdouble center_y,
+ gboolean clip_result);
+static void gimp_layer_real_transform (GimpLayer *layer,
+ GimpContext *context,
+ const GimpMatrix3 *matrix,
+ GimpTransformDirection direction,
+ GimpInterpolationType interpolation_type,
+ GimpTransformResize clip_result,
+ GimpProgress *progress);
+static void gimp_layer_real_convert_type (GimpLayer *layer,
+ GimpImage *dest_image,
+ const Babl *new_format,
+ GimpColorProfile *dest_profile,
+ GeglDitherMethod layer_dither_type,
+ GeglDitherMethod mask_dither_type,
+ gboolean push_undo,
+ GimpProgress *progress);
static gboolean
gimp_layer_real_get_excludes_backdrop (GimpLayer *layer);
@@ -406,6 +449,13 @@ gimp_layer_class_init (GimpLayerClass *klass)
klass->apply_mask_changed = NULL;
klass->edit_mask_changed = NULL;
klass->show_mask_changed = NULL;
+ klass->translate = gimp_layer_real_translate;
+ klass->scale = gimp_layer_real_scale;
+ klass->resize = gimp_layer_real_resize;
+ klass->flip = gimp_layer_real_flip;
+ klass->rotate = gimp_layer_real_rotate;
+ klass->transform = gimp_layer_real_transform;
+ klass->convert_type = gimp_layer_real_convert_type;
klass->get_excludes_backdrop = gimp_layer_real_get_excludes_backdrop;
g_object_class_install_property (object_class, PROP_OPACITY,
@@ -995,17 +1045,7 @@ gimp_layer_translate (GimpItem *item,
if (push_undo)
gimp_image_undo_push_item_displace (gimp_item_get_image (item), NULL, item);
- /* update the old region */
- gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, -1, -1);
-
- /* invalidate the selection boundary because of a layer modification */
- gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
-
- GIMP_ITEM_CLASS (parent_class)->translate (item, offset_x, offset_y,
- push_undo);
-
- /* update the new region */
- gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, -1, -1);
+ GIMP_LAYER_GET_CLASS (layer)->translate (layer, offset_x, offset_y);
if (layer->mask)
{
@@ -1029,9 +1069,9 @@ gimp_layer_scale (GimpItem *item,
{
GimpLayer *layer = GIMP_LAYER (item);
- GIMP_ITEM_CLASS (parent_class)->scale (item, new_width, new_height,
- new_offset_x, new_offset_y,
- interpolation_type, progress);
+ GIMP_LAYER_GET_CLASS (layer)->scale (layer, new_width, new_height,
+ new_offset_x, new_offset_y,
+ interpolation_type, progress);
if (layer->mask)
gimp_item_scale (GIMP_ITEM (layer->mask),
@@ -1051,15 +1091,9 @@ gimp_layer_resize (GimpItem *item,
{
GimpLayer *layer = GIMP_LAYER (item);
- if (fill_type == GIMP_FILL_TRANSPARENT &&
- ! gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))
- {
- fill_type = GIMP_FILL_BACKGROUND;
- }
-
- GIMP_ITEM_CLASS (parent_class)->resize (item, context, fill_type,
- new_width, new_height,
- offset_x, offset_y);
+ GIMP_LAYER_GET_CLASS (layer)->resize (layer, context, fill_type,
+ new_width, new_height,
+ offset_x, offset_y);
if (layer->mask)
gimp_item_resize (GIMP_ITEM (layer->mask), context, GIMP_FILL_TRANSPARENT,
@@ -1075,8 +1109,8 @@ gimp_layer_flip (GimpItem *item,
{
GimpLayer *layer = GIMP_LAYER (item);
- GIMP_ITEM_CLASS (parent_class)->flip (item, context, flip_type, axis,
- clip_result);
+ GIMP_LAYER_GET_CLASS (layer)->flip (layer, context, flip_type, axis,
+ clip_result);
if (layer->mask)
gimp_item_flip (GIMP_ITEM (layer->mask), context,
@@ -1093,9 +1127,9 @@ gimp_layer_rotate (GimpItem *item,
{
GimpLayer *layer = GIMP_LAYER (item);
- GIMP_ITEM_CLASS (parent_class)->rotate (item, context,
- rotate_type, center_x, center_y,
- clip_result);
+ GIMP_LAYER_GET_CLASS (layer)->rotate (layer, context,
+ rotate_type, center_x, center_y,
+ clip_result);
if (layer->mask)
gimp_item_rotate (GIMP_ITEM (layer->mask), context,
@@ -1113,15 +1147,10 @@ gimp_layer_transform (GimpItem *item,
{
GimpLayer *layer = GIMP_LAYER (item);
- /* FIXME: make interpolated transformations work on layers without alpha */
- if (interpolation_type != GIMP_INTERPOLATION_NONE &&
- ! gimp_drawable_has_alpha (GIMP_DRAWABLE (item)))
- gimp_layer_add_alpha (layer);
-
- GIMP_ITEM_CLASS (parent_class)->transform (item, context, matrix, direction,
- interpolation_type,
- clip_result,
- progress);
+ GIMP_LAYER_GET_CLASS (layer)->transform (layer, context, matrix, direction,
+ interpolation_type,
+ clip_result,
+ progress);
if (layer->mask)
gimp_item_transform (GIMP_ITEM (layer->mask), context,
@@ -1190,57 +1219,12 @@ gimp_layer_convert_type (GimpDrawable *drawable,
gboolean push_undo,
GimpProgress *progress)
{
- GimpLayer *layer = GIMP_LAYER (drawable);
- GeglBuffer *src_buffer;
- GeglBuffer *dest_buffer;
-
- if (layer_dither_type == GEGL_DITHER_NONE)
- {
- src_buffer = g_object_ref (gimp_drawable_get_buffer (drawable));
- }
- else
- {
- gint bits;
-
- src_buffer =
- gegl_buffer_new (GEGL_RECTANGLE (0, 0,
- gimp_item_get_width (GIMP_ITEM (drawable)),
- gimp_item_get_height (GIMP_ITEM (drawable))),
- gimp_drawable_get_format (drawable));
-
- bits = (babl_format_get_bytes_per_pixel (new_format) * 8 /
- babl_format_get_n_components (new_format));
-
- gimp_gegl_apply_dither (gimp_drawable_get_buffer (drawable),
- NULL, NULL,
- src_buffer, 1 << bits, layer_dither_type);
- }
-
- dest_buffer =
- gegl_buffer_new (GEGL_RECTANGLE (0, 0,
- gimp_item_get_width (GIMP_ITEM (drawable)),
- gimp_item_get_height (GIMP_ITEM (drawable))),
- new_format);
-
- if (dest_profile)
- {
- GimpColorProfile *src_profile =
- gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (layer));
+ GimpLayer *layer = GIMP_LAYER (drawable);
- gimp_gegl_convert_color_profile (src_buffer, NULL, src_profile,
- dest_buffer, NULL, dest_profile,
- GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
- TRUE, progress);
- }
- else
- {
- gegl_buffer_copy (src_buffer, NULL, GEGL_ABYSS_NONE, dest_buffer, NULL);
- }
-
- gimp_drawable_set_buffer (drawable, push_undo, NULL, dest_buffer);
-
- g_object_unref (src_buffer);
- g_object_unref (dest_buffer);
+ GIMP_LAYER_GET_CLASS (layer)->convert_type (layer, dest_image, new_format,
+ dest_profile, layer_dither_type,
+ mask_dither_type, push_undo,
+ progress);
if (layer->mask &&
gimp_babl_format_get_precision (new_format) !=
@@ -1403,6 +1387,170 @@ gimp_layer_srgb_to_pixel (GimpPickable *pickable,
gimp_pickable_srgb_to_pixel (GIMP_PICKABLE (image), color, format, pixel);
}
+static void
+gimp_layer_real_translate (GimpLayer *layer,
+ gint offset_x,
+ gint offset_y)
+{
+ /* update the old region */
+ gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, -1, -1);
+
+ /* invalidate the selection boundary because of a layer modification */
+ gimp_drawable_invalidate_boundary (GIMP_DRAWABLE (layer));
+
+ GIMP_ITEM_CLASS (parent_class)->translate (GIMP_ITEM (layer),
+ offset_x, offset_y,
+ FALSE);
+
+ /* update the new region */
+ gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, -1, -1);
+}
+
+static void
+gimp_layer_real_scale (GimpLayer *layer,
+ gint new_width,
+ gint new_height,
+ gint new_offset_x,
+ gint new_offset_y,
+ GimpInterpolationType interpolation_type,
+ GimpProgress *progress)
+{
+ GIMP_ITEM_CLASS (parent_class)->scale (GIMP_ITEM (layer),
+ new_width, new_height,
+ new_offset_x, new_offset_y,
+ interpolation_type, progress);
+}
+
+static void
+gimp_layer_real_resize (GimpLayer *layer,
+ GimpContext *context,
+ GimpFillType fill_type,
+ gint new_width,
+ gint new_height,
+ gint offset_x,
+ gint offset_y)
+{
+ if (fill_type == GIMP_FILL_TRANSPARENT &&
+ ! gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))
+ {
+ fill_type = GIMP_FILL_BACKGROUND;
+ }
+
+ GIMP_ITEM_CLASS (parent_class)->resize (GIMP_ITEM (layer),
+ context, fill_type,
+ new_width, new_height,
+ offset_x, offset_y);
+}
+
+static void
+gimp_layer_real_flip (GimpLayer *layer,
+ GimpContext *context,
+ GimpOrientationType flip_type,
+ gdouble axis,
+ gboolean clip_result)
+{
+ GIMP_ITEM_CLASS (parent_class)->flip (GIMP_ITEM (layer),
+ context, flip_type, axis, clip_result);
+}
+
+static void
+gimp_layer_real_rotate (GimpLayer *layer,
+ GimpContext *context,
+ GimpRotationType rotate_type,
+ gdouble center_x,
+ gdouble center_y,
+ gboolean clip_result)
+{
+ GIMP_ITEM_CLASS (parent_class)->rotate (GIMP_ITEM (layer),
+ context, rotate_type,
+ center_x, center_y,
+ clip_result);
+}
+
+static void
+gimp_layer_real_transform (GimpLayer *layer,
+ GimpContext *context,
+ const GimpMatrix3 *matrix,
+ GimpTransformDirection direction,
+ GimpInterpolationType interpolation_type,
+ GimpTransformResize clip_result,
+ GimpProgress *progress)
+{
+ /* FIXME: make interpolated transformations work on layers without alpha */
+ if (interpolation_type != GIMP_INTERPOLATION_NONE &&
+ ! gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))
+ gimp_layer_add_alpha (layer);
+
+ GIMP_ITEM_CLASS (parent_class)->transform (GIMP_ITEM (layer),
+ context, matrix, direction,
+ interpolation_type,
+ clip_result,
+ progress);
+}
+
+static void
+gimp_layer_real_convert_type (GimpLayer *layer,
+ GimpImage *dest_image,
+ const Babl *new_format,
+ GimpColorProfile *dest_profile,
+ GeglDitherMethod layer_dither_type,
+ GeglDitherMethod mask_dither_type,
+ gboolean push_undo,
+ GimpProgress *progress)
+{
+ GimpDrawable *drawable = GIMP_DRAWABLE (layer);
+ GeglBuffer *src_buffer;
+ GeglBuffer *dest_buffer;
+
+ if (layer_dither_type == GEGL_DITHER_NONE)
+ {
+ src_buffer = g_object_ref (gimp_drawable_get_buffer (drawable));
+ }
+ else
+ {
+ gint bits;
+
+ src_buffer =
+ gegl_buffer_new (GEGL_RECTANGLE (0, 0,
+ gimp_item_get_width (GIMP_ITEM (layer)),
+ gimp_item_get_height (GIMP_ITEM (layer))),
+ gimp_drawable_get_format (drawable));
+
+ bits = (babl_format_get_bytes_per_pixel (new_format) * 8 /
+ babl_format_get_n_components (new_format));
+
+ gimp_gegl_apply_dither (gimp_drawable_get_buffer (drawable),
+ NULL, NULL,
+ src_buffer, 1 << bits, layer_dither_type);
+ }
+
+ dest_buffer =
+ gegl_buffer_new (GEGL_RECTANGLE (0, 0,
+ gimp_item_get_width (GIMP_ITEM (layer)),
+ gimp_item_get_height (GIMP_ITEM (layer))),
+ new_format);
+
+ if (dest_profile)
+ {
+ GimpColorProfile *src_profile =
+ gimp_color_managed_get_color_profile (GIMP_COLOR_MANAGED (layer));
+
+ gimp_gegl_convert_color_profile (src_buffer, NULL, src_profile,
+ dest_buffer, NULL, dest_profile,
+ GIMP_COLOR_RENDERING_INTENT_PERCEPTUAL,
+ TRUE, progress);
+ }
+ else
+ {
+ gegl_buffer_copy (src_buffer, NULL, GEGL_ABYSS_NONE, dest_buffer, NULL);
+ }
+
+ gimp_drawable_set_buffer (drawable, push_undo, NULL, dest_buffer);
+
+ g_object_unref (src_buffer);
+ g_object_unref (dest_buffer);
+}
+
static gboolean
gimp_layer_real_get_excludes_backdrop (GimpLayer *layer)
{
diff --git a/app/core/gimplayer.h b/app/core/gimplayer.h
index c222a5c..42a1246 100644
--- a/app/core/gimplayer.h
+++ b/app/core/gimplayer.h
@@ -67,20 +67,63 @@ struct _GimpLayerClass
GimpDrawableClass parent_class;
/* signals */
- void (* opacity_changed) (GimpLayer *layer);
- void (* mode_changed) (GimpLayer *layer);
- void (* blend_space_changed) (GimpLayer *layer);
- void (* composite_space_changed) (GimpLayer *layer);
- void (* composite_mode_changed) (GimpLayer *layer);
- void (* excludes_backdrop_changed) (GimpLayer *layer);
- void (* lock_alpha_changed) (GimpLayer *layer);
- void (* mask_changed) (GimpLayer *layer);
- void (* apply_mask_changed) (GimpLayer *layer);
- void (* edit_mask_changed) (GimpLayer *layer);
- void (* show_mask_changed) (GimpLayer *layer);
+ void (* opacity_changed) (GimpLayer *layer);
+ void (* mode_changed) (GimpLayer *layer);
+ void (* blend_space_changed) (GimpLayer *layer);
+ void (* composite_space_changed) (GimpLayer *layer);
+ void (* composite_mode_changed) (GimpLayer *layer);
+ void (* excludes_backdrop_changed) (GimpLayer *layer);
+ void (* lock_alpha_changed) (GimpLayer *layer);
+ void (* mask_changed) (GimpLayer *layer);
+ void (* apply_mask_changed) (GimpLayer *layer);
+ void (* edit_mask_changed) (GimpLayer *layer);
+ void (* show_mask_changed) (GimpLayer *layer);
/* virtual functions */
- gboolean (* get_excludes_backdrop) (GimpLayer *layer);
+ void (* translate) (GimpLayer *layer,
+ gint offset_x,
+ gint offset_y);
+ void (* scale) (GimpLayer *layer,
+ gint new_width,
+ gint new_height,
+ gint new_offset_x,
+ gint new_offset_y,
+ GimpInterpolationType interpolation_type,
+ GimpProgress *progress);
+ void (* resize) (GimpLayer *layer,
+ GimpContext *context,
+ GimpFillType fill_type,
+ gint new_width,
+ gint new_height,
+ gint offset_x,
+ gint offset_y);
+ void (* flip) (GimpLayer *layer,
+ GimpContext *context,
+ GimpOrientationType flip_type,
+ gdouble axis,
+ gboolean clip_result);
+ void (* rotate) (GimpLayer *layer,
+ GimpContext *context,
+ GimpRotationType rotate_type,
+ gdouble center_x,
+ gdouble center_y,
+ gboolean clip_result);
+ void (* transform) (GimpLayer *layer,
+ GimpContext *context,
+ const GimpMatrix3 *matrix,
+ GimpTransformDirection direction,
+ GimpInterpolationType interpolation_type,
+ GimpTransformResize clip_result,
+ GimpProgress *progress);
+ void (* convert_type) (GimpLayer *layer,
+ GimpImage *dest_image,
+ const Babl *new_format,
+ GimpColorProfile *dest_profile,
+ GeglDitherMethod layer_dither_type,
+ GeglDitherMethod mask_dither_type,
+ gboolean push_undo,
+ GimpProgress *progress);
+ gboolean (* get_excludes_backdrop) (GimpLayer *layer);
};
diff --git a/app/text/gimptextlayer.c b/app/text/gimptextlayer.c
index cbd7338..2c1b39b 100644
--- a/app/text/gimptextlayer.c
+++ b/app/text/gimptextlayer.c
@@ -85,14 +85,6 @@ static gboolean gimp_text_layer_rename (GimpItem *item,
const gchar *undo_desc,
GError **error);
-static void gimp_text_layer_convert_type (GimpDrawable *drawable,
- GimpImage *dest_image,
- const Babl *new_format,
- GimpColorProfile *dest_profile,
- GeglDitherMethod layer_dither_type,
- GeglDitherMethod mask_dither_type,
- gboolean push_undo,
- GimpProgress *progress);
static void gimp_text_layer_set_buffer (GimpDrawable *drawable,
gboolean push_undo,
const gchar *undo_desc,
@@ -107,6 +99,15 @@ static void gimp_text_layer_push_undo (GimpDrawable *drawable,
gint width,
gint height);
+static void gimp_text_layer_convert_type (GimpLayer *layer,
+ GimpImage *dest_image,
+ const Babl *new_format,
+ GimpColorProfile *dest_profile,
+ GeglDitherMethod layer_dither_type,
+ GeglDitherMethod mask_dither_type,
+ gboolean push_undo,
+ GimpProgress *progress);
+
static void gimp_text_layer_text_changed (GimpTextLayer *layer);
static gboolean gimp_text_layer_render (GimpTextLayer *layer);
static void gimp_text_layer_render_layout (GimpTextLayer *layer,
@@ -126,6 +127,7 @@ gimp_text_layer_class_init (GimpTextLayerClass *klass)
GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
GimpItemClass *item_class = GIMP_ITEM_CLASS (klass);
GimpDrawableClass *drawable_class = GIMP_DRAWABLE_CLASS (klass);
+ GimpLayerClass *layer_class = GIMP_LAYER_CLASS (klass);
object_class->finalize = gimp_text_layer_finalize;
object_class->get_property = gimp_text_layer_get_property;
@@ -154,10 +156,11 @@ gimp_text_layer_class_init (GimpTextLayerClass *klass)
item_class->rotate_desc = _("Rotate Text Layer");
item_class->transform_desc = _("Transform Text Layer");
- drawable_class->convert_type = gimp_text_layer_convert_type;
drawable_class->set_buffer = gimp_text_layer_set_buffer;
drawable_class->push_undo = gimp_text_layer_push_undo;
+ layer_class->convert_type = gimp_text_layer_convert_type;
+
GIMP_CONFIG_PROP_OBJECT (object_class, PROP_TEXT,
"text",
NULL, NULL,
@@ -315,44 +318,6 @@ gimp_text_layer_rename (GimpItem *item,
}
static void
-gimp_text_layer_convert_type (GimpDrawable *drawable,
- GimpImage *dest_image,
- const Babl *new_format,
- GimpColorProfile *dest_profile,
- GeglDitherMethod layer_dither_type,
- GeglDitherMethod mask_dither_type,
- gboolean push_undo,
- GimpProgress *progress)
-{
- GimpTextLayer *layer = GIMP_TEXT_LAYER (drawable);
- GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
-
- if (! layer->text ||
- layer->modified ||
- layer_dither_type != GEGL_DITHER_NONE)
- {
- GIMP_DRAWABLE_CLASS (parent_class)->convert_type (drawable, dest_image,
- new_format,
- dest_profile,
- layer_dither_type,
- mask_dither_type,
- push_undo,
- progress);
- }
- else
- {
- if (push_undo)
- gimp_image_undo_push_text_layer_convert (image, NULL, layer);
-
- layer->convert_format = new_format;
-
- gimp_text_layer_render (layer);
-
- layer->convert_format = NULL;
- }
-}
-
-static void
gimp_text_layer_set_buffer (GimpDrawable *drawable,
gboolean push_undo,
const gchar *undo_desc,
@@ -411,6 +376,44 @@ gimp_text_layer_push_undo (GimpDrawable *drawable,
}
}
+static void
+gimp_text_layer_convert_type (GimpLayer *layer,
+ GimpImage *dest_image,
+ const Babl *new_format,
+ GimpColorProfile *dest_profile,
+ GeglDitherMethod layer_dither_type,
+ GeglDitherMethod mask_dither_type,
+ gboolean push_undo,
+ GimpProgress *progress)
+{
+ GimpTextLayer *text_layer = GIMP_TEXT_LAYER (layer);
+ GimpImage *image = gimp_item_get_image (GIMP_ITEM (text_layer));
+
+ if (! text_layer->text ||
+ text_layer->modified ||
+ layer_dither_type != GEGL_DITHER_NONE)
+ {
+ GIMP_LAYER_CLASS (parent_class)->convert_type (layer, dest_image,
+ new_format,
+ dest_profile,
+ layer_dither_type,
+ mask_dither_type,
+ push_undo,
+ progress);
+ }
+ else
+ {
+ if (push_undo)
+ gimp_image_undo_push_text_layer_convert (image, NULL, text_layer);
+
+ text_layer->convert_format = new_format;
+
+ gimp_text_layer_render (text_layer);
+
+ text_layer->convert_format = NULL;
+ }
+}
+
/* public functions */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]