summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2019-07-14 00:27:51 -0400
committerMatthias Clasen <mclasen@redhat.com>2021-08-19 13:01:17 -0400
commitaa44907f6da25fb5538c6e918604f1e8f8e35e33 (patch)
tree9c1205d63d594c43d81ffee3fe222fec3719fac1
parentdb4410bf91885eace600ed9290ca324f6d1e82bf (diff)
downloadpango-aa44907f6da25fb5538c6e918604f1e8f8e35e33.tar.gz
layout: Add a text transform
-rw-r--r--pango/pango-layout-private.h8
-rw-r--r--pango/pango-layout.c109
-rw-r--r--pango/pango-layout.h5
3 files changed, 83 insertions, 39 deletions
diff --git a/pango/pango-layout-private.h b/pango/pango-layout-private.h
index 1805e730..563f63f2 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 ee58243b..224658e4 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -254,6 +254,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)
@@ -684,6 +690,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`
@@ -697,31 +705,22 @@ void
pango_layout_set_attributes (PangoLayout *layout,
PangoAttrList *attrs)
{
- PangoAttrList *old_attrs;
-
g_return_if_fail (layout != NULL);
- /* Both empty */
- if (!attrs && !layout->attrs)
+ if (!attrs && !layout->orig_attrs)
return;
- if (layout->attrs &&
- pango_attr_list_equal (layout->attrs, attrs))
+ if (attrs && layout->orig_attrs &&
+ pango_attr_list_equal (attrs, layout->orig_attrs))
return;
- old_attrs = layout->attrs;
+ g_clear_pointer (&layout->orig_attrs, pango_attr_list_unref);
+ layout->orig_attrs = pango_attr_list_ref (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);
+ apply_text_transform (layout);
layout_changed (layout);
- if (old_attrs)
- pango_attr_list_unref (old_attrs);
layout->tab_width = -1;
}
@@ -738,7 +737,7 @@ pango_layout_get_attributes (PangoLayout *layout)
{
g_return_val_if_fail (PANGO_IS_LAYOUT (layout), NULL);
- return layout->attrs;
+ return layout->orig_attrs;
}
/**
@@ -1222,28 +1221,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->length = strlen (text);
- layout->text = g_strndup (text, layout->length);
- }
+ layout->orig_text = g_strdup (text);
else if (length > 0)
- {
- /* This is not exactly what we want. We don't need the padding...
- */
- layout->length = length;
- layout->text = g_strndup (text, length);
- }
+ /* This is not exactly what we want. We don't need the padding...
+ */
+ layout->orig_text = g_strndup (text, length);
else
- {
- layout->length = 0;
- layout->text = g_malloc0 (1);
- }
+ layout->orig_text = g_malloc0 (1);
/* validate it, and replace invalid bytes with -1 */
- start = layout->text;
+ start = layout->orig_text;
for (;;) {
gboolean valid;
@@ -1263,15 +1255,17 @@ 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->length = strlen (layout->text);
+ layout->n_chars = pango_utf8_strlen (layout->orig_text, -1);
+ layout->length = strlen (layout->orig_text);
layout_changed (layout);
+ apply_text_transform (layout);
+
g_free (old_text);
}
@@ -1292,10 +1286,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;
}
/**
@@ -7257,3 +7251,44 @@ 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;
+ 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 9436dbcb..2ded20bc 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
@@ -182,6 +183,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);