[pango/text-transform] layout: Add a text transform



commit 33304e0da01f4a7793ef84276622833169d211e5
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Jul 14 00:27:51 2019 -0400

    layout: Add a text transform

 pango/pango-layout-private.h |  8 +++--
 pango/pango-layout.c         | 86 ++++++++++++++++++++++++++++++++++----------
 pango/pango-layout.h         |  5 +++
 3 files changed, 78 insertions(+), 21 deletions(-)
---
diff --git a/pango/pango-layout-private.h b/pango/pango-layout-private.h
index 38e2e196..45147636 100644
--- a/pango/pango-layout-private.h
+++ b/pango/pango-layout-private.h
@@ -36,12 +36,16 @@ struct _PangoLayout
 
   /* Referenced items */
   PangoContext *context;
-  PangoAttrList *attrs;
+  PangoAttrList *attrs; /* may be transformed */
   PangoFontDescription *font_desc;
   PangoTabArray *tabs;
 
   /* Dupped */
-  gchar *text;
+  char *text; /* may be transformed */
+
+  char *orig_text;
+  PangoAttrList *orig_attrs;
+  PangoTextTransform transform;
 
   /* Value fields.  These will be memcpy'd in _copy() */
   int copy_begin;
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 4660b069..b1bf7f27 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -233,6 +233,12 @@ pango_layout_finalize (GObject *object)
   if (layout->attrs)
     pango_attr_list_unref (layout->attrs);
 
+  if (layout->orig_attrs)
+    pango_attr_list_unref (layout->orig_attrs);
+
+  if (layout->orig_text != layout->text)
+    g_free (layout->orig_text);
+
   g_free (layout->text);
 
   if (layout->font_desc)
@@ -651,6 +657,8 @@ pango_layout_get_line_spacing (PangoLayout *layout)
   return layout->line_spacing;
 }
 
+static void apply_text_transform (PangoLayout *layout);
+
 /**
  * pango_layout_set_attributes:
  * @layout: a #PangoLayout
@@ -666,17 +674,17 @@ pango_layout_set_attributes (PangoLayout   *layout,
   PangoAttrList *old_attrs;
   g_return_if_fail (layout != NULL);
 
-  old_attrs = layout->attrs;
+  old_attrs = layout->orig_attrs;
 
   /* We always clear lines such that this function can be called
    * whenever attrs changes.
    */
 
-  layout->attrs = attrs;
-  if (layout->attrs)
-    pango_attr_list_ref (layout->attrs);
+  layout->orig_attrs = attrs;
+  if (layout->orig_attrs)
+    pango_attr_list_ref (layout->orig_attrs);
 
-  layout_changed (layout);
+  apply_text_transform (layout);
 
   if (old_attrs)
     pango_attr_list_unref (old_attrs);
@@ -696,7 +704,7 @@ pango_layout_get_attributes (PangoLayout *layout)
 {
   g_return_val_if_fail (PANGO_IS_LAYOUT (layout), NULL);
 
-  return layout->attrs;
+  return layout->orig_attrs;
 }
 
 /**
@@ -1099,21 +1107,21 @@ pango_layout_set_text (PangoLayout *layout,
   g_return_if_fail (layout != NULL);
   g_return_if_fail (length == 0 || text != NULL);
 
-  old_text = layout->text;
+  old_text = layout->orig_text;
+  if (layout->text == layout->orig_text)
+    layout->text = NULL;
 
   if (length < 0)
-    layout->text = g_strdup (text);
+    layout->orig_text = g_strdup (text);
   else if (length > 0)
     /* This is not exactly what we want.  We don't need the padding...
      */
-    layout->text = g_strndup (text, length);
+    layout->orig_text = g_strndup (text, length);
   else
-    layout->text = g_malloc0 (1);
-
-  layout->length = strlen (layout->text);
+    layout->orig_text = g_malloc0 (1);
 
   /* validate it, and replace invalid bytes with -1 */
-  start = layout->text;
+  start = layout->orig_text;
   for (;;) {
     gboolean valid;
 
@@ -1133,13 +1141,11 @@ pango_layout_set_text (PangoLayout *layout,
     start = end;
   }
 
-  if (start != layout->text)
+  if (start != layout->orig_text)
     /* TODO: Write out the beginning excerpt of text? */
     g_warning ("Invalid UTF-8 string passed to pango_layout_set_text()");
 
-  layout->n_chars = pango_utf8_strlen (layout->text, -1);
-
-  layout_changed (layout);
+  apply_text_transform (layout);
 
   g_free (old_text);
 }
@@ -1160,10 +1166,10 @@ pango_layout_get_text (PangoLayout *layout)
 
   /* We don't ever want to return NULL as the text.
    */
-  if (G_UNLIKELY (!layout->text))
+  if (G_UNLIKELY (!layout->orig_text))
     return "";
 
-  return layout->text;
+  return layout->orig_text;
 }
 
 /**
@@ -6791,3 +6797,45 @@ pango_layout_iter_get_layout_extents  (PangoLayoutIter *iter,
 
   pango_layout_get_extents (iter->layout, ink_rect, logical_rect);
 }
+
+static void
+apply_text_transform (PangoLayout *layout)
+{
+  if (layout->orig_text == NULL)
+    return;
+
+  if (layout->text != layout->orig_text)
+    g_clear_pointer (&layout->text, g_free);
+  g_clear_pointer (&layout->attrs, pango_attr_list_unref);
+
+  if (layout->transform != PANGO_TEXT_TRANSFORM_NONE)
+    pango_transform_text (layout->orig_text, -1,
+                          layout->orig_attrs,
+                          layout->transform,
+                          NULL,
+                          &layout->text,
+                          &layout->attrs);
+  else
+    {
+      layout->text = layout->orig_text;
+      if (layout->orig_attrs)
+        layout->attrs = pango_attr_list_ref (layout->orig_attrs);
+    }
+
+  layout->length = strlen (layout->text);
+  layout->n_chars = g_utf8_strlen (layout->text, -1);
+
+  layout_changed (layout);
+}
+
+void
+pango_layout_set_text_transform (PangoLayout        *layout,
+                                 PangoTextTransform  transform)
+{
+  if (layout->transform == transform)
+    return;
+
+  layout->transform = transform;
+
+  apply_text_transform (layout);
+}
diff --git a/pango/pango-layout.h b/pango/pango-layout.h
index 0639b1b4..f5bab619 100644
--- a/pango/pango-layout.h
+++ b/pango/pango-layout.h
@@ -26,6 +26,7 @@
 #include <pango/pango-context.h>
 #include <pango/pango-glyph-item.h>
 #include <pango/pango-tabs.h>
+#include <pango/pango-utils.h>
 
 G_BEGIN_DECLS
 
@@ -172,6 +173,10 @@ void           pango_layout_set_markup_with_accel (PangoLayout    *layout,
                                                   gunichar        accel_marker,
                                                   gunichar       *accel_char);
 
+PANGO_AVAILABLE_IN_1_44
+void           pango_layout_set_text_transform   (PangoLayout        *layout,
+                                                  PangoTextTransform  transform);
+
 PANGO_AVAILABLE_IN_ALL
 void           pango_layout_set_font_description (PangoLayout                *layout,
                                                  const PangoFontDescription *desc);


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