From b892330253904191c47e5319b0ffdc705961b609 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Sun, 14 Nov 2021 00:12:34 -0500 Subject: Add pango_tab_array_to/from_string --- pango/pango-tabs.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++ pango/pango-tabs.h | 4 ++ tests/testserialize.c | 48 ++++++++++++++++++++++++ 3 files changed, 154 insertions(+) diff --git a/pango/pango-tabs.c b/pango/pango-tabs.c index 28027454..c126ec91 100644 --- a/pango/pango-tabs.c +++ b/pango/pango-tabs.c @@ -371,3 +371,105 @@ pango_tab_array_get_positions_in_pixels (PangoTabArray *tab_array) return tab_array->positions_in_pixels; } + +/** + * pango_tab_array_to_string: + * @tab_array: a `PangoTabArray` + * + * Serializes a `PangoTabArray` to a string. + * + * No guarantees are made about the format of the string, + * it may change between Pango versions. + * + * The intended use of this function is testing and + * debugging. The format is not meant as a permanent + * storage format. + * + * Returns: (transfer full): a newly allocated string + * Since: 1.50 + */ +char * +pango_tab_array_to_string (PangoTabArray *tab_array) +{ + GString *s; + + s = g_string_new (""); + + for (int i = 0; i < tab_array->size; i++) + { + if (i > 0) + g_string_append_c (s, ' '); + g_string_append_printf (s, "%d", tab_array->tabs[i].location); + if (tab_array->positions_in_pixels) + g_string_append (s, "px"); + } + + return g_string_free (s, FALSE); +} + +static const char * +skip_whitespace (const char *p) +{ + while (g_ascii_isspace (*p)) + p++; + return p; +} + +/** + * pango_tab_array_from_string: + * @text: a string + * + * Deserializes a `PangoTabArray` from a string. + * + * This is the counterpart to [func@Pango.TabArray.to_string]. + * See that functions for details about the format. + * + * Returns: (transfer full) (nullable): a new `PangoTabArray` + * Since: 1.50 + */ +PangoTabArray * +pango_tab_array_from_string (const char *text) +{ + PangoTabArray *array; + gboolean pixels; + const char *p; + int i; + + pixels = strstr (text, "px") != NULL; + + array = pango_tab_array_new (0, pixels); + + p = skip_whitespace (text); + + i = 0; + while (*p) + { + char *endp; + gint64 pos; + + pos = g_ascii_strtoll (p, &endp, 10); + if (pos < 0 || + (pixels && *endp != 'p') || + (!pixels && !g_ascii_isspace (*endp) && *endp != '\0')) goto fail; + + pango_tab_array_set_tab (array, i, PANGO_TAB_LEFT, pos); + i++; + + p = (const char *)endp; + if (pixels) + { + if (p[0] != 'p' || p[1] != 'x') goto fail; + p += 2; + } + p = skip_whitespace (p); + } + + goto success; + +fail: + pango_tab_array_free (array); + array = NULL; + +success: + return array; +} diff --git a/pango/pango-tabs.h b/pango/pango-tabs.h index 893132ed..e8ce1b97 100644 --- a/pango/pango-tabs.h +++ b/pango/pango-tabs.h @@ -87,6 +87,10 @@ void pango_tab_array_get_tabs (PangoTabArray *tab_array, PANGO_AVAILABLE_IN_ALL gboolean pango_tab_array_get_positions_in_pixels (PangoTabArray *tab_array); +PANGO_AVAILABLE_IN_1_50 +char * pango_tab_array_to_string (PangoTabArray *tab_array); +PANGO_AVAILABLE_IN_1_50 +PangoTabArray * pango_tab_array_from_string (const char *text); G_END_DECLS diff --git a/tests/testserialize.c b/tests/testserialize.c index cb5b27fd..cc6c67bc 100644 --- a/tests/testserialize.c +++ b/tests/testserialize.c @@ -75,12 +75,60 @@ test_serialize_attr_list (void) } } +static void +test_serialize_tab_array (void) +{ + const char *valid[] = { + "0 10 100 200 400", + "0px 10px 100px 200px 400px", + " 0 10 ", + "20 10", + "" + }; + const char *roundtripped[] = { + "0 10 100 200 400", + "0px 10px 100px 200px 400px", + "0 10", + "20 10", + "" + }; + const char *invalid[] = { + "not a tabarray", + "-10\n-20", + "10ps 20pu", + "10, 20", + "10 20px 30", + }; + + for (int i = 0; i < G_N_ELEMENTS (valid); i++) + { + PangoTabArray *tabs; + char *str; + + tabs = pango_tab_array_from_string (valid[i]); + g_assert_nonnull (tabs); + str = pango_tab_array_to_string (tabs); + g_assert_cmpstr (str, ==, roundtripped[i]); + g_free (str); + pango_tab_array_free (tabs); + } + + for (int i = 0; i < G_N_ELEMENTS (invalid); i++) + { + PangoTabArray *tabs; + + tabs = pango_tab_array_from_string (invalid[i]); + g_assert_null (tabs); + } +} + int main (int argc, char *argv[]) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/serialize/attr-list", test_serialize_attr_list); + g_test_add_func ("/serialize/tab-array", test_serialize_tab_array); return g_test_run (); } -- cgit v1.2.1