[pango/text-transform-2: 1/4] Add a utility for text transforms




commit 7ddc97528daddd4d41552a6fee2a762bf201cb96
Author: Matthias Clasen <mclasen redhat com>
Date:   Sat Jul 13 23:21:59 2019 -0400

    Add a utility for text transforms
    
    This is related to Pango's text segmentation
    functionality, and thus makes sense to provide
    as part of Pango.

 pango/pango-utils.c | 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 pango/pango-utils.h |  28 +++++++++++++
 2 files changed, 142 insertions(+)
---
diff --git a/pango/pango-utils.c b/pango/pango-utils.c
index 894935e7..dc95b73f 100644
--- a/pango/pango-utils.c
+++ b/pango/pango-utils.c
@@ -1154,3 +1154,117 @@ _pango_shape_get_extents (gint              n_chars,
     }
 }
 
+/**
+ * pango_transform_text:
+ * @text: the text to transform
+ * @len: the length of @text in bytes, or -1 if NUL-terminated
+ * @attrs: (nullable): a `PangoAttrList` for @text
+ * @transform: the transformation to apply
+ * @language: (nullable): the language to use for segmentation,
+ *     or `NULL` to use the current locale
+ * @transformed_text: (out): return location for the transformed @text
+ * @transformed_attrs: (out): return location for transformed @attrs
+ *
+ * Apply a text transformation (such as capitalizing words)
+ * to @text.
+ *
+ * Text transformations can change the length of
+ * the text, therefore attributes that apply to the text
+ * need to be updated as well, which is why this function
+ * takes @attrs as an argument as well.
+ */
+void
+pango_transform_text (const char          *text,
+                      int                  len,
+                      PangoAttrList       *attrs,
+                      PangoTextTransform   transform,
+                      PangoLanguage       *language,
+                      char               **transformed_text,
+                      PangoAttrList      **transformed_attrs)
+{
+  int n_chars;
+  PangoLogAttr *log_attrs;
+  GString *str;
+  int i;
+  const char *p;
+
+  if (len == -1)
+    len = strlen (text);
+
+  if (language == NULL)
+    language = pango_language_get_default ();
+
+  if (attrs)
+    *transformed_attrs = pango_attr_list_copy (attrs);
+  else
+    *transformed_attrs = NULL;
+
+  n_chars = g_utf8_strlen (text, len);
+  log_attrs = g_new (PangoLogAttr, n_chars + 1);
+  pango_get_log_attrs (text, len, -1, language, log_attrs, n_chars + 1);
+
+  str = g_string_sized_new (len);
+  for (i = 0, p = text; i < n_chars; i++, p = g_utf8_next_char (p))
+    {
+      if (log_attrs[i].is_word_start)
+        {
+          /* collect a word, and transform it */
+          const char *w;
+          char *wt;
+          int added;
+
+          w = p;
+          do
+            {
+              i++;
+              p = g_utf8_next_char (p);
+            }
+          while (i < n_chars && !log_attrs[i].is_word_end);
+
+          switch (transform)
+            {
+            case PANGO_TEXT_TRANSFORM_NONE:
+              g_string_append_len (str, w, p - w);
+              added = p - w;
+              break;
+
+            case PANGO_TEXT_TRANSFORM_UPPERCASE:
+              wt = g_utf8_strup (w, p - w);
+              g_string_append (str, wt);
+              added = strlen (wt);
+              g_free (wt);
+              break;
+
+            case PANGO_TEXT_TRANSFORM_LOWERCASE:
+              wt = g_utf8_strdown (w, p - w);
+              g_string_append (str, wt);
+              added = strlen (wt);
+              g_free (wt);
+              break;
+
+            case PANGO_TEXT_TRANSFORM_CAPITALIZE:
+              {
+                char *ct;
+                char *n = g_utf8_next_char (w);
+                ct = g_utf8_strup (w, n - w);
+                g_string_append (str, ct);
+                g_string_append_len (str, n, p - n);
+                added = strlen (ct) + (p - n);
+                g_free (ct);
+              }
+              break;
+            default:
+              g_assert_not_reached ();
+            }
+
+          if (*transformed_attrs && added != p - w)
+            pango_attr_list_update (*transformed_attrs, w - text, p - w, added);
+        }
+
+      g_string_append_unichar (str, g_utf8_get_char (p));
+    }
+
+  *transformed_text = g_string_free (str, FALSE);
+
+  g_free (log_attrs);
+}
diff --git a/pango/pango-utils.h b/pango/pango-utils.h
index 04452eb4..7108c2bd 100644
--- a/pango/pango-utils.h
+++ b/pango/pango-utils.h
@@ -25,6 +25,7 @@
 #include <stdio.h>
 #include <glib.h>
 #include <pango/pango-font.h>
+#include <pango/pango-attributes.h>
 
 G_BEGIN_DECLS
 
@@ -99,6 +100,33 @@ guint8 * pango_log2vis_get_embedding_levels (const gchar    *text,
 PANGO_AVAILABLE_IN_1_10
 gboolean pango_is_zero_width (gunichar ch) G_GNUC_CONST;
 
+/**
+ * PangoTextTransform:
+ * @PANGO_TEXT_TRANSFORM_NONE: No change
+ * @PANGO_TEXT_TRANSFORM_UPPERCASE: Change each word to uppercase
+ * @PANGO_TEXT_TRANSFORM_LOWERCASE: Change each word to lowercase
+ * @PANGO_TEXT_TRANSFORM_CAPITALIZE: Capitalize the first character
+ *     of every word
+ *
+ * Specifies a text transformation that can
+ * be applied to a text with pango_transform_text().
+ */
+typedef enum {
+  PANGO_TEXT_TRANSFORM_NONE,
+  PANGO_TEXT_TRANSFORM_UPPERCASE,
+  PANGO_TEXT_TRANSFORM_LOWERCASE,
+  PANGO_TEXT_TRANSFORM_CAPITALIZE
+} PangoTextTransform;
+
+PANGO_AVAILABLE_IN_1_44
+void pango_transform_text (const char          *text,
+                           int                  len,
+                           PangoAttrList       *attrs,
+                           PangoTextTransform   transform,
+                           PangoLanguage       *language,
+                           char               **transformed_text,
+                           PangoAttrList      **transformed_attrs);
+
 /* Pango version checking */
 
 /* Encode a Pango version as an integer */


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