[gimp] app: move arrays of magic GimpLayerMode knowledge to gimp-layer-modes.c



commit 8771361cb9540110599cd2b4ca25568f1906d034
Author: Michael Natterer <mitch gimp org>
Date:   Tue Jan 31 01:33:11 2017 +0100

    app: move arrays of magic GimpLayerMode knowledge to gimp-layer-modes.c
    
    and provide API to access them.

 app/core/gimp-layer-modes.c         |  691 ++++++++++++++++++++++-------------
 app/core/gimp-layer-modes.h         |    3 +
 app/widgets/gimplayermodecombobox.c |  217 ++++--------
 3 files changed, 519 insertions(+), 392 deletions(-)
---
diff --git a/app/core/gimp-layer-modes.c b/app/core/gimp-layer-modes.c
index ce0f455..aab693a 100644
--- a/app/core/gimp-layer-modes.c
+++ b/app/core/gimp-layer-modes.c
@@ -28,6 +28,388 @@
 #include "gimp-layer-modes.h"
 
 
+/*  static variables  */
+
+static const GimpLayerMode layer_mode_group_default[] =
+{
+  GIMP_LAYER_MODE_NORMAL,
+  GIMP_LAYER_MODE_DISSOLVE,
+
+  GIMP_LAYER_MODE_LIGHTEN_ONLY,
+  GIMP_LAYER_MODE_LUMINANCE_LIGHTEN_ONLY,
+  GIMP_LAYER_MODE_SCREEN,
+  GIMP_LAYER_MODE_DODGE,
+  GIMP_LAYER_MODE_ADDITION,
+
+  GIMP_LAYER_MODE_DARKEN_ONLY,
+  GIMP_LAYER_MODE_LUMINANCE_DARKEN_ONLY,
+  GIMP_LAYER_MODE_MULTIPLY,
+  GIMP_LAYER_MODE_BURN,
+
+  GIMP_LAYER_MODE_OVERLAY,
+  GIMP_LAYER_MODE_SOFTLIGHT,
+  GIMP_LAYER_MODE_HARDLIGHT,
+  GIMP_LAYER_MODE_VIVID_LIGHT,
+  GIMP_LAYER_MODE_PIN_LIGHT,
+  GIMP_LAYER_MODE_LINEAR_LIGHT,
+
+  GIMP_LAYER_MODE_DIFFERENCE,
+  GIMP_LAYER_MODE_SUBTRACT,
+  GIMP_LAYER_MODE_GRAIN_EXTRACT,
+  GIMP_LAYER_MODE_GRAIN_MERGE,
+  GIMP_LAYER_MODE_DIVIDE,
+
+  GIMP_LAYER_MODE_LCH_HUE,
+  GIMP_LAYER_MODE_LCH_CHROMA,
+  GIMP_LAYER_MODE_LCH_COLOR,
+  GIMP_LAYER_MODE_LCH_LIGHTNESS,
+
+  GIMP_LAYER_MODE_EXCLUSION,
+  GIMP_LAYER_MODE_LINEAR_BURN
+};
+
+static const GimpLayerMode layer_mode_group_linear[] =
+{
+  GIMP_LAYER_MODE_NORMAL_LINEAR,
+  GIMP_LAYER_MODE_DISSOLVE,
+
+  GIMP_LAYER_MODE_LIGHTEN_ONLY,
+  GIMP_LAYER_MODE_LUMINANCE_LIGHTEN_ONLY,
+  GIMP_LAYER_MODE_SCREEN_LINEAR,
+  GIMP_LAYER_MODE_DODGE_LINEAR,
+  GIMP_LAYER_MODE_ADDITION_LINEAR,
+
+  GIMP_LAYER_MODE_DARKEN_ONLY,
+  GIMP_LAYER_MODE_LUMINANCE_DARKEN_ONLY,
+  GIMP_LAYER_MODE_MULTIPLY_LINEAR,
+  GIMP_LAYER_MODE_BURN_LINEAR,
+
+  GIMP_LAYER_MODE_OVERLAY_LINEAR,
+  GIMP_LAYER_MODE_SOFTLIGHT_LINEAR,
+  GIMP_LAYER_MODE_HARDLIGHT_LINEAR,
+  GIMP_LAYER_MODE_VIVID_LIGHT_LINEAR,
+  GIMP_LAYER_MODE_PIN_LIGHT_LINEAR,
+  GIMP_LAYER_MODE_LINEAR_LIGHT_LINEAR,
+
+  GIMP_LAYER_MODE_DIFFERENCE_LINEAR,
+  GIMP_LAYER_MODE_SUBTRACT_LINEAR,
+  GIMP_LAYER_MODE_GRAIN_EXTRACT_LINEAR,
+  GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR,
+  GIMP_LAYER_MODE_DIVIDE_LINEAR,
+
+  GIMP_LAYER_MODE_EXCLUSION_LINEAR,
+  GIMP_LAYER_MODE_LINEAR_BURN_LINEAR
+};
+
+static const GimpLayerMode layer_mode_group_perceptual[] =
+{
+  GIMP_LAYER_MODE_NORMAL,
+  GIMP_LAYER_MODE_DISSOLVE,
+
+  GIMP_LAYER_MODE_LIGHTEN_ONLY,
+  GIMP_LAYER_MODE_LUMA_LIGHTEN_ONLY,
+  GIMP_LAYER_MODE_SCREEN,
+  GIMP_LAYER_MODE_DODGE,
+  GIMP_LAYER_MODE_ADDITION,
+
+  GIMP_LAYER_MODE_DARKEN_ONLY,
+  GIMP_LAYER_MODE_LUMA_DARKEN_ONLY,
+  GIMP_LAYER_MODE_MULTIPLY,
+  GIMP_LAYER_MODE_BURN,
+
+  GIMP_LAYER_MODE_OVERLAY,
+  GIMP_LAYER_MODE_SOFTLIGHT,
+  GIMP_LAYER_MODE_HARDLIGHT,
+  GIMP_LAYER_MODE_VIVID_LIGHT,
+  GIMP_LAYER_MODE_PIN_LIGHT,
+  GIMP_LAYER_MODE_LINEAR_LIGHT,
+
+  GIMP_LAYER_MODE_DIFFERENCE,
+  GIMP_LAYER_MODE_SUBTRACT,
+  GIMP_LAYER_MODE_GRAIN_EXTRACT,
+  GIMP_LAYER_MODE_GRAIN_MERGE,
+  GIMP_LAYER_MODE_DIVIDE,
+
+  GIMP_LAYER_MODE_HSV_HUE,
+  GIMP_LAYER_MODE_HSV_SATURATION,
+  GIMP_LAYER_MODE_HSV_COLOR,
+  GIMP_LAYER_MODE_HSV_VALUE,
+
+  GIMP_LAYER_MODE_LCH_HUE,
+  GIMP_LAYER_MODE_LCH_CHROMA,
+  GIMP_LAYER_MODE_LCH_COLOR,
+  GIMP_LAYER_MODE_LCH_LIGHTNESS,
+
+  GIMP_LAYER_MODE_EXCLUSION,
+  GIMP_LAYER_MODE_LINEAR_BURN
+};
+
+static const GimpLayerMode layer_mode_group_legacy[] =
+{
+  GIMP_LAYER_MODE_NORMAL,
+  GIMP_LAYER_MODE_DISSOLVE,
+
+  GIMP_LAYER_MODE_LIGHTEN_ONLY_LEGACY,
+  GIMP_LAYER_MODE_SCREEN_LEGACY,
+  GIMP_LAYER_MODE_DODGE_LEGACY,
+  GIMP_LAYER_MODE_ADDITION_LEGACY,
+
+  GIMP_LAYER_MODE_DARKEN_ONLY_LEGACY,
+  GIMP_LAYER_MODE_MULTIPLY_LEGACY,
+  GIMP_LAYER_MODE_BURN_LEGACY,
+
+  GIMP_LAYER_MODE_SOFTLIGHT_LEGACY,
+  GIMP_LAYER_MODE_HARDLIGHT_LEGACY,
+
+  GIMP_LAYER_MODE_DIFFERENCE_LEGACY,
+  GIMP_LAYER_MODE_SUBTRACT_LEGACY,
+  GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY,
+  GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY,
+  GIMP_LAYER_MODE_DIVIDE_LEGACY,
+
+  GIMP_LAYER_MODE_HSV_HUE_LEGACY,
+  GIMP_LAYER_MODE_HSV_SATURATION_LEGACY,
+  GIMP_LAYER_MODE_HSV_COLOR_LEGACY,
+  GIMP_LAYER_MODE_HSV_VALUE_LEGACY
+};
+
+static const GimpLayerMode layer_mode_groups[][4] =
+{
+  {
+    GIMP_LAYER_MODE_NORMAL,
+    GIMP_LAYER_MODE_NORMAL_LINEAR,
+    GIMP_LAYER_MODE_NORMAL,
+    GIMP_LAYER_MODE_NORMAL
+  },
+
+  {
+    GIMP_LAYER_MODE_DISSOLVE,
+    GIMP_LAYER_MODE_DISSOLVE,
+    GIMP_LAYER_MODE_DISSOLVE,
+    GIMP_LAYER_MODE_DISSOLVE
+  },
+
+  {
+    GIMP_LAYER_MODE_BEHIND,
+    GIMP_LAYER_MODE_BEHIND_LINEAR,
+    GIMP_LAYER_MODE_BEHIND,
+    GIMP_LAYER_MODE_BEHIND
+  },
+
+  {
+    GIMP_LAYER_MODE_MULTIPLY,
+    GIMP_LAYER_MODE_MULTIPLY_LINEAR,
+    GIMP_LAYER_MODE_MULTIPLY,
+    GIMP_LAYER_MODE_MULTIPLY_LEGACY
+  },
+
+  {
+    GIMP_LAYER_MODE_SCREEN,
+    GIMP_LAYER_MODE_SCREEN_LINEAR,
+    GIMP_LAYER_MODE_SCREEN,
+    GIMP_LAYER_MODE_SCREEN_LEGACY
+  },
+
+  {
+    GIMP_LAYER_MODE_OVERLAY,
+    GIMP_LAYER_MODE_OVERLAY_LINEAR,
+    GIMP_LAYER_MODE_OVERLAY,
+    -1
+  },
+
+  {
+    GIMP_LAYER_MODE_DIFFERENCE,
+    GIMP_LAYER_MODE_DIFFERENCE_LINEAR,
+    GIMP_LAYER_MODE_DIFFERENCE,
+    GIMP_LAYER_MODE_DIFFERENCE_LEGACY
+  },
+
+  {
+    GIMP_LAYER_MODE_ADDITION,
+    GIMP_LAYER_MODE_ADDITION_LINEAR,
+    GIMP_LAYER_MODE_ADDITION,
+    GIMP_LAYER_MODE_ADDITION_LEGACY
+  },
+
+  {
+    GIMP_LAYER_MODE_SUBTRACT,
+    GIMP_LAYER_MODE_SUBTRACT_LINEAR,
+    GIMP_LAYER_MODE_SUBTRACT,
+    GIMP_LAYER_MODE_SUBTRACT_LEGACY
+  },
+
+  {
+    GIMP_LAYER_MODE_DARKEN_ONLY,
+    GIMP_LAYER_MODE_DARKEN_ONLY,
+    GIMP_LAYER_MODE_DARKEN_ONLY,
+    GIMP_LAYER_MODE_DARKEN_ONLY_LEGACY
+  },
+
+  {
+    GIMP_LAYER_MODE_LIGHTEN_ONLY,
+    GIMP_LAYER_MODE_LIGHTEN_ONLY,
+    GIMP_LAYER_MODE_LIGHTEN_ONLY,
+    GIMP_LAYER_MODE_LIGHTEN_ONLY_LEGACY
+  },
+
+  {
+    -1,
+    -1,
+    GIMP_LAYER_MODE_HSV_HUE,
+    GIMP_LAYER_MODE_HSV_HUE_LEGACY
+  },
+
+  {
+    -1,
+    -1,
+    GIMP_LAYER_MODE_HSV_SATURATION,
+    GIMP_LAYER_MODE_HSV_SATURATION_LEGACY
+  },
+
+  {
+    -1,
+    -1,
+    GIMP_LAYER_MODE_HSV_COLOR,
+    GIMP_LAYER_MODE_HSV_COLOR_LEGACY
+  },
+
+  {
+    -1,
+    -1,
+    GIMP_LAYER_MODE_HSV_VALUE,
+    GIMP_LAYER_MODE_HSV_VALUE_LEGACY
+  },
+
+  {
+    GIMP_LAYER_MODE_DIVIDE,
+    GIMP_LAYER_MODE_DIVIDE_LINEAR,
+    GIMP_LAYER_MODE_DIVIDE,
+    GIMP_LAYER_MODE_DIVIDE_LEGACY
+  },
+
+  {
+    GIMP_LAYER_MODE_DODGE,
+    GIMP_LAYER_MODE_DODGE_LINEAR,
+    GIMP_LAYER_MODE_DODGE,
+    GIMP_LAYER_MODE_DODGE_LEGACY
+  },
+
+  {
+    GIMP_LAYER_MODE_BURN,
+    GIMP_LAYER_MODE_BURN_LINEAR,
+    GIMP_LAYER_MODE_BURN,
+    GIMP_LAYER_MODE_BURN_LEGACY
+  },
+
+  {
+    GIMP_LAYER_MODE_HARDLIGHT,
+    GIMP_LAYER_MODE_HARDLIGHT_LINEAR,
+    GIMP_LAYER_MODE_HARDLIGHT,
+    GIMP_LAYER_MODE_HARDLIGHT_LEGACY
+  },
+
+  {
+    GIMP_LAYER_MODE_SOFTLIGHT,
+    GIMP_LAYER_MODE_SOFTLIGHT_LINEAR,
+    GIMP_LAYER_MODE_SOFTLIGHT,
+    GIMP_LAYER_MODE_SOFTLIGHT_LEGACY
+  },
+
+  {
+    GIMP_LAYER_MODE_GRAIN_EXTRACT,
+    GIMP_LAYER_MODE_GRAIN_EXTRACT_LINEAR,
+    GIMP_LAYER_MODE_GRAIN_EXTRACT,
+    GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY
+  },
+
+  {
+    GIMP_LAYER_MODE_GRAIN_MERGE,
+    GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR,
+    GIMP_LAYER_MODE_GRAIN_MERGE,
+    GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY
+  },
+
+  {
+    GIMP_LAYER_MODE_COLOR_ERASE,
+    -1,
+    GIMP_LAYER_MODE_COLOR_ERASE,
+    -1,
+  },
+
+  {
+    GIMP_LAYER_MODE_VIVID_LIGHT,
+    GIMP_LAYER_MODE_VIVID_LIGHT_LINEAR,
+    GIMP_LAYER_MODE_VIVID_LIGHT,
+    -1
+  },
+
+  {
+    GIMP_LAYER_MODE_PIN_LIGHT,
+    GIMP_LAYER_MODE_PIN_LIGHT_LINEAR,
+    GIMP_LAYER_MODE_PIN_LIGHT,
+    -1
+  },
+
+  {
+    GIMP_LAYER_MODE_LINEAR_LIGHT,
+    GIMP_LAYER_MODE_LINEAR_LIGHT_LINEAR,
+    GIMP_LAYER_MODE_LINEAR_LIGHT,
+    -1
+  },
+
+  {
+    GIMP_LAYER_MODE_EXCLUSION,
+    GIMP_LAYER_MODE_EXCLUSION_LINEAR,
+    GIMP_LAYER_MODE_EXCLUSION,
+    -1
+  },
+
+  {
+    GIMP_LAYER_MODE_LINEAR_BURN,
+    GIMP_LAYER_MODE_LINEAR_BURN_LINEAR,
+    GIMP_LAYER_MODE_LINEAR_BURN,
+    -1
+  },
+
+  {
+    GIMP_LAYER_MODE_LUMINANCE_DARKEN_ONLY,
+    GIMP_LAYER_MODE_LUMINANCE_DARKEN_ONLY,
+    GIMP_LAYER_MODE_LUMA_DARKEN_ONLY,
+    -1
+  },
+
+  {
+    GIMP_LAYER_MODE_LUMINANCE_LIGHTEN_ONLY,
+    GIMP_LAYER_MODE_LUMINANCE_LIGHTEN_ONLY,
+    GIMP_LAYER_MODE_LUMA_LIGHTEN_ONLY,
+    -1
+  },
+
+  {
+    GIMP_LAYER_MODE_ERASE,
+    GIMP_LAYER_MODE_ERASE,
+    -1,
+    -1
+  },
+
+  {
+    GIMP_LAYER_MODE_REPLACE,
+    GIMP_LAYER_MODE_REPLACE,
+    -1,
+    -1
+  },
+
+  {
+    GIMP_LAYER_MODE_ANTI_ERASE,
+    GIMP_LAYER_MODE_ANTI_ERASE,
+    -1,
+    -1
+  },
+};
+
+
+/*  public functions  */
+
 gboolean
 gimp_layer_mode_is_legacy (GimpLayerMode  mode)
 {
@@ -469,280 +851,95 @@ gimp_layer_mode_get_operation (GimpLayerMode  mode)
   return "gimp:layer-mode";
 }
 
+static gboolean
+is_mode_in_array (const GimpLayerMode *modes,
+                  gint                 n_modes,
+                  GimpLayerMode        mode)
+{
+  gint i;
+
+  for (i = 0; i < n_modes; i++)
+    if (modes[i] == mode)
+      return TRUE;
+
+  return FALSE;
+}
+
 GimpLayerModeGroup
 gimp_layer_mode_get_group (GimpLayerMode  mode)
 {
-  if (gimp_layer_mode_is_legacy (mode))
+  if (is_mode_in_array (layer_mode_group_default,
+                        G_N_ELEMENTS (layer_mode_group_default), mode))
     {
-      return GIMP_LAYER_MODE_GROUP_LEGACY;
+      return GIMP_LAYER_MODE_GROUP_DEFAULT;
     }
-  else if (gimp_layer_mode_get_blend_space (mode) ==
-           GIMP_LAYER_COLOR_SPACE_RGB_PERCEPTUAL)
+  else if (is_mode_in_array (layer_mode_group_linear,
+                             G_N_ELEMENTS (layer_mode_group_linear), mode))
+    {
+      return GIMP_LAYER_MODE_GROUP_LINEAR;
+    }
+  else if (is_mode_in_array (layer_mode_group_perceptual,
+                             G_N_ELEMENTS (layer_mode_group_perceptual), mode))
     {
       return GIMP_LAYER_MODE_GROUP_PERCEPTUAL;
     }
+  else if (is_mode_in_array (layer_mode_group_legacy,
+                             G_N_ELEMENTS (layer_mode_group_legacy), mode))
+    {
+      return GIMP_LAYER_MODE_GROUP_LEGACY;
+    }
 
-  return GIMP_LAYER_MODE_GROUP_LINEAR;
+  return GIMP_LAYER_MODE_GROUP_DEFAULT;
 }
 
-gboolean
-gimp_layer_mode_get_for_group (GimpLayerMode       old_mode,
-                               GimpLayerModeGroup  new_group,
-                               GimpLayerMode      *new_mode)
+const GimpLayerMode *
+gimp_layer_mode_get_group_array (GimpLayerModeGroup  group,
+                                 gint               *n_modes)
 {
-  static GimpLayerMode mode_groups[][4] =
-  {
-    {
-      GIMP_LAYER_MODE_NORMAL,
-      GIMP_LAYER_MODE_NORMAL_LINEAR,
-      GIMP_LAYER_MODE_NORMAL,
-      GIMP_LAYER_MODE_NORMAL
-    },
-
-    {
-      GIMP_LAYER_MODE_DISSOLVE,
-      GIMP_LAYER_MODE_DISSOLVE,
-      GIMP_LAYER_MODE_DISSOLVE,
-      GIMP_LAYER_MODE_DISSOLVE
-    },
-
-    {
-      GIMP_LAYER_MODE_BEHIND,
-      GIMP_LAYER_MODE_BEHIND_LINEAR,
-      GIMP_LAYER_MODE_BEHIND,
-      GIMP_LAYER_MODE_BEHIND
-    },
-
-    {
-      GIMP_LAYER_MODE_MULTIPLY,
-      GIMP_LAYER_MODE_MULTIPLY_LINEAR,
-      GIMP_LAYER_MODE_MULTIPLY,
-      GIMP_LAYER_MODE_MULTIPLY_LEGACY
-    },
-
-    {
-      GIMP_LAYER_MODE_SCREEN,
-      GIMP_LAYER_MODE_SCREEN_LINEAR,
-      GIMP_LAYER_MODE_SCREEN,
-      GIMP_LAYER_MODE_SCREEN_LEGACY
-    },
-
-    {
-      GIMP_LAYER_MODE_OVERLAY,
-      GIMP_LAYER_MODE_OVERLAY_LINEAR,
-      GIMP_LAYER_MODE_OVERLAY,
-      -1
-    },
-
-    {
-      GIMP_LAYER_MODE_DIFFERENCE,
-      GIMP_LAYER_MODE_DIFFERENCE_LINEAR,
-      GIMP_LAYER_MODE_DIFFERENCE,
-      GIMP_LAYER_MODE_DIFFERENCE_LEGACY
-    },
-
-    {
-      GIMP_LAYER_MODE_ADDITION,
-      GIMP_LAYER_MODE_ADDITION_LINEAR,
-      GIMP_LAYER_MODE_ADDITION,
-      GIMP_LAYER_MODE_ADDITION_LEGACY
-    },
-
-    {
-      GIMP_LAYER_MODE_SUBTRACT,
-      GIMP_LAYER_MODE_SUBTRACT_LINEAR,
-      GIMP_LAYER_MODE_SUBTRACT,
-      GIMP_LAYER_MODE_SUBTRACT_LEGACY
-    },
-
-    {
-      GIMP_LAYER_MODE_DARKEN_ONLY,
-      GIMP_LAYER_MODE_DARKEN_ONLY,
-      GIMP_LAYER_MODE_DARKEN_ONLY,
-      GIMP_LAYER_MODE_DARKEN_ONLY_LEGACY
-    },
-
-    {
-      GIMP_LAYER_MODE_LIGHTEN_ONLY,
-      GIMP_LAYER_MODE_LIGHTEN_ONLY,
-      GIMP_LAYER_MODE_LIGHTEN_ONLY,
-      GIMP_LAYER_MODE_LIGHTEN_ONLY_LEGACY
-    },
-
-    {
-      -1,
-      -1,
-      GIMP_LAYER_MODE_HSV_HUE,
-      GIMP_LAYER_MODE_HSV_HUE_LEGACY
-    },
-
-    {
-      -1,
-      -1,
-      GIMP_LAYER_MODE_HSV_SATURATION,
-      GIMP_LAYER_MODE_HSV_SATURATION_LEGACY
-    },
-
-    {
-      -1,
-      -1,
-      GIMP_LAYER_MODE_HSV_COLOR,
-      GIMP_LAYER_MODE_HSV_COLOR_LEGACY
-    },
-
-    {
-      -1,
-      -1,
-      GIMP_LAYER_MODE_HSV_VALUE,
-      GIMP_LAYER_MODE_HSV_VALUE_LEGACY
-    },
-
-    {
-      GIMP_LAYER_MODE_DIVIDE,
-      GIMP_LAYER_MODE_DIVIDE_LINEAR,
-      GIMP_LAYER_MODE_DIVIDE,
-      GIMP_LAYER_MODE_DIVIDE_LEGACY
-    },
-
-    {
-      GIMP_LAYER_MODE_DODGE,
-      GIMP_LAYER_MODE_DODGE_LINEAR,
-      GIMP_LAYER_MODE_DODGE,
-      GIMP_LAYER_MODE_DODGE_LEGACY
-    },
-
-    {
-      GIMP_LAYER_MODE_BURN,
-      GIMP_LAYER_MODE_BURN_LINEAR,
-      GIMP_LAYER_MODE_BURN,
-      GIMP_LAYER_MODE_BURN_LEGACY
-    },
-
-    {
-      GIMP_LAYER_MODE_HARDLIGHT,
-      GIMP_LAYER_MODE_HARDLIGHT_LINEAR,
-      GIMP_LAYER_MODE_HARDLIGHT,
-      GIMP_LAYER_MODE_HARDLIGHT_LEGACY
-    },
-
-    {
-      GIMP_LAYER_MODE_SOFTLIGHT,
-      GIMP_LAYER_MODE_SOFTLIGHT_LINEAR,
-      GIMP_LAYER_MODE_SOFTLIGHT,
-      GIMP_LAYER_MODE_SOFTLIGHT_LEGACY
-    },
-
-    {
-      GIMP_LAYER_MODE_GRAIN_EXTRACT,
-      GIMP_LAYER_MODE_GRAIN_EXTRACT_LINEAR,
-      GIMP_LAYER_MODE_GRAIN_EXTRACT,
-      GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY
-    },
-
-    {
-      GIMP_LAYER_MODE_GRAIN_MERGE,
-      GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR,
-      GIMP_LAYER_MODE_GRAIN_MERGE,
-      GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY
-    },
-
-    {
-      GIMP_LAYER_MODE_COLOR_ERASE,
-      -1,
-      GIMP_LAYER_MODE_COLOR_ERASE,
-      -1,
-    },
-
-    {
-      GIMP_LAYER_MODE_VIVID_LIGHT,
-      GIMP_LAYER_MODE_VIVID_LIGHT_LINEAR,
-      GIMP_LAYER_MODE_VIVID_LIGHT,
-      -1
-    },
-
-    {
-      GIMP_LAYER_MODE_PIN_LIGHT,
-      GIMP_LAYER_MODE_PIN_LIGHT_LINEAR,
-      GIMP_LAYER_MODE_PIN_LIGHT,
-      -1
-    },
-
-    {
-      GIMP_LAYER_MODE_LINEAR_LIGHT,
-      GIMP_LAYER_MODE_LINEAR_LIGHT_LINEAR,
-      GIMP_LAYER_MODE_LINEAR_LIGHT,
-      -1
-    },
-
-    {
-      GIMP_LAYER_MODE_EXCLUSION,
-      GIMP_LAYER_MODE_EXCLUSION_LINEAR,
-      GIMP_LAYER_MODE_EXCLUSION,
-      -1
-    },
+  g_return_val_if_fail (n_modes != NULL, NULL);
 
+  switch (group)
     {
-      GIMP_LAYER_MODE_LINEAR_BURN,
-      GIMP_LAYER_MODE_LINEAR_BURN_LINEAR,
-      GIMP_LAYER_MODE_LINEAR_BURN,
-      -1
-    },
+    case GIMP_LAYER_MODE_GROUP_DEFAULT:
+      *n_modes = G_N_ELEMENTS (layer_mode_group_default);
+      return layer_mode_group_default;
 
-    {
-      GIMP_LAYER_MODE_LUMINANCE_DARKEN_ONLY,
-      GIMP_LAYER_MODE_LUMINANCE_DARKEN_ONLY,
-      GIMP_LAYER_MODE_LUMA_DARKEN_ONLY,
-      -1
-    },
+    case GIMP_LAYER_MODE_GROUP_LINEAR:
+      *n_modes = G_N_ELEMENTS (layer_mode_group_linear);
+      return layer_mode_group_linear;
 
-    {
-      GIMP_LAYER_MODE_LUMINANCE_LIGHTEN_ONLY,
-      GIMP_LAYER_MODE_LUMINANCE_LIGHTEN_ONLY,
-      GIMP_LAYER_MODE_LUMA_LIGHTEN_ONLY,
-      -1
-    },
+    case GIMP_LAYER_MODE_GROUP_PERCEPTUAL:
+      *n_modes = G_N_ELEMENTS (layer_mode_group_perceptual);
+      return layer_mode_group_perceptual;
 
-    {
-      GIMP_LAYER_MODE_ERASE,
-      GIMP_LAYER_MODE_ERASE,
-      -1,
-      -1
-    },
-
-    {
-      GIMP_LAYER_MODE_REPLACE,
-      GIMP_LAYER_MODE_REPLACE,
-      -1,
-      -1
-    },
+    case GIMP_LAYER_MODE_GROUP_LEGACY:
+      *n_modes = G_N_ELEMENTS (layer_mode_group_legacy);
+      return layer_mode_group_legacy;
 
-    {
-      GIMP_LAYER_MODE_ANTI_ERASE,
-      GIMP_LAYER_MODE_ANTI_ERASE,
-      -1,
-      -1
-    },
-  };
+    default:
+      g_return_val_if_reached (NULL);
+    }
+}
 
+gboolean
+gimp_layer_mode_get_for_group (GimpLayerMode       old_mode,
+                               GimpLayerModeGroup  new_group,
+                               GimpLayerMode      *new_mode)
+{
   gint i;
 
   g_return_val_if_fail (new_mode != NULL, FALSE);
 
-  for (i = 0; i < G_N_ELEMENTS (mode_groups); i++)
+  for (i = 0; i < G_N_ELEMENTS (layer_mode_groups); i++)
     {
-      gint j;
-
-      for (j = 0; j < 4; j++)
+      if (is_mode_in_array (layer_mode_groups[i], 4, old_mode))
         {
-          if (mode_groups[i][j] == old_mode)
-            {
-              *new_mode = mode_groups[i][new_group];
+          *new_mode = layer_mode_groups[i][new_group];
 
-              if (*new_mode != -1)
-                return TRUE;
+          if (*new_mode != -1)
+            return TRUE;
 
-              return FALSE;
-            }
+          return FALSE;
         }
     }
 
diff --git a/app/core/gimp-layer-modes.h b/app/core/gimp-layer-modes.h
index 8a36f34..94e6d5f 100644
--- a/app/core/gimp-layer-modes.h
+++ b/app/core/gimp-layer-modes.h
@@ -34,6 +34,9 @@ const gchar            * gimp_layer_mode_get_operation       (GimpLayerMode
 
 GimpLayerModeGroup       gimp_layer_mode_get_group           (GimpLayerMode       mode);
 
+const GimpLayerMode    * gimp_layer_mode_get_group_array     (GimpLayerModeGroup  group,
+                                                              gint               *n_modes);
+
 gboolean                 gimp_layer_mode_get_for_group       (GimpLayerMode       old_mode,
                                                               GimpLayerModeGroup  new_group,
                                                               GimpLayerMode      *new_mode);
diff --git a/app/widgets/gimplayermodecombobox.c b/app/widgets/gimplayermodecombobox.c
index 9f6112f..4d727aa 100644
--- a/app/widgets/gimplayermodecombobox.c
+++ b/app/widgets/gimplayermodecombobox.c
@@ -328,42 +328,59 @@ gimp_layer_mode_combo_box_get_group (GimpLayerModeComboBox *combo)
 
 /*  private functions  */
 
-static GtkTreeModel *
-gimp_layer_mode_combo_box_create_default_model (GimpLayerModeComboBox *combo)
+static void
+gimp_enum_store_add_value (GtkListStore *store,
+                           GEnumValue   *value)
+{
+  GtkTreeIter  iter = { 0, };
+  const gchar *desc;
+  gchar       *stripped;
+
+  desc = gimp_enum_value_get_desc (GIMP_ENUM_STORE (store)->enum_class, value);
+
+  /* no mnemonics in combo boxes */
+  stripped = gimp_strip_uline (desc);
+
+  gtk_list_store_append (store, &iter);
+  gtk_list_store_set (store, &iter,
+                      GIMP_INT_STORE_VALUE, value->value,
+                      GIMP_INT_STORE_LABEL, stripped,
+                      -1);
+
+  g_free (stripped);
+}
+
+static GtkListStore *
+gimp_enum_store_new_from_array (GType       enum_type,
+                                gint        n_values,
+                                const gint *values)
 {
   GtkListStore *store;
+  GEnumValue   *value;
+  gint          i;
+
+  g_return_val_if_fail (G_TYPE_IS_ENUM (enum_type), NULL);
+  g_return_val_if_fail (n_values > 1, NULL);
+  g_return_val_if_fail (values != NULL, NULL);
 
-  store = gimp_enum_store_new_with_values (GIMP_TYPE_LAYER_MODE,
-                                           28,
-                                           GIMP_LAYER_MODE_NORMAL,
-                                           GIMP_LAYER_MODE_DISSOLVE,
-                                           GIMP_LAYER_MODE_LIGHTEN_ONLY,
-                                           GIMP_LAYER_MODE_LUMINANCE_LIGHTEN_ONLY,
-                                           GIMP_LAYER_MODE_SCREEN,
-                                           GIMP_LAYER_MODE_DODGE,
-                                           GIMP_LAYER_MODE_ADDITION,
-                                           GIMP_LAYER_MODE_DARKEN_ONLY,
-                                           GIMP_LAYER_MODE_LUMINANCE_DARKEN_ONLY,
-                                           GIMP_LAYER_MODE_MULTIPLY,
-                                           GIMP_LAYER_MODE_BURN,
-                                           GIMP_LAYER_MODE_OVERLAY,
-                                           GIMP_LAYER_MODE_SOFTLIGHT,
-                                           GIMP_LAYER_MODE_HARDLIGHT,
-                                           GIMP_LAYER_MODE_VIVID_LIGHT,
-                                           GIMP_LAYER_MODE_PIN_LIGHT,
-                                           GIMP_LAYER_MODE_LINEAR_LIGHT,
-                                           GIMP_LAYER_MODE_DIFFERENCE,
-                                           GIMP_LAYER_MODE_SUBTRACT,
-                                           GIMP_LAYER_MODE_GRAIN_EXTRACT,
-                                           GIMP_LAYER_MODE_GRAIN_MERGE,
-                                           GIMP_LAYER_MODE_DIVIDE,
-                                           GIMP_LAYER_MODE_LCH_HUE,
-                                           GIMP_LAYER_MODE_LCH_CHROMA,
-                                           GIMP_LAYER_MODE_LCH_COLOR,
-                                           GIMP_LAYER_MODE_LCH_LIGHTNESS,
-                                           GIMP_LAYER_MODE_EXCLUSION,
-                                           GIMP_LAYER_MODE_LINEAR_BURN);
+  store = g_object_new (GIMP_TYPE_ENUM_STORE,
+                        "enum-type", enum_type,
+                        NULL);
 
+  for (i = 0; i < n_values; i++)
+    {
+      value = g_enum_get_value (GIMP_ENUM_STORE (store)->enum_class, values[i]);
+      if (value)
+        gimp_enum_store_add_value (store, value);
+    }
+
+  return store;
+}
+
+static void
+gimp_layer_mode_combo_box_fix_default_store (GimpLayerModeComboBox *combo,
+                                             GtkListStore          *store)
+{
   gimp_layer_mode_combo_box_insert_separator (store,
                                               GIMP_LAYER_MODE_DISSOLVE, -1);
 
@@ -404,42 +421,12 @@ gimp_layer_mode_combo_box_create_default_model (GimpLayerModeComboBox *combo)
                                               GIMP_LAYER_MODE_ERASE,
                                               GIMP_LAYER_MODE_ANTI_ERASE);
     }
-
-  return GTK_TREE_MODEL (store);
 }
 
-static GtkTreeModel *
-gimp_layer_mode_combo_box_create_linear_model (GimpLayerModeComboBox *combo)
+static void
+gimp_layer_mode_combo_box_fix_linear_store (GimpLayerModeComboBox *combo,
+                                            GtkListStore          *store)
 {
-  GtkListStore *store;
-
-  store = gimp_enum_store_new_with_values (GIMP_TYPE_LAYER_MODE,
-                                           24,
-                                           GIMP_LAYER_MODE_NORMAL_LINEAR,
-                                           GIMP_LAYER_MODE_DISSOLVE,
-                                           GIMP_LAYER_MODE_LIGHTEN_ONLY,
-                                           GIMP_LAYER_MODE_LUMINANCE_LIGHTEN_ONLY,
-                                           GIMP_LAYER_MODE_SCREEN_LINEAR,
-                                           GIMP_LAYER_MODE_DODGE_LINEAR,
-                                           GIMP_LAYER_MODE_ADDITION_LINEAR,
-                                           GIMP_LAYER_MODE_DARKEN_ONLY,
-                                           GIMP_LAYER_MODE_LUMINANCE_DARKEN_ONLY,
-                                           GIMP_LAYER_MODE_MULTIPLY_LINEAR,
-                                           GIMP_LAYER_MODE_BURN_LINEAR,
-                                           GIMP_LAYER_MODE_OVERLAY_LINEAR,
-                                           GIMP_LAYER_MODE_SOFTLIGHT_LINEAR,
-                                           GIMP_LAYER_MODE_HARDLIGHT_LINEAR,
-                                           GIMP_LAYER_MODE_VIVID_LIGHT_LINEAR,
-                                           GIMP_LAYER_MODE_PIN_LIGHT_LINEAR,
-                                           GIMP_LAYER_MODE_LINEAR_LIGHT_LINEAR,
-                                           GIMP_LAYER_MODE_DIFFERENCE_LINEAR,
-                                           GIMP_LAYER_MODE_SUBTRACT_LINEAR,
-                                           GIMP_LAYER_MODE_GRAIN_EXTRACT_LINEAR,
-                                           GIMP_LAYER_MODE_GRAIN_MERGE_LINEAR,
-                                           GIMP_LAYER_MODE_DIVIDE_LINEAR,
-                                           GIMP_LAYER_MODE_EXCLUSION_LINEAR,
-                                           GIMP_LAYER_MODE_LINEAR_BURN_LINEAR);
-
   gimp_layer_mode_combo_box_insert_separator (store,
                                               GIMP_LAYER_MODE_DISSOLVE, -1);
 
@@ -474,50 +461,12 @@ gimp_layer_mode_combo_box_create_linear_model (GimpLayerModeComboBox *combo)
                                               GIMP_LAYER_MODE_ERASE,
                                               GIMP_LAYER_MODE_ANTI_ERASE);
     }
-
-  return GTK_TREE_MODEL (store);
 }
 
-static GtkTreeModel *
-gimp_layer_mode_combo_box_create_perceptual_model (GimpLayerModeComboBox *combo)
+static void
+gimp_layer_mode_combo_box_fix_perceptual_store (GimpLayerModeComboBox *combo,
+                                                GtkListStore          *store)
 {
-  GtkListStore *store;
-
-  store = gimp_enum_store_new_with_values (GIMP_TYPE_LAYER_MODE,
-                                           32,
-                                           GIMP_LAYER_MODE_NORMAL,
-                                           GIMP_LAYER_MODE_DISSOLVE,
-                                           GIMP_LAYER_MODE_LIGHTEN_ONLY,
-                                           GIMP_LAYER_MODE_LUMA_LIGHTEN_ONLY,
-                                           GIMP_LAYER_MODE_SCREEN,
-                                           GIMP_LAYER_MODE_DODGE,
-                                           GIMP_LAYER_MODE_ADDITION,
-                                           GIMP_LAYER_MODE_DARKEN_ONLY,
-                                           GIMP_LAYER_MODE_LUMA_DARKEN_ONLY,
-                                           GIMP_LAYER_MODE_MULTIPLY,
-                                           GIMP_LAYER_MODE_BURN,
-                                           GIMP_LAYER_MODE_OVERLAY,
-                                           GIMP_LAYER_MODE_SOFTLIGHT,
-                                           GIMP_LAYER_MODE_HARDLIGHT,
-                                           GIMP_LAYER_MODE_VIVID_LIGHT,
-                                           GIMP_LAYER_MODE_PIN_LIGHT,
-                                           GIMP_LAYER_MODE_LINEAR_LIGHT,
-                                           GIMP_LAYER_MODE_DIFFERENCE,
-                                           GIMP_LAYER_MODE_SUBTRACT,
-                                           GIMP_LAYER_MODE_GRAIN_EXTRACT,
-                                           GIMP_LAYER_MODE_GRAIN_MERGE,
-                                           GIMP_LAYER_MODE_DIVIDE,
-                                           GIMP_LAYER_MODE_HSV_HUE,
-                                           GIMP_LAYER_MODE_HSV_SATURATION,
-                                           GIMP_LAYER_MODE_HSV_COLOR,
-                                           GIMP_LAYER_MODE_HSV_VALUE,
-                                           GIMP_LAYER_MODE_LCH_HUE,
-                                           GIMP_LAYER_MODE_LCH_CHROMA,
-                                           GIMP_LAYER_MODE_LCH_COLOR,
-                                           GIMP_LAYER_MODE_LCH_LIGHTNESS,
-                                           GIMP_LAYER_MODE_EXCLUSION,
-                                           GIMP_LAYER_MODE_LINEAR_BURN);
-
   gimp_layer_mode_combo_box_insert_separator (store,
                                               GIMP_LAYER_MODE_DISSOLVE, -1);
 
@@ -548,38 +497,12 @@ gimp_layer_mode_combo_box_create_perceptual_model (GimpLayerModeComboBox *combo)
                                               GIMP_LAYER_MODE_BEHIND,
                                               GIMP_LAYER_MODE_COLOR_ERASE);
     }
-
-  return GTK_TREE_MODEL (store);
 }
 
-static GtkTreeModel *
-gimp_layer_mode_combo_box_create_legacy_model (GimpLayerModeComboBox *combo)
+static void
+gimp_layer_mode_combo_box_fix_legacy_store (GimpLayerModeComboBox *combo,
+                                            GtkListStore          *store)
 {
-  GtkListStore *store;
-
-  store = gimp_enum_store_new_with_values (GIMP_TYPE_LAYER_MODE,
-                                           20,
-                                           GIMP_LAYER_MODE_NORMAL,
-                                           GIMP_LAYER_MODE_DISSOLVE,
-                                           GIMP_LAYER_MODE_LIGHTEN_ONLY_LEGACY,
-                                           GIMP_LAYER_MODE_SCREEN_LEGACY,
-                                           GIMP_LAYER_MODE_DODGE_LEGACY,
-                                           GIMP_LAYER_MODE_ADDITION_LEGACY,
-                                           GIMP_LAYER_MODE_DARKEN_ONLY_LEGACY,
-                                           GIMP_LAYER_MODE_MULTIPLY_LEGACY,
-                                           GIMP_LAYER_MODE_BURN_LEGACY,
-                                           GIMP_LAYER_MODE_SOFTLIGHT_LEGACY,
-                                           GIMP_LAYER_MODE_HARDLIGHT_LEGACY,
-                                           GIMP_LAYER_MODE_DIFFERENCE_LEGACY,
-                                           GIMP_LAYER_MODE_SUBTRACT_LEGACY,
-                                           GIMP_LAYER_MODE_GRAIN_EXTRACT_LEGACY,
-                                           GIMP_LAYER_MODE_GRAIN_MERGE_LEGACY,
-                                           GIMP_LAYER_MODE_DIVIDE_LEGACY,
-                                           GIMP_LAYER_MODE_HSV_HUE_LEGACY,
-                                           GIMP_LAYER_MODE_HSV_SATURATION_LEGACY,
-                                           GIMP_LAYER_MODE_HSV_COLOR_LEGACY,
-                                           GIMP_LAYER_MODE_HSV_VALUE_LEGACY);
-
   gimp_layer_mode_combo_box_insert_separator (store,
                                               GIMP_LAYER_MODE_DISSOLVE, -1);
 
@@ -594,40 +517,44 @@ gimp_layer_mode_combo_box_create_legacy_model (GimpLayerModeComboBox *combo)
 
   gimp_layer_mode_combo_box_insert_separator (store,
                                               GIMP_LAYER_MODE_DIVIDE_LEGACY, -1);
-
-  return GTK_TREE_MODEL (store);
 }
 
 static void
 gimp_layer_mode_combo_box_update_model (GimpLayerModeComboBox *combo,
                                         gboolean               change_mode)
 {
-  GtkTreeModel *model;
+  GtkListStore        *store;
+  const GimpLayerMode *modes;
+  gint                 n_modes;
+
+  modes = gimp_layer_mode_get_group_array (combo->priv->group, &n_modes);
+  store = gimp_enum_store_new_from_array (GIMP_TYPE_LAYER_MODE,
+                                          n_modes, (gint *) modes);
 
   switch (combo->priv->group)
     {
     case GIMP_LAYER_MODE_GROUP_DEFAULT:
-      model = gimp_layer_mode_combo_box_create_default_model (combo);
+      gimp_layer_mode_combo_box_fix_default_store (combo, store);
       break;
 
     case GIMP_LAYER_MODE_GROUP_LINEAR:
-      model = gimp_layer_mode_combo_box_create_linear_model (combo);
+      gimp_layer_mode_combo_box_fix_linear_store (combo, store);
       break;
 
     case GIMP_LAYER_MODE_GROUP_PERCEPTUAL:
-      model = gimp_layer_mode_combo_box_create_perceptual_model (combo);
+      gimp_layer_mode_combo_box_fix_perceptual_store (combo, store);
       break;
 
     case GIMP_LAYER_MODE_GROUP_LEGACY:
-      model = gimp_layer_mode_combo_box_create_legacy_model (combo);
+      gimp_layer_mode_combo_box_fix_legacy_store (combo, store);
       break;
 
     default:
       g_return_if_reached ();
     }
 
-  gtk_combo_box_set_model (GTK_COMBO_BOX (combo), model);
-  g_object_unref (model);
+  gtk_combo_box_set_model (GTK_COMBO_BOX (combo), GTK_TREE_MODEL (store));
+  g_object_unref (store);
 
   if (change_mode)
     {
@@ -644,7 +571,7 @@ gimp_layer_mode_combo_box_update_model (GimpLayerModeComboBox *combo,
           GtkTreeIter iter;
 
           /*  switch to the first mode, which will be one of the "normal"  */
-          gtk_tree_model_get_iter_first (model, &iter);
+          gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter);
           gtk_combo_box_set_active_iter (GTK_COMBO_BOX (combo), &iter);
         }
     }


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