summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2019-07-14 00:27:51 -0400
committerMatthias Clasen <mclasen@redhat.com>2019-07-14 00:35:05 -0400
commit33304e0da01f4a7793ef84276622833169d211e5 (patch)
treea0cd3e9f7b780c419a00545721dc520bc98ed2e6
parent96276466a0d12c3222bbba8425b4c3c0036678e9 (diff)
downloadpango-33304e0da01f4a7793ef84276622833169d211e5.tar.gz
layout: Add a text transform
-rw-r--r--pango/pango-layout-private.h8
-rw-r--r--pango/pango-layout.c86
-rw-r--r--pango/pango-layout.h5
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);