diff --git a/ChangeLog b/ChangeLog index 7dadbffb42..a35f7f2cb2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2008-11-05 Michael Natterer + + This should remove any image or viewable dependency from the + projection (apart from the projectable's get_image() method, but + that one is not supposed to return the projection's model but + rather the image the projection is part of). + + * app/core/gimpprojectable.[ch]: add vfunc get_size() which + completes the API needed for GEGL projection. + + Add vfuncs get_layers(), get_channels(), get_components() and + get_colormap() which are needed for the legacy projection code. + + * app/core/gimpimage.c: implement the new methods. + + * app/core/gimpprojection.c + * app/core/gimpprojection-construct.c: use them and remove all + calls to image and viewable API. + 2008-11-05 Sven Neumann * po-libgimp/Makefile.in.in diff --git a/app/core/gimpimage.c b/app/core/gimpimage.c index 50298ecb22..7620ddfc56 100644 --- a/app/core/gimpimage.c +++ b/app/core/gimpimage.c @@ -172,8 +172,9 @@ static const guint8 * gimp_image_get_icc_profile (GimpColorManaged *managed, static void gimp_image_projectable_flush (GimpProjectable *projectable, gboolean invalidate_preview); -static GimpImage * gimp_image_get_image (GimpProjectable *projectable); -static GeglNode * gimp_image_get_graph (GimpProjectable *projectable); +static GeglNode * gimp_image_get_graph (GimpProjectable *projectable); +static GimpImage * gimp_image_get_image (GimpProjectable *projectable); +static gboolean * gimp_image_get_components (GimpProjectable *projectable); static void gimp_image_mask_update (GimpDrawable *drawable, gint x, @@ -564,8 +565,13 @@ gimp_projectable_iface_init (GimpProjectableInterface *iface) { iface->flush = gimp_image_projectable_flush; iface->get_image = gimp_image_get_image; + iface->get_size = (void (*) (GimpProjectable*, gint*, gint*)) gimp_image_get_size; iface->get_graph = gimp_image_get_graph; - iface->invalidate_preview = (void (*) (GimpProjectable *p)) gimp_viewable_invalidate_preview; + iface->invalidate_preview = (void (*) (GimpProjectable*)) gimp_viewable_invalidate_preview; + iface->get_layers = (GList * (*) (GimpProjectable*)) gimp_image_get_layer_iter; + iface->get_channels = (GList * (*) (GimpProjectable*)) gimp_image_get_channel_iter; + iface->get_components = gimp_image_get_components; + iface->get_colormap = (const guchar * (*) (GimpProjectable*)) gimp_image_get_colormap; } static void @@ -1190,6 +1196,14 @@ gimp_image_get_image (GimpProjectable *projectable) return GIMP_IMAGE (projectable); } +static gboolean * +gimp_image_get_components (GimpProjectable *projectable) +{ + GimpImage *image = GIMP_IMAGE (projectable); + + return image->visible; +} + static GeglNode * gimp_image_get_graph (GimpProjectable *projectable) { diff --git a/app/core/gimpprojectable.c b/app/core/gimpprojectable.c index a13fbc6e65..21106827e5 100644 --- a/app/core/gimpprojectable.c +++ b/app/core/gimpprojectable.c @@ -165,6 +165,26 @@ gimp_projectable_get_image (GimpProjectable *projectable) return NULL; } +void +gimp_projectable_get_size (GimpProjectable *projectable, + gint *width, + gint *height) +{ + GimpProjectableInterface *iface; + + g_return_if_fail (GIMP_IS_PROJECTABLE (projectable)); + g_return_if_fail (width != NULL); + g_return_if_fail (height != NULL); + + iface = GIMP_PROJECTABLE_GET_INTERFACE (projectable); + + *width = 0; + *height = 0; + + if (iface->get_size) + iface->get_size (projectable, width, height); +} + GeglNode * gimp_projectable_get_graph (GimpProjectable *projectable) { @@ -192,3 +212,63 @@ gimp_projectable_invalidate_preview (GimpProjectable *projectable) if (iface->invalidate_preview) iface->invalidate_preview (projectable); } + +GList * +gimp_projectable_get_layers (GimpProjectable *projectable) +{ + GimpProjectableInterface *iface; + + g_return_val_if_fail (GIMP_IS_PROJECTABLE (projectable), NULL); + + iface = GIMP_PROJECTABLE_GET_INTERFACE (projectable); + + if (iface->get_layers) + return iface->get_layers (projectable); + + return NULL; +} + +GList * +gimp_projectable_get_channels (GimpProjectable *projectable) +{ + GimpProjectableInterface *iface; + + g_return_val_if_fail (GIMP_IS_PROJECTABLE (projectable), NULL); + + iface = GIMP_PROJECTABLE_GET_INTERFACE (projectable); + + if (iface->get_channels) + return iface->get_channels (projectable); + + return NULL; +} + +gboolean * +gimp_projectable_get_components (GimpProjectable *projectable) +{ + GimpProjectableInterface *iface; + + g_return_val_if_fail (GIMP_IS_PROJECTABLE (projectable), NULL); + + iface = GIMP_PROJECTABLE_GET_INTERFACE (projectable); + + if (iface->get_components) + return iface->get_components (projectable); + + return NULL; +} + +const guchar * +gimp_projectable_get_colormap (GimpProjectable *projectable) +{ + GimpProjectableInterface *iface; + + g_return_val_if_fail (GIMP_IS_PROJECTABLE (projectable), NULL); + + iface = GIMP_PROJECTABLE_GET_INTERFACE (projectable); + + if (iface->get_colormap) + return iface->get_colormap (projectable); + + return NULL; +} diff --git a/app/core/gimpprojectable.h b/app/core/gimpprojectable.h index 84c93adc37..ff22773b6c 100644 --- a/app/core/gimpprojectable.h +++ b/app/core/gimpprojectable.h @@ -36,36 +36,54 @@ struct _GimpProjectableInterface GTypeInterface base_iface; /* signals */ - void (* update) (GimpProjectable *projectable, - gint x, - gint y, - gint width, - gint height); - void (* flush) (GimpProjectable *projectable, - gboolean invalidate_preview); - void (* structure_changed) (GimpProjectable *projectable); + void (* update) (GimpProjectable *projectable, + gint x, + gint y, + gint width, + gint height); + void (* flush) (GimpProjectable *projectable, + gboolean invalidate_preview); + void (* structure_changed) (GimpProjectable *projectable); /* virtual functions */ - GimpImage * (* get_image) (GimpProjectable *projectable); - GeglNode * (* get_graph) (GimpProjectable *projectable); - void (* invalidate_preview) (GimpProjectable *projectable); + GimpImage * (* get_image) (GimpProjectable *projectable); + void (* get_size) (GimpProjectable *projectable, + gint *width, + gint *height); + GeglNode * (* get_graph) (GimpProjectable *projectable); + void (* invalidate_preview) (GimpProjectable *projectable); + + /* legacy API virtual functions */ + GList * (* get_layers) (GimpProjectable *projectable); + GList * (* get_channels) (GimpProjectable *projectable); + gboolean * (* get_components) (GimpProjectable *projectable); + const guchar * (* get_colormap) (GimpProjectable *projectable); }; -GType gimp_projectable_interface_get_type (void) G_GNUC_CONST; +GType gimp_projectable_interface_get_type (void) G_GNUC_CONST; -void gimp_projectable_update (GimpProjectable *projectable, - gint x, - gint y, - gint width, - gint height); -void gimp_projectable_flush (GimpProjectable *projectable, - gboolean preview_invalidated); -void gimp_projectable_structure_changed (GimpProjectable *projectable); +void gimp_projectable_update (GimpProjectable *projectable, + gint x, + gint y, + gint width, + gint height); +void gimp_projectable_flush (GimpProjectable *projectable, + gboolean preview_invalidated); +void gimp_projectable_structure_changed (GimpProjectable *projectable); -GimpImage * gimp_projectable_get_image (GimpProjectable *projectable); -GeglNode * gimp_projectable_get_graph (GimpProjectable *projectable); -void gimp_projectable_invalidate_preview (GimpProjectable *projectable); +GimpImage * gimp_projectable_get_image (GimpProjectable *projectable); +void gimp_projectable_get_size (GimpProjectable *projectable, + gint *width, + gint *height); +GeglNode * gimp_projectable_get_graph (GimpProjectable *projectable); +void gimp_projectable_invalidate_preview (GimpProjectable *projectable); + +/* legacy API */ +GList * gimp_projectable_get_layers (GimpProjectable *projectable); +GList * gimp_projectable_get_channels (GimpProjectable *projectable); +gboolean * gimp_projectable_get_components (GimpProjectable *projectable); +const guchar * gimp_projectable_get_colormap (GimpProjectable *projectable); #endif /* __GIMP_PROJECTABLE_H__ */ diff --git a/app/core/gimpprojection-construct.c b/app/core/gimpprojection-construct.c index d41fb64cf6..03cd480ab1 100644 --- a/app/core/gimpprojection-construct.c +++ b/app/core/gimpprojection-construct.c @@ -29,8 +29,6 @@ #include "paint-funcs/paint-funcs.h" -#include "gimpimage.h" -#include "gimpimage-colormap.h" #include "gimplayer.h" #include "gimplayer-floating-sel.h" #include "gimplayermask.h" @@ -101,24 +99,27 @@ gimp_projection_construct (GimpProjection *proj, g_return_if_fail (GIMP_IS_PROJECTION (proj)); #if 0 - GimpImage *image = gimp_projectable_get_image (proj->projectable); + GList *layers = gimp_projectable_get_layers (proj->projectable); - if (gimp_container_num_children (image->layers) == 1) /* a single layer */ + if (layers && ! layers->next) /* a single layer */ { - GimpDrawable *layer; + GimpLayer *layer = layers->data; + GimpDrawable *drawable = GIMP_DRAWABLE (layer); + GimpItem *item = GIMP_ITEM (layer); + gint width, height; gint off_x, off_y; - layer = GIMP_DRAWABLE (gimp_image_get_layer_by_index (image, 0)); + gimp_projectable_get_size (proj->projectable, &width, &height); - gimp_item_get_offset (GIMP_ITEM (layer), &off_x, &off_y); + gimp_item_get_offset (item, &off_x, &off_y); - if (gimp_drawable_has_alpha (layer) && - gimp_item_get_visible (GIMP_ITEM (layer)) && - gimp_item_get_width (GIMP_ITEM (layer)) == image->width && - gimp_item_get_height (GIMP_ITEM (layer)) == image->height && - ! gimp_drawable_is_indexed (layer) && - gimp_layer_get_opacity (GIMP_LAYER (layer)) == GIMP_OPACITY_OPAQUE && - off_x == 0 && + if (gimp_drawable_has_alpha (drawable) && + gimp_item_get_visible (item) && + gimp_item_get_width (item) == width && + gimp_item_get_height (item) == height && + ! gimp_drawable_is_indexed (layer) && + gimp_layer_get_opacity (layer) == GIMP_OPACITY_OPAQUE && + off_x == 0 && off_y == 0) { PixelRegion srcPR, destPR; @@ -201,32 +202,30 @@ gimp_projection_construct_layers (GimpProjection *proj, gint w, gint h) { - GimpImage *image = gimp_projectable_get_image (proj->projectable); GimpLayer *layer; GList *list; - GList *reverse_list; + GList *reverse_list = NULL; gint x1, y1, x2, y2; gint off_x; gint off_y; - /* composite the floating selection if it exists */ - if ((layer = gimp_image_floating_sel (image))) - floating_sel_composite (layer, x, y, w, h, FALSE); - - reverse_list = NULL; - - for (list = gimp_image_get_layer_iter (image); + for (list = gimp_projectable_get_layers (proj->projectable); list; list = g_list_next (list)) { layer = list->data; - /* only add layers that are visible and not floating selections - * to the list - */ - if (! gimp_layer_is_floating_sel (layer) && - gimp_item_get_visible (GIMP_ITEM (layer))) + if (gimp_layer_is_floating_sel (layer)) { + /* composite the floating selection if it exists + */ + floating_sel_composite (layer, x, y, w, h, FALSE); + } + else if (gimp_item_get_visible (GIMP_ITEM (layer))) + { + /* only add layers that are visible and not floating selections + * to the list + */ reverse_list = g_list_prepend (reverse_list, layer); } } @@ -327,12 +326,11 @@ gimp_projection_construct_channels (GimpProjection *proj, gint w, gint h) { - GimpImage *image = gimp_projectable_get_image (proj->projectable); - GList *list; - GList *reverse_list = NULL; + GList *list; + GList *reverse_list = NULL; /* reverse the channel list */ - for (list = gimp_image_get_channel_iter (image); + for (list = gimp_projectable_get_channels (proj->projectable); list; list = g_list_next (list)) { @@ -386,28 +384,29 @@ gimp_projection_initialize (GimpProjection *proj, gint w, gint h) { - GimpImage *image = gimp_projectable_get_image (proj->projectable); - GList *list; - gboolean coverage = FALSE; + GList *list; + gboolean coverage = FALSE; - for (list = gimp_image_get_layer_iter (image); + for (list = gimp_projectable_get_layers (proj->projectable); list; list = g_list_next (list)) { - GimpItem *item = list->data; - gint off_x, off_y; + GimpLayer *layer = list->data; + GimpDrawable *drawable = GIMP_DRAWABLE (layer); + GimpItem *item = GIMP_ITEM (layer); + gint off_x, off_y; gimp_item_get_offset (item, &off_x, &off_y); - if (gimp_item_get_visible (item) && - ! gimp_drawable_has_alpha (GIMP_DRAWABLE (item)) && - ! gimp_layer_get_mask (GIMP_LAYER (item)) && - gimp_layer_get_mode (GIMP_LAYER (item)) == GIMP_NORMAL_MODE && - gimp_layer_get_opacity (GIMP_LAYER (item)) == GIMP_OPACITY_OPAQUE && - (off_x <= x) && - (off_y <= y) && - (off_x + gimp_item_get_width (item) >= x + w) && - (off_y + gimp_item_get_height (item) >= y + h)) + if (gimp_item_get_visible (item) && + ! gimp_drawable_has_alpha (drawable) && + ! gimp_layer_get_mask (layer) && + gimp_layer_get_mode (layer) == GIMP_NORMAL_MODE && + gimp_layer_get_opacity (layer) == GIMP_OPACITY_OPAQUE && + off_x <= x && + off_y <= y && + (off_x + gimp_item_get_width (item)) >= (x + w) && + (off_y + gimp_item_get_height (item)) >= (y + h)) { coverage = TRUE; break; @@ -432,14 +431,12 @@ project_intensity (GimpProjection *proj, PixelRegion *dest, PixelRegion *mask) { - GimpImage *image = gimp_projectable_get_image (proj->projectable); - if (proj->construct_flag) { combine_regions (dest, src, dest, mask, NULL, gimp_layer_get_opacity (layer) * 255.999, gimp_layer_get_mode (layer), - image->visible, + gimp_projectable_get_components (proj->projectable), COMBINE_INTEN_A_INTEN); } else @@ -447,7 +444,7 @@ project_intensity (GimpProjection *proj, initial_region (src, dest, mask, NULL, gimp_layer_get_opacity (layer) * 255.999, gimp_layer_get_mode (layer), - image->visible, + gimp_projectable_get_components (proj->projectable), INITIAL_INTENSITY); } } @@ -459,14 +456,12 @@ project_intensity_alpha (GimpProjection *proj, PixelRegion *dest, PixelRegion *mask) { - GimpImage *image = gimp_projectable_get_image (proj->projectable); - if (proj->construct_flag) { combine_regions (dest, src, dest, mask, NULL, gimp_layer_get_opacity (layer) * 255.999, gimp_layer_get_mode (layer), - image->visible, + gimp_projectable_get_components (proj->projectable), COMBINE_INTEN_A_INTEN_A); } else @@ -474,7 +469,7 @@ project_intensity_alpha (GimpProjection *proj, initial_region (src, dest, mask, NULL, gimp_layer_get_opacity (layer) * 255.999, gimp_layer_get_mode (layer), - image->visible, + gimp_projectable_get_components (proj->projectable), INITIAL_INTENSITY_ALPHA); } } @@ -486,25 +481,22 @@ project_indexed (GimpProjection *proj, PixelRegion *dest, PixelRegion *mask) { - GimpImage *image = gimp_projectable_get_image (proj->projectable); - const guchar *colormap = gimp_image_get_colormap (image); - - g_return_if_fail (colormap != NULL); - if (proj->construct_flag) { - combine_regions (dest, src, dest, mask, colormap, + combine_regions (dest, src, dest, mask, + gimp_projectable_get_colormap (proj->projectable), gimp_layer_get_opacity (layer) * 255.999, gimp_layer_get_mode (layer), - image->visible, + gimp_projectable_get_components (proj->projectable), COMBINE_INTEN_A_INDEXED); } else { - initial_region (src, dest, mask, colormap, + initial_region (src, dest, mask, + gimp_projectable_get_colormap (proj->projectable), gimp_layer_get_opacity (layer) * 255.999, gimp_layer_get_mode (layer), - image->visible, + gimp_projectable_get_components (proj->projectable), INITIAL_INDEXED); } } @@ -516,25 +508,22 @@ project_indexed_alpha (GimpProjection *proj, PixelRegion *dest, PixelRegion *mask) { - GimpImage *image = gimp_projectable_get_image (proj->projectable); - const guchar *colormap = gimp_image_get_colormap (image); - - g_return_if_fail (colormap != NULL); - if (proj->construct_flag) { - combine_regions (dest, src, dest, mask, colormap, + combine_regions (dest, src, dest, mask, + gimp_projectable_get_colormap (proj->projectable), gimp_layer_get_opacity (layer) * 255.999, gimp_layer_get_mode (layer), - image->visible, + gimp_projectable_get_components (proj->projectable), COMBINE_INTEN_A_INDEXED_A); } else { - initial_region (src, dest, mask, colormap, + initial_region (src, dest, mask, + gimp_projectable_get_colormap (proj->projectable), gimp_layer_get_opacity (layer) * 255.999, gimp_layer_get_mode (layer), - image->visible, + gimp_projectable_get_components (proj->projectable), INITIAL_INDEXED_ALPHA); } } diff --git a/app/core/gimpprojection.c b/app/core/gimpprojection.c index 2b8e716249..67c367a92a 100644 --- a/app/core/gimpprojection.c +++ b/app/core/gimpprojection.c @@ -408,8 +408,7 @@ gimp_projection_get_tiles_at_level (GimpProjection *proj, { gint width, height; - gimp_viewable_get_size (GIMP_VIEWABLE (proj->projectable), - &width, &height); + gimp_projectable_get_size (proj->projectable, &width, &height); proj->pyramid = tile_pyramid_new (gimp_projection_get_image_type (GIMP_PICKABLE (proj)), width, height); @@ -448,7 +447,7 @@ gimp_projection_get_level (GimpProjection *proj, { gint width, height; - gimp_viewable_get_size (GIMP_VIEWABLE (proj->projectable), &width, &height); + gimp_projectable_get_size (proj->projectable, &width, &height); return tile_pyramid_get_level (width, height, MAX (scale_x, scale_y)); } @@ -502,7 +501,7 @@ gimp_projection_add_update_area (GimpProjection *proj, GimpArea *area; gint width, height; - gimp_viewable_get_size (GIMP_VIEWABLE (proj->projectable), &width, &height); + gimp_projectable_get_size (proj->projectable, &width, &height); area = gimp_area_new (CLAMP (x, 0, width), CLAMP (y, 0, height), @@ -717,7 +716,7 @@ gimp_projection_paint_area (GimpProjection *proj, gint width, height; gint x1, y1, x2, y2; - gimp_viewable_get_size (GIMP_VIEWABLE (proj->projectable), &width, &height); + gimp_projectable_get_size (proj->projectable, &width, &height); /* Bounds check */ x1 = CLAMP (x, 0, width); @@ -793,7 +792,7 @@ gimp_projection_projectable_changed (GimpProjectable *projectable, proj->pyramid = NULL; } - gimp_viewable_get_size (GIMP_VIEWABLE (projectable), &width, &height); + gimp_projectable_get_size (projectable, &width, &height); gimp_projection_add_update_area (proj, 0, 0, width, height); }