[gimp/gimp-2-10] Issue #1213 - Text Tool Preset does not restore font face/name...



commit 4ea171c50e4b8a9e63a52dfb414aac2d6dea289b
Author: Michael Natterer <mitch gimp org>
Date:   Sun Jun 17 14:09:55 2018 +0200

    Issue #1213 - Text Tool Preset does not restore font face/name...
    
    ...after program restart
    
    GimpContext was always supposed to keep the names of objects (brush,
    pattern, font etc.) around even if these objects don't exist, for
    cases like refreshing the data in a GimpDataFactory (which worked
    fine), but also for deserializing the names of objects which don't
    exist *yet* (delayed loading, no-data or whatever).
    
    This commit fixes the delayed loading case (particularly affects fonts):
    
    gimp_context_deserialize_property(): always keep the name of the
    object around when it is not found, not only in the no-data case.
    
    gimp_context_copy_property(): always copy the object *and* its name to
    the dest context.
    
    Add GimpConfig::duplicate() and ::copy() implementations which chain
    up for duplicating/copying all properties and additionally copy all
    object names to the new/dest context.
    
    (cherry picked from commit ed1e2b15246bff0a5552316c664c88b6c2e1d602)

 app/core/gimpcontext.c | 191 +++++++++++++++++++++++++++----------------------
 1 file changed, 104 insertions(+), 87 deletions(-)
---
diff --git a/app/core/gimpcontext.c b/app/core/gimpcontext.c
index 2f2a773f33..860ab20bb1 100644
--- a/app/core/gimpcontext.c
+++ b/app/core/gimpcontext.c
@@ -61,10 +61,14 @@ typedef void (* GimpContextCopyPropFunc) (GimpContext *src,
                                           GimpContext *dest);
 
 
-#define context_find_defined(context,prop) \
+#define context_find_defined(context, prop)                              \
   while (!(((context)->defined_props) & (1 << (prop))) && (context)->parent) \
     (context) = (context)->parent
 
+#define COPY_NAME(src, dest, member)            \
+  g_free (dest->member);                        \
+  dest->member = g_strdup (src->member)
+
 
 /*  local function prototypes  */
 
@@ -102,6 +106,10 @@ static gboolean   gimp_context_deserialize_property (GimpConfig       *config,
                                                      GParamSpec       *pspec,
                                                      GScanner         *scanner,
                                                      GTokenType       *expected);
+static GimpConfig * gimp_context_duplicate          (GimpConfig       *config);
+static gboolean     gimp_context_copy               (GimpConfig       *src,
+                                                     GimpConfig       *dest,
+                                                     GParamFlags       flags);
 
 /*  image  */
 static void gimp_context_image_removed       (GimpContainer    *container,
@@ -379,6 +387,8 @@ G_DEFINE_TYPE_WITH_CODE (GimpContext, gimp_context, GIMP_TYPE_VIEWABLE,
 
 #define parent_class gimp_context_parent_class
 
+static GimpConfigInterface *parent_config_iface = NULL;
+
 static guint gimp_context_signals[LAST_SIGNAL] = { 0 };
 
 
@@ -830,10 +840,17 @@ gimp_context_init (GimpContext *context)
 static void
 gimp_context_config_iface_init (GimpConfigInterface *iface)
 {
+  parent_config_iface = g_type_interface_peek_parent (iface);
+
+  if (! parent_config_iface)
+    parent_config_iface = g_type_default_interface_peek (GIMP_TYPE_CONFIG);
+
   iface->serialize            = gimp_context_serialize;
   iface->deserialize          = gimp_context_deserialize;
   iface->serialize_property   = gimp_context_serialize_property;
   iface->deserialize_property = gimp_context_deserialize_property;
+  iface->duplicate            = gimp_context_duplicate;
+  iface->copy                 = gimp_context_copy;
 }
 
 static void
@@ -1289,81 +1306,70 @@ gimp_context_deserialize_property (GimpConfig *object,
 {
   GimpContext   *context = GIMP_CONTEXT (object);
   GimpContainer *container;
-  GimpObject    *current;
+  gpointer       standard;
   gchar        **name_loc;
-  gboolean       no_data;
   gchar         *object_name;
 
   switch (property_id)
     {
     case GIMP_CONTEXT_PROP_TOOL:
       container = context->gimp->tool_info_list;
-      current   = (GimpObject *) context->tool_info;
+      standard  = gimp_tool_info_get_standard (context->gimp);
       name_loc  = &context->tool_name;
-      no_data   = TRUE;
       break;
 
     case GIMP_CONTEXT_PROP_PAINT_INFO:
       container = context->gimp->paint_info_list;
-      current   = (GimpObject *) context->paint_info;
+      standard  = gimp_paint_info_get_standard (context->gimp);
       name_loc  = &context->paint_name;
-      no_data   = TRUE;
       break;
 
     case GIMP_CONTEXT_PROP_BRUSH:
       container = gimp_data_factory_get_container (context->gimp->brush_factory);
-      current   = (GimpObject *) context->brush;
+      standard  = gimp_brush_get_standard (context);
       name_loc  = &context->brush_name;
-      no_data   = context->gimp->no_data;
       break;
 
     case GIMP_CONTEXT_PROP_DYNAMICS:
       container = gimp_data_factory_get_container (context->gimp->dynamics_factory);
-      current   = (GimpObject *) context->dynamics;
+      standard  = gimp_dynamics_get_standard (context);
       name_loc  = &context->dynamics_name;
-      no_data   = context->gimp->no_data;
       break;
 
     case GIMP_CONTEXT_PROP_MYBRUSH:
       container = gimp_data_factory_get_container (context->gimp->mybrush_factory);
-      current   = (GimpObject *) context->mybrush;
+      standard  = gimp_mybrush_get_standard (context);
       name_loc  = &context->mybrush_name;
-      no_data   = context->gimp->no_data;
       break;
 
     case GIMP_CONTEXT_PROP_PATTERN:
       container = gimp_data_factory_get_container (context->gimp->pattern_factory);
-      current   = (GimpObject *) context->pattern;
+      standard  = gimp_pattern_get_standard (context);
       name_loc  = &context->pattern_name;
-      no_data   = context->gimp->no_data;
       break;
 
     case GIMP_CONTEXT_PROP_GRADIENT:
       container = gimp_data_factory_get_container (context->gimp->gradient_factory);
-      current   = (GimpObject *) context->gradient;
+      standard  = gimp_gradient_get_standard (context);
       name_loc  = &context->gradient_name;
-      no_data   = context->gimp->no_data;
       break;
 
     case GIMP_CONTEXT_PROP_PALETTE:
       container = gimp_data_factory_get_container (context->gimp->palette_factory);
-      current   = (GimpObject *) context->palette;
+      standard  = gimp_palette_get_standard (context);
       name_loc  = &context->palette_name;
-      no_data   = context->gimp->no_data;
       break;
 
     case GIMP_CONTEXT_PROP_FONT:
       container = gimp_data_factory_get_container (context->gimp->font_factory);
-      current   = (GimpObject *) context->font;
+      standard  = gimp_font_get_standard ();
       name_loc  = &context->font_name;
-      no_data   = context->gimp->no_fonts;
       break;
 
     case GIMP_CONTEXT_PROP_TOOL_PRESET:
       container = gimp_data_factory_get_container (context->gimp->tool_preset_factory);
-      current   = (GimpObject *) context->tool_preset;
+      standard  = NULL;
       name_loc  = &context->tool_preset_name;
-      no_data   = context->gimp->no_data;
       break;
 
     default:
@@ -1386,18 +1392,15 @@ gimp_context_deserialize_property (GimpConfig *object,
 
       if (! deserialize_obj)
         {
-          if (no_data)
-            {
-              g_free (*name_loc);
-              *name_loc = g_strdup (object_name);
-            }
-          else
-            {
-              deserialize_obj = current;
-            }
-        }
+          g_value_set_object (value, standard);
 
-      g_value_set_object (value, deserialize_obj);
+          g_free (*name_loc);
+          *name_loc = g_strdup (object_name);
+        }
+      else
+        {
+          g_value_set_object (value, deserialize_obj);
+        }
 
       g_free (object_name);
     }
@@ -1409,6 +1412,57 @@ gimp_context_deserialize_property (GimpConfig *object,
   return TRUE;
 }
 
+static GimpConfig *
+gimp_context_duplicate (GimpConfig *config)
+{
+  GimpContext *context = GIMP_CONTEXT (config);
+  GimpContext *new;
+
+  new = GIMP_CONTEXT (parent_config_iface->duplicate (config));
+
+  COPY_NAME (context, new, tool_name);
+  COPY_NAME (context, new, paint_name);
+  COPY_NAME (context, new, brush_name);
+  COPY_NAME (context, new, dynamics_name);
+  COPY_NAME (context, new, mybrush_name);
+  COPY_NAME (context, new, pattern_name);
+  COPY_NAME (context, new, gradient_name);
+  COPY_NAME (context, new, palette_name);
+  COPY_NAME (context, new, font_name);
+  COPY_NAME (context, new, tool_preset_name);
+  COPY_NAME (context, new, buffer_name);
+  COPY_NAME (context, new, imagefile_name);
+  COPY_NAME (context, new, template_name);
+
+  return GIMP_CONFIG (new);
+}
+
+static gboolean
+gimp_context_copy (GimpConfig  *src,
+                   GimpConfig  *dest,
+                   GParamFlags  flags)
+{
+  GimpContext *src_context  = GIMP_CONTEXT (src);
+  GimpContext *dest_context = GIMP_CONTEXT (dest);
+  gboolean     success      = parent_config_iface->copy (src, dest, flags);
+
+  COPY_NAME (src_context, dest_context, tool_name);
+  COPY_NAME (src_context, dest_context, paint_name);
+  COPY_NAME (src_context, dest_context, brush_name);
+  COPY_NAME (src_context, dest_context, dynamics_name);
+  COPY_NAME (src_context, dest_context, mybrush_name);
+  COPY_NAME (src_context, dest_context, pattern_name);
+  COPY_NAME (src_context, dest_context, gradient_name);
+  COPY_NAME (src_context, dest_context, palette_name);
+  COPY_NAME (src_context, dest_context, font_name);
+  COPY_NAME (src_context, dest_context, tool_preset_name);
+  COPY_NAME (src_context, dest_context, buffer_name);
+  COPY_NAME (src_context, dest_context, imagefile_name);
+  COPY_NAME (src_context, dest_context, template_name);
+
+  return success;
+}
+
 
 /*****************************************************************************/
 /*  public functions  ********************************************************/
@@ -1597,11 +1651,6 @@ gimp_context_copy_property (GimpContext         *src,
                             GimpContext         *dest,
                             GimpContextPropType  prop)
 {
-  gpointer   object          = NULL;
-  gpointer   standard_object = NULL;
-  gchar     *src_name        = NULL;
-  gchar    **dest_name_loc   = NULL;
-
   g_return_if_fail (GIMP_IS_CONTEXT (src));
   g_return_if_fail (GIMP_IS_CONTEXT (dest));
   g_return_if_fail ((prop >= GIMP_CONTEXT_PROP_FIRST) &&
@@ -1619,18 +1668,12 @@ gimp_context_copy_property (GimpContext         *src,
 
     case GIMP_CONTEXT_PROP_TOOL:
       gimp_context_real_set_tool (dest, src->tool_info);
-      object          = src->tool_info;
-      standard_object = gimp_tool_info_get_standard (src->gimp);
-      src_name        = src->tool_name;
-      dest_name_loc   = &dest->tool_name;
+      COPY_NAME (src, dest, tool_name);
       break;
 
     case GIMP_CONTEXT_PROP_PAINT_INFO:
       gimp_context_real_set_paint_info (dest, src->paint_info);
-      object          = src->paint_info;
-      standard_object = gimp_paint_info_get_standard (src->gimp);
-      src_name        = src->paint_name;
-      dest_name_loc   = &dest->paint_name;
+      COPY_NAME (src, dest, paint_name);
       break;
 
     case GIMP_CONTEXT_PROP_FOREGROUND:
@@ -1651,91 +1694,62 @@ gimp_context_copy_property (GimpContext         *src,
 
     case GIMP_CONTEXT_PROP_BRUSH:
       gimp_context_real_set_brush (dest, src->brush);
-      object          = src->brush;
-      standard_object = gimp_brush_get_standard (src);
-      src_name        = src->brush_name;
-      dest_name_loc   = &dest->brush_name;
+      COPY_NAME (src, dest, brush_name);
       break;
 
     case GIMP_CONTEXT_PROP_DYNAMICS:
       gimp_context_real_set_dynamics (dest, src->dynamics);
-      object          = src->dynamics;
-      standard_object = gimp_dynamics_get_standard (src);
-      src_name        = src->dynamics_name;
-      dest_name_loc   = &dest->dynamics_name;
+      COPY_NAME (src, dest, dynamics_name);
       break;
 
     case GIMP_CONTEXT_PROP_MYBRUSH:
       gimp_context_real_set_mybrush (dest, src->mybrush);
-      object          = src->mybrush;
-      standard_object = gimp_mybrush_get_standard (src);
-      src_name        = src->mybrush_name;
-      dest_name_loc   = &dest->mybrush_name;
+      COPY_NAME (src, dest, mybrush_name);
       break;
 
     case GIMP_CONTEXT_PROP_PATTERN:
       gimp_context_real_set_pattern (dest, src->pattern);
-      object          = src->pattern;
-      standard_object = gimp_pattern_get_standard (src);
-      src_name        = src->pattern_name;
-      dest_name_loc   = &dest->pattern_name;
+      COPY_NAME (src, dest, pattern_name);
       break;
 
     case GIMP_CONTEXT_PROP_GRADIENT:
       gimp_context_real_set_gradient (dest, src->gradient);
-      object          = src->gradient;
-      standard_object = gimp_gradient_get_standard (src);
-      src_name        = src->gradient_name;
-      dest_name_loc   = &dest->gradient_name;
+      COPY_NAME (src, dest, gradient_name);
       break;
 
     case GIMP_CONTEXT_PROP_PALETTE:
       gimp_context_real_set_palette (dest, src->palette);
-      object          = src->palette;
-      standard_object = gimp_palette_get_standard (src);
-      src_name        = src->palette_name;
-      dest_name_loc   = &dest->palette_name;
+      COPY_NAME (src, dest, palette_name);
       break;
 
     case GIMP_CONTEXT_PROP_FONT:
       gimp_context_real_set_font (dest, src->font);
-      object          = src->font;
-      standard_object = gimp_font_get_standard ();
-      src_name        = src->font_name;
-      dest_name_loc   = &dest->font_name;
+      COPY_NAME (src, dest, font_name);
       break;
 
     case GIMP_CONTEXT_PROP_TOOL_PRESET:
       gimp_context_real_set_tool_preset (dest, src->tool_preset);
-      object          = src->tool_preset;
-      src_name        = src->tool_preset_name;
-      dest_name_loc   = &dest->tool_preset_name;
+      COPY_NAME (src, dest, tool_preset_name);
       break;
 
     case GIMP_CONTEXT_PROP_BUFFER:
       gimp_context_real_set_buffer (dest, src->buffer);
+      COPY_NAME (src, dest, buffer_name);
       break;
 
     case GIMP_CONTEXT_PROP_IMAGEFILE:
       gimp_context_real_set_imagefile (dest, src->imagefile);
+      COPY_NAME (src, dest, imagefile_name);
       break;
 
     case GIMP_CONTEXT_PROP_TEMPLATE:
       gimp_context_real_set_template (dest, src->template);
+      COPY_NAME (src, dest, template_name);
       break;
 
     default:
       break;
     }
-
-  if (src_name && dest_name_loc)
-    {
-      if (! object || (standard_object && object == standard_object))
-        {
-          g_free (*dest_name_loc);
-          *dest_name_loc = g_strdup (src_name);
-        }
-    }
 }
 
 void
@@ -1753,6 +1767,7 @@ gimp_context_copy_properties (GimpContext         *src,
       gimp_context_copy_property (src, dest, prop);
 }
 
+
 /*  attribute access functions  */
 
 /*****************************************************************************/
@@ -1884,6 +1899,7 @@ gimp_context_changed_by_type (GimpContext *context,
                  object);
 }
 
+
 /*****************************************************************************/
 /*  image  *******************************************************************/
 
@@ -2417,6 +2433,7 @@ gimp_context_swap_colors (GimpContext *context)
   gimp_context_real_set_background (bg_context, &fg);
 }
 
+
 /*****************************************************************************/
 /*  opacity  *****************************************************************/
 


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