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.
This commit is contained in:
@ -96,48 +96,48 @@ static GimpItem * gimp_group_layer_duplicate (GimpItem *item,
|
|||||||
static void gimp_group_layer_convert (GimpItem *item,
|
static void gimp_group_layer_convert (GimpItem *item,
|
||||||
GimpImage *dest_image,
|
GimpImage *dest_image,
|
||||||
GType old_type);
|
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_x,
|
||||||
gint offset_y,
|
gint offset_y);
|
||||||
gboolean push_undo);
|
static void gimp_group_layer_scale (GimpLayer *layer,
|
||||||
static void gimp_group_layer_scale (GimpItem *item,
|
|
||||||
gint new_width,
|
gint new_width,
|
||||||
gint new_height,
|
gint new_height,
|
||||||
gint new_offset_x,
|
gint new_offset_x,
|
||||||
gint new_offset_y,
|
gint new_offset_y,
|
||||||
GimpInterpolationType interp_type,
|
GimpInterpolationType interp_type,
|
||||||
GimpProgress *progress);
|
GimpProgress *progress);
|
||||||
static void gimp_group_layer_resize (GimpItem *item,
|
static void gimp_group_layer_resize (GimpLayer *layer,
|
||||||
GimpContext *context,
|
GimpContext *context,
|
||||||
GimpFillType fill_type,
|
GimpFillType fill_type,
|
||||||
gint new_width,
|
gint new_width,
|
||||||
gint new_height,
|
gint new_height,
|
||||||
gint offset_x,
|
gint offset_x,
|
||||||
gint offset_y);
|
gint offset_y);
|
||||||
static void gimp_group_layer_flip (GimpItem *item,
|
static void gimp_group_layer_flip (GimpLayer *layer,
|
||||||
GimpContext *context,
|
GimpContext *context,
|
||||||
GimpOrientationType flip_type,
|
GimpOrientationType flip_type,
|
||||||
gdouble axis,
|
gdouble axis,
|
||||||
gboolean clip_result);
|
gboolean clip_result);
|
||||||
static void gimp_group_layer_rotate (GimpItem *item,
|
static void gimp_group_layer_rotate (GimpLayer *layer,
|
||||||
GimpContext *context,
|
GimpContext *context,
|
||||||
GimpRotationType rotate_type,
|
GimpRotationType rotate_type,
|
||||||
gdouble center_x,
|
gdouble center_x,
|
||||||
gdouble center_y,
|
gdouble center_y,
|
||||||
gboolean clip_result);
|
gboolean clip_result);
|
||||||
static void gimp_group_layer_transform (GimpItem *item,
|
static void gimp_group_layer_transform (GimpLayer *layer,
|
||||||
GimpContext *context,
|
GimpContext *context,
|
||||||
const GimpMatrix3 *matrix,
|
const GimpMatrix3 *matrix,
|
||||||
GimpTransformDirection direction,
|
GimpTransformDirection direction,
|
||||||
GimpInterpolationType interpolation_type,
|
GimpInterpolationType interpolation_type,
|
||||||
GimpTransformResize clip_result,
|
GimpTransformResize clip_result,
|
||||||
GimpProgress *progress);
|
GimpProgress *progress);
|
||||||
|
static void gimp_group_layer_convert_type (GimpLayer *layer,
|
||||||
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,
|
|
||||||
GimpImage *dest_image,
|
GimpImage *dest_image,
|
||||||
const Babl *new_format,
|
const Babl *new_format,
|
||||||
GimpColorProfile *dest_profile,
|
GimpColorProfile *dest_profile,
|
||||||
@ -201,6 +201,7 @@ gimp_group_layer_class_init (GimpGroupLayerClass *klass)
|
|||||||
GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
|
GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
|
||||||
GimpItemClass *item_class = GIMP_ITEM_CLASS (klass);
|
GimpItemClass *item_class = GIMP_ITEM_CLASS (klass);
|
||||||
GimpDrawableClass *drawable_class = GIMP_DRAWABLE_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->set_property = gimp_group_layer_set_property;
|
||||||
object_class->get_property = gimp_group_layer_get_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->is_position_locked = gimp_group_layer_is_position_locked;
|
||||||
item_class->duplicate = gimp_group_layer_duplicate;
|
item_class->duplicate = gimp_group_layer_duplicate;
|
||||||
item_class->convert = gimp_group_layer_convert;
|
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->default_name = _("Layer Group");
|
||||||
item_class->rename_desc = C_("undo-type", "Rename 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");
|
item_class->transform_desc = C_("undo-type", "Transform Layer Group");
|
||||||
|
|
||||||
drawable_class->estimate_memsize = gimp_group_layer_estimate_memsize;
|
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));
|
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);
|
GIMP_ITEM_CLASS (parent_class)->convert (item, dest_image, old_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static gint64
|
||||||
gimp_group_layer_translate (GimpItem *item,
|
gimp_group_layer_estimate_memsize (GimpDrawable *drawable,
|
||||||
gint offset_x,
|
GimpComponentType component_type,
|
||||||
gint offset_y,
|
gint width,
|
||||||
gboolean push_undo)
|
gint height)
|
||||||
{
|
{
|
||||||
GimpGroupLayer *group = GIMP_GROUP_LAYER (item);
|
GimpGroupLayerPrivate *private = GET_PRIVATE (drawable);
|
||||||
GimpGroupLayerPrivate *private = GET_PRIVATE (item);
|
GList *list;
|
||||||
GimpLayerMask *mask;
|
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;
|
GList *list;
|
||||||
|
|
||||||
/* don't push an undo here because undo will call us again */
|
/* 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;
|
GimpItem *child = list->data;
|
||||||
|
|
||||||
gimp_item_translate (child, offset_x, offset_y, push_undo);
|
/* don't push an undo here because undo will call us again */
|
||||||
}
|
gimp_item_translate (child, offset_x, offset_y, FALSE);
|
||||||
|
|
||||||
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 */
|
/* don't push an undo here because undo will call us again */
|
||||||
@ -560,7 +592,7 @@ gimp_group_layer_translate (GimpItem *item,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_group_layer_scale (GimpItem *item,
|
gimp_group_layer_scale (GimpLayer *layer,
|
||||||
gint new_width,
|
gint new_width,
|
||||||
gint new_height,
|
gint new_height,
|
||||||
gint new_offset_x,
|
gint new_offset_x,
|
||||||
@ -568,9 +600,9 @@ gimp_group_layer_scale (GimpItem *item,
|
|||||||
GimpInterpolationType interpolation_type,
|
GimpInterpolationType interpolation_type,
|
||||||
GimpProgress *progress)
|
GimpProgress *progress)
|
||||||
{
|
{
|
||||||
GimpGroupLayer *group = GIMP_GROUP_LAYER (item);
|
GimpGroupLayer *group = GIMP_GROUP_LAYER (layer);
|
||||||
GimpGroupLayerPrivate *private = GET_PRIVATE (item);
|
GimpGroupLayerPrivate *private = GET_PRIVATE (layer);
|
||||||
GimpLayerMask *mask;
|
GimpItem *item = GIMP_ITEM (layer);
|
||||||
GList *list;
|
GList *list;
|
||||||
gdouble width_factor;
|
gdouble width_factor;
|
||||||
gdouble height_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);
|
gimp_group_layer_resume_resize (group, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_group_layer_resize (GimpItem *item,
|
gimp_group_layer_resize (GimpLayer *layer,
|
||||||
GimpContext *context,
|
GimpContext *context,
|
||||||
GimpFillType fill_type,
|
GimpFillType fill_type,
|
||||||
gint new_width,
|
gint new_width,
|
||||||
@ -646,14 +670,13 @@ gimp_group_layer_resize (GimpItem *item,
|
|||||||
gint offset_x,
|
gint offset_x,
|
||||||
gint offset_y)
|
gint offset_y)
|
||||||
{
|
{
|
||||||
GimpGroupLayer *group = GIMP_GROUP_LAYER (item);
|
GimpGroupLayer *group = GIMP_GROUP_LAYER (layer);
|
||||||
GimpGroupLayerPrivate *private = GET_PRIVATE (item);
|
GimpGroupLayerPrivate *private = GET_PRIVATE (layer);
|
||||||
GimpLayerMask *mask;
|
|
||||||
GList *list;
|
GList *list;
|
||||||
gint x, y;
|
gint x, y;
|
||||||
|
|
||||||
x = gimp_item_get_offset_x (item) - offset_x;
|
x = gimp_item_get_offset_x (GIMP_ITEM (group)) - offset_x;
|
||||||
y = gimp_item_get_offset_y (item) - offset_y;
|
y = gimp_item_get_offset_y (GIMP_ITEM (group)) - offset_y;
|
||||||
|
|
||||||
gimp_group_layer_suspend_resize (group, TRUE);
|
gimp_group_layer_suspend_resize (group, TRUE);
|
||||||
|
|
||||||
@ -689,9 +712,9 @@ gimp_group_layer_resize (GimpItem *item,
|
|||||||
child_width, child_height,
|
child_width, child_height,
|
||||||
child_offset_x, child_offset_y);
|
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),
|
GIMP_LAYER (child),
|
||||||
TRUE, NULL);
|
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);
|
gimp_group_layer_resume_resize (group, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_group_layer_flip (GimpItem *item,
|
gimp_group_layer_flip (GimpLayer *layer,
|
||||||
GimpContext *context,
|
GimpContext *context,
|
||||||
GimpOrientationType flip_type,
|
GimpOrientationType flip_type,
|
||||||
gdouble axis,
|
gdouble axis,
|
||||||
gboolean clip_result)
|
gboolean clip_result)
|
||||||
{
|
{
|
||||||
GimpGroupLayer *group = GIMP_GROUP_LAYER (item);
|
GimpGroupLayer *group = GIMP_GROUP_LAYER (layer);
|
||||||
GimpGroupLayerPrivate *private = GET_PRIVATE (item);
|
GimpGroupLayerPrivate *private = GET_PRIVATE (layer);
|
||||||
GimpLayerMask *mask;
|
|
||||||
GList *list;
|
GList *list;
|
||||||
|
|
||||||
gimp_group_layer_suspend_resize (group, TRUE);
|
gimp_group_layer_suspend_resize (group, TRUE);
|
||||||
@ -734,26 +750,19 @@ gimp_group_layer_flip (GimpItem *item,
|
|||||||
flip_type, axis, clip_result);
|
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);
|
gimp_group_layer_resume_resize (group, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_group_layer_rotate (GimpItem *item,
|
gimp_group_layer_rotate (GimpLayer *layer,
|
||||||
GimpContext *context,
|
GimpContext *context,
|
||||||
GimpRotationType rotate_type,
|
GimpRotationType rotate_type,
|
||||||
gdouble center_x,
|
gdouble center_x,
|
||||||
gdouble center_y,
|
gdouble center_y,
|
||||||
gboolean clip_result)
|
gboolean clip_result)
|
||||||
{
|
{
|
||||||
GimpGroupLayer *group = GIMP_GROUP_LAYER (item);
|
GimpGroupLayer *group = GIMP_GROUP_LAYER (layer);
|
||||||
GimpGroupLayerPrivate *private = GET_PRIVATE (item);
|
GimpGroupLayerPrivate *private = GET_PRIVATE (layer);
|
||||||
GimpLayerMask *mask;
|
|
||||||
GList *list;
|
GList *list;
|
||||||
|
|
||||||
gimp_group_layer_suspend_resize (group, TRUE);
|
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);
|
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);
|
gimp_group_layer_resume_resize (group, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_group_layer_transform (GimpItem *item,
|
gimp_group_layer_transform (GimpLayer *layer,
|
||||||
GimpContext *context,
|
GimpContext *context,
|
||||||
const GimpMatrix3 *matrix,
|
const GimpMatrix3 *matrix,
|
||||||
GimpTransformDirection direction,
|
GimpTransformDirection direction,
|
||||||
@ -786,9 +789,8 @@ gimp_group_layer_transform (GimpItem *item,
|
|||||||
GimpTransformResize clip_result,
|
GimpTransformResize clip_result,
|
||||||
GimpProgress *progress)
|
GimpProgress *progress)
|
||||||
{
|
{
|
||||||
GimpGroupLayer *group = GIMP_GROUP_LAYER (item);
|
GimpGroupLayer *group = GIMP_GROUP_LAYER (layer);
|
||||||
GimpGroupLayerPrivate *private = GET_PRIVATE (item);
|
GimpGroupLayerPrivate *private = GET_PRIVATE (layer);
|
||||||
GimpLayerMask *mask;
|
|
||||||
GList *list;
|
GList *list;
|
||||||
|
|
||||||
gimp_group_layer_suspend_resize (group, TRUE);
|
gimp_group_layer_suspend_resize (group, TRUE);
|
||||||
@ -805,60 +807,9 @@ gimp_group_layer_transform (GimpItem *item,
|
|||||||
clip_result, progress);
|
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);
|
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 *
|
static const Babl *
|
||||||
get_projection_format (GimpProjectable *projectable,
|
get_projection_format (GimpProjectable *projectable,
|
||||||
GimpImageBaseType base_type,
|
GimpImageBaseType base_type,
|
||||||
@ -882,7 +833,7 @@ get_projection_format (GimpProjectable *projectable,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gimp_group_layer_convert_type (GimpDrawable *drawable,
|
gimp_group_layer_convert_type (GimpLayer *layer,
|
||||||
GimpImage *dest_image,
|
GimpImage *dest_image,
|
||||||
const Babl *new_format,
|
const Babl *new_format,
|
||||||
GimpColorProfile *dest_profile,
|
GimpColorProfile *dest_profile,
|
||||||
@ -891,9 +842,8 @@ gimp_group_layer_convert_type (GimpDrawable *drawable,
|
|||||||
gboolean push_undo,
|
gboolean push_undo,
|
||||||
GimpProgress *progress)
|
GimpProgress *progress)
|
||||||
{
|
{
|
||||||
GimpGroupLayer *group = GIMP_GROUP_LAYER (drawable);
|
GimpGroupLayer *group = GIMP_GROUP_LAYER (layer);
|
||||||
GimpGroupLayerPrivate *private = GET_PRIVATE (drawable);
|
GimpGroupLayerPrivate *private = GET_PRIVATE (layer);
|
||||||
GimpLayerMask *mask;
|
|
||||||
GeglBuffer *buffer;
|
GeglBuffer *buffer;
|
||||||
|
|
||||||
if (push_undo)
|
if (push_undo)
|
||||||
@ -908,37 +858,22 @@ gimp_group_layer_convert_type (GimpDrawable *drawable,
|
|||||||
* depth
|
* depth
|
||||||
*/
|
*/
|
||||||
private->convert_format =
|
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_base_type (new_format),
|
||||||
gimp_babl_format_get_precision (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));
|
gimp_pickable_flush (GIMP_PICKABLE (private->projection));
|
||||||
|
|
||||||
buffer = gimp_pickable_get_buffer (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,
|
FALSE, NULL,
|
||||||
buffer,
|
buffer,
|
||||||
gimp_item_get_offset_x (GIMP_ITEM (drawable)),
|
gimp_item_get_offset_x (GIMP_ITEM (group)),
|
||||||
gimp_item_get_offset_y (GIMP_ITEM (drawable)));
|
gimp_item_get_offset_y (GIMP_ITEM (group)));
|
||||||
|
|
||||||
/* reset, the actual format is right now */
|
/* reset, the actual format is right now */
|
||||||
private->convert_format = NULL;
|
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 *
|
static const Babl *
|
||||||
|
@ -210,6 +210,49 @@ static void gimp_layer_srgb_to_pixel (GimpPickable *pickable,
|
|||||||
const Babl *format,
|
const Babl *format,
|
||||||
gpointer pixel);
|
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
|
static gboolean
|
||||||
gimp_layer_real_get_excludes_backdrop (GimpLayer *layer);
|
gimp_layer_real_get_excludes_backdrop (GimpLayer *layer);
|
||||||
|
|
||||||
@ -406,6 +449,13 @@ gimp_layer_class_init (GimpLayerClass *klass)
|
|||||||
klass->apply_mask_changed = NULL;
|
klass->apply_mask_changed = NULL;
|
||||||
klass->edit_mask_changed = NULL;
|
klass->edit_mask_changed = NULL;
|
||||||
klass->show_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;
|
klass->get_excludes_backdrop = gimp_layer_real_get_excludes_backdrop;
|
||||||
|
|
||||||
g_object_class_install_property (object_class, PROP_OPACITY,
|
g_object_class_install_property (object_class, PROP_OPACITY,
|
||||||
@ -995,17 +1045,7 @@ gimp_layer_translate (GimpItem *item,
|
|||||||
if (push_undo)
|
if (push_undo)
|
||||||
gimp_image_undo_push_item_displace (gimp_item_get_image (item), NULL, item);
|
gimp_image_undo_push_item_displace (gimp_item_get_image (item), NULL, item);
|
||||||
|
|
||||||
/* update the old region */
|
GIMP_LAYER_GET_CLASS (layer)->translate (layer, offset_x, offset_y);
|
||||||
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);
|
|
||||||
|
|
||||||
if (layer->mask)
|
if (layer->mask)
|
||||||
{
|
{
|
||||||
@ -1029,9 +1069,9 @@ gimp_layer_scale (GimpItem *item,
|
|||||||
{
|
{
|
||||||
GimpLayer *layer = GIMP_LAYER (item);
|
GimpLayer *layer = GIMP_LAYER (item);
|
||||||
|
|
||||||
GIMP_ITEM_CLASS (parent_class)->scale (item, new_width, new_height,
|
GIMP_LAYER_GET_CLASS (layer)->scale (layer, new_width, new_height,
|
||||||
new_offset_x, new_offset_y,
|
new_offset_x, new_offset_y,
|
||||||
interpolation_type, progress);
|
interpolation_type, progress);
|
||||||
|
|
||||||
if (layer->mask)
|
if (layer->mask)
|
||||||
gimp_item_scale (GIMP_ITEM (layer->mask),
|
gimp_item_scale (GIMP_ITEM (layer->mask),
|
||||||
@ -1051,15 +1091,9 @@ gimp_layer_resize (GimpItem *item,
|
|||||||
{
|
{
|
||||||
GimpLayer *layer = GIMP_LAYER (item);
|
GimpLayer *layer = GIMP_LAYER (item);
|
||||||
|
|
||||||
if (fill_type == GIMP_FILL_TRANSPARENT &&
|
GIMP_LAYER_GET_CLASS (layer)->resize (layer, context, fill_type,
|
||||||
! gimp_drawable_has_alpha (GIMP_DRAWABLE (layer)))
|
new_width, new_height,
|
||||||
{
|
offset_x, offset_y);
|
||||||
fill_type = GIMP_FILL_BACKGROUND;
|
|
||||||
}
|
|
||||||
|
|
||||||
GIMP_ITEM_CLASS (parent_class)->resize (item, context, fill_type,
|
|
||||||
new_width, new_height,
|
|
||||||
offset_x, offset_y);
|
|
||||||
|
|
||||||
if (layer->mask)
|
if (layer->mask)
|
||||||
gimp_item_resize (GIMP_ITEM (layer->mask), context, GIMP_FILL_TRANSPARENT,
|
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);
|
GimpLayer *layer = GIMP_LAYER (item);
|
||||||
|
|
||||||
GIMP_ITEM_CLASS (parent_class)->flip (item, context, flip_type, axis,
|
GIMP_LAYER_GET_CLASS (layer)->flip (layer, context, flip_type, axis,
|
||||||
clip_result);
|
clip_result);
|
||||||
|
|
||||||
if (layer->mask)
|
if (layer->mask)
|
||||||
gimp_item_flip (GIMP_ITEM (layer->mask), context,
|
gimp_item_flip (GIMP_ITEM (layer->mask), context,
|
||||||
@ -1093,9 +1127,9 @@ gimp_layer_rotate (GimpItem *item,
|
|||||||
{
|
{
|
||||||
GimpLayer *layer = GIMP_LAYER (item);
|
GimpLayer *layer = GIMP_LAYER (item);
|
||||||
|
|
||||||
GIMP_ITEM_CLASS (parent_class)->rotate (item, context,
|
GIMP_LAYER_GET_CLASS (layer)->rotate (layer, context,
|
||||||
rotate_type, center_x, center_y,
|
rotate_type, center_x, center_y,
|
||||||
clip_result);
|
clip_result);
|
||||||
|
|
||||||
if (layer->mask)
|
if (layer->mask)
|
||||||
gimp_item_rotate (GIMP_ITEM (layer->mask), context,
|
gimp_item_rotate (GIMP_ITEM (layer->mask), context,
|
||||||
@ -1113,15 +1147,10 @@ gimp_layer_transform (GimpItem *item,
|
|||||||
{
|
{
|
||||||
GimpLayer *layer = GIMP_LAYER (item);
|
GimpLayer *layer = GIMP_LAYER (item);
|
||||||
|
|
||||||
/* FIXME: make interpolated transformations work on layers without alpha */
|
GIMP_LAYER_GET_CLASS (layer)->transform (layer, context, matrix, direction,
|
||||||
if (interpolation_type != GIMP_INTERPOLATION_NONE &&
|
interpolation_type,
|
||||||
! gimp_drawable_has_alpha (GIMP_DRAWABLE (item)))
|
clip_result,
|
||||||
gimp_layer_add_alpha (layer);
|
progress);
|
||||||
|
|
||||||
GIMP_ITEM_CLASS (parent_class)->transform (item, context, matrix, direction,
|
|
||||||
interpolation_type,
|
|
||||||
clip_result,
|
|
||||||
progress);
|
|
||||||
|
|
||||||
if (layer->mask)
|
if (layer->mask)
|
||||||
gimp_item_transform (GIMP_ITEM (layer->mask), context,
|
gimp_item_transform (GIMP_ITEM (layer->mask), context,
|
||||||
@ -1190,57 +1219,12 @@ gimp_layer_convert_type (GimpDrawable *drawable,
|
|||||||
gboolean push_undo,
|
gboolean push_undo,
|
||||||
GimpProgress *progress)
|
GimpProgress *progress)
|
||||||
{
|
{
|
||||||
GimpLayer *layer = GIMP_LAYER (drawable);
|
GimpLayer *layer = GIMP_LAYER (drawable);
|
||||||
GeglBuffer *src_buffer;
|
|
||||||
GeglBuffer *dest_buffer;
|
|
||||||
|
|
||||||
if (layer_dither_type == GEGL_DITHER_NONE)
|
GIMP_LAYER_GET_CLASS (layer)->convert_type (layer, dest_image, new_format,
|
||||||
{
|
dest_profile, layer_dither_type,
|
||||||
src_buffer = g_object_ref (gimp_drawable_get_buffer (drawable));
|
mask_dither_type, push_undo,
|
||||||
}
|
progress);
|
||||||
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);
|
|
||||||
|
|
||||||
if (layer->mask &&
|
if (layer->mask &&
|
||||||
gimp_babl_format_get_precision (new_format) !=
|
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);
|
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
|
static gboolean
|
||||||
gimp_layer_real_get_excludes_backdrop (GimpLayer *layer)
|
gimp_layer_real_get_excludes_backdrop (GimpLayer *layer)
|
||||||
{
|
{
|
||||||
|
@ -67,20 +67,63 @@ struct _GimpLayerClass
|
|||||||
GimpDrawableClass parent_class;
|
GimpDrawableClass parent_class;
|
||||||
|
|
||||||
/* signals */
|
/* signals */
|
||||||
void (* opacity_changed) (GimpLayer *layer);
|
void (* opacity_changed) (GimpLayer *layer);
|
||||||
void (* mode_changed) (GimpLayer *layer);
|
void (* mode_changed) (GimpLayer *layer);
|
||||||
void (* blend_space_changed) (GimpLayer *layer);
|
void (* blend_space_changed) (GimpLayer *layer);
|
||||||
void (* composite_space_changed) (GimpLayer *layer);
|
void (* composite_space_changed) (GimpLayer *layer);
|
||||||
void (* composite_mode_changed) (GimpLayer *layer);
|
void (* composite_mode_changed) (GimpLayer *layer);
|
||||||
void (* excludes_backdrop_changed) (GimpLayer *layer);
|
void (* excludes_backdrop_changed) (GimpLayer *layer);
|
||||||
void (* lock_alpha_changed) (GimpLayer *layer);
|
void (* lock_alpha_changed) (GimpLayer *layer);
|
||||||
void (* mask_changed) (GimpLayer *layer);
|
void (* mask_changed) (GimpLayer *layer);
|
||||||
void (* apply_mask_changed) (GimpLayer *layer);
|
void (* apply_mask_changed) (GimpLayer *layer);
|
||||||
void (* edit_mask_changed) (GimpLayer *layer);
|
void (* edit_mask_changed) (GimpLayer *layer);
|
||||||
void (* show_mask_changed) (GimpLayer *layer);
|
void (* show_mask_changed) (GimpLayer *layer);
|
||||||
|
|
||||||
/* virtual functions */
|
/* 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);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -85,14 +85,6 @@ static gboolean gimp_text_layer_rename (GimpItem *item,
|
|||||||
const gchar *undo_desc,
|
const gchar *undo_desc,
|
||||||
GError **error);
|
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,
|
static void gimp_text_layer_set_buffer (GimpDrawable *drawable,
|
||||||
gboolean push_undo,
|
gboolean push_undo,
|
||||||
const gchar *undo_desc,
|
const gchar *undo_desc,
|
||||||
@ -107,6 +99,15 @@ static void gimp_text_layer_push_undo (GimpDrawable *drawable,
|
|||||||
gint width,
|
gint width,
|
||||||
gint height);
|
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 void gimp_text_layer_text_changed (GimpTextLayer *layer);
|
||||||
static gboolean gimp_text_layer_render (GimpTextLayer *layer);
|
static gboolean gimp_text_layer_render (GimpTextLayer *layer);
|
||||||
static void gimp_text_layer_render_layout (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);
|
GimpViewableClass *viewable_class = GIMP_VIEWABLE_CLASS (klass);
|
||||||
GimpItemClass *item_class = GIMP_ITEM_CLASS (klass);
|
GimpItemClass *item_class = GIMP_ITEM_CLASS (klass);
|
||||||
GimpDrawableClass *drawable_class = GIMP_DRAWABLE_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->finalize = gimp_text_layer_finalize;
|
||||||
object_class->get_property = gimp_text_layer_get_property;
|
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->rotate_desc = _("Rotate Text Layer");
|
||||||
item_class->transform_desc = _("Transform 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->set_buffer = gimp_text_layer_set_buffer;
|
||||||
drawable_class->push_undo = gimp_text_layer_push_undo;
|
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,
|
GIMP_CONFIG_PROP_OBJECT (object_class, PROP_TEXT,
|
||||||
"text",
|
"text",
|
||||||
NULL, NULL,
|
NULL, NULL,
|
||||||
@ -314,44 +317,6 @@ gimp_text_layer_rename (GimpItem *item,
|
|||||||
return FALSE;
|
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
|
static void
|
||||||
gimp_text_layer_set_buffer (GimpDrawable *drawable,
|
gimp_text_layer_set_buffer (GimpDrawable *drawable,
|
||||||
gboolean push_undo,
|
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 */
|
/* public functions */
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user