[gimp] app: add gimp_layer_get_effective_mode()



commit bdba43e4954198e3205be30076bfb0a5c2d28bfb
Author: Ell <ell_se yahoo com>
Date:   Wed Dec 6 13:10:38 2017 -0500

    app: add gimp_layer_get_effective_mode()
    
    gimp_layer_get_effective_mode() returns the actual layer mode,
    blend space, comosite space, and composite mode used for the
    layer's mode node, allowing them to be different from the values of
    the corresponding layer properties.  The aim is to allow us to
    replace expensive layer configurations with cheaper but equivalent
    ones transparently.  This is used in the next commit to replace
    pass-through groups with normal groups under certain conditions.
    
    The effective values are computed by the new
    GimpLayer::get_effective_mode() virtual function.  The default
    implementation provided by GimpLayer returns the corresponding
    layer properties as-is (replaceing AUTO with concrete values).
    Subclasses can override this function, providing more
    sophisticated logic.

 app/core/gimplayer.c |  152 +++++++++++++++++++++++++++++++++-----------------
 app/core/gimplayer.h |   41 ++++++++++----
 2 files changed, 129 insertions(+), 64 deletions(-)
---
diff --git a/app/core/gimplayer.c b/app/core/gimplayer.c
index 8e36bf3..fe33e92 100644
--- a/app/core/gimplayer.c
+++ b/app/core/gimplayer.c
@@ -64,6 +64,7 @@ enum
   BLEND_SPACE_CHANGED,
   COMPOSITE_SPACE_CHANGED,
   COMPOSITE_MODE_CHANGED,
+  EFFECTIVE_MODE_CHANGED,
   EXCLUDES_BACKDROP_CHANGED,
   LOCK_ALPHA_CHANGED,
   MASK_CHANGED,
@@ -253,6 +254,11 @@ static void       gimp_layer_real_convert_type  (GimpLayer          *layer,
                                                  GeglDitherMethod    mask_dither_type,
                                                  gboolean            push_undo,
                                                  GimpProgress       *progress);
+static void  gimp_layer_real_get_effective_mode (GimpLayer          *layer,
+                                                 GimpLayerMode          *mode,
+                                                 GimpLayerColorSpace    *blend_space,
+                                                 GimpLayerColorSpace    *composite_space,
+                                                 GimpLayerCompositeMode *composite_mode);
 static gboolean
           gimp_layer_real_get_excludes_backdrop (GimpLayer          *layer);
 
@@ -330,6 +336,15 @@ gimp_layer_class_init (GimpLayerClass *klass)
                   gimp_marshal_VOID__VOID,
                   G_TYPE_NONE, 0);
 
+  layer_signals[EFFECTIVE_MODE_CHANGED] =
+    g_signal_new ("effective-mode-changed",
+                  G_TYPE_FROM_CLASS (klass),
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (GimpLayerClass, effective_mode_changed),
+                  NULL, NULL,
+                  gimp_marshal_VOID__VOID,
+                  G_TYPE_NONE, 0);
+
   layer_signals[EXCLUDES_BACKDROP_CHANGED] =
     g_signal_new ("excludes-backdrop-changed",
                   G_TYPE_FROM_CLASS (klass),
@@ -456,6 +471,7 @@ gimp_layer_class_init (GimpLayerClass *klass)
   klass->rotate                       = gimp_layer_real_rotate;
   klass->transform                    = gimp_layer_real_transform;
   klass->convert_type                 = gimp_layer_real_convert_type;
+  klass->get_effective_mode           = gimp_layer_real_get_effective_mode;
   klass->get_excludes_backdrop        = gimp_layer_real_get_excludes_backdrop;
 
   g_object_class_install_property (object_class, PROP_OPACITY,
@@ -520,13 +536,17 @@ gimp_layer_class_init (GimpLayerClass *klass)
 static void
 gimp_layer_init (GimpLayer *layer)
 {
-  layer->opacity           = GIMP_OPACITY_OPAQUE;
-  layer->mode              = GIMP_LAYER_MODE_NORMAL;
-  layer->blend_space       = GIMP_LAYER_COLOR_SPACE_AUTO;
-  layer->composite_space   = GIMP_LAYER_COLOR_SPACE_AUTO;
-  layer->composite_mode    = GIMP_LAYER_COMPOSITE_AUTO;
-  layer->excludes_backdrop = FALSE;
-  layer->lock_alpha        = FALSE;
+  layer->opacity                   = GIMP_OPACITY_OPAQUE;
+  layer->mode                      = GIMP_LAYER_MODE_NORMAL;
+  layer->blend_space               = GIMP_LAYER_COLOR_SPACE_AUTO;
+  layer->composite_space           = GIMP_LAYER_COLOR_SPACE_AUTO;
+  layer->composite_mode            = GIMP_LAYER_COMPOSITE_AUTO;
+  layer->effective_mode            = layer->mode;
+  layer->effective_blend_space     = gimp_layer_get_real_blend_space (layer);
+  layer->effective_composite_space = gimp_layer_get_real_composite_space (layer);
+  layer->effective_composite_mode  = gimp_layer_get_real_composite_mode (layer);
+  layer->excludes_backdrop         = FALSE;
+  layer->lock_alpha                = FALSE;
 
   layer->mask       = NULL;
   layer->apply_mask = TRUE;
@@ -675,10 +695,10 @@ gimp_layer_update_mode_node (GimpLayer *layer)
     }
   else
     {
-      visible_mode            = layer->mode;
-      visible_blend_space     = layer->blend_space;
-      visible_composite_space = layer->composite_space;
-      visible_composite_mode  = layer->composite_mode;
+      visible_mode            = layer->effective_mode;
+      visible_blend_space     = layer->effective_blend_space;
+      visible_composite_space = layer->effective_composite_space;
+      visible_composite_mode  = layer->effective_composite_mode;
     }
 
   gimp_gegl_mode_node_set_mode (mode_node,
@@ -1546,13 +1566,26 @@ gimp_layer_real_convert_type (GimpLayer        *layer,
   g_object_unref (dest_buffer);
 }
 
+static void
+gimp_layer_real_get_effective_mode (GimpLayer              *layer,
+                                    GimpLayerMode          *mode,
+                                    GimpLayerColorSpace    *blend_space,
+                                    GimpLayerColorSpace    *composite_space,
+                                    GimpLayerCompositeMode *composite_mode)
+{
+  *mode            = gimp_layer_get_mode (layer);
+  *blend_space     = gimp_layer_get_real_blend_space (layer);
+  *composite_space = gimp_layer_get_real_composite_space (layer);
+  *composite_mode  = gimp_layer_get_real_composite_mode (layer);
+}
+
 static gboolean
 gimp_layer_real_get_excludes_backdrop (GimpLayer *layer)
 {
   GimpLayerCompositeRegion included_region;
 
   included_region = gimp_layer_mode_get_included_region (layer->mode,
-                                                         layer->composite_mode);
+                                                         layer->effective_composite_mode);
 
   return ! (included_region & GIMP_LAYER_COMPOSITE_REGION_DESTINATION);
 }
@@ -2383,11 +2416,7 @@ gimp_layer_set_mode (GimpLayer     *layer,
 
       g_object_thaw_notify (G_OBJECT (layer));
 
-      if (gimp_filter_peek_node (GIMP_FILTER (layer)))
-        gimp_layer_update_mode_node (layer);
-
-      gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, -1, -1);
-
+      gimp_layer_update_effective_mode (layer);
       gimp_layer_update_excludes_backdrop (layer);
     }
 }
@@ -2412,10 +2441,6 @@ gimp_layer_set_blend_space (GimpLayer           *layer,
 
   if (layer->blend_space != blend_space)
     {
-      GimpLayerColorSpace prev_real_blend_space;
-
-      prev_real_blend_space = gimp_layer_get_real_blend_space (layer);
-
       if (push_undo && gimp_item_is_attached (GIMP_ITEM (layer)))
         {
           GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
@@ -2428,13 +2453,7 @@ gimp_layer_set_blend_space (GimpLayer           *layer,
       g_signal_emit (layer, layer_signals[BLEND_SPACE_CHANGED], 0);
       g_object_notify (G_OBJECT (layer), "blend-space");
 
-      if (gimp_layer_get_real_blend_space (layer) != prev_real_blend_space)
-        {
-          if (gimp_filter_peek_node (GIMP_FILTER (layer)))
-            gimp_layer_update_mode_node (layer);
-
-          gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, -1, -1);
-        }
+      gimp_layer_update_effective_mode (layer);
     }
 }
 
@@ -2469,10 +2488,6 @@ gimp_layer_set_composite_space (GimpLayer           *layer,
 
   if (layer->composite_space != composite_space)
     {
-      GimpLayerColorSpace prev_real_composite_space;
-
-      prev_real_composite_space = gimp_layer_get_real_composite_space (layer);
-
       if (push_undo && gimp_item_is_attached (GIMP_ITEM (layer)))
         {
           GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
@@ -2485,13 +2500,7 @@ gimp_layer_set_composite_space (GimpLayer           *layer,
       g_signal_emit (layer, layer_signals[COMPOSITE_SPACE_CHANGED], 0);
       g_object_notify (G_OBJECT (layer), "composite-space");
 
-      if (gimp_layer_get_real_composite_space (layer) != prev_real_composite_space)
-        {
-          if (gimp_filter_peek_node (GIMP_FILTER (layer)))
-            gimp_layer_update_mode_node (layer);
-
-          gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, -1, -1);
-        }
+      gimp_layer_update_effective_mode (layer);
     }
 }
 
@@ -2526,10 +2535,6 @@ gimp_layer_set_composite_mode (GimpLayer              *layer,
 
   if (layer->composite_mode != composite_mode)
     {
-      GimpLayerCompositeMode prev_real_composite_mode;
-
-      prev_real_composite_mode = gimp_layer_get_real_composite_mode (layer);
-
       if (push_undo && gimp_item_is_attached (GIMP_ITEM (layer)))
         {
           GimpImage *image = gimp_item_get_image (GIMP_ITEM (layer));
@@ -2542,15 +2547,8 @@ gimp_layer_set_composite_mode (GimpLayer              *layer,
       g_signal_emit (layer, layer_signals[COMPOSITE_MODE_CHANGED], 0);
       g_object_notify (G_OBJECT (layer), "composite-mode");
 
-      if (gimp_layer_get_real_composite_mode (layer) != prev_real_composite_mode)
-        {
-          if (gimp_filter_peek_node (GIMP_FILTER (layer)))
-            gimp_layer_update_mode_node (layer);
-
-          gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, -1, -1);
-
-          gimp_layer_update_excludes_backdrop (layer);
-        }
+      gimp_layer_update_effective_mode (layer);
+      gimp_layer_update_excludes_backdrop (layer);
     }
 }
 
@@ -2573,6 +2571,21 @@ gimp_layer_get_real_composite_mode (GimpLayer *layer)
     return layer->composite_mode;
 }
 
+void
+gimp_layer_get_effective_mode (GimpLayer              *layer,
+                               GimpLayerMode          *mode,
+                               GimpLayerColorSpace    *blend_space,
+                               GimpLayerColorSpace    *composite_space,
+                               GimpLayerCompositeMode *composite_mode)
+{
+  g_return_if_fail (GIMP_IS_LAYER (layer));
+
+  if (mode)            *mode            = layer->effective_mode;
+  if (blend_space)     *blend_space     = layer->effective_blend_space;
+  if (composite_space) *composite_space = layer->effective_composite_space;
+  if (composite_mode)  *composite_mode  = layer->effective_composite_mode;
+}
+
 gboolean
 gimp_layer_get_excludes_backdrop (GimpLayer *layer)
 {
@@ -2630,6 +2643,41 @@ gimp_layer_can_lock_alpha (GimpLayer *layer)
 /*  protected functions  */
 
 void
+gimp_layer_update_effective_mode (GimpLayer *layer)
+{
+  GimpLayerMode          mode;
+  GimpLayerColorSpace    blend_space;
+  GimpLayerColorSpace    composite_space;
+  GimpLayerCompositeMode composite_mode;
+
+  g_return_if_fail (GIMP_IS_LAYER (layer));
+
+  GIMP_LAYER_GET_CLASS (layer)->get_effective_mode (layer,
+                                                    &mode,
+                                                    &blend_space,
+                                                    &composite_space,
+                                                    &composite_mode);
+
+  if (mode            != layer->effective_mode            ||
+      blend_space     != layer->effective_blend_space     ||
+      composite_space != layer->effective_composite_space ||
+      composite_mode  != layer->effective_composite_mode)
+    {
+      layer->effective_mode            = mode;
+      layer->effective_blend_space     = blend_space;
+      layer->effective_composite_space = composite_space;
+      layer->effective_composite_mode  = composite_mode;
+
+      g_signal_emit (layer, layer_signals[EFFECTIVE_MODE_CHANGED], 0);
+
+      if (gimp_filter_peek_node (GIMP_FILTER (layer)))
+        gimp_layer_update_mode_node (layer);
+
+      gimp_drawable_update (GIMP_DRAWABLE (layer), 0, 0, -1, -1);
+    }
+}
+
+void
 gimp_layer_update_excludes_backdrop (GimpLayer *layer)
 {
   gboolean excludes_backdrop;
diff --git a/app/core/gimplayer.h b/app/core/gimplayer.h
index b607688..76a287d 100644
--- a/app/core/gimplayer.h
+++ b/app/core/gimplayer.h
@@ -36,18 +36,22 @@ struct _GimpLayer
 {
   GimpDrawable            parent_instance;
 
-  gdouble                 opacity;            /*  layer opacity              */
-  GimpLayerMode           mode;               /*  layer combination mode     */
-  GimpLayerColorSpace     blend_space;        /*  layer blend space          */
-  GimpLayerColorSpace     composite_space;    /*  layer composite space      */
-  GimpLayerCompositeMode  composite_mode;     /*  layer composite mode       */
-  gboolean                excludes_backdrop;  /*  layer clips backdrop       */
-  gboolean                lock_alpha;         /*  lock the alpha channel     */
-
-  GimpLayerMask          *mask;               /*  possible layer mask        */
-  gboolean                apply_mask;         /*  controls mask application  */
-  gboolean                edit_mask;          /*  edit mask or layer?        */
-  gboolean                show_mask;          /*  show mask or layer?        */
+  gdouble                 opacity;                    /*  layer opacity                     */
+  GimpLayerMode           mode;                       /*  layer combination mode            */
+  GimpLayerColorSpace     blend_space;                /*  layer blend space                 */
+  GimpLayerColorSpace     composite_space;            /*  layer composite space             */
+  GimpLayerCompositeMode  composite_mode;             /*  layer composite mode              */
+  GimpLayerMode           effective_mode;             /*  layer effective combination mode  */
+  GimpLayerColorSpace     effective_blend_space;      /*  layer effective blend space       */
+  GimpLayerColorSpace     effective_composite_space;  /*  layer effective composite space   */
+  GimpLayerCompositeMode  effective_composite_mode;   /*  layer effective composite mode    */
+  gboolean                excludes_backdrop;          /*  layer clips backdrop              */
+  gboolean                lock_alpha;                 /*  lock the alpha channel            */
+
+  GimpLayerMask          *mask;                       /*  possible layer mask               */
+  gboolean                apply_mask;                 /*  controls mask application         */
+  gboolean                edit_mask;                  /*  edit mask or layer?               */
+  gboolean                show_mask;                  /*  show mask or layer?               */
 
   GeglNode               *layer_offset_node;
   GeglNode               *mask_offset_node;
@@ -72,6 +76,7 @@ struct _GimpLayerClass
   void     (* blend_space_changed)       (GimpLayer              *layer);
   void     (* composite_space_changed)   (GimpLayer              *layer);
   void     (* composite_mode_changed)    (GimpLayer              *layer);
+  void     (* effective_mode_changed)    (GimpLayer              *layer);
   void     (* excludes_backdrop_changed) (GimpLayer              *layer);
   void     (* lock_alpha_changed)        (GimpLayer              *layer);
   void     (* mask_changed)              (GimpLayer              *layer);
@@ -123,6 +128,11 @@ struct _GimpLayerClass
                                           GeglDitherMethod        mask_dither_type,
                                           gboolean                push_undo,
                                           GimpProgress           *progress);
+  void     (* get_effective_mode)        (GimpLayer              *layer,
+                                          GimpLayerMode          *mode,
+                                          GimpLayerColorSpace    *blend_space,
+                                          GimpLayerColorSpace    *composite_space,
+                                          GimpLayerCompositeMode *composite_mode);
   gboolean (* get_excludes_backdrop)     (GimpLayer              *layer);
 };
 
@@ -206,6 +216,12 @@ GimpLayerCompositeMode
 GimpLayerCompositeMode
            gimp_layer_get_real_composite_mode  (GimpLayer            *layer);
 
+void            gimp_layer_get_effective_mode  (GimpLayer            *layer,
+                                                GimpLayerMode          *mode,
+                                                GimpLayerColorSpace    *blend_space,
+                                                GimpLayerColorSpace    *composite_space,
+                                                GimpLayerCompositeMode *composite_mode);
+
 gboolean      gimp_layer_get_excludes_backdrop (GimpLayer            *layer);
 
 void            gimp_layer_set_lock_alpha      (GimpLayer            *layer,
@@ -217,6 +233,7 @@ gboolean        gimp_layer_can_lock_alpha      (GimpLayer            *layer);
 
 /*  protected  */
 
+void          gimp_layer_update_effective_mode (GimpLayer            *layer);
 void       gimp_layer_update_excludes_backdrop (GimpLayer            *layer);
 
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]