[gimp] app: if there is no "text", generate the layer name from "markup"



commit e9abde75eecef2b5545f53bdda0719a0c7fae4f4
Author: Michael Natterer <mitch gimp org>
Date:   Tue Mar 2 21:19:57 2010 +0100

    app: if there is no "text", generate the layer name from "markup"
    
    Add gimp_markup_extract_text() which does just what it says (includes
    code stolen from gmarkup.c), and use it if the layer's text object
    doesn't have any text set.

 app/core/gimp-utils.c    |  157 ++++++++++++++++++++++++++++++++++++++++++++++
 app/core/gimp-utils.h    |    3 +
 app/text/gimptextlayer.c |   32 +++++++---
 3 files changed, 184 insertions(+), 8 deletions(-)
---
diff --git a/app/core/gimp-utils.c b/app/core/gimp-utils.c
index 9fe4a4a..a9d1189 100644
--- a/app/core/gimp-utils.c
+++ b/app/core/gimp-utils.c
@@ -17,6 +17,7 @@
 
 #include "config.h"
 
+#include <errno.h>
 #include <stdlib.h>
 #include <string.h>
 #include <locale.h>
@@ -528,6 +529,162 @@ gimp_container_get_neighbor_of_active (GimpContainer *container,
   return NULL;
 }
 
+/*  markup unescape code stolen and adapted from gmarkup.c
+ */
+static gchar *
+char_str (gunichar c,
+          gchar   *buf)
+{
+  memset (buf, 0, 8);
+  g_unichar_to_utf8 (c, buf);
+  return buf;
+}
+
+static gboolean
+unescape_gstring (GString *string)
+{
+  const gchar *from;
+  gchar       *to;
+
+  /*
+   * Meeks' theorum: unescaping can only shrink text.
+   * for &lt; etc. this is obvious, for &#xffff; more
+   * thought is required, but this is patently so.
+   */
+  for (from = to = string->str; *from != '\0'; from++, to++)
+    {
+      *to = *from;
+
+      if (*to == '\r')
+        {
+          *to = '\n';
+          if (from[1] == '\n')
+            from++;
+        }
+      if (*from == '&')
+        {
+          from++;
+          if (*from == '#')
+            {
+              gboolean is_hex = FALSE;
+              gulong   l;
+              gchar   *end = NULL;
+
+              from++;
+
+              if (*from == 'x')
+                {
+                  is_hex = TRUE;
+                  from++;
+                }
+
+              /* digit is between start and p */
+              errno = 0;
+              if (is_hex)
+                l = strtoul (from, &end, 16);
+              else
+                l = strtoul (from, &end, 10);
+
+              if (end == from || errno != 0)
+                {
+                  return FALSE;
+                }
+              else if (*end != ';')
+                {
+                  return FALSE;
+                }
+              else
+                {
+                  /* characters XML 1.1 permits */
+                  if ((0 < l && l <= 0xD7FF) ||
+                      (0xE000 <= l && l <= 0xFFFD) ||
+                      (0x10000 <= l && l <= 0x10FFFF))
+                    {
+                      gchar buf[8];
+                      char_str (l, buf);
+                      strcpy (to, buf);
+                      to += strlen (buf) - 1;
+                      from = end;
+                    }
+                  else
+                    {
+                      return FALSE;
+                    }
+                }
+            }
+
+          else if (strncmp (from, "lt;", 3) == 0)
+            {
+              *to = '<';
+              from += 2;
+            }
+          else if (strncmp (from, "gt;", 3) == 0)
+            {
+              *to = '>';
+              from += 2;
+            }
+          else if (strncmp (from, "amp;", 4) == 0)
+            {
+              *to = '&';
+              from += 3;
+            }
+          else if (strncmp (from, "quot;", 5) == 0)
+            {
+              *to = '"';
+              from += 4;
+            }
+          else if (strncmp (from, "apos;", 5) == 0)
+            {
+              *to = '\'';
+              from += 4;
+            }
+          else
+            {
+              return FALSE;
+            }
+        }
+    }
+
+  g_assert (to - string->str <= string->len);
+  if (to - string->str != string->len)
+    g_string_truncate (string, to - string->str);
+
+  return TRUE;
+}
+
+gchar *
+gimp_markup_extract_text (const gchar *markup)
+{
+  GString     *string;
+  const gchar *p;
+  gboolean     in_tag = FALSE;
+
+  if (! markup)
+    return NULL;
+
+  string = g_string_new (NULL);
+
+  for (p = markup; *p; p++)
+    {
+      if (in_tag)
+        {
+          if (*p == '>')
+            in_tag = FALSE;
+        }
+      else
+        {
+          if (*p == '<')
+            in_tag = TRUE;
+          else
+            g_string_append_c (string, *p);
+        }
+    }
+
+  unescape_gstring (string);
+
+  return g_string_free (string, FALSE);
+}
+
 /**
  * gimp_utils_point_to_line_distance:
  * @point:              The point to calculate the distance for.
diff --git a/app/core/gimp-utils.h b/app/core/gimp-utils.h
index 9ed2254..f916d1e 100644
--- a/app/core/gimp-utils.h
+++ b/app/core/gimp-utils.h
@@ -67,6 +67,9 @@ GimpObject * gimp_container_get_neighbor_of_active (GimpContainer   *container,
                                                     GimpContext     *context,
                                                     GimpObject      *active);
 
+gchar      * gimp_markup_extract_text              (const gchar     *markup);
+
+
 /* Common values for the n_snap_lines parameter of
  * gimp_constrain_line.
  */
diff --git a/app/text/gimptextlayer.c b/app/text/gimptextlayer.c
index e1edb1a..aaaa499 100644
--- a/app/text/gimptextlayer.c
+++ b/app/text/gimptextlayer.c
@@ -36,6 +36,7 @@
 #include "paint-funcs/paint-funcs.h"
 
 #include "core/gimp.h"
+#include "core/gimp-utils.h"
 #include "core/gimpcontext.h"
 #include "core/gimpcontainer.h"
 #include "core/gimpimage.h"
@@ -588,17 +589,32 @@ gimp_text_layer_render (GimpTextLayer *layer)
   if (layer->auto_rename)
     {
       GimpItem *item = GIMP_ITEM (layer);
-      gchar    *name = (layer->text->text ?
-                        gimp_utf8_strtrim (layer->text->text, 30) :
-                        g_strdup (_("Empty Text Layer")));
+      gchar    *name = NULL;
+
+      if (layer->text->text)
+        {
+          name = gimp_utf8_strtrim (layer->text->text, 30);
+        }
+      else if (layer->text->markup)
+        {
+          gchar *tmp = gimp_markup_extract_text (layer->text->markup);
+          name = gimp_utf8_strtrim (tmp, 30);
+          g_free (tmp);
+        }
+
+      if (! name)
+        name = g_strdup (_("Empty Text Layer"));
 
       if (gimp_item_is_attached (item))
-        gimp_item_tree_rename_item (gimp_item_get_tree (item), item,
-                                    name, FALSE, NULL);
+        {
+          gimp_item_tree_rename_item (gimp_item_get_tree (item), item,
+                                      name, FALSE, NULL);
+          g_free (name);
+        }
       else
-        gimp_object_set_name (GIMP_OBJECT (layer), name);
-
-      g_free (name);
+        {
+          gimp_object_take_name (GIMP_OBJECT (layer), name);
+        }
     }
 
   gimp_text_layer_render_layout (layer, layout);



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