diff --git a/app/core/gimpgrouplayer.c b/app/core/gimpgrouplayer.c index 2be8de71a2..331e872b9a 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,15 +522,56 @@ 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; + 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 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; /* don't push an undo here because undo will call us again */ @@ -540,19 +583,8 @@ gimp_group_layer_translate (GimpItem *item, { GimpItem *child = list->data; - gimp_item_translate (child, offset_x, offset_y, push_undo); - } - - mask = gimp_layer_get_mask (GIMP_LAYER (group)); - - if (mask) - { - gint off_x, off_y; - - gimp_item_get_offset (item, &off_x, &off_y); - gimp_item_set_offset (GIMP_ITEM (mask), off_x, off_y); - - 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 ff5a7408dd..b8d61b45b2 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; + GimpLayer *layer = GIMP_LAYER (drawable); - 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)); - - 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 c222a5cd06..42a1246a1a 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 cbd733862a..2c1b39bb35 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, @@ -314,44 +317,6 @@ gimp_text_layer_rename (GimpItem *item, return FALSE; } -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, @@ -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 */